diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb9019f2..8e49114b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,6 +19,7 @@ Please understand that we only bundle languages with the monaco editor that have - create `$/src/basic-languages/{myLang}/{myLang}.ts` - create `$/src/basic-languages/{myLang}/{myLang}.test.ts` - edit `$/src/basic-languages/monaco.contribution.ts` and register your new language +- create `$/website/index/samples/sample.{myLang}.txt` ```js import './{myLang}/{myLang}.contribution'; diff --git a/MAINTAINING.md b/MAINTAINING.md index b1922e0e..41b7ebbd 100644 --- a/MAINTAINING.md +++ b/MAINTAINING.md @@ -2,6 +2,8 @@ (For maintainers) +- [Inbox Queue](https://github.com/microsoft/monaco-editor/issues?q=is%3Aissue+is%3Aopen+no%3Aassignee+-label%3Afeature-request+-label%3Aquestion+-label%3Aupstream+-label%3A%22help+wanted%22+-label%3A%22needs+more+info%22+-label%3A%22as-designed%22) + ## Updating TypeScript - change typescript's version in `package.json`. diff --git a/docs/integrate-esm.md b/docs/integrate-esm.md index 44fac11e..d4b11cc9 100644 --- a/docs/integrate-esm.md +++ b/docs/integrate-esm.md @@ -1,7 +1,7 @@ ## Integrating the ESM version of the Monaco Editor - [Webpack](#using-webpack) - - [Option 1: Using the Monaco Editor Loader Plugin](#option-1-using-the-monaco-editor-loader-plugin) + - [Option 1: Using the Monaco Editor WebPack Plugin](#option-1-using-the-monaco-editor-webpack-plugin) - [Option 2: Using plain webpack](#option-2-using-plain-webpack) - [Parcel](#using-parcel) - [Vite](#using-vite) diff --git a/samples/package-lock.json b/samples/package-lock.json index 8f17ae5f..1ba1a4d7 100644 --- a/samples/package-lock.json +++ b/samples/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "license": "MIT", "devDependencies": { - "css-loader": "^6.6.0", + "css-loader": "^5.2.7", "electron": "^17.2.0", "file-loader": "^6.2.0", "glob": "^7.2.0", @@ -1261,29 +1261,31 @@ } }, "node_modules/css-loader": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.6.0.tgz", - "integrity": "sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", + "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", "dev": true, "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.5", + "loader-utils": "^2.0.0", + "postcss": "^8.2.15", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^3.0.0", "semver": "^7.3.5" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^4.27.0 || ^5.0.0" } }, "node_modules/css-select": { @@ -6317,18 +6319,20 @@ } }, "css-loader": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.6.0.tgz", - "integrity": "sha512-FK7H2lisOixPT406s5gZM1S3l8GrfhEBT3ZiL2UX1Ng1XWs0y2GPllz/OTyvbaHe12VgQrIXIzuEGVlbUhodqg==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", + "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", "dev": true, "requires": { "icss-utils": "^5.1.0", - "postcss": "^8.4.5", + "loader-utils": "^2.0.0", + "postcss": "^8.2.15", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^3.0.0", "semver": "^7.3.5" } }, diff --git a/samples/package.json b/samples/package.json index bed37f9c..c971b2f1 100644 --- a/samples/package.json +++ b/samples/package.json @@ -10,7 +10,7 @@ "author": "Microsoft Corporation", "license": "MIT", "devDependencies": { - "css-loader": "^6.6.0", + "css-loader": "^5.2.7", "electron": "^17.2.0", "file-loader": "^6.2.0", "glob": "^7.2.0", diff --git a/src/basic-languages/cypher/cypher.contribution.ts b/src/basic-languages/cypher/cypher.contribution.ts new file mode 100644 index 00000000..e9d06430 --- /dev/null +++ b/src/basic-languages/cypher/cypher.contribution.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { registerLanguage } from '../_.contribution'; + +declare var AMD: any; +declare var require: any; + +registerLanguage({ + id: 'cypher', + extensions: ['.cypher', '.cyp'], + aliases: ['Cypher', 'OpenCypher'], + loader: () => { + if (AMD) { + return new Promise((resolve, reject) => { + require(['vs/basic-languages/cypher/cypher'], resolve, reject); + }); + } else { + return import('./cypher'); + } + } +}); diff --git a/src/basic-languages/cypher/cypher.test.ts b/src/basic-languages/cypher/cypher.test.ts new file mode 100644 index 00000000..51b9daf0 --- /dev/null +++ b/src/basic-languages/cypher/cypher.test.ts @@ -0,0 +1,327 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { testTokenization } from '../test/testRunner'; + +testTokenization('cypher', [ + // Comments + [ + { + line: '// Single line comment', + tokens: [{ startIndex: 0, type: 'comment.cypher' }] + } + ], + [ + { + line: 'MATCH /* comment part */ xyz', + tokens: [ + { startIndex: 0, type: 'keyword.cypher' }, + { startIndex: 5, type: 'white.cypher' }, + { startIndex: 6, type: 'comment.cypher' }, + { startIndex: 24, type: 'white.cypher' }, + { startIndex: 25, type: 'identifier.cypher' } + ] + } + ], + [ + { + line: '/* multi line comment', + tokens: [{ startIndex: 0, type: 'comment.cypher' }] + }, + { + line: 'comment continues MATCH // not done yet', + tokens: [{ startIndex: 0, type: 'comment.cypher' }] + }, + { + line: 'comment ends */ MATCH', + tokens: [ + { startIndex: 0, type: 'comment.cypher' }, + { startIndex: 15, type: 'white.cypher' }, + { startIndex: 16, type: 'keyword.cypher' } + ] + } + ], + + // Numbers: A decimal (integer or float) literal: + [ + { + line: '13', + tokens: [{ startIndex: 0, type: 'number.cypher' }] + } + ], + [ + { + line: '-40000', + tokens: [{ startIndex: 0, type: 'number.cypher' }] + } + ], + [ + { + line: '3.14', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '.314', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '-.314', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '6.022E23', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '-6.022e23', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '12E10', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '12e10', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '12e-10', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + [ + { + line: '12E-10', + tokens: [{ startIndex: 0, type: 'number.float.cypher' }] + } + ], + + // Numbers: A hexadecimal integer literal (starting with 0x) + [ + { + line: '0x13af', + tokens: [{ startIndex: 0, type: 'number.hex.cypher' }] + } + ], + [ + { + line: '0xFC3A9', + tokens: [{ startIndex: 0, type: 'number.hex.cypher' }] + } + ], + [ + { + line: '-0x66eff', + tokens: [{ startIndex: 0, type: 'number.hex.cypher' }] + } + ], + + // Numbers: An octal integer literal (starting with 0) + [ + { + line: '01372', + tokens: [{ startIndex: 0, type: 'number.octal.cypher' }] + } + ], + [ + { + line: '02127', + tokens: [{ startIndex: 0, type: 'number.octal.cypher' }] + } + ], + [ + { + line: '-05671', + tokens: [{ startIndex: 0, type: 'number.octal.cypher' }] + } + ], + + // Strings: A String literal ('', ""), escaped and non-escaped + [ + { + line: '"two \'words\'"', + tokens: [{ startIndex: 0, type: 'string.cypher' }] + } + ], + [ + { + line: '"two \\"words\\""', + tokens: [{ startIndex: 0, type: 'string.cypher' }] + } + ], + [ + { + line: '\'two "words"\'', + tokens: [{ startIndex: 0, type: 'string.cypher' }] + } + ], + [ + { + line: "'two \\'words\\''", + tokens: [{ startIndex: 0, type: 'string.cypher' }] + } + ], + + // Identifiers wrapped with backtick (``) + [ + { + line: '`variable`', + tokens: [{ startIndex: 0, type: 'identifier.escape.cypher' }] + } + ], + [ + { + line: '`A variable with weird stuff in it[]!`', + tokens: [{ startIndex: 0, type: 'identifier.escape.cypher' }] + } + ], + [ + { + line: '`Escaped \\`variable\\``', + tokens: [{ startIndex: 0, type: 'identifier.escape.cypher' }] + } + ], + + // Operators + [ + { + line: '1+2', + tokens: [ + { startIndex: 0, type: 'number.cypher' }, + { startIndex: 1, type: 'delimiter.cypher' }, + { startIndex: 2, type: 'number.cypher' } + ] + } + ], + [ + { + line: '1++2', + tokens: [ + { startIndex: 0, type: 'number.cypher' }, + { startIndex: 1, type: '' }, + { startIndex: 3, type: 'number.cypher' } + ] + } + ], + + // Builtin literals: A boolean literal (true | false) + [ + { + line: 'true', + tokens: [{ startIndex: 0, type: 'predefined.literal.cypher' }] + } + ], + [ + { + line: 'false', + tokens: [{ startIndex: 0, type: 'predefined.literal.cypher' }] + } + ], + [ + { + line: 'TRUE', + tokens: [{ startIndex: 0, type: 'predefined.literal.cypher' }] + } + ], + [ + { + line: 'FALSE', + tokens: [{ startIndex: 0, type: 'predefined.literal.cypher' }] + } + ], + + // Builtin literals: A null literal + [ + { + line: 'null', + tokens: [{ startIndex: 0, type: 'predefined.literal.cypher' }] + } + ], + [ + { + line: 'NULL', + tokens: [{ startIndex: 0, type: 'predefined.literal.cypher' }] + } + ], + + // Builtin functions + [ + { + line: 'properties(node)', + tokens: [ + { startIndex: 0, type: 'predefined.function.cypher' }, + { startIndex: 10, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 11, type: 'identifier.cypher' }, + { startIndex: 15, type: 'delimiter.parenthesis.cypher' } + ] + } + ], + [ + { + line: 'left(right("Hello Cypher"))', + tokens: [ + { startIndex: 0, type: 'predefined.function.cypher' }, + { startIndex: 4, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 5, type: 'predefined.function.cypher' }, + { startIndex: 10, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 11, type: 'string.cypher' }, + { startIndex: 25, type: 'delimiter.parenthesis.cypher' } + ] + } + ], + + // Keywords + [ + { + line: 'MATCH (n) RETURN n', + tokens: [ + { startIndex: 0, type: 'keyword.cypher' }, + { startIndex: 5, type: 'white.cypher' }, + { startIndex: 6, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 7, type: 'identifier.cypher' }, + { startIndex: 8, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 9, type: 'white.cypher' }, + { startIndex: 10, type: 'keyword.cypher' }, + { startIndex: 16, type: 'white.cypher' }, + { startIndex: 17, type: 'identifier.cypher' } + ] + } + ], + + // Labels on nodes and relationships + [ + { + line: '(n:NodeLabel1)-[:RelationshipType]->(:NodeLabel2:NodeLabel3)', + tokens: [ + { startIndex: 0, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 1, type: 'identifier.cypher' }, + { startIndex: 2, type: 'type.identifier.cypher' }, + { startIndex: 13, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 14, type: 'delimiter.cypher' }, + { startIndex: 15, type: 'delimiter.bracket.cypher' }, + { startIndex: 16, type: 'type.identifier.cypher' }, + { startIndex: 33, type: 'delimiter.bracket.cypher' }, + { startIndex: 34, type: 'delimiter.cypher' }, + { startIndex: 36, type: 'delimiter.parenthesis.cypher' }, + { startIndex: 37, type: 'type.identifier.cypher' }, + { startIndex: 59, type: 'delimiter.parenthesis.cypher' } + ] + } + ] +]); diff --git a/src/basic-languages/cypher/cypher.ts b/src/basic-languages/cypher/cypher.ts new file mode 100644 index 00000000..c7901517 --- /dev/null +++ b/src/basic-languages/cypher/cypher.ts @@ -0,0 +1,274 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { languages } from '../../fillers/monaco-editor-core'; + +export const conf: languages.LanguageConfiguration = { + comments: { + lineComment: '//', + blockComment: ['/*', '*/'] + }, + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'] + ], + autoClosingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '(', close: ')' }, + { open: '"', close: '"' }, + { open: "'", close: "'" }, + { open: '`', close: '`' } + ], + surroundingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '(', close: ')' }, + { open: '"', close: '"' }, + { open: "'", close: "'" }, + { open: '`', close: '`' } + ] +}; + +// Ref: Cypher Query Language Reference, Version 9 (https://opencypher.org/resources/) +export const language = { + defaultToken: '', + tokenPostfix: `.cypher`, + ignoreCase: true, + + brackets: [ + { open: '{', close: '}', token: 'delimiter.curly' }, + { open: '[', close: ']', token: 'delimiter.bracket' }, + { open: '(', close: ')', token: 'delimiter.parenthesis' } + ], + + keywords: [ + 'ALL', + 'AND', + 'AS', + 'ASC', + 'ASCENDING', + 'BY', + 'CALL', + 'CASE', + 'CONTAINS', + 'CREATE', + 'DELETE', + 'DESC', + 'DESCENDING', + 'DETACH', + 'DISTINCT', + 'ELSE', + 'END', + 'ENDS', + 'EXISTS', + 'IN', + 'IS', + 'LIMIT', + 'MANDATORY', + 'MATCH', + 'MERGE', + 'NOT', + 'ON', + 'ON', + 'OPTIONAL', + 'OR', + 'ORDER', + 'REMOVE', + 'RETURN', + 'SET', + 'SKIP', + 'STARTS', + 'THEN', + 'UNION', + 'UNWIND', + 'WHEN', + 'WHERE', + 'WITH', + 'XOR', + 'YIELD' + ], + builtinLiterals: ['true', 'TRUE', 'false', 'FALSE', 'null', 'NULL'], + builtinFunctions: [ + 'abs', + 'acos', + 'asin', + 'atan', + 'atan2', + 'avg', + 'ceil', + 'coalesce', + 'collect', + 'cos', + 'cot', + 'count', + 'degrees', + 'e', + 'endNode', + 'exists', + 'exp', + 'floor', + 'head', + 'id', + 'keys', + 'labels', + 'last', + 'left', + 'length', + 'log', + 'log10', + 'lTrim', + 'max', + 'min', + 'nodes', + 'percentileCont', + 'percentileDisc', + 'pi', + 'properties', + 'radians', + 'rand', + 'range', + 'relationships', + 'replace', + 'reverse', + 'right', + 'round', + 'rTrim', + 'sign', + 'sin', + 'size', + 'split', + 'sqrt', + 'startNode', + 'stDev', + 'stDevP', + 'substring', + 'sum', + 'tail', + 'tan', + 'timestamp', + 'toBoolean', + 'toFloat', + 'toInteger', + 'toLower', + 'toString', + 'toUpper', + 'trim', + 'type' + ], + + operators: [ + // Math operators + '+', + '-', + '*', + '/', + '%', + '^', + // Comparison operators + '=', + '<>', + '<', + '>', + '<=', + '>=', + // Pattern operators + '->', + '<-', + '-->', + '<--' + ], + + escapes: /\\(?:[tbnrf\\"'`]|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/, + digits: /\d+/, + octaldigits: /[0-7]+/, + hexdigits: /[0-9a-fA-F]+/, + + tokenizer: { + root: [[/[{}[\]()]/, '@brackets'], { include: 'common' }], + common: [ + { include: '@whitespace' }, + { include: '@numbers' }, + { include: '@strings' }, + + // Cypher labels on nodes/relationships, e.g. (n:NodeLabel)-[e:RelationshipLabel] + [/:[a-zA-Z_][\w]*/, 'type.identifier'], + [ + /[a-zA-Z_][\w]*(?=\()/, + { + cases: { + '@builtinFunctions': 'predefined.function' + } + } + ], + [ + /[a-zA-Z_$][\w$]*/, + { + cases: { + '@keywords': 'keyword', + '@builtinLiterals': 'predefined.literal', + '@default': 'identifier' + } + } + ], + [/`/, 'identifier.escape', '@identifierBacktick'], + + // delimiter and operator after number because of `.\d` floats and `:` in labels + [/[;,.:|]/, 'delimiter'], + [ + /[<>=%+\-*/^]+/, + { + cases: { + '@operators': 'delimiter', + '@default': '' + } + } + ] + ], + numbers: [ + [/-?(@digits)[eE](-?(@digits))?/, 'number.float'], + [/-?(@digits)?\.(@digits)([eE]-?(@digits))?/, 'number.float'], + [/-?0x(@hexdigits)/, 'number.hex'], + [/-?0(@octaldigits)/, 'number.octal'], + [/-?(@digits)/, 'number'] + ], + strings: [ + [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-teminated string + [/'([^'\\]|\\.)*$/, 'string.invalid'], // non-teminated string + [/"/, 'string', '@stringDouble'], + [/'/, 'string', '@stringSingle'] + ], + whitespace: [ + [/[ \t\r\n]+/, 'white'], + [/\/\*/, 'comment', '@comment'], + [/\/\/.*$/, 'comment'] + ], + comment: [ + [/\/\/.*/, 'comment'], + [/[^/*]+/, 'comment'], + [/\*\//, 'comment', '@pop'], + [/[/*]/, 'comment'] + ], + stringDouble: [ + [/[^\\"]+/, 'string'], + [/@escapes/, 'string'], + [/\\./, 'string.invalid'], + [/"/, 'string', '@pop'] + ], + stringSingle: [ + [/[^\\']+/, 'string'], + [/@escapes/, 'string'], + [/\\./, 'string.invalid'], + [/'/, 'string', '@pop'] + ], + identifierBacktick: [ + [/[^\\`]+/, 'identifier.escape'], + [/@escapes/, 'identifier.escape'], + [/\\./, 'identifier.escape.invalid'], + [/`/, 'identifier.escape', '@pop'] + ] + } +}; diff --git a/src/basic-languages/monaco.contribution.ts b/src/basic-languages/monaco.contribution.ts index 56b078c1..db51ca61 100644 --- a/src/basic-languages/monaco.contribution.ts +++ b/src/basic-languages/monaco.contribution.ts @@ -15,6 +15,7 @@ import './cpp/cpp.contribution'; import './csharp/csharp.contribution'; import './csp/csp.contribution'; import './css/css.contribution'; +import './cypher/cypher.contribution'; import './dart/dart.contribution'; import './dockerfile/dockerfile.contribution'; import './ecl/ecl.contribution'; diff --git a/src/basic-languages/mysql/mysql.test.ts b/src/basic-languages/mysql/mysql.test.ts index a8111a25..e33f7417 100644 --- a/src/basic-languages/mysql/mysql.test.ts +++ b/src/basic-languages/mysql/mysql.test.ts @@ -385,41 +385,6 @@ testTokenization('mysql', [ } ], - [ - { - line: 'declare `abc 321`;', - tokens: [ - { startIndex: 0, type: 'keyword.sql' }, - { startIndex: 7, type: 'white.sql' }, - { startIndex: 8, type: 'identifier.quote.sql' }, - { startIndex: 9, type: 'identifier.sql' }, - { startIndex: 16, type: 'identifier.quote.sql' }, - { startIndex: 17, type: 'delimiter.sql' } - ] - } - ], - - [ - { - line: '`abc`` 321 `` xyz`', - tokens: [ - { startIndex: 0, type: 'identifier.quote.sql' }, - { startIndex: 1, type: 'identifier.sql' }, - { startIndex: 17, type: 'identifier.quote.sql' } - ] - } - ], - - [ - { - line: '`abc', - tokens: [ - { startIndex: 0, type: 'identifier.quote.sql' }, - { startIndex: 1, type: 'identifier.sql' } - ] - } - ], - [ { line: 'int', diff --git a/src/basic-languages/qsharp/qsharp.ts b/src/basic-languages/qsharp/qsharp.ts index 6f79768e..f89f4437 100644 --- a/src/basic-languages/qsharp/qsharp.ts +++ b/src/basic-languages/qsharp/qsharp.ts @@ -74,7 +74,8 @@ export const language = { 'borrow', 'using', 'borrowing', - 'mutable' + 'mutable', + 'internal' ], typeKeywords: [ diff --git a/webpack-plugin/README.md b/webpack-plugin/README.md index b457178c..e97f5c9e 100644 --- a/webpack-plugin/README.md +++ b/webpack-plugin/README.md @@ -78,8 +78,12 @@ Options can be passed in to `MonacoWebpackPlugin`. They can be used to generate | handlebars | html | | scss, less | css | + To view a list of all available languages, you can run `import metadata from 'monaco-editor/esm/metadata'; console.log(metadata.languages);`. + - `features` (`string[]`) - include only a subset of the editor features. By default, all features shipped with the `monaco-editor` will be included. Instead of enumerating included features, it is also possible to exclude certain default features prefixing them with an exclamation mark '!'. + To view a list of all available features, you can run `import metadata from 'monaco-editor/esm/metadata'; console.log(metadata.features);`. + - `globalAPI` (`boolean`) - specify whether the editor API should be exposed through a global `monaco` object or not. This option is applicable to `0.22.0` and newer version of `monaco-editor`. Since `0.22.0`, the ESM version of the monaco editor does no longer define a global `monaco` object unless `global.MonacoEnvironment = { globalAPI: true }` is set ([change log](https://github.com/microsoft/monaco-editor/blob/main/CHANGELOG.md#0220-29012021)). - default value: `false`. diff --git a/website/index/samples/sample.cypher.txt b/website/index/samples/sample.cypher.txt new file mode 100644 index 00000000..b81b3e2e --- /dev/null +++ b/website/index/samples/sample.cypher.txt @@ -0,0 +1,3 @@ +MATCH (nicole:Actor {name: 'Nicole Kidman'})-[:ACTED_IN]->(movie:Movie) +WHERE movie.year < $yearParameter +RETURN movie diff --git a/website/index/samples/sample.dart.txt b/website/index/samples/sample.dart.txt index 3a16aa6d..c9eb663e 100644 --- a/website/index/samples/sample.dart.txt +++ b/website/index/samples/sample.dart.txt @@ -1,21 +1,24 @@ -import 'dart:async'; import 'dart:math' show Random; -main() async { + +void main() async { print('Compute π using the Monte Carlo method.'); - await for (var estimate in computePi().take(100)) { + await for (final estimate in computePi().take(100)) { print('π ≅ $estimate'); } } + /// Generates a stream of increasingly accurate estimates of π. -Stream computePi({int batch: 100000}) async* { - var total = 0; +Stream computePi({int batch = 100000}) async* { + var total = 0; // Inferred to be of type int var count = 0; while (true) { - var points = generateRandom().take(batch); - var inside = points.where((p) => p.isInsideUnitCircle); + final points = generateRandom().take(batch); + final inside = points.where((p) => p.isInsideUnitCircle); + total += batch; count += inside.length; - var ratio = count / total; + final ratio = count / total; + // Area of a circle is A = π⋅r², therefore π = A/r². // So, when given random points with x ∈ <0,1>, // y ∈ <0,1>, the ratio of those inside a unit circle @@ -24,14 +27,19 @@ Stream computePi({int batch: 100000}) async* { yield ratio * 4; } } -Iterable generateRandom([int seed]) sync* { + +Iterable generateRandom([int? seed]) sync* { final random = Random(seed); while (true) { yield Point(random.nextDouble(), random.nextDouble()); } } + class Point { - final double x, y; + final double x; + final double y; + const Point(this.x, this.y); + bool get isInsideUnitCircle => x * x + y * y <= 1; } diff --git a/website/playground/new-samples/all.js b/website/playground/new-samples/all.js index 06323f21..004108a4 100644 --- a/website/playground/new-samples/all.js +++ b/website/playground/new-samples/all.js @@ -156,6 +156,12 @@ id: 'extending-language-services-hover-provider-example', path: 'extending-language-services/hover-provider-example' }, + { + chapter: 'Extending Language Services', + name: 'Model markers example', + id: 'extending-language-services-model-markers-example', + path: 'extending-language-services/model-markers-example' + }, { chapter: 'Extending Language Services', name: 'Semantic tokens provider example', diff --git a/website/playground/new-samples/extending-language-services/model-markers-example/sample.css b/website/playground/new-samples/extending-language-services/model-markers-example/sample.css new file mode 100644 index 00000000..e69de29b diff --git a/website/playground/new-samples/extending-language-services/model-markers-example/sample.html b/website/playground/new-samples/extending-language-services/model-markers-example/sample.html new file mode 100644 index 00000000..75b9b160 --- /dev/null +++ b/website/playground/new-samples/extending-language-services/model-markers-example/sample.html @@ -0,0 +1 @@ +
diff --git a/website/playground/new-samples/extending-language-services/model-markers-example/sample.js b/website/playground/new-samples/extending-language-services/model-markers-example/sample.js new file mode 100644 index 00000000..010f6d05 --- /dev/null +++ b/website/playground/new-samples/extending-language-services/model-markers-example/sample.js @@ -0,0 +1,48 @@ +function validate(model) { + const markers = []; + // lines start at 1 + for (let i = 1; i < model.getLineCount() + 1; i++) { + const range = { + startLineNumber: i, + startColumn: 1, + endLineNumber: i, + endColumn: model.getLineLength(i) + 1 + }; + const content = model.getValueInRange(range).trim(); + const number = Number(content); + if (Number.isNaN(number)) { + markers.push({ + message: 'not a number', + severity: monaco.MarkerSeverity.Error, + startLineNumber: range.startLineNumber, + startColumn: range.startColumn, + endLineNumber: range.endLineNumber, + endColumn: range.endColumn + }); + } else if (!Number.isInteger(number)) { + markers.push({ + message: 'not an integer', + severity: monaco.MarkerSeverity.Warning, + startLineNumber: range.startLineNumber, + startColumn: range.startColumn, + endLineNumber: range.endLineNumber, + endColumn: range.endColumn + }); + } + } + monaco.editor.setModelMarkers(model, 'owner', markers); +} + +const value = `12345 +abcd +234.56 +12345 +abcd +234.56`; +const uri = monaco.Uri.parse('inmemory://test'); +const model = monaco.editor.createModel(value, 'demoLanguage', uri); +editor = monaco.editor.create(document.getElementById('container'), { model }); +validate(model); +model.onDidChangeContent(() => { + validate(model); +});