Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move language syntax highlighting for the Monaco Editor #3058

Merged
merged 1 commit into from Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/remix-ide/src/app/editor/editor.js
Expand Up @@ -50,7 +50,8 @@ class Editor extends Plugin {
abi: 'json',
rs: 'rust',
cairo: 'cairo',
ts: 'typescript'
ts: 'typescript',
move: 'move'
}

this.activated = false
Expand Down
7 changes: 7 additions & 0 deletions libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
Expand Up @@ -6,6 +6,7 @@ import { reducerActions, reducerListener, initialState } from './actions/editor'
import { solidityTokensProvider, solidityLanguageConfig } from './syntaxes/solidity'
import { cairoTokensProvider, cairoLanguageConfig } from './syntaxes/cairo'
import { zokratesTokensProvider, zokratesLanguageConfig } from './syntaxes/zokrates'
import { moveTokenProvider, moveLanguageConfig } from './syntaxes/move'

import './remix-ui-editor.css'
import { loadTypes } from './web-types'
Expand Down Expand Up @@ -303,6 +304,8 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-cairo')
} else if (file.language === 'zokrates') {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-zokrates')
} else if (file.language === 'move') {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-move')
}
}, [props.currentFile])

Expand Down Expand Up @@ -647,6 +650,7 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.languages.register({ id: 'remix-solidity' })
monacoRef.current.languages.register({ id: 'remix-cairo' })
monacoRef.current.languages.register({ id: 'remix-zokrates' })
monacoRef.current.languages.register({ id: 'remix-move' })

// Register a tokens provider for the language
monacoRef.current.languages.setMonarchTokensProvider('remix-solidity', solidityTokensProvider as any)
Expand All @@ -658,6 +662,9 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.languages.setMonarchTokensProvider('remix-zokrates', zokratesTokensProvider as any)
monacoRef.current.languages.setLanguageConfiguration('remix-zokrates', zokratesLanguageConfig as any)

monacoRef.current.languages.setMonarchTokensProvider('remix-move', moveTokenProvider as any)
monacoRef.current.languages.setLanguageConfiguration('remix-move', moveLanguageConfig as any)

monacoRef.current.languages.registerDefinitionProvider('remix-solidity', new RemixDefinitionProvider(props, monaco))
monacoRef.current.languages.registerDocumentHighlightProvider('remix-solidity', new RemixHighLightProvider(props, monaco))
monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco))
Expand Down
264 changes: 264 additions & 0 deletions libs/remix-ui/editor/src/lib/syntaxes/move.ts
@@ -0,0 +1,264 @@
/* eslint-disable no-useless-escape */
export const moveLanguageConfig = {
comments: {
lineComment: "//",
blockComment: ["/*", "*/"],
},
brackets: [
["{", "}"],
["[", "]"],
["(", ")"],
],
autoClosingPairs: [
{ open: "[", close: "]" },
{ open: "{", close: "}" },
{ open: "(", close: ")" },
{ open: '"', close: '"', notIn: ["string"] },
],
surroundingPairs: [
{ open: "{", close: "}" },
{ open: "[", close: "]" },
{ open: "(", close: ")" },
{ open: '"', close: '"' },
{ open: "'", close: "'" },
],
folding: {
markers: {
start: new RegExp("^\\s*#pragma\\s+region\\b"),
end: new RegExp("^\\s*#pragma\\s+endregion\\b"),
},
},
};
export const moveTokenProvider = {
// Set defaultToken to invalid to see what you do not tokenize yet
// defaultToken: 'invalid',
keywords: [
"as",
"break",
"const",
"crate",
"enum",
"extern",
"false",
"fun",
"script",
"in",
"let",
"module",
"move",
"mut",
"pub",
"ref",
"return",
"self",
"Self",
"static",
"struct",
"super",
"trait",
"true",
"type",
"unsafe",
"use",
"where",
"use",
"macro_rules",
],

controlFlowKeywords: [
"continue",
"else",
"for",
"if",
"while",
"loop",
"match",
],

typeKeywords: [
"Self",
"m32",
"m64",
"m128",
"f80",
"f16",
"f128",
"int",
"uint",
"float",
"char",
"bool",
"u8",
"u16",
"u32",
"u64",
"f32",
"f64",
"i8",
"i16",
"i32",
"i64",
"str",
"Option",
"Either",
"c_float",
"c_double",
"c_void",
"FILE",
"fpos_t",
"DIR",
"dirent",
"c_char",
"c_schar",
"c_uchar",
"c_short",
"c_ushort",
"c_int",
"c_uint",
"c_long",
"c_ulong",
"size_t",
"ptrdiff_t",
"clock_t",
"time_t",
"c_longlong",
"c_ulonglong",
"intptr_t",
"uintptr_t",
"off_t",
"dev_t",
"ino_t",
"pid_t",
"mode_t",
"ssize_t",
],

operators: [
"=",
">",
"<",
"!",
"~",
"?",
":",
"==",
"<=",
">=",
"!=",
"&&",
"||",
"++",
"--",
"+",
"-",
"*",
"/",
"&",
"|",
"^",
"%",
"<<",
">>",
">>>",
"+=",
"-=",
"*=",
"/=",
"&=",
"|=",
"^=",
"%=",
"<<=",
">>=",
">>>=",
],

// we include these common regular expressions
symbols: /[=><!~?:&|+\-*\/\^%]+/,

// C# style strings
escapes:
/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,

// The main tokenizer for languages
tokenizer: {
root: [
// identifiers and keywords
[
/[a-z_$][\w$]*/,
{
cases: {
"@typeKeywords": "type.identifier",
"@keywords": {
cases: {
fun: { token: "keyword", next: "@func_decl" },
let: { token: "keyword", next: "@func_decl" },
if: { token: "keyword", next: "@func_decl" },
use: { token: "keyword", next: "@func_decl" },
"@default": "keyword",
},
},
"@controlFlowKeywords": "keyword.control",
"@default": "variable",
},
},
],
[/[A-Z][\w\$]*/, "type.identifier"], // to show class names nicely

// whitespace
{ include: "@whitespace" },

// delimiters and operators
[/[{}()\[\]]/, "@brackets"],
[/[<>](?!@symbols)/, "@brackets"],
[/@symbols/, { cases: { "@operators": "operator", "@default": "" } }],

// @ annotations.
// As an example, we emit a debugging log message on these tokens.
// Note: message are supressed during the first load -- change some lines to see them.
[
/@\s*[a-zA-Z_\$][\w\$]*/,
{ token: "annotation", log: "annotation token: $0" },
],

// numbers
[/\d*\.\d+([eE][\-+]?\d+)?/, "number.float"],
[/0[xX][0-9a-fA-F]+/, "number.hex"],
[/\d+/, "number"],

// delimiter: after number because of .\d floats
[/[;,.]/, "delimiter"],

// strings
[/"([^"\\]|\\.)*$/, "string.invalid"], // non-teminated string
[/"/, { token: "string.quote", bracket: "@open", next: "@string" }],

// characters
[/'[^\\']'/, "string"],
[/(')(@escapes)(')/, ["string", "string.escape", "string"]],
[/'/, "string.invalid"],
],

comment: [
[/[^\/*]+/, "comment"],
[/\/\*/, "comment", "@push"], // nested comment
["\\*/", "comment", "@pop"],
[/[\/*]/, "comment"],
],

string: [
[/[^\\"]+/, "string"],
[/@escapes/, "string.escape"],
[/\\./, "string.escape.invalid"],
[/"/, { token: "string.quote", bracket: "@close", next: "@pop" }],
],

whitespace: [
[/[ \t\r\n]+/, "white"],
[/\/\*/, "comment", "@comment"],
[/\/\/.*$/, "comment"],
],

func_decl: [[/[a-z_$][\w$]*/, "support.function", "@pop"]],
},
};