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

@shikijs/monaco how to use editor default theme? #580

Closed
SuperManito opened this issue Feb 8, 2024 · 15 comments
Closed

@shikijs/monaco how to use editor default theme? #580

SuperManito opened this issue Feb 8, 2024 · 15 comments

Comments

@SuperManito
Copy link

SuperManito commented Feb 8, 2024

I used monaco.editor.defineTheme() to define my personalization theme. But now it seems to conflict with the theme syntax configuration customized by getHighlighter(). I don't know how the two work together.

I previously used the monaco-editor-textmate library as a solution, as you mentioned. I'm glad to see that you have solved many problems under the native solution.

I need to use monaco.editor.defineTheme() to implement the colors key for custom editor theme configuration, such as 'editor.background'

@SuperManito
Copy link
Author

By the way, I would like to add the Atom One Light/Dark themes.

@antfu
Copy link
Member

antfu commented Feb 8, 2024

Can you explain more about how you do that and what you are trying to do? Best with a reproduction

@SuperManito
Copy link
Author

SuperManito commented Feb 8, 2024

Can you explain more about how you do that and what you are trying to do? Best with a reproduction

我正在 Vue 项目中使用摩纳哥编辑器,定义了主题 IStandaloneThemeData,里面有很多语法规则

我按照文档配置了 getHighlighter 的 themes 主题配置,我发现高亮语法渲染现在是混乱的,因为我之前使用的是 monaco-editor-textmate 的解决方案正如你们在文档中所提到的,对比了效果发现在shiki加载textmate后有些语法token高亮走的是编辑器主题的

我尝试过将 rules 删除或保留为空数组,这会让语法解释器失效

文档中并没有详细说明 themes 配置项在 monaco 子库里面是如何工作的,我目前更改编辑器主题的策略是通过覆盖 vs 和 vs-dark 这两个默认主题来实现,没有定义第三方主题,其中还涉及到深浅主题切换的问题

@SuperManito
Copy link
Author

SuperManito commented Feb 8, 2024

根据我的测试,我发现目前 getHighlighter themes 会覆盖摩纳哥编辑器的所有主题配置包括 colors

我项目需要动态加载内容就跟IDE一样,正如我上面所描述的问题关键,核心问题是需要保证在编辑器整体风格不便的情况下去加载 TextMate 语法高亮渲染,我目前找到了一个折中的解决方案:

  1. 两边的配置文件(自定义编辑器主题配置和 shiki 的vscode原生样式的主题配置)需要使用相同的name和colors配置
  2. 删除自定义编辑器主题配置的rules规则(设置为空数组)

这意味着编辑器主题全局配置 colors 被配置了两遍,这是不合理的设计,并且我还发现 getHighlighter themes colors 的一些配置项与 Monaco 原生配置项不兼容

@SuperManito
Copy link
Author

我认为需要改进的地方如下:

  1. 加强文档中对于 themes 的解释
  2. shikiToMonaco方法不再覆盖编辑器 colors 配置,让该库专注于覆盖tokens语法配置

@antfu
Copy link
Member

antfu commented Feb 8, 2024

I am sorry, but I still don't understand what you are trying to do. Please bring a minimal reproduction, or better, we can directly discuss the fix in a PR if it's not too complicated.

@SuperManito
Copy link
Author

SuperManito commented Feb 8, 2024

index

import * as monaco from 'monaco-editor'
import { shikiToMonaco } from '@shikijs/monaco'
import { getHighlighterInstance, textMateLanguages } from './useTextMate'

...

let editor: any = null

monaco.editor.defineTheme('vs', {
  inherit: false,
  base: 'vs',
  colors: {
    ...
  },
  rules: [],
} as monaco.editor.IStandaloneThemeData)
monaco.editor.defineTheme('vs-dark', {
  inherit: false,
  base: 'vs',
  colors: {
    ...
  },
  rules: [],
} as monaco.editor.IStandaloneThemeData)

