diff --git a/apps/lsp/src/custom.ts b/apps/lsp/src/custom.ts index 726f790b..8606eb41 100644 --- a/apps/lsp/src/custom.ts +++ b/apps/lsp/src/custom.ts @@ -31,7 +31,8 @@ import { Hover, Position, TextDocuments } from "vscode-languageserver"; import { CodeViewCellContext, CodeViewCompletionContext, kCodeViewAssist, kCodeViewGetDiagnostics, kCodeViewGetCompletions, LintItem } from "editor-types"; import { yamlCompletions } from "./service/providers/completion/completion-yaml"; import { yamlHover } from "./service/providers/hover/hover-yaml"; -import { EditorContext, Quarto, codeEditorContext } from "./service/quarto"; +import { EditorContext, codeEditorContext } from "./service/quarto"; +import { Quarto } from "./quarto"; export function registerCustomMethods( quarto: Quarto, diff --git a/apps/lsp/src/quarto.ts b/apps/lsp/src/quarto.ts index 60a4877f..c1965197 100644 --- a/apps/lsp/src/quarto.ts +++ b/apps/lsp/src/quarto.ts @@ -31,7 +31,6 @@ import { import { QuartoContext } from "quarto-core"; import { - Quarto, CompletionResult, EditorContext, HoverResult, @@ -42,6 +41,16 @@ import { } from "./service/quarto"; import { LintItem } from "editor-types"; +export interface Quarto extends QuartoContext { + getYamlCompletions(context: EditorContext): Promise; + getAttrCompletions( + token: AttrToken, + context: EditorContext + ): Promise; + getYamlDiagnostics(context: EditorContext): Promise; + getHover?: (context: EditorContext) => Promise; +} + export async function initializeQuarto(context: QuartoContext): Promise { const quartoModule = await initializeQuartoYamlModule(context.resourcePath) as QuartoYamlModule; return { diff --git a/apps/lsp/src/service/quarto.ts b/apps/lsp/src/service/quarto.ts index 99d541e0..333150f6 100644 --- a/apps/lsp/src/service/quarto.ts +++ b/apps/lsp/src/service/quarto.ts @@ -13,12 +13,11 @@ * */ -import { CompletionItem, Position } from "vscode-languageserver-types"; +import { Position } from "vscode-languageserver-types"; -import { QuartoContext, Document, filePathForDoc, isQuartoDoc, isQuartoRevealDoc, isQuartoYaml, isQuartoDashboardDoc } from "quarto-core"; +import { Document, filePathForDoc, isQuartoDoc, isQuartoRevealDoc, isQuartoYaml, isQuartoDashboardDoc } from "quarto-core"; import { lines } from "core"; -import { LintItem } from "editor-types"; export interface CompletionResult { token: string; @@ -28,7 +27,7 @@ export interface CompletionResult { export interface HoverResult { content: string; - range: { start: Position; end: Position }; + range: { start: Position; end: Position; }; } export interface Completion { @@ -78,17 +77,6 @@ export interface AttrToken { token: string; } -export interface Quarto extends QuartoContext { - getYamlCompletions(context: EditorContext): Promise; - getAttrCompletions( - token: AttrToken, - context: EditorContext - ): Promise; - getYamlDiagnostics(context: EditorContext): Promise; - getHover?: (context: EditorContext) => Promise; -} - - export function codeEditorContext( path: string, filetype: string, @@ -149,5 +137,5 @@ export function docEditorContext( false, explicit, trigger - ) + ); } diff --git a/apps/overview.md b/apps/overview.md new file mode 100644 index 00000000..624242f0 --- /dev/null +++ b/apps/overview.md @@ -0,0 +1,167 @@ +## Terminology + +- Source Editor + - controlled by VSCode/Positron + - we add some functionality to the source editor by registering commands and + providing our LSP + +- Visual Editor + - controlled by this repo! See CLIENT below. + +- EXTENSION HOST + - a.k.a. HOST + - code lives in [./vscode](./vscode/) and various packages + - entry point in [main.ts](./vscode/src/main.ts), this is the entry point to + the entire extension. The `activate` function is called by VSCODE/Positron + to start the extension. +- CLIENT + - a.k.a. Visual Editor + - code lives in [./vscode-editor](./vscode-editor/) and various packages + - initialized in the HOST by `VisualEditorProvider` in + [editor.ts](./vscode/src/providers/editor/editor.ts) + - more specifically, the actual html with css and scripts for the Visual + Editor is created in `getHtmlForWebview` + - this is loaded into a webview, a separate process from the HOST, + containing the Visual Editor + - there may be multiple CLIENTs running at the same time (one for every file + open in the Visual Editor). There is code in here to manage and coordinate + from the HOST to multiple CLIENTs. + - entry point in `runEditor` in [index.tsx](./vscode-editor/src/index.tsx) +- LSP + - code lives in [./vscode](./vscode/src/lsp/) + - initialized in the HOST by `activateLSP` in + [client.ts](./vscode/src/lsp/client.ts) + - entry point in [index.ts](./lsp/src/index.ts) + - this runs in a separate process from the HOST + +## Handling User Input + +- VSCODE/POSITRON --commands-> EXTENSION HOST + - see [package.json](./vscode/package.json) for declaration of commands + - see [main.ts](./vscode/src/main.ts) for registration of command + +- Look for "behaviors" in ProseMirror, CodeMirror + - arrow keys, ctrl+z, mouse click, etc. + +- [commands in Ace](packages/editor/src/optional/ace/ace.ts) + - used instead of CodeMirror for code cells in the Visual Editor in RStudio + +## Communication boundaries + +- EXTENSION HOST <-req-> CLIENT + - Set up on the EXTENSION HOST side: + [connection.ts](./vscode/src/providers/editor/connection.ts) + `visualEditorServer` and `visualEditorClient` + - Set up on the CLIENT side: [sync.ts](./vscode-editor/src/sync.ts) + `visualEditorHostServer` and `visualEditorHostClient` + - Communication is sent by using `request: JsonRpcRequestTransport` e.g. + `request(kCodeViewGetDiagnostics, [context])` + +- EXTENSION HOST --req-> LSP + - received by [custom.ts](./lsp/src/custom.ts) + - sent by `lspRequest: JsonRpcRequestTransport` +- EXTENSION HOST <-req-- LSP + - I don't think this happens? + +- EXTENSION HOST / LSP --command-> VSCODE/POSITRON + - sent by `vscode.commands.executeCommand(..)` + +- LSP <-provider-- VSCODE/POSITRON + - How does this work? + +- LSP --req-> Quarto CLI + - [quarto.ts](./lsp/src/quarto.ts) defines the methods that the LSP uses to + call the Quarto CLI. + +## Logging + +You can use `console.log`. When running an extension development host to test +out the extension there are a couple of places where your logs can end up: + +- browser console or `window` output console for [[CLIENT]] and [[EXTENSION + HOST]] code + - logs from these two places will look different. Logs from [[CLIENT]] will + look like normal logs; logs from [[EXTENSION HOST]] will have a blue prefix + that says EXTENSION HOST. +- `Quarto` output console for [[LSP]] code + +## Examples of Controlling the Visual Editor from the server-side of the extension + +### Example: Setting cursor position + +for example in [commands.ts](./vscode/src/providers/cell/commands.ts): + +```ts +const visualEditor = VisualEditorProvider.activeEditor(); +visualEditor.setBlockSelection(blockContext, "nextblock"); +``` + +which passes through `VisualEditorPovider`, `visualEditorClient`, +`visualEditorHostServer`, `Editor`. See the "Communication Boundaries" section. + +## Examples of Getting server-side info from the Visual Editor + +### Example: Getting diagnostics + +For example in +[diagnostics.ts](../packages/editor-codemirror/src/behaviors/diagnostics.ts) + +```ts +const diagnostics = await getDiagnostics(cellContext, behaviorContext); +if (!diagnostics) return; + +for (const error of diagnostics) { + underline( + cmView, + rowColumnToIndex(code, [error[kStartColumn], error[kStartRow]]), + rowColumnToIndex(code, [error[kEndColumn], error[kEndRow]]), + error.text, + ); +} +``` + +which passes through + +- [[CLIENT]] [services.ts](../packages/editor-core/src/services.ts) function + `editorCodeViewJsonRpcServer` registers `codeViewDiagnostics` calls + `request(kCodeViewGetDiagnostics` + - request seems to communicate from the CLIENT to the EXTENSION HOST? +- [[EXTENSION HOST]] + [codeview.ts](../packages/editor-server/src/services/codeview.ts) function + `codeViewServerMethods` registers `kCodeViewGetDiagnostics` calls + `server.codeViewDiagnostics` +- [[EXTENSION HOST]] + [other codeview.ts](./vscode/src/providers/editor/codeview.ts) function + `vscodeCodeViewServer` return object with prop `codeViewDiagnostics` calls + `lspRequest(kCodeViewGetDiagnostics, [context])` +- [[LSP]] [custom.ts](./lsp/src/custom.ts) `codeViewDiagnostics` + `getYamlDiagnostics` + - `initializeQuartoYamlModule` + +#### Examples providing information to the Source Editor + +### Example: Completions + +- [vdoc-completion.ts](./vscode/src/vdoc/vdoc-completion.ts) + +```ts +await withVirtualDocUri(vdoc, parentUri, "completion", async (uri: Uri) => { + return await commands.executeCommand( + "vscode.executeCompletionItemProvider" + ... +``` + +In the Visual Editor, completions are obtained via +[codeview.ts](./vscode/src/providers/editor/codeview.ts) + +In the Source Editor, completions are obtained `embeddedCodeCompletionProvider` +in [client.ts](./vscode/src/lsp/client.ts) + +### Example: Positron Specific - Help Topic & Statement Range + +`EmbeddedStatementRangeProvider` or `EmbeddedHelpTopicProvider` in +[hooks.ts](./vscode/src/host/hooks.ts) + +- simply executes the command "vscode.executeStatementRangeProvider" or + "positron.executeHelpTopicProvider" respectively inside a virtual doc for a + cell diff --git a/apps/vscode/src/extension.ts b/apps/vscode/src/extension.ts deleted file mode 100644 index b85e7e2b..00000000 --- a/apps/vscode/src/extension.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * extension.ts - * - * Copyright (C) 2022 by Posit Software, PBC - * - * Unless you have received this program directly from Posit Software pursuant - * to the terms of a commercial license agreement with Posit Software, then - * this program is licensed to you under the terms of version 3 of the - * GNU Affero General Public License. This program is distributed WITHOUT - * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the - * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. - * - */ - -import * as vscode from "vscode"; -import { MarkdownEngine } from "./markdown/engine"; -import { activateBackgroundHighlighter } from "./providers/background"; -import { Command, CommandManager } from "./core/command"; -import { newDocumentCommands } from "./providers/newdoc"; -import { insertCommands } from "./providers/insert"; -import { activateDiagram } from "./providers/diagram/diagram"; -import { activateOptionEnterProvider } from "./providers/option"; -import { textFormattingCommands } from "./providers/text-format"; -import { activateCodeFormatting } from "./providers/format"; -import { activateContextKeySetter } from "./providers/context-keys"; -import { ExtensionHost } from "./host"; - -export function activateCommon( - context: vscode.ExtensionContext, - host: ExtensionHost, - engine: MarkdownEngine, - commands?: Command[] -) { - // option enter handler - activateOptionEnterProvider(context, engine); - - // background highlighter - activateBackgroundHighlighter(context, engine); - - // context setter - activateContextKeySetter(context, engine); - - // diagramming - const diagramCommands = activateDiagram(context, host, engine); - - // code formatting - const codeFormattingCommands = activateCodeFormatting(engine); - - // commands (common + passed) - const commandManager = new CommandManager(); - for (const cmd of codeFormattingCommands) { - commandManager.register(cmd); - } - for (const cmd of textFormattingCommands()) { - commandManager.register(cmd); - } - for (const cmd of newDocumentCommands()) { - commandManager.register(cmd); - } - for (const cmd of insertCommands(engine)) { - commandManager.register(cmd); - } - for (const cmd of diagramCommands) { - commandManager.register(cmd); - } - if (commands) { - for (const cmd of commands) { - commandManager.register(cmd); - } - } - context.subscriptions.push(commandManager); -} diff --git a/apps/vscode/src/host/hooks.ts b/apps/vscode/src/host/hooks.ts index 13bd2708..aebeaf37 100644 --- a/apps/vscode/src/host/hooks.ts +++ b/apps/vscode/src/host/hooks.ts @@ -1,6 +1,8 @@ /* * hooks.ts * + * Positron-specific functionality. + * * Copyright (C) 2022 by Posit Software, PBC * * Unless you have received this program directly from Posit Software pursuant @@ -21,7 +23,6 @@ import { CellExecutor, cellExecutorForLanguage, executableLanguages, isKnitrDocu import { ExecuteQueue } from './execute-queue'; import { MarkdownEngine } from '../markdown/engine'; import { virtualDoc, adjustedPosition, unadjustedRange, withVirtualDocUri } from "../vdoc/vdoc"; -import { EmbeddedLanguage } from '../vdoc/languages'; declare global { function acquirePositronApi(): hooks.PositronApi; @@ -76,7 +77,7 @@ export function hooksExtensionHost(): ExtensionHost { for (const block of blocks) { await runtime.executeCode(language, block, false, true); } - } + }; await ExecuteQueue.instance.add(language, callback); }, @@ -164,32 +165,18 @@ class EmbeddedStatementRangeProvider implements HostStatementRangeProvider { token: vscode.CancellationToken): Promise { const vdoc = await virtualDoc(document, position, this._engine); if (vdoc) { - return await withVirtualDocUri(vdoc, document.uri, "statementRange", async (uri: vscode.Uri) => { - return getStatementRange( - uri, - adjustedPosition(vdoc.language, position), - vdoc.language - ); - }); + const result = await vscode.commands.executeCommand( + "vscode.executeStatementRangeProvider", + document.uri, + adjustedPosition(vdoc.language, position) + ); + return { range: unadjustedRange(vdoc.language, result.range), code: result.code }; } else { return undefined; } }; } -async function getStatementRange( - uri: vscode.Uri, - position: vscode.Position, - language: EmbeddedLanguage -) { - const result = await vscode.commands.executeCommand( - "vscode.executeStatementRangeProvider", - uri, - position - ); - return { range: unadjustedRange(language, result.range), code: result.code }; -} - class EmbeddedHelpTopicProvider implements HostHelpTopicProvider { private readonly _engine: MarkdownEngine; diff --git a/apps/vscode/src/host/index.ts b/apps/vscode/src/host/index.ts index 929d0f1c..3100c59f 100644 --- a/apps/vscode/src/host/index.ts +++ b/apps/vscode/src/host/index.ts @@ -13,15 +13,16 @@ * */ -import vscode, { DocumentSelector, Disposable, WebviewPanelOptions, WebviewOptions } from "vscode"; +import vscode, { DocumentSelector, Disposable, WebviewPanelOptions, WebviewOptions, window } from "vscode"; import { CellExecutor, cellExecutorForLanguage, executableLanguages, isKnitrDocument } from "./executors"; import { EditorToolbarProvider } from "./toolbar"; -import { createPreviewPanel } from "./preview"; import { hasHooks, hooksExtensionHost } from "./hooks"; import { TextDocument } from "vscode"; import { MarkdownEngine } from "../markdown/engine"; +import { WebviewPanel } from "vscode"; +import { ViewColumn } from "vscode"; export type { CellExecutor }; export type { EditorToolbarProvider, ToolbarItem, ToolbarCommand, ToolbarButton, ToolbarMenu } from './toolbar'; @@ -55,6 +56,11 @@ export interface HostHelpTopicProvider { ): vscode.ProviderResult; } +/** + * There are currently two extension hosts: + * - [`hooksExtensionHost`](./hooks.ts) for Positron + * - [`defaultExtensionHost`](./index.ts) otherwise + */ export interface ExtensionHost { // code execution @@ -112,13 +118,20 @@ function defaultExtensionHost(): ExtensionHost { return languages.filter(language => knitr || !visualMode || (language !== "python")); }, cellExecutorForLanguage, - // in the default extension host, both of these are just a noop: - registerStatementRangeProvider: (engine: MarkdownEngine): vscode.Disposable => { - return new vscode.Disposable(() => { }); - }, - registerHelpTopicProvider: (engine: MarkdownEngine): vscode.Disposable => { - return new vscode.Disposable(() => { }); - }, - createPreviewPanel, + // In contrast to the Positron-specific `hooksExtensionHost`, here in the default host we + // do not have statement range or help topic functionality + registerStatementRangeProvider: doNothing, + registerHelpTopicProvider: doNothing, + createPreviewPanel: ( + viewType: string, + title: string, + preserveFocus?: boolean, + options?: WebviewPanelOptions & WebviewOptions + ): WebviewPanel => { + return window.createWebviewPanel(viewType, title, { viewColumn: ViewColumn.Beside, preserveFocus, }, options); + } }; } + +const doNothing = (engine: MarkdownEngine): vscode.Disposable => + new vscode.Disposable(() => { }); diff --git a/apps/vscode/src/host/preview.ts b/apps/vscode/src/host/preview.ts deleted file mode 100644 index fd81df5b..00000000 --- a/apps/vscode/src/host/preview.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * preview.ts - * - * Copyright (C) 2022 by Posit Software, PBC - * - * Unless you have received this program directly from Posit Software pursuant - * to the terms of a commercial license agreement with Posit Software, then - * this program is licensed to you under the terms of version 3 of the - * GNU Affero General Public License. This program is distributed WITHOUT - * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the - * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. - * - */ - -import { window, WebviewPanel, WebviewOptions, WebviewPanelOptions, ViewColumn } from "vscode"; - -export function createPreviewPanel( - viewType: string, - title: string, - preserveFocus?: boolean, - options?: WebviewPanelOptions & WebviewOptions -): WebviewPanel { - return window.createWebviewPanel( - viewType, - title, - { - viewColumn: ViewColumn.Beside, - preserveFocus, - }, - options - ); -} diff --git a/apps/vscode/src/main.ts b/apps/vscode/src/main.ts index bb7712f6..7150a3ee 100644 --- a/apps/vscode/src/main.ts +++ b/apps/vscode/src/main.ts @@ -22,7 +22,6 @@ import { activateLsp, deactivate as deactivateLsp } from "./lsp/client"; import { cellCommands } from "./providers/cell/commands"; import { quartoCellExecuteCodeLensProvider } from "./providers/cell/codelens"; import { activateQuartoAssistPanel } from "./providers/assist/panel"; -import { activateCommon } from "./extension"; import { activatePreview } from "./providers/preview/preview"; import { activateRender } from "./providers/render"; import { activateStatusBar } from "./providers/statusbar"; @@ -31,12 +30,24 @@ import { activateLuaTypes } from "./providers/lua-types"; import { activateCreate } from "./providers/create/create"; import { activateEditor } from "./providers/editor/editor"; import { activateCopyFiles } from "./providers/copyfiles"; -import { activateZotero } from "./providers/zotero/zotero";; +import { activateZotero } from "./providers/zotero/zotero"; import { extensionHost } from "./host"; import { initQuartoContext } from "quarto-core"; import { configuredQuartoPath } from "./core/quarto"; import { activateDenoConfig } from "./providers/deno-config"; +import { textFormattingCommands } from "./providers/text-format"; +import { newDocumentCommands } from "./providers/newdoc"; +import { insertCommands } from "./providers/insert"; +import { activateDiagram } from "./providers/diagram/diagram"; +import { activateCodeFormatting } from "./providers/format"; +import { activateOptionEnterProvider } from "./providers/option"; +import { activateBackgroundHighlighter } from "./providers/background"; +import { activateContextKeySetter } from "./providers/context-keys"; +import { CommandManager } from "./core/command"; +/** + * Entry point for the entire extension! This initializes the LSP, quartoContext, extension host, and more... + */ export async function activate(context: vscode.ExtensionContext) { // create output channel for extension logs and lsp client logs const outputChannel = vscode.window.createOutputChannel("Quarto", { log: true }); @@ -118,6 +129,16 @@ export async function activate(context: vscode.ExtensionContext) { const createCommands = await activateCreate(context, quartoContext); commands.push(...createCommands); + commands.push(...textFormattingCommands()); + + commands.push(...newDocumentCommands()); + + commands.push(...insertCommands(engine)); + + commands.push(...activateDiagram(context, host, engine)); + + commands.push(...activateCodeFormatting(engine)); + // provide code lens vscode.languages.registerCodeLensProvider( kQuartoDocSelector, @@ -127,8 +148,21 @@ export async function activate(context: vscode.ExtensionContext) { // provide file copy/drop handling activateCopyFiles(context); - // activate providers common to browser/node - activateCommon(context, host, engine, commands); + // option enter handler + activateOptionEnterProvider(context, engine); + + // background highlighter + activateBackgroundHighlighter(context, engine); + + // context setter + activateContextKeySetter(context, engine); + + // commands + const commandManager = new CommandManager(); + for (const cmd of commands) { + commandManager.register(cmd); + } + context.subscriptions.push(commandManager); // Register configuration change listener for Quarto path settings registerQuartoPathConfigListener(context, outputChannel); diff --git a/apps/vscode/src/providers/cell/commands.ts b/apps/vscode/src/providers/cell/commands.ts index a95b1d80..11a07a39 100644 --- a/apps/vscode/src/providers/cell/commands.ts +++ b/apps/vscode/src/providers/cell/commands.ts @@ -1,6 +1,8 @@ /* * commands.ts * + * commands for executing code in cells, both in the Source Editor and Visual Editor. + * * Copyright (C) 2022 by Posit Software, PBC * * Unless you have received this program directly from Posit Software pursuant @@ -73,7 +75,6 @@ abstract class RunCommand { ) { } public async execute(line?: number): Promise { - // see if this is for the visual or the source editor const visualEditor = VisualEditorProvider.activeEditor(); if (visualEditor) { @@ -145,6 +146,8 @@ abstract class RunCommand { } private async hasExecutorForLanguage(language: string, document: TextDocument, engine: MarkdownEngine) { + // TODO: this is incorrect right? `cellExecutorForLanguage` returns a promise, and a promise will always be truthy? + // We should have to await it before doing `!!` return !!this.cellExecutorForLanguage(language, document, engine); } diff --git a/apps/vscode/src/providers/editor/codeview.ts b/apps/vscode/src/providers/editor/codeview.ts index a05d0282..13a990ce 100644 --- a/apps/vscode/src/providers/editor/codeview.ts +++ b/apps/vscode/src/providers/editor/codeview.ts @@ -47,13 +47,14 @@ import { LintItem } from "editor-types"; -import { hasHooks } from "../../host/hooks"; import { embeddedLanguage } from "../../vdoc/languages"; import { virtualDocForCode } from "../../vdoc/vdoc"; import { vdocCompletions } from "../../vdoc/vdoc-completion"; import { MarkdownEngine } from "../../markdown/engine"; - +/** + * In the host, this initializes functions that can be called by the client (the visual editor) for doing code cell things. + */ export function vscodeCodeViewServer(_engine: MarkdownEngine, document: TextDocument, lspRequest: JsonRpcRequestTransport): CodeViewServer { return { async codeViewAssist(context: CodeViewCellContext) { diff --git a/packages/editor-types/src/codeview.ts b/packages/editor-types/src/codeview.ts index 349a961a..2977f404 100644 --- a/packages/editor-types/src/codeview.ts +++ b/packages/editor-types/src/codeview.ts @@ -20,6 +20,9 @@ export const kCodeViewAssist = 'code_view_assist'; export const kCodeViewGetCompletions = 'code_view_get_completions'; export const kCodeViewExecute = 'code_view_execute'; export const kCodeViewPreviewDiagram = 'code_view_preview_diagram'; +/** + * for calling [`codeViewDiagnostics` in custom.ts](../../../apps/lsp/src/custom.ts) + */ export const kCodeViewGetDiagnostics = 'code_view_get_diagnostics'; export type CodeViewExecute = "selection" | "cell" | "cell+advance" | "above" | "below"; @@ -59,6 +62,9 @@ export interface CodeViewCompletionContext extends CodeViewCellContext { explicit: boolean; } +/** + * Constructed by `vscodeCodeViewServer` in [codeview.ts](../../../apps/vscode/src/providers/editor/codeview.ts). + */ export interface CodeViewServer { codeViewAssist: (contxt: CodeViewCellContext) => Promise; codeViewExecute: (execute: CodeViewExecute, context: CodeViewActiveBlockContext) => Promise;