Skip to content

Commit

Permalink
Merge pull request #131 from melnikga/feat/new-code-editor
Browse files Browse the repository at this point in the history
feat: Implement Step-by-Step Cairo Code Highlighting - Issue #124
  • Loading branch information
barabanovro authored Apr 1, 2024
2 parents b671a45 + 9696517 commit 9192869
Show file tree
Hide file tree
Showing 6 changed files with 495 additions and 181 deletions.
38 changes: 26 additions & 12 deletions components/Editor/ExtraColumn.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useContext, useState } from 'react'

import { Editor as MonacoEditor, Monaco } from '@monaco-editor/react'
import cn from 'classnames'
import SCEditor from 'react-simple-code-editor'
import { editor } from 'monaco-editor'

import { CodeType } from '../../context/appUiContext'
import { CairoVMApiContext } from '../../context/cairoVMApiContext'
Expand All @@ -11,13 +12,18 @@ import { InstructionsTable } from './InstructionsTable'

type ExtraColumnProps = {
cairoCode: string
highlightCode: (value: string, codeType: string | undefined) => string
handleCairoCodeChange: (value: string | undefined) => void
handleEditorDidMount: (
editor: editor.IStandaloneCodeEditor,
monaco: Monaco,
) => void
isBytecode: boolean
}

const ExtraColumn = ({
cairoCode,
highlightCode,
handleCairoCodeChange,
handleEditorDidMount,
isBytecode,
}: ExtraColumnProps) => {
const [codeType, setCodeType] = useState<string | undefined>(CodeType.Sierra)
Expand All @@ -27,7 +33,7 @@ const ExtraColumn = ({
activeCasmInstructionIndex,
errorCasmInstructionIndex,
sierraStatements,
casmToSierraMap,
casmToSierraProgramMap,
currentSierraVariables,
} = useContext(CairoVMApiContext)

Expand All @@ -53,19 +59,27 @@ const ExtraColumn = ({
<InstructionsTable
instructions={sierraStatements}
codeType={codeType}
activeIndexes={casmToSierraMap[activeCasmInstructionIndex] ?? []}
errorIndexes={casmToSierraMap[errorCasmInstructionIndex] ?? []}
activeIndexes={
casmToSierraProgramMap[activeCasmInstructionIndex] ?? []
}
errorIndexes={
casmToSierraProgramMap[errorCasmInstructionIndex] ?? []
}
variables={currentSierraVariables || {}}
/>
) : (
<SCEditor
<MonacoEditor
// @ts-ignore: SCEditor is not TS-friendly
onMount={handleEditorDidMount}
options={{
minimap: { enabled: false },
wordBreak: 'keepAll',
wordWrap: 'on',
}}
value={codeType === CodeType.Cairo ? cairoCode : ''}
readOnly={true}
onValueChange={() => void 0} // as its readonly mode, we do nothing onValueChange(a required prop)
highlight={(value) => highlightCode(value, codeType)}
tabSize={4}
className={cn('code-editor', {
onChange={handleCairoCodeChange}
language={'cairo'}
className={cn('code-editor whitespace-pre-wrap overflow-hidden', {
'with-numbers': !isBytecode,
})}
/>
Expand Down
212 changes: 212 additions & 0 deletions components/Editor/cairoLangConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import * as MonacoEditor from 'monaco-editor-core/esm/vs/editor/editor.api'
export function registerCairoLanguageSupport(_monaco: typeof MonacoEditor) {
const languageId = 'cairo'
_monaco.languages.register({ id: languageId })
_monaco.languages.setLanguageConfiguration(languageId, {
comments: {
lineComment: '//',
},
brackets: [
['{', '}'],
['[', ']'],
['(', ')'],
['%{', '%}'],
],
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '%{', close: '%}' },
{ open: "'", close: "'", notIn: ['string', 'comment'] },
{ open: '<', close: '>' },
],
surroundingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '%{', close: '%}' },
{ open: "'", close: "'" },
{ open: '<', close: '>' },
],
})
_monaco.languages.setMonarchTokensProvider(languageId, {
defaultToken: '',
tokenPostfix: '.cairo',

brackets: [
{ token: 'delimiter.curly', open: '{', close: '}' },
{ token: 'delimiter.parenthesis', open: '(', close: ')' },
{ token: 'delimiter.square', open: '[', close: ']' },
{ token: 'delimiter.curly', open: '%{', close: '%}' },
{ token: 'delimiter.angle', open: '<', close: '>' },
],

keywords: [
'as',
'break',
'const',
'continue',
'else',
'enum',
'extern',
'false',
'fn',
'if',
'impl',
'implicits',
'let',
'loop',
'match',
'mod',
'mut',
'nopanic',
'of',
'ref',
'return',
'struct',
'trait',
'true',
'type',
'use',
'Self',
'assert',
'do',
'dyn',
'for',
'hint',
'in',
'macro',
'move',
'pub',
'self',
'static',
'static_assert',
'super',
'try',
'typeof',
'unsafe',
'where',
'while',
'with',
'yield',
'type',
'cotype',
],
types: ['bool', 'u8', 'u16', 'u32', 'u64', 'u128', 'u256', 'usize'],
literals: ['true', 'false'],
operators: [
'!',
'~',
'!=',
'%',
'%=',
'&',
'&&',
'*',
'*=',
'@',
'*',
'+',
'+=',
',',
'-',
'-',
'-=',
'->',
'.',
'/',
'/=',
':',
':',
';',
'<',
'<=',
'=',
'==',
'=>',
'>',
'>=',
'^',
'|',
'||',
'?',
],
// we include these common regular expressions
// eslint-disable-next-line no-useless-escape
symbols: /[=><!~?:&|+\-*\/\^%]+/,
numberDecimal: /[+-]?[0-9]+/,
numberHex: /[+-]?0x[0-9a-fA-F]+/,

// The main tokenizer for our languages
tokenizer: {
root: [
// identifiers and keywords
[
/[a-z_$][\w$]*/,
{
cases: {
'@types': 'type.keyword',
'@keywords': 'keyword',
'@default': 'identifier',
},
},
],

// eslint-disable-next-line no-useless-escape
[/[A-Z][\w\$]*/, 'type.identifier'],
// whitespace
{ include: '@whitespace' },

// directives
[/^%[a-zA-Z]\w*/, 'tag'],

// delimiters and operators
// eslint-disable-next-line no-useless-escape
[/[{}()\[\]]/, '@brackets'],
[/[<>](?!@symbols)/, '@brackets'],
[/\b(?:let|const)\s+([a-zA-Z_$][a-zA-Z\d_$]*)/, 'variableinit'],
[
/@symbols/,
{
cases: {
'@operators': 'delimiter',
'@default': '',
},
},
],

// numbers
[/(@numberHex)/, 'number.hex'],
[/(@numberDecimal)/, 'number'],

// strings
[/['"][^'"]*['"]/g, 'string'],
],

common: [],

whitespace: [
[/\s+/, 'white'],
[/\/\/.*/, 'comment'],
],
},
})
_monaco.editor.defineTheme('myTheme', {
base: 'vs',
inherit: true,
rules: [
{
foreground: '#981B64',
token: 'variableinit',
},
],
colors: {
'editor.foreground': '#000000',
'editorCursor.foreground': '#8B0000',
'editor.lineHighlightBackground': '#0000FF20',
'editor.selectionBackground': '#88000030',
'editor.inactiveSelectionBackground': '#88000015',
},
})
_monaco.editor.setTheme('myTheme')
}
Loading

0 comments on commit 9192869

Please sign in to comment.