摩纳哥在自定义语言中输入单词时触发自动完成?

问题描述 投票:0回答:0

我基本上想使用 React 的 Monaco 编辑器 以幻想语言、自然语言(只是纯文本)进行编写。我会用英语写单词,自动完成功能会将它们翻译成幻想语言(这也许是学习幻想语言词汇的更简单的方法)。所以基本上,我写英语单词,当我输入时,它会自动填充匹配的英语单词列表,当我按 Tab 键时,它应该附加幻想单词。

我该怎么做?

这是我尝试过的:

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import Editor, { Monaco } from '@monaco-editor/react'
import type monaco from 'monaco-editor'
import React, { useEffect, useState } from 'react'
import styled from 'styled-components'
import draculaTheme from '~/configurations/dracula.monaco.json'

export const configuration = {
  brackets: [
    ['{', '}'],
    ['[', ']'],
    ['(', ')'],
  ],
  comments: {
    lineComment: '#',
  },
}

function createDependencyProposals(
  monaco: Monaco,
  range: monaco.IRange,
): Array<monaco.languages.CompletionItem> {
  return [
    {
      documentation: 'beautiful',
      insertText: 'byut',
      kind: monaco.languages.CompletionItemKind.Keyword,
      label: 'beautiful',
      range,
    },
  ]
}

export const languageDef = {
  defaultToken: '',
  tokenizer: {
    root: [{ include: '@whitespace' }, { include: '@strings' }],
    strings: [[/\w+/, 'string']],
    whitespace: [[/\s+/, 'white']],
  },
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
function initializeEditor(monaco: Monaco) {
  monaco.editor.defineTheme(
    'dracula',
    draculaTheme as monaco.editor.IStandaloneThemeData,
  )

  monaco.languages.register({ id: 'bead' })

  monaco.languages.setMonarchTokensProvider(
    'bead',
    languageDef as monaco.languages.IMonarchLanguage,
  )

  monaco.languages.setLanguageConfiguration(
    'bead',
    configuration as monaco.languages.LanguageConfiguration,
  )

  return monaco.languages.registerCompletionItemProvider('bead', {
    provideCompletionItems: function (
      model: monaco.editor.ITextModel,
      position: monaco.Position,
    ) {
      // find out if we are completing a property in the 'dependencies' object.
      console.log('here')
      const range = {
        endColumn: position.column,
        endLineNumber: position.lineNumber,
        startColumn: 1,
        startLineNumber: position.lineNumber,
      }
      var textUntilPosition = model.getValueInRange(range)
      var match = textUntilPosition.match(/beau/)
      if (match) {
        return { suggestions: createDependencyProposals(monaco, range) }
      }
      return { suggestions: [] }
    },
    triggerCharacters: ['a', 'b', 'c'],
  })
}

type TextEditorPropsType = {
  defaultLanguage: string
  height: string | number
  lineNumbers?: boolean
  onChange?: (string?: string) => void
  readOnly?: boolean
  value?: string
}

const Container = styled.div(props => ({
  background: props.theme.colors.black,
  marginBottom: 16,
  marginTop: 16,
  paddingBottom: 16,
  paddingLeft: 16,
  paddingTop: 16,
}))

export default function TextEditor({
  height,
  defaultLanguage,
  onChange,
  lineNumbers,
  readOnly,
  value,
}: TextEditorPropsType) {
  const [completionDisposable, setCompletionDisposable] =
    useState<monaco.IDisposable>()

  const handleBeforeMount = (monaco: Monaco) => {
    setCompletionDisposable(initializeEditor(monaco))
  }

  useEffect(() => {
    completionDisposable?.dispose()
  }, [completionDisposable])

  return (
    <Container>
      <Editor
        height={height}
        theme="dracula"
        value={value}
        defaultLanguage={defaultLanguage}
        beforeMount={handleBeforeMount}
        onChange={onChange}
        options={{
          acceptSuggestionOnEnter: 'off',
          autoClosingBrackets: 'always',
          contextmenu: false,
          cursorStyle: 'line',
          fontSize: 16,
          hover: {
            // enabled: false,
          },
          minimap: {
            enabled: false,
          },
          parameterHints: {
            enabled: false,
          },
          quickSuggestions: {
            comments: true,
            other: true,
            strings: true,
          },
          readOnly,
          scrollbar: {
            alwaysConsumeMouseWheel: false,
            // handleMouseWheel: false,
          },
          suggestOnTriggerCharacters: true,
          tabCompletion: 'on',
          tabSize: 2,
          wordBasedSuggestions: true,
          wordWrap: 'off',
          ...(lineNumbers
            ? {}
            : {
                folding: false,
                glyphMargin: false,
                lineDecorationsWidth: 0,
                lineNumbers: 'off',
                lineNumbersMinChars: 0,
              }),
        }}
      />
    </Container>
  )
}

然后我将其用作:

<TextEditor
  height={400}
  defaultLanguage="bead"
/>

不过我明白了:

我希望当我在

b
中输入第一个字母
beautiful
时,它应该从列表中找到
beautiful
并将其替换为
byut

我尝试过的事情:

  1. triggerCharacters:我尝试设置
    triggerCharacters: ['?']
    ,尽管我不知道触发字符是什么意思。这是否意味着“接受”自动完成或初始化自动完成的字符?我希望它能够自动完成每个小写字母字符 /a-z/
  2. 添加
  3. languageDef
    configuration
    。不确定这些是否有必要,但我添加了它们。
  4. 更改编辑器选项
  5. 。比如suggestOnTriggerCharacters: true之类的。但是忽略所有自定义选项,我得到相同的结果(没有自动完成)。
    
    
  6. 我认为在连接这个过程中我遗漏了一些基本的东西。

Bead 不是一种编程语言,它是一种用空格分隔的小写字母书写的口语。所以我想用小写字母写一个英文单词,并让它吐出幻想单词。我怎样才能做到这一点?我错过了什么?

它应该正在记录

here

,但它从来没有记录过。

另外,我想避免必须按 

CTRL+Space

手动执行此操作。

    

javascript monaco-editor
© www.soinside.com 2019 - 2024. All rights reserved.