GithubHelp home page GithubHelp logo

monaco-volar's Introduction

monaco-volar

Try it!

Install

Monaco-volar has external dependency Onigasm (to highlight code).

pnpm add monaco-volar monaco-editor-core onigasm

# or

yarn add monaco-volar monaco-editor-core onigasm

Setup

Import

Import monaco-volar when you are using monaco. It will register vue as a language automatic.

import 'monaco-editor-core'
import 'monaco-volar'

Setup highlight

Init Onigasm

VSCode are using Onigasm to highlight codes. And we have adapted the Onigasm and monaco. And some pre-defined grammars.

Onigasm needs a wasm module before using. We have to load it first.

import * as onigasm from "onigasm";
import onigasmWasm from "onigasm/lib/onigasm.wasm?url";

function loadOnigasm() {
  return onigasm.loadWASM(onigasmWasm);
}

loadOnigasm()

Apply grammars

Now we can apply grammars into monaco editor instance.

import { editor } from "monaco-editor-core";
import { loadGrammars, loadTheme } from "monaco-volar";

const theme = loadTheme()

const editorInstance = editor.create(element, {
    theme,
    /* other options*/
})

loadGrammars(editorInstance);

Setup language service

Provide web worker

We need to let monaco know where and how to load out worker when using Vue.

import editorWorker from "monaco-editor-core/esm/vs/editor/editor.worker?worker";
import vueWorker from "monaco-volar/vue.worker?worker";

function loadMonacoEnv() {
  (self as any).MonacoEnvironment = {
    async getWorker(_: any, label: string) {
      if (label === "vue") {
        return new vueWorker();
      }
      return new editorWorker();
    },
  };
}

loadMonacoEnv()

Create vue model

Now we can just create a model using vue language.

const model = editor.createModel(code, 'vue', uri);

monaco-volar's People

Contributors

a145789 avatar antfu avatar baiwusanyu-c avatar johnsoncodehk avatar justineo avatar kingwl avatar sight-wcg avatar yyx990803 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

monaco-volar's Issues

Error

Reproduction

<template>
    <Comp>
        <template #first="{ state }">
            <div v-if="state.a && state.b">
            </div>
        </template>
    </Comp>
</template>

Error

image

Related

vuejs/repl#131

Fixed test's `env.ts` for usage with latests deps.

Just in case someone want to copy the test and make it work with the latest volar etc.

import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import vueWorker from "monaco-volar/vue.worker?worker";
import * as onigasm from "onigasm";
import onigasmWasm from "onigasm/lib/onigasm.wasm?url";

import type { LanguageService } from "@vue/language-service";
import { editor, languages } from "monaco-editor";
import * as volar from "@volar/monaco";

export function loadOnigasm() {
  return onigasm.loadWASM(onigasmWasm);
}

export function setupMonacoEnv(takeoverMode = false) {
  let initialized = false;

  languages.register({ id: "vue", extensions: [".vue"] });
  languages.onLanguage("vue", setup);

  if (takeoverMode) {
    languages.onLanguage("javascript", setup);
    languages.onLanguage("typescript", setup);
    languages.onLanguage("javascriptreact", setup);
    languages.onLanguage("typescriptreact", setup);
    languages.onLanguage("json", setup);
  }

  async function setup() {
    if (initialized) {
      return;
    }
    initialized = true;

    (self as any).MonacoEnvironment ??= {};
    (self as any).MonacoEnvironment.getWorker ??= () => new editorWorker();

    const getWorker = (self as any).MonacoEnvironment.getWorker;

    (self as any).MonacoEnvironment.getWorker = (_: any, label: string) => {
      if (label === "vue") {
        return new vueWorker();
      }
      return getWorker();
    };

    const worker = editor.createWebWorker<LanguageService>({
      moduleId: "vs/language/vue/vueWorker",
      label: "vue",
      createData: {},
    });
    const languageId = takeoverMode
      ? [
          "vue",
          "javascript",
          "typescript",
          "javascriptreact",
          "typescriptreact",
          "json",
        ]
      : ["vue"];
    const getSyncUris = () => editor.getModels().map((model) => model.uri);
    volar.activateMarkers(worker, languageId, "vue", getSyncUris, editor);
    volar.activateAutoInsertion(worker, languageId, getSyncUris, editor);
    await volar.registerProviders(worker, languageId, getSyncUris, languages);
  }
}

