From 0db04455ec2625f593837a9611bc0a23f12d7879 Mon Sep 17 00:00:00 2001 From: Donny Kim Date: Tue, 18 Mar 2025 15:29:20 +0900 Subject: [PATCH 1/6] fix(vscode-plugin): restrict document scheme to file See https://code.visualstudio.com/api/references/document-selector --- packages/vscode-plugin/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vscode-plugin/src/extension.ts b/packages/vscode-plugin/src/extension.ts index 4a7f26651..c6f9c9aef 100644 --- a/packages/vscode-plugin/src/extension.ts +++ b/packages/vscode-plugin/src/extension.ts @@ -31,7 +31,7 @@ export async function activate(context: ExtensionContext): Promise { clientOptions.documentSelector = manifest.activationEvents .filter((e) => e.startsWith('onLanguage:')) - .map((e) => ({ language: e.split(':')[1] })); + .map((e) => ({ language: e.split(':')[1], scheme: 'file' })); clientOptions.outputChannel = window.createOutputChannel('Harper'); context.subscriptions.push(clientOptions.outputChannel); From 89c818cd1c1b6b5edf84c64c3c530b53b57d9690 Mon Sep 17 00:00:00 2001 From: Donny Kim Date: Tue, 18 Mar 2025 15:59:01 +0900 Subject: [PATCH 2/6] fix(vscode-plugin): add a test to check against untitled --- packages/vscode-plugin/src/tests/suite/helper.ts | 7 +++++++ .../vscode-plugin/src/tests/suite/integration.test.ts | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/packages/vscode-plugin/src/tests/suite/helper.ts b/packages/vscode-plugin/src/tests/suite/helper.ts index aa5904ae3..924093841 100644 --- a/packages/vscode-plugin/src/tests/suite/helper.ts +++ b/packages/vscode-plugin/src/tests/suite/helper.ts @@ -27,6 +27,13 @@ export async function openFile(...pathSegments: string[]): Promise { return uri; } +export async function openUntitled(text: string): Promise { + const document = await workspace.openTextDocument(); + const editor = await window.showTextDocument(document); + await editor.edit((editBuilder) => editBuilder.insert(new Position(0, 0), text)); + return document.uri; +} + export function getActualDiagnostics(resource: Uri): Diagnostic[] { return languages.getDiagnostics(resource).filter((d) => d.source === 'Harper'); } diff --git a/packages/vscode-plugin/src/tests/suite/integration.test.ts b/packages/vscode-plugin/src/tests/suite/integration.test.ts index f51cc1fa3..542a14b42 100644 --- a/packages/vscode-plugin/src/tests/suite/integration.test.ts +++ b/packages/vscode-plugin/src/tests/suite/integration.test.ts @@ -9,6 +9,7 @@ import { createRange, getActualDiagnostics, openFile, + openUntitled, sleep } from './helper'; @@ -96,4 +97,13 @@ describe('Integration >', () => { await workspace.fs.writeFile(markdownUri, markdownContent); await openFile('integration.md'); }); + + it('does nothing for untitled', async () => { + const untitledUri = await openUntitled('Errorz'); + + compareActualVsExpectedDiagnostics( + getActualDiagnostics(untitledUri), + createExpectedDiagnostics() + ); + }); }); From 72784978fdc43ada842363cdbefdebaa1317fb0d Mon Sep 17 00:00:00 2001 From: Donny Kim Date: Tue, 18 Mar 2025 16:50:10 +0900 Subject: [PATCH 3/6] chore: retrigger Build Web From 0bbb22119338354bf96288b0d9c57dfb0d159de9 Mon Sep 17 00:00:00 2001 From: Donny Kim Date: Tue, 18 Mar 2025 21:41:06 +0900 Subject: [PATCH 4/6] chore: move 89c818c up and minor change --- .../src/tests/suite/integration.test.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/vscode-plugin/src/tests/suite/integration.test.ts b/packages/vscode-plugin/src/tests/suite/integration.test.ts index 542a14b42..7aebc3db8 100644 --- a/packages/vscode-plugin/src/tests/suite/integration.test.ts +++ b/packages/vscode-plugin/src/tests/suite/integration.test.ts @@ -29,7 +29,7 @@ describe('Integration >', () => { expect(harper.isActive).toBe(true); }); - it('gives correct diagnostics', () => { + it('gives correct diagnostics for files', () => { compareActualVsExpectedDiagnostics( getActualDiagnostics(markdownUri), createExpectedDiagnostics( @@ -45,6 +45,15 @@ describe('Integration >', () => { ); }); + it('does nothing for untitled', async () => { + const untitledUri = await openUntitled('Errorz'); + + compareActualVsExpectedDiagnostics( + getActualDiagnostics(untitledUri), + createExpectedDiagnostics() + ); + }); + it('updates diagnostics on configuration change', async () => { const config = workspace.getConfiguration('harper.linters'); await config.update('RepeatedWords', false, ConfigurationTarget.Workspace); @@ -97,13 +106,4 @@ describe('Integration >', () => { await workspace.fs.writeFile(markdownUri, markdownContent); await openFile('integration.md'); }); - - it('does nothing for untitled', async () => { - const untitledUri = await openUntitled('Errorz'); - - compareActualVsExpectedDiagnostics( - getActualDiagnostics(untitledUri), - createExpectedDiagnostics() - ); - }); }); From e5bb937ce83ceced8280b41ebc2a9eddae4b043d Mon Sep 17 00:00:00 2001 From: Donny Kim Date: Wed, 19 Mar 2025 00:12:35 +0900 Subject: [PATCH 5/6] fix(harper-ls): always return empty MutableDictionary for "untitled" --- harper-ls/src/backend.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/harper-ls/src/backend.rs b/harper-ls/src/backend.rs index 42c32af4d..470c889b0 100644 --- a/harper-ls/src/backend.rs +++ b/harper-ls/src/backend.rs @@ -51,6 +51,11 @@ impl Backend { /// Load a specific file's dictionary async fn load_file_dictionary(&self, url: &Url) -> anyhow::Result { + // VS Code's unsaved documents have "untitled" scheme + if url.scheme() == "untitled" { + return Ok(MutableDictionary::new()); + } + let path = self .get_file_dict_path(url) .await From aa05fabe3dcd14e0d6fd3c0f101ef2f1235cbe9b Mon Sep 17 00:00:00 2001 From: Donny Kim Date: Wed, 19 Mar 2025 00:13:01 +0900 Subject: [PATCH 6/6] fix(vscode-plugin): add support for untitled scheme --- packages/vscode-plugin/src/extension.ts | 8 +++++++- .../vscode-plugin/src/tests/suite/integration.test.ts | 10 ++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/vscode-plugin/src/extension.ts b/packages/vscode-plugin/src/extension.ts index c6f9c9aef..ecae425ae 100644 --- a/packages/vscode-plugin/src/extension.ts +++ b/packages/vscode-plugin/src/extension.ts @@ -31,7 +31,13 @@ export async function activate(context: ExtensionContext): Promise { clientOptions.documentSelector = manifest.activationEvents .filter((e) => e.startsWith('onLanguage:')) - .map((e) => ({ language: e.split(':')[1], scheme: 'file' })); + .flatMap((e) => { + const language = e.split(':')[1]; + return [ + { language, scheme: 'file' }, + { language, scheme: 'untitled' } + ]; + }); clientOptions.outputChannel = window.createOutputChannel('Harper'); context.subscriptions.push(clientOptions.outputChannel); diff --git a/packages/vscode-plugin/src/tests/suite/integration.test.ts b/packages/vscode-plugin/src/tests/suite/integration.test.ts index 7aebc3db8..be877f2be 100644 --- a/packages/vscode-plugin/src/tests/suite/integration.test.ts +++ b/packages/vscode-plugin/src/tests/suite/integration.test.ts @@ -45,12 +45,18 @@ describe('Integration >', () => { ); }); - it('does nothing for untitled', async () => { + it('gives correct diagnostics for untitled', async () => { const untitledUri = await openUntitled('Errorz'); + // Wait for `harper-ls` to send diagnostics + await sleep(500); + compareActualVsExpectedDiagnostics( getActualDiagnostics(untitledUri), - createExpectedDiagnostics() + createExpectedDiagnostics({ + message: 'Did you mean to spell “Errorz” this way?', + range: createRange(0, 0, 0, 6) + }) ); });