// Load TextMate
;(async () => {
  const highlighter = await getHighlighterInstance()
  shikiToMonaco(highlighter, monaco)
})()

// onMounted (vue)
editor = monaco.editor.create(ref, {
  ...editorGobalOptions,
  ...editorOptions,
  value: props.value.content,
  language: props.value.language || 'plaintext',
}) as monaco.editor.IStandaloneCodeEditor

./useTextMate.ts

import { getHighlighter } from 'shiki'

export const textMateLanguages = [
  'shell',
  'python',
  'javascript',
  'typescript',
  'json',
  ...
]

let highlighter: any | null = null

export const getHighlighterInstance = async () => {
  if (!highlighter) {
    console.log('Init TextMate Start')
    highlighter = await getHighlighter({
      themes: [
       {
          displayName: 'Dark',
          name: 'vs-dark',
          semanticHighlighting: true,
          colors: {
            ...
          },
          settings: [...],
        },
        {
          displayName: 'Light',
          name: 'vs',
          semanticHighlighting: true,
          colors: {
            ...
          },
          settings: [..],
        },
      ],
      langs: textMateLanguages,
    })
    console.log('Init TextMate End')
  }
  return highlighter
}

change theme in project (global)

monaco.editor.setTheme('<vs/vs-dark>')

on did change language (vue)

watch(value, async (newValue: { content: string; language: string }) => {
  if (editor) {
    const model = editor.getModel()
    if (model) {
      const originLanguage = model.getLanguageId()
      if (originLanguage !== newValue.language) {
        monaco.editor.setModelLanguage(model, newValue.language)
        // TextMate
        if (newValue.language && textMateLanguages.includes(newValue.language)) {
          const highlighter = await getHighlighterInstance()
          shikiToMonaco(highlighter, monaco)
        }
      }
      model.setValue(newValue.content)
    }
  }
})

@SuperManito
Copy link
Author

Perhaps my usage method is incorrect. If I don't customize the editor theme colors options. There will be a transition effect from the default native theme to the new theme.

At least there are some issues now, such as compatibility issues in colors. Because I have noticed subtle differences in the effects of the editor before and after.

@antfu
Copy link
Member

antfu commented Feb 8, 2024

Why do you want to assign a theme twice? I am still not sure what you are trying to achieve.

@SuperManito
Copy link
Author

Why do you want to assign a theme twice? I am still not sure what you are trying to achieve.

If I don't customize the editor theme colors options. There will be a transition effect from the default native theme to the new theme.

@antfu
Copy link
Member

antfu commented Feb 8, 2024

I think you either use different names for native themes and shiki themes, or use shiki themes all the time from the beginning. I don't think a single theme can behaviour different on different languages. This is not Shiki's issue.

@antfu antfu closed this as not planned Won't fix, can't repro, duplicate, stale Feb 8, 2024
@SuperManito
Copy link
Author

I need change many editor global theme options. Perhaps you still haven't understood my scene.

no colors

image
image

have colors

image
image

This comparison was made with colors defined in monaco.editor.defineTheme()

@SuperManito
Copy link
Author

SuperManito commented Feb 8, 2024

Using a different theme name will indeed solve the transition error problem I mentioned above.

@SuperManito
Copy link
Author

SuperManito commented Feb 8, 2024

The entire configuration process is indeed very confusing. TextMate affects the token configuration related to grammars highlighting and should not be forced to override the default colors configuration.

@SuperManito
Copy link
Author

SuperManito commented Feb 8, 2024

I think you either use different names for native themes and shiki themes, or use shiki themes all the time from the beginning. I don't think a single theme can behaviour different on different languages. This is not Shiki's issue.

我找到了问题的关键,现在创建的自定义主题默认使用的是深色主题模板,没有像 Monaco Editor 主题配置 base 选项一样提供基准主题支持。这会导致在自定义的浅色主题模式下出现一些问题,对于高度定制的场景来说这样的体验真的是太糟糕了。

我翻了ts才找到 type 配置,这与默认 base 选项的功能一致,但是文档中并没有任何提及...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants