Skip to content

Commit

Permalink
fix(monaco-editor-textmate): to be used in standalone
Browse files Browse the repository at this point in the history
  • Loading branch information
mouse484 committed May 9, 2021
1 parent 803fab3 commit dafaade
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 116 deletions.
17 changes: 3 additions & 14 deletions packages/monaco-editor-textmate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "monaco-editor-textmate",
"version": "2.2.2",
"version": "0.0.0",
"description": "Wire monaco-textmate with monaco-editor",
"main": "dist/index.js",
"typings": "dist/typings/index.d.ts",
Expand All @@ -9,10 +9,6 @@
"watch": "tsc -w",
"prepack": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/NeekSandhu/monaco-editor-textmate.git"
},
"keywords": [
"monaco",
"editor",
Expand All @@ -21,17 +17,10 @@
"grammar",
"vscode"
],
"author": "Neek Sandhu <[email protected]>",
"license": "MIT",
"bugs": {
"url": "https://github.com/NeekSandhu/monaco-editor-textmate/issues"
},
"homepage": "https://github.com/NeekSandhu/monaco-editor-textmate#readme",
"devDependencies": {
"monaco-editor": "^0.23.0",
"monaco-textmate": "^3.0.1",
"typescript": "^2.8.3"
},
"peerDependencies": {
"monaco-editor": "0.x.x",
"monaco-textmate": "^3.0.0"
}
}
124 changes: 67 additions & 57 deletions packages/monaco-editor-textmate/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,69 @@
import { Registry, StackElement, INITIAL } from 'monaco-textmate'
import * as monacoNsps from 'monaco-editor'
import { TMToMonacoToken } from './tm-to-monaco-token';

class TokenizerState implements monacoNsps.languages.IState {

constructor(
private _ruleStack: StackElement
) { }

public get ruleStack(): StackElement {
return this._ruleStack
}

public clone(): TokenizerState {
return new TokenizerState(this._ruleStack);
}

public equals(other: monacoNsps.languages.IState): boolean {
if (!other ||
!(other instanceof TokenizerState) ||
other !== this ||
other._ruleStack !== this._ruleStack
) {
return false;
}
return true;
}
}

/**
* Wires up monaco-editor with monaco-textmate
*
* @param monaco monaco namespace this operation should apply to (usually the `monaco` global unless you have some other setup)
* @param registry TmGrammar `Registry` this wiring should rely on to provide the grammars
* @param languages `Map` of language ids (string) to TM names (string)
* [email protected]
* MIT License
* https://github.com/NeekSandhu/monaco-editor-textmate/blob/master/LICENSE
*/
export function wireTmGrammars(monaco: typeof monacoNsps, registry: Registry, languages: Map<string, string>, editor?: monacoNsps.editor.ICodeEditor) {
return Promise.all(
Array.from(languages.keys())
.map(async (languageId) => {
const grammar = await registry.loadGrammar(languages.get(languageId))
monaco.languages.setTokensProvider(languageId, {
getInitialState: () => new TokenizerState(INITIAL),
tokenize: (line: string, state: TokenizerState) => {
const res = grammar.tokenizeLine(line, state.ruleStack)
return {
endState: new TokenizerState(res.ruleStack),
tokens: res.tokens.map(token => ({
...token,
// TODO: At the moment, monaco-editor doesn't seem to accept array of scopes
scopes: editor ? TMToMonacoToken(editor, token.scopes) : token.scopes[token.scopes.length - 1]
})),
}
}
})
})
)
}

import { Registry, StackElement, INITIAL } from 'monaco-textmate';
import type * as monacoNsps from 'monaco-editor';
import { TMToMonacoToken } from './tm-to-monaco-token';

class TokenizerState implements monacoNsps.languages.IState {
constructor(private _ruleStack: StackElement) {}

public get ruleStack(): StackElement {
return this._ruleStack;
}

public clone(): TokenizerState {
return new TokenizerState(this._ruleStack);
}

public equals(other: monacoNsps.languages.IState): boolean {
if (
!other ||
!(other instanceof TokenizerState) ||
other !== this ||
other._ruleStack !== this._ruleStack
) {
return false;
}
return true;
}
}

