From dca4735acc984eae8069de8dae4e6748ee7f09e8 Mon Sep 17 00:00:00 2001 From: Julia Silge Date: Tue, 26 Nov 2024 14:06:58 -0700 Subject: [PATCH] Set context keys for document language (#608) * Set context keys for cell language when background is painted * Update changelog * Do not set context keys along with painting background * Add new `activateContextKeySetter()` * Context keys only apply to *active* documents * We don't need `onDidOpenTextDocument()` because we have `onDidChangeActiveTextEditor()` --- apps/vscode/CHANGELOG.md | 2 +- apps/vscode/src/extension.ts | 4 ++ apps/vscode/src/providers/context-keys.ts | 69 +++++++++++++++++++++++ apps/vscode/src/vdoc/vdoc.ts | 8 +-- 4 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 apps/vscode/src/providers/context-keys.ts diff --git a/apps/vscode/CHANGELOG.md b/apps/vscode/CHANGELOG.md index 490e1432..89c6d2ee 100644 --- a/apps/vscode/CHANGELOG.md +++ b/apps/vscode/CHANGELOG.md @@ -3,7 +3,7 @@ ## 1.118.0 (unreleased) - Provide F1 help at cursor in Positron () -- Expose new context keys for the language of a specific cell () +- Expose new context keys for the main language of a document () - No longer send all snippet suggestions to the bottom of the completion list (). ## 1.117.0 (Release on 2024-11-07) diff --git a/apps/vscode/src/extension.ts b/apps/vscode/src/extension.ts index 251db7b9..b85e7e2b 100644 --- a/apps/vscode/src/extension.ts +++ b/apps/vscode/src/extension.ts @@ -23,6 +23,7 @@ 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( @@ -37,6 +38,9 @@ export function activateCommon( // background highlighter activateBackgroundHighlighter(context, engine); + // context setter + activateContextKeySetter(context, engine); + // diagramming const diagramCommands = activateDiagram(context, host, engine); diff --git a/apps/vscode/src/providers/context-keys.ts b/apps/vscode/src/providers/context-keys.ts new file mode 100644 index 00000000..7b7dca6b --- /dev/null +++ b/apps/vscode/src/providers/context-keys.ts @@ -0,0 +1,69 @@ +/* + * context-keys.ts + * + * Copyright (C) 2024 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 debounce from "lodash.debounce"; + +import { isQuartoDoc } from "../core/doc"; +import { MarkdownEngine } from "../markdown/engine"; +import { mainLanguage } from "../vdoc/vdoc"; + +const debounceOnDidChangeDocumentMs = 250; + +export function activateContextKeySetter( + context: vscode.ExtensionContext, + engine: MarkdownEngine +) { + + // set context keys when active text editor changes + vscode.window.onDidChangeActiveTextEditor( + (editor) => { + if (editor) { + setContextKeys(editor, engine); + } + }, + null, + context.subscriptions + ); + + // set context keys on changes to the document (if it's active) + vscode.workspace.onDidChangeTextDocument( + (event) => { + const activeEditor = vscode.window.activeTextEditor; + if (activeEditor) { + debounce( + () => setContextKeys(activeEditor, engine), + debounceOnDidChangeDocumentMs + )(); + } + }, + null, + context.subscriptions + ); +} + +function setContextKeys(editor: vscode.TextEditor, engine: MarkdownEngine) { + if (!editor || !isQuartoDoc(editor.document)) { + return; + } + + // expose main language for use in keybindings, etc + const tokens = engine.parse(editor.document); + const language = mainLanguage(tokens); + vscode.commands.executeCommand( + 'setContext', + 'quarto.document.languageId', + language?.ids[0]); +} diff --git a/apps/vscode/src/vdoc/vdoc.ts b/apps/vscode/src/vdoc/vdoc.ts index 4e011fd6..bfe942a9 100644 --- a/apps/vscode/src/vdoc/vdoc.ts +++ b/apps/vscode/src/vdoc/vdoc.ts @@ -13,7 +13,7 @@ * */ -import { Position, TextDocument, Uri, Range, commands } from "vscode"; +import { Position, TextDocument, Uri, Range } from "vscode"; import { Token, isExecutableLanguageBlock, languageBlockAtPosition, languageNameFromBlock } from "quarto-core"; import { isQuartoDoc } from "../core/doc"; @@ -157,12 +157,8 @@ export async function virtualDocUri( export function languageAtPosition(tokens: Token[], position: Position) { const block = languageBlockAtPosition(tokens, position); if (block) { - const language = languageFromBlock(block); - // expose cell language for use in keybindings, etc - commands.executeCommand('setContext', 'quarto.cellLangId', language?.ids[0]); - return language; + return languageFromBlock(block); } else { - commands.executeCommand('setContext', 'quarto.cellLangId', undefined); return undefined; } }