Add language config and tokens provider for circom support in the editor

pull/3935/head
ioedeveloper 1 year ago
parent 32bec06501
commit 6d52c96b5d
  1. 3
      apps/remix-ide/src/app/editor/editor.js
  2. 7
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  3. 211
      libs/remix-ui/editor/src/lib/syntaxes/circom.ts

@ -51,7 +51,8 @@ class Editor extends Plugin {
rs: 'rust', rs: 'rust',
cairo: 'cairo', cairo: 'cairo',
ts: 'typescript', ts: 'typescript',
move: 'move' move: 'move',
circom: 'circom'
} }
this.activated = false this.activated = false

@ -17,6 +17,7 @@ import { RemixHighLightProvider } from './providers/highlightProvider'
import { RemixDefinitionProvider } from './providers/definitionProvider' import { RemixDefinitionProvider } from './providers/definitionProvider'
import { RemixCodeActionProvider } from './providers/codeActionProvider' import { RemixCodeActionProvider } from './providers/codeActionProvider'
import './remix-ui-editor.css' import './remix-ui-editor.css'
import { circomLanguageConfig, circomTokensProvider } from './syntaxes/circom'
enum MarkerSeverity { enum MarkerSeverity {
@ -322,6 +323,8 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-zokrates') monacoRef.current.editor.setModelLanguage(file.model, 'remix-zokrates')
} else if (file.language === 'move') { } else if (file.language === 'move') {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-move') monacoRef.current.editor.setModelLanguage(file.model, 'remix-move')
} else if (file.language === 'circom') {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-circom')
} }
}, [props.currentFile]) }, [props.currentFile])
@ -731,6 +734,7 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.languages.register({ id: 'remix-cairo' }) monacoRef.current.languages.register({ id: 'remix-cairo' })
monacoRef.current.languages.register({ id: 'remix-zokrates' }) monacoRef.current.languages.register({ id: 'remix-zokrates' })
monacoRef.current.languages.register({ id: 'remix-move' }) monacoRef.current.languages.register({ id: 'remix-move' })
monacoRef.current.languages.register({ id: 'remix-circom' })
// Register a tokens provider for the language // Register a tokens provider for the language
monacoRef.current.languages.setMonarchTokensProvider('remix-solidity', solidityTokensProvider as any) monacoRef.current.languages.setMonarchTokensProvider('remix-solidity', solidityTokensProvider as any)
@ -745,6 +749,9 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.languages.setMonarchTokensProvider('remix-move', moveTokenProvider as any) monacoRef.current.languages.setMonarchTokensProvider('remix-move', moveTokenProvider as any)
monacoRef.current.languages.setLanguageConfiguration('remix-move', moveLanguageConfig as any) monacoRef.current.languages.setLanguageConfiguration('remix-move', moveLanguageConfig as any)
monacoRef.current.languages.setMonarchTokensProvider('remix-circom', circomTokensProvider as any)
monacoRef.current.languages.setLanguageConfiguration('remix-circom', circomLanguageConfig(monacoRef.current) as any)
monacoRef.current.languages.registerDefinitionProvider('remix-solidity', new RemixDefinitionProvider(props, monaco)) monacoRef.current.languages.registerDefinitionProvider('remix-solidity', new RemixDefinitionProvider(props, monaco))
monacoRef.current.languages.registerDocumentHighlightProvider('remix-solidity', new RemixHighLightProvider(props, monaco)) monacoRef.current.languages.registerDocumentHighlightProvider('remix-solidity', new RemixHighLightProvider(props, monaco))
monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco)) monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco))

@ -0,0 +1,211 @@
/* eslint-disable */
export const circomLanguageConfig = (monaco) => ({
wordPattern:
/(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g,
comments: {
lineComment: "//",
blockComment: ["/*", "*/"],
},
brackets: [
["{", "}"],
["[", "]"],
["(", ")"],
],
onEnterRules: [
{
// e.g. /** | */
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
afterText: /^\s*\*\/$/,
action: {
indentAction: monaco.languages.IndentAction.IndentOutdent,
appendText: " * ",
},
},
{
// e.g. /** ...|
beforeText: /^\s*\/\*\*(?!\/)([^\*]|\*(?!\/))*$/,
action: {
indentAction: monaco.languages.IndentAction.None,
appendText: " * ",
},
},
{
// e.g. * ...|
beforeText: /^(\t|(\ \ ))*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
action: {
indentAction: monaco.languages.IndentAction.None,
appendText: "* ",
},
},
{
// e.g. */|
beforeText: /^(\t|(\ \ ))*\ \*\/\s*$/,
action: {
indentAction: monaco.languages.IndentAction.None,
removeText: 1,
},
},
],
autoClosingPairs: [
{ open: "{", close: "}" },
{ open: "[", close: "]" },
{ open: "(", close: ")" },
{ open: '"', close: '"', notIn: ["string"] },
{ open: "'", close: "'", notIn: ["string", "comment"] },
{ open: "`", close: "`", notIn: ["string", "comment"] },
{ open: "/**", close: " */", notIn: ["string"] },
],
folding: {
markers: {
start: new RegExp("^\\s*//\\s*#?region\\b"),
end: new RegExp("^\\s*//\\s*#?endregion\\b"),
},
},
})
export const circomTokensProvider = {
defaultToken: "",
tokenPostfix: ".circom",
keywords: [
"signal",
"input",
"output",
"public",
"template",
"component",
"parallel",
"custom",
"var",
"function",
"return",
"if",
"else",
"for",
"while",
"do",
"log",
"assert",
"include",
"pragma",
],
typeKeywords: ["input", "output", "public"],
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 our languages
tokenizer: {
root: [
// identifiers and keywords
[
/[a-z_$][\w$]*/,
{
cases: {
"@typeKeywords": "keyword",
"@keywords": "keyword",
"@default": "identifier",
},
},
],
[/[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"],
],
},
}
Loading…
Cancel
Save