diff --git a/src/config.ts b/src/config.ts index 20063a278..13426b70b 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,7 +1,9 @@ const config = { REPL_FILE_EXT: 'calva-repl', KEYBINDINGS_ENABLED_CONFIG_KEY: 'calva.keybindingsEnabled', - KEYBINDINGS_ENABLED_CONTEXT_KEY: 'calva:keybindingsEnabled' + KEYBINDINGS_ENABLED_CONTEXT_KEY: 'calva:keybindingsEnabled', + CURSOR_CONTEXT_IN_STRING: 'calva:inString', + CURSOR_CONTEXT_IN_COMMENT: 'calva:inComment', }; type ReplSessionType = 'clj' | 'cljs'; diff --git a/src/cursor-doc/token-cursor.ts b/src/cursor-doc/token-cursor.ts index 0796993ab..3c4356494 100644 --- a/src/cursor-doc/token-cursor.ts +++ b/src/cursor-doc/token-cursor.ts @@ -670,6 +670,14 @@ export class LispTokenCursor extends TokenCursor { return false; } + /** + * Indicates if the current token is in a comment line + */ + withinComment() { + const cursor = this.clone(); + return cursor.getToken().type === 'comment' || cursor.getPrevToken().type === 'comment'; + } + /** * Tells if the cursor is inside a properly closed list. */ diff --git a/src/extension.ts b/src/extension.ts index a1782c3e9..acb81d41a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -30,6 +30,9 @@ import config from './config'; import handleNewCljFiles from './fileHandler'; import lsp from './lsp'; import * as snippets from './custom-snippets'; +import * as docMirror from './doc-mirror' +import { testDataDir } from './extension-test/integration/suite/util'; +import { commands } from 'fast-check/*'; async function onDidSave(document) { let { @@ -65,6 +68,7 @@ function setKeybindingsEnabledContext() { } async function activate(context: vscode.ExtensionContext) { + vscode.commands.executeCommand('setContext', "@AFARK", "farked"); status.updateNeedReplUi(false, context); lsp.activate(context).then(debugDecorations.triggerUpdateAndRenderDecorations); state.cursor.set('analytics', new Analytics(context)); @@ -219,6 +223,7 @@ async function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor((editor) => { status.update(); replHistory.setReplHistoryCommandsActiveContext(editor); + checkForContextChange(editor); })); context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(annotations.onDidChangeTextDocument)); context.subscriptions.push(new vscode.Disposable(() => { @@ -231,6 +236,7 @@ async function activate(context: vscode.ExtensionContext) { })); context.subscriptions.push(vscode.window.onDidChangeTextEditorSelection(event => { replHistory.setReplHistoryCommandsActiveContext(event.textEditor); + checkForContextChange(event.textEditor); })); context.subscriptions.push(vscode.workspace.onDidCloseTextDocument(document => { if (outputWindow.isResultsDoc(document)) { @@ -311,6 +317,62 @@ async function activate(context: vscode.ExtensionContext) { } } +// TODO: remove console.logs +type CursorContext = 'calva-standard' | AltCursorContext; +type AltCursorContext = 'string' | 'comment'; +let lastContext: CursorContext = null; + +function checkForContextChange(editor: vscode.TextEditor) { + if (!editor || !editor.document || editor.document.languageId !== 'clojure') return; + + const currentContext = getCursorContext(editor.document, editor.selection.active); + setNewContext(currentContext); +} + +function setNewContext(currentContext: CursorContext) { + if (lastContext === currentContext) { + return; + } + lastContext = currentContext; + const commentContext = config.CURSOR_CONTEXT_IN_COMMENT; + const stringContext = config.CURSOR_CONTEXT_IN_STRING; + vscode.commands.executeCommand('setContext', commentContext, false); + vscode.commands.executeCommand('setContext', stringContext, false); + + switch (currentContext) { + case 'calva-standard': + console.log(`context: calva-standard`); + break; + case 'comment': + console.log(`context: ${commentContext}`); + vscode.commands.executeCommand('setContext', commentContext, true); + break; + case 'string': + console.log(`context: ${stringContext}`); + vscode.commands.executeCommand('setContext', stringContext, true); + break; + default: + // TODO: throw? log? + } +} + +function getCursorContext(document: vscode.TextDocument, position: vscode.Position): CursorContext { + const idx = document.offsetAt(position); + const mirrorDoc = docMirror.getDocument(document); + const tokenCursor = mirrorDoc.getTokenCursor(idx); + + let context: CursorContext; + if (tokenCursor.withinString()) { + context = 'string'; + } else if (tokenCursor.withinComment()) { + context = 'comment'; + } else { + context = 'calva-standard'; + } + + return context; +} + function deactivate(): Promise | undefined { state.analytics().logEvent("LifeCycle", "Deactivated").send(); jackIn.calvaJackout();