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

monaco i18n #433

Merged
merged 2 commits into from
Apr 29, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions spx-gui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions spx-gui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"test": "vitest"
},
"dependencies": {
"@monaco-editor/loader": "^1.4.0",
"dayjs": "^1.11.10",
"file-saver": "^2.0.5",
"js-pkce": "^1.4.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
</template>

<script setup lang="ts">
import { onUnmounted, onMounted, ref, shallowRef, watch } from 'vue'
import * as monaco from 'monaco-editor'
import { ref, shallowRef, watch, watchEffect } from 'vue'
import { formatSpxCode as onlineFormatSpxCode } from '@/apis/util'
import { useMonacoInitialization, defaultThemeName } from './initialization'
import { initMonaco, defaultThemeName } from './initialization'
import loader from '@monaco-editor/loader'
import { KeyCode, languages, type editor, Position, MarkerSeverity, KeyMod } from 'monaco-editor'
import { useUIVariables } from '@/components/ui'
import { useI18n } from '@/utils/i18n'

const props = defineProps<{
value: string
Expand All @@ -16,12 +19,25 @@ const emit = defineEmits<{
}>()

const editorElement = ref<HTMLElement | null>(null)
const monacoEditor = shallowRef<monaco.editor.IStandaloneCodeEditor | null>(null)

useMonacoInitialization()
const monaco = shallowRef<typeof import('monaco-editor')>()
const monacoEditor = shallowRef<editor.IStandaloneCodeEditor>()

onMounted(() => {
const editor = monaco.editor.create(editorElement.value!, {
const uiVariables = useUIVariables()
const { t, lang } = useI18n()

loader.config({
'vs/nls': {
availableLanguages: {
'*': lang.value === 'zh' ? 'zh-cn' : 'en'
}
}
})

watchEffect(async (onClenaup) => {
const monaco_ = await loader.init()
initMonaco(monaco_, uiVariables)
const editor = monaco_.editor.create(editorElement.value!, {
value: props.value, // set the initial value of the editor
theme: defaultThemeName,
language: 'spx', // define the language mode
Expand Down Expand Up @@ -56,8 +72,8 @@ onMounted(() => {

editor.addAction({
id: 'format',
label: 'Format Code',
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyL],
label: t({ zh: '格式化', en: 'Format Code' }),
keybindings: [KeyMod.CtrlCmd | KeyCode.KeyL],
contextMenuGroupId: 'navigation',
run: format
})
Expand All @@ -66,17 +82,18 @@ onMounted(() => {
emit('update:value', editor.getValue())
})

monaco.value = monaco_
monacoEditor.value = editor
})

onUnmounted(() => {
monacoEditor.value?.dispose()
onClenaup(() => {
editor.dispose()
})
})

watch(
() => props.value,
(val) => {
if (monacoEditor.value) {
if (monaco.value && monacoEditor.value) {
const editorValue = monacoEditor.value.getValue()
if (val !== editorValue) {
monacoEditor.value.setValue(val)
Expand All @@ -85,7 +102,7 @@ watch(
}
)

function insertSnippet(snippet: monaco.languages.CompletionItem, position?: monaco.Position) {
function insertSnippet(snippet: languages.CompletionItem, position?: Position) {
const editor = monacoEditor.value
if (editor == null) return

Expand All @@ -105,10 +122,10 @@ async function format() {
if (res.Body) {
editor.setValue(res.Body)
} else {
monaco.editor.setModelMarkers(editor.getModel()!, 'owner', [
monaco.value?.editor.setModelMarkers(editor.getModel()!, 'owner', [
{
message: res.Error.Msg,
severity: monaco.MarkerSeverity.Warning,
severity: MarkerSeverity.Warning,
startLineNumber: res.Error.Line,
startColumn: res.Error.Column,
endLineNumber: res.Error.Column,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { onMounted } from 'vue'
import * as monaco from 'monaco-editor'
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import { keywords, brackets, typeKeywords, operators } from '@/utils/spx'
import type { FormatResponse } from '@/apis/util'
import formatWasm from '@/assets/format.wasm?url'
import { allSnippets } from './snippets'
import { useUIVariables } from '@/components/ui'
import type { IRange, languages } from 'monaco-editor'

function completionItem(
range: monaco.IRange | monaco.languages.CompletionItemRanges
): monaco.languages.CompletionItem[] {
range: IRange | languages.CompletionItemRanges,
monaco: typeof import('monaco-editor')
): languages.CompletionItem[] {
return [
...keywords.map((keyword) => ({
label: keyword,
Expand Down Expand Up @@ -47,7 +47,10 @@ async function initFormatWasm() {
export const defaultThemeName = 'spx-default-theme'

/** Global initializations for monaco editor */
function init({ color }: ReturnType<typeof useUIVariables>) {
export function initMonaco(
monaco: typeof import('monaco-editor'),
{ color }: ReturnType<typeof useUIVariables>
) {
self.MonacoEnvironment = {
getWorker() {
return new EditorWorker()
Expand Down Expand Up @@ -216,24 +219,11 @@ function init({ color }: ReturnType<typeof useUIVariables>) {
startColumn: word.startColumn,
endColumn: word.endColumn
}
const suggestions: monaco.languages.CompletionItem[] = completionItem(range)
const suggestions: languages.CompletionItem[] = completionItem(range, monaco)
return { suggestions }
}
})

// tempararily disable in-browser format
// initFormat()
}

let inited = false

/** Ensure global initializations for monaco editor */
export function useMonacoInitialization() {
const uiVariables = useUIVariables()

onMounted(() => {
if (inited) return
init(uiVariables)
inited = true
})
}
2 changes: 2 additions & 0 deletions spx-gui/src/components/top-nav/TopNav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ const langContent = computed(() => (i18n.lang.value === 'en' ? enSvg : zhSvg))

function toggleLang() {
i18n.setLang(i18n.lang.value === 'en' ? 'zh' : 'en')
// Refresh the page to apply the new language for monaco editor
location.reload()
}

const handleSave = useMessageHandle(
Expand Down
Loading