【问题标题】:How do I add javascript autocomplete to markdown mode of monaco editor?如何将javascript自动完成添加到摩纳哥编辑器的降价模式?
【发布时间】:2021-05-26 10:30:32
【问题描述】:

我也希望能够在 markdown 文档中使用 monaco 编辑器的 javascript-autocomplete,因为 markdown 文档可以包含 javascript 类型的代码 sn-ps:

```javascript
window.blah
```

我知道我可以为降价注册一个自定义 CompletionItemProvider,但我想使用 monaco 已经提供的 javascript。但是,我还没有找到接收他们的提供者的方法。

Javascript 语法高亮已经在markdown代码块中工作了。

我的想法是以某种方式让他们的提供者使用这样的东西:

(await monaco.languages.typescript.getJavaScriptWorker()).something

不过,为了让它工作,我必须在编辑器上注册 javascript。即使我这样做,我似乎也无法在他们的工人身上找到任何可以帮助我的东西。

虽然有注册 CompletionItemProvider (https://microsoft.github.io/monaco-editor/api/modules/monaco.languages.html#registercompletionitemprovider) 的方法,但我找不到任何可以帮助我获得注册提供程序的方法。

如何在 markdown 代码块中使用 javascript-autocomplete?

【问题讨论】:

    标签: javascript monaco-editor


    【解决方案1】:

    你在正确的轨道上。以下是我如何使用 typescript/javascript worker API 在混合语言环境中提供完成:

                    return new Promise((resolve) => {
                        const workerPromise = (context.language === "javascript")
                            ? languages.typescript.getJavaScriptWorker()
                            : languages.typescript.getTypeScriptWorker();
                        void workerPromise.then((worker: (...uris: Uri[]) => Promise<TypescriptWorker>) => {
                            void worker(model.uri).then((service) => {
                                const offset = model.getOffsetAt(localPosition);
                                const promise = service.getCompletionsAtPosition(model.uri.toString(), offset);
    
                                void promise.then((completions: CompletionInfo | undefined) => {
                                    if (completions) {
                                        const info = model.getWordUntilPosition(localPosition);
                                        const replaceRange: IRange = {
                                            startLineNumber: position.lineNumber,
                                            startColumn: info.startColumn,
                                            endLineNumber: position.lineNumber,
                                            endColumn: info.endColumn,
                                        };
    
                                        resolve({
                                            incomplete: false,
                                            suggestions: completions.entries.map((entry) => ({
                                                label: entry.name,
                                                kind: this.convertKind(entry.kind),
                                                range: replaceRange,
                                                insertText: entry.insertText || entry.name,
                                            } as CompletionItem)),
                                        });
                                    } else {
                                        resolve({ incomplete: false, suggestions: [] });
                                    }
                                });
                            });
                        });
                    });
    

    这里重要的是,您创建的子模型仅包含单一语言的部分内容(请参阅Monaco.createModel())并使用它来调用完成项代码。

    在我的应用程序中,我将编辑器的内容分成多个块(每个块只覆盖整行并且附加了特定的语言)。所以他们有一条起点线和一条终点线。有了这些信息,我可以为每个块创建子模型:

        /**
         * @returns A local model which contains only the text of this block. The caller must dispose of it!
         */
        public get model(): Monaco.ITextModel {
            const editorModel = super.model; // Model for the entire editor content.
    
            if (!this.internalModel || this.internalModel.isDisposed()) {
                const localModel = Monaco.createModel("", this.language);
                // Do other required preparations of the local model, if needed.
                this.internalModel = localModel;
            }
    
            if (editorModel && this.modelNeedsUpdate) {
                this.modelNeedsUpdate = false;
                this.internalModel.setValue(editorModel.getValueInRange(
                    {
                        startLineNumber: this.startLine,
                        startColumn: 1,
                        endLineNumber: this.endLine,
                        endColumn: editorModel.getLineMaxColumn(this.endLine),
                    }, Monaco.EndOfLinePreference.LF),
                );
            }
    
            return this.internalModel;
        }
    

    【讨论】:

    • 感谢您的回答。我真正不明白的是如何调用此代码。我目前每个文件都有一个模型,如何使用您建议的这些子模型?您能否展示一个简短的代码-sn-p 让我开始使用这些子模型?
    • 我用代码更新了我的答案以创建子模型。
    • 好的,现在有点清楚了,但是我该怎么处理这些子模型呢?摩纳哥编辑器可以容纳多个模型吗?如何将这些子模型放在一个编辑器中?
    • 您仅将子模型用于语言服务 API。编辑器仍然有自己的整体(完整)模型。您必须将子模型保存在自己的结构中,以便跟踪主文档中的子区域。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多