如何将 javascript 自动完成添加到摩纳哥编辑器的降价模式?

How do I add javascript autocomplete to markdown mode of monaco editor?

我也希望能够在 markdown 文档中使用 monaco 编辑器的 javascript-自动完成功能,因为 markdown 文档可以包含 javascript:[=14= 类型的代码片段]

```javascript
window.blah
```

我知道我可以为降价注册自定义 CompletionItemProvider,但我想使用摩纳哥已经提供的 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-自动完成功能?

你走在正确的轨道上。以下是我如何使用 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;
    }