/**
* Wires up monaco-editor with monaco-textmate
*
* @param monaco monaco namespace this operation should apply to (usually the `monaco` global unless you have some other setup)
* @param registry TmGrammar `Registry` this wiring should rely on to provide the grammars
* @param languages `Map` of language ids (string) to TM names (string)
*/
export function wireTmGrammars(
monaco: typeof monacoNsps,
registry: Registry,
languages: Map<string, string>,
editor?: monacoNsps.editor.ICodeEditor
): Promise<void[]> {
return Promise.all(
Array.from(languages.keys()).map(async (languageId) => {
const grammar = await registry.loadGrammar(languages.get(languageId));
monaco.languages.setTokensProvider(languageId, {
getInitialState: () => new TokenizerState(INITIAL),
tokenize: (line: string, state: TokenizerState) => {
const res = grammar.tokenizeLine(line, state.ruleStack);
return {
endState: new TokenizerState(res.ruleStack),
tokens: res.tokens.map((token) => ({
...token,
// TODO: At the moment, monaco-editor doesn't seem to accept array of scopes
scopes: editor
? TMToMonacoToken(editor, token.scopes)
: token.scopes[token.scopes.length - 1],
})),
};
},
});
})
);
}
93 changes: 48 additions & 45 deletions packages/monaco-editor-textmate/src/tm-to-monaco-token.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,56 @@
import * as monacoNsps from 'monaco-editor'
import type * as monacoNsps from 'monaco-editor';

// as described in issue: https://github.com/NeekSandhu/monaco-textmate/issues/5
export const TMToMonacoToken = (editor: monacoNsps.editor.ICodeEditor, scopes: string[]) => {
let scopeName = "";
// get the scope name. Example: cpp , java, haskell
for (let i = scopes[0].length - 1; i >= 0; i -= 1) {
const char = scopes[0][i];
if (char === ".") {
break;
}
scopeName = char + scopeName;
export const TMToMonacoToken = (
editor: monacoNsps.editor.ICodeEditor,
scopes: string[]
): string => {
let scopeName = '';
// get the scope name. Example: cpp , java, haskell
for (let i = scopes[0].length - 1; i >= 0; i -= 1) {
const char = scopes[0][i];
if (char === '.') {
break;
}
scopeName = char + scopeName;
}

// iterate through all scopes from last to first
for (let i = scopes.length - 1; i >= 0; i -= 1) {
const scope = scopes[i];
// iterate through all scopes from last to first
for (let i = scopes.length - 1; i >= 0; i -= 1) {
const scope = scopes[i];

/**
* Try all possible tokens from high specific token to low specific token
*
* Example:
* 0 meta.function.definition.parameters.cpp
* 1 meta.function.definition.parameters
*
* 2 meta.function.definition.cpp
* 3 meta.function.definition
*
* 4 meta.function.cpp
* 5 meta.function
*
* 6 meta.cpp
* 7 meta
*/
for (let i = scope.length - 1; i >= 0; i -= 1) {
const char = scope[i];
if (char === ".") {
const token = scope.slice(0, i);
if (
editor['_themeService'].getTheme()._tokenTheme._match(token + "." + scopeName)._foreground >
1
) {
return token + "." + scopeName;
}
if (editor['_themeService'].getTheme()._tokenTheme._match(token)._foreground > 1) {
return token;
}
}
/**
* Try all possible tokens from high specific token to low specific token
*
* Example:
* 0 meta.function.definition.parameters.cpp
* 1 meta.function.definition.parameters
*
* 2 meta.function.definition.cpp
* 3 meta.function.definition
*
* 4 meta.function.cpp
* 5 meta.function
*
* 6 meta.cpp
* 7 meta
*/
for (let i = scope.length - 1; i >= 0; i -= 1) {
const char = scope[i];
if (char === '.') {
const token = scope.slice(0, i);
const theme =
editor['_standaloneThemeService']._theme ||
editor['_themeService'].getTheme();
if (theme._tokenTheme._match(token + '.' + scopeName)._foreground > 1) {
return token + '.' + scopeName;
}
if (theme._tokenTheme._match(token)._foreground > 1) {
return token;
}
}
}
}

return "";
};
return '';
};
17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2457,6 +2457,11 @@ fast-json-stable-stringify@^2.0.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==

fast-plist@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/fast-plist/-/fast-plist-0.1.2.tgz#a45aff345196006d406ca6cdcd05f69051ef35b8"
integrity sha1-pFr/NFGWAG1AbKbNzQX2kFHvNbg=

[email protected]:
version "1.1.3"
resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d"
Expand Down Expand Up @@ -4066,6 +4071,18 @@ modify-values@^1.0.0:
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==

monaco-editor@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.23.0.tgz#24844ba5640c7adb3a2a3ff3b520cf2d7170a6f0"
integrity sha512-q+CP5zMR/aFiMTE9QlIavGyGicKnG2v/H8qVvybLzeFsARM8f6G9fL0sMST2tyVYCwDKkGamZUI6647A0jR/Lg==

monaco-textmate@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/monaco-textmate/-/monaco-textmate-3.0.1.tgz#b6d26d266aa12edaff7069dae0d6e3747cba5cd7"
integrity sha512-ZxxY3OsqUczYP1sGqo97tu+CJmMBwuSW+dL0WEBdDhOZ5G1zntw72hvBc68ZQAirosWvbDKgN1dL5k173QtFww==
dependencies:
fast-plist "^0.1.2"

[email protected]:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
Expand Down

0 comments on commit dafaade

Please sign in to comment.