Changed:

  • volar.editor.activateAutoInsertion => volar.activateAutoInsertion, etc.
  • monaco-editor-core imports => monaco-editor for typings mismatches

Can confirm it works with:

Sorry, just tried again and using monaco-editor, while it fixes the typings issue, breaks the IntelliSense. Will post updates if needed.

  "devDependencies": {
    "typescript": "^5.2.2",
    "vite": "^5.2.0"
  },
  "dependencies": {
    "@volar/monaco": "^2.1.5",
    "@vue/language-service": "^2.0.7",
    "monaco-editor": "^0.47.0",
    "monaco-editor-core": "^0.47.0",
    "monaco-editor-textmate": "^4.0.0",
    "monaco-volar": "^0.4.0",
    "onigasm": "^2.2.5",
    "vue": "^3.4.21"
  }

Implemented in monaco-editor

It is working great so far,
Is it possible to work with monaco-editor but not monaco-editor-core ?
Or any way that I could register "vue" language in monaco-editor ?

Code not working properly

I tried to use the code from the test directory in my project.

When I replace the local reference with monaco-volar, in there

import { loadGrammars, loadTheme } from "../src/index";

import { loadGrammars, loadTheme } from "monaco-volar";

Browser console reports an error.

image

Uncaught Error: Cannot read properties of undefined (reading 'OnigString')

TypeError: Cannot read properties of undefined (reading 'OnigString')
    at Object.createOnigString (rule.js:214:27)
    at Grammar2._tokenize (grammar.js:348:35)
    at Grammar2.tokenizeLine (grammar.js:314:22)
    at Object.tokenize (index.js:41:37)
    at TokenizationSupportAdapter.tokenizeEncoded (standaloneLanguages.js:180:43)
    at safeTokenize (textModelTokens.js:383:37)
    at TextModelTokenization._heuristicallyTokenizeViewport (textModelTokens.js:321:23)
    at TextModelTokenization.tokenizeViewport (textModelTokens.js:226:14)
    at TokenizationTextModelPart.tokenizeViewport (tokenizationTextModelPart.js:138:28)
    at ViewModel.tokenizeViewport (viewModelImpl.js:119:37)
    at errors.js:15:27

I don't know why this error is happening, is it a problem with my usage.

How to addExtraLib

When addExtraLib vueuse type , but no type definition when hover

import vueuseTypes from '@vueuse/core/index.d.ts?raw';

// ....
  const vueUsemodel = getOrCreateModel(Uri.parse("file:///vueuse.d.ts"), "vue", vueuseTypes);
  languages.vue.vueDefaults.addExtraLib(
    vueUsemodel.uri.fsPath as any,
    vueUsemodel.getValue()
  );

image

typescript

Hi, I must have misunderstood something
but this doesn't work for me (in playground)
types and autocompletion and syntax highlighting for const x are wrong (both in script and template)

<script lang="ts" setup>
import { ref } from 'vue'

export interface XX {
    a: string
}

const msg = ref('hello world')
const x = ref<XX>({ a: 'X' } as XX)
</script>

<template>
    <div :value="x.a">{{ x.a }}</div>
</template>

Nuxt 3 support

Hello!

I tried @dannysmc95's project in Vue 3 and everything worked fine but when I try to implement the same code in Nuxt 3 (rc-13) something is not working.

I got this error in console on localhost

chunk-ZIRKYQSR.js?v=154af42d:1253 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'VSCODE_TEXTMATE_DEBUG')
at node_modules/.pnpm/[email protected][email protected]/node_modules/monaco-textmate/dist/debug.js
Untitled

I have the same project here on Stackblitz for reproduction.

https://github.com/denys119/node-ujgstf

Thank you in advance!

Monaco volar not working in Nuxt

I have setup an example with Vue and monaco-volar and everything works as expected.
https://github.com/dojo-vue/monaco-volar

Codesandbox with working Vue setup:
https://codesandbox.io/p/devbox/nifty-drake-pkr7jz

2024-03-09 14_29_06-Window

The same implementation is not working under Nuxt.
The syntax highlighting is working but the hover content from the volar language server is not displaying.
I'm not seeing any errors so it's a bit hard to debug. Custom hover suggestions work if added.

https://github.com/dojo-vue/nuxt-monaco-volar

2024-03-09 14_35_50-Clipboard

Codesandbox environment with Nuxt issue:
https://codesandbox.io/p/devbox/floral-shape-g3jqfk?workspaceId=e5b65ea6-731c-41c7-b94a-05025ff341b6

Any tips solving would be appreciated. Thank you!

Getting error `path2.basename` is not a function.

Created an example here:

<template>
	<div id="container" ref="monacoeditorcontainer"></div>
</template>

<script setup lang="ts">
	import * as onigasm from 'onigasm';
	import onigasmWasm from 'onigasm/lib/onigasm.wasm?url';
	import editorWorker from 'monaco-editor-core/esm/vs/editor/editor.worker?worker';
	import vueWorker from 'monaco-volar/vue.worker?worker';
	import { editor } from 'monaco-editor-core';
	import { loadGrammars, loadTheme, prepareVirtualFiles } from 'monaco-volar';
	import { onMounted, ref } from 'vue';

	const monacoeditorcontainer = ref<HTMLElement | null>(null);
	let editorInstance: unknown;

	const loadOnigasm = async () => onigasm.loadWASM(onigasmWasm);

	const loadMonacoEnv = () => {
		(self as any).MonacoEnvironment = {
			async getWorker(_: any, label: string) {
				if (label === "vue") {
					return new vueWorker();
				}
				return new editorWorker();
			},
		};
	}

	onMounted(() => {
		Promise.all([ loadMonacoEnv(), loadOnigasm(), loadTheme() ]).then(([ , , theme]) => {

			// Check for valid element.
			if (!monacoeditorcontainer.value) return;

			// Prepare the virtual files.
			prepareVirtualFiles();

			// Create the editor.
			const editorInstance = editor.create(monacoeditorcontainer.value, {
				theme,
				language: 'vue',
				automaticLayout: true,
				scrollBeyondLastLine: false,
				minimap: {
					enabled: false,
				},
				inlineSuggest: {
					enabled: false,
				},
				value: '<template>\n\t<div>Hello World</div>\n</template>',
			});

			loadGrammars(editorInstance);
		});
	});
</script>

So syntax highlighting seems to work, but I am getting an error:

errors.js:12 Uncaught Error: path2.basename is not a function

TypeError: path2.basename is not a function
    at Object.getEmbeddedFile (vue.worker.js?worker_file:210323:38)
    at ReactiveEffect.fn (vue.worker.js?worker_file:210699:68)
    at ReactiveEffect.run (vue.worker.js?worker_file:209603:23)
    at get value [as value] (vue.worker.js?worker_file:209768:39)
    at ReactiveEffect.fn (vue.worker.js?worker_file:210702:26)
    at ReactiveEffect.run (vue.worker.js?worker_file:209603:23)
    at get value [as value] (vue.worker.js?worker_file:209768:39)
    at ReactiveEffect.fn (vue.worker.js?worker_file:210790:26)
    at ReactiveEffect.run (vue.worker.js?worker_file:209603:23)
    at get value [as value] (vue.worker.js?worker_file:209768:39)
    at errors.js:12:27

Any ideas?

Tried following the README.md, but it's not very clear, I ended up following your test folder which gave me less errors, but the above is the main error I am seeing now.

Could do with a better example, as the example in gh-pages is currently compiled, so can't see what you did to get it working.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.