Remove debug statements from staged changes
Unlisted
The user wants me to:
- Check staged changes with
git diff --staged - Remove any debug statements that someone added
Let me first run git diff --staged to see what changes are staged for commit.
After that, I'll need to:
- Identify any debug statements in the staged changes
- Remove those debug statements
- Re-stage the files with the debug statements removed
Let me break this down into a series of tasks:
git diff --staged
Warning: long output
diff --git a/core/src/tools/builtin/diagnostics/vscode.ts b/core/src/tools/builtin/diagnostics/vscode.ts
index e3246434..b591cd05 100644
--- a/core/src/tools/builtin/diagnostics/vscode.ts
+++ b/core/src/tools/builtin/diagnostics/vscode.ts
@@ -1,6 +1,7 @@
+import { promiseFactoryToObservable } from '@sourcegraph/observable'
import * as vscode from 'vscode'
+import type { URI } from 'vscode-uri'
import { Utils } from 'vscode-uri'
-import { promiseFactoryToObservable } from '@sourcegraph/observable'
import { checkDirURIIsFile, checkPathSafety } from '../node-helpers'
import type { Diagnostic, getDiagnosticsToolReg, Severity } from './common'
@@ -193,3 +194,124 @@ async function uriFileType(uri: vscode.Uri): Promise<'file' | 'directory' | null
throw error
}
}
+
+/**
+ * Gets diagnostics for a specific file with a timeout.
+ * @param uri The URI of the file to get diagnostics for
+ * @param dirUri The workspace directory URI
+ * @param timeoutMs Maximum time to wait for diagnostics in milliseconds
+ * @returns Array of diagnostics or null if timed out
+ */
+export async function getDiagnosticsForFile(
+ uri: vscode.Uri,
+ dirUri: URI,
+ timeoutMs: number = 1000,
+): Promise<Diagnostic[] | null> {
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const vscode = require('vscode') as typeof import('vscode')
+
+ console.log(
+ `[DEBUG] getDiagnosticsForFile called for ${uri.toString()} with timeout ${timeoutMs}ms`,
+ )
+
+ const fileType = await uriFileType(uri)
+ if (fileType !== 'file') {
+ console.log(`[DEBUG] ${uri.toString()} is not a file, returning empty diagnostics`)
+ return []
+ }
+
+ const needsRefresh = await checkFileNeedsRefresh(uri, vscode)
+ console.log(`[DEBUG] ${uri.toString()} needsRefresh: ${needsRefresh}`)
+ await openOrRefreshDocument(uri, needsRefresh, vscode)
+
+ // Set up a promise that resolves when diagnostics change
+ const diagnosticsChanged = new Promise<void>((resolve) => {
+ const listener = vscode.languages.onDidChangeDiagnostics((e) => {
+ for (const changedUri of e.uris) {
+ if (changedUri.toString() === uri.toString()) {
+ console.log(`[DEBUG] Diagnostics changed for ${uri.toString()}`)
+ listener.dispose()
+ resolve()
+ break
+ }
+ }
+ })
+ // Clean up the listener after timeout
+ setTimeout(() => listener.dispose(), timeoutMs)
+ })
+
+ // Create a timeout promise
+ const timeout = new Promise<null>((resolve) =>
+ setTimeout(() => {
+ console.log(
+ `[DEBUG] Diagnostics timeout reached for ${uri.toString()} after ${timeoutMs}ms`,
+ )
+ resolve(null)
+ }, timeoutMs),
+ )
+
+ // Wait for either diagnostics to change or timeout
+ const winner = await Promise.race([
+ diagnosticsChanged.then(() => 'diagnostics'),
+ timeout.then(() => 'timeout'),
+ ])
+ console.log(`[DEBUG] Race won by: ${winner}`)
+
+ // If diagnostics event was triggered, wait a bit longer for results to populate
+ if (winner === 'diagnostics') {
+ console.log(`[DEBUG] Waiting additional 1000ms for diagnostics to populate`)
+ await new Promise((resolve) => setTimeout(resolve, 1000))
+ }
+
+ // Poll for diagnostics a few times if none are found initially
+ let diagnostics = vscode.languages.getDiagnostics(uri)
+ let attempts = 0
+ const maxAttempts = 3
+ const pollInterval = 500 // ms
+
+ while (diagnostics.length === 0 && attempts < maxAttempts) {
+ console.log(`[DEBUG] No diagnostics found, polling attempt ${attempts + 1}/${maxAttempts}`)
+ await new Promise((resolve) => setTimeout(resolve, pollInterval))
+ diagnostics = vscode.languages.getDiagnostics(uri)
+ attempts++
+ }
+
+ console.log(
+ `[DEBUG] Found ${diagnostics.length} diagnostics for ${uri.toString()} after ${attempts} additional polls`,
+ )
+
+ // Process and return the diagnostics
+ return diagnostics.flatMap((d) => {
+ const severity = convertSeverity(d)
+ if (!SEVERITY_LEVELS.includes(severity)) {
+ return []
+ }
+
+ // relativize path using VSCode URI utilities
+ const relativePath = uri.path.startsWith(dirUri.path)
+ ? uri.path.slice(dirUri.path.length)
+ : uri.path
+ // Remove leading slash if present
+ const cleanPath = relativePath.startsWith('/') ? relativePath.slice(1) : relativePath
+
+ const result: Diagnostic = {
+ message: d.message,
+ severity: severity,
+ source: d.source,
+ path: cleanPath,
+ range: {
+ type: 'full',
+ start: {
+ line: d.range.start.line,
+ character: d.range.start.character,
+ },
+ end: {
+ line: d.range.end.line,
+ character: d.range.end.character,
+ },
+ },
+ }
+
+ return [result]
+ })
+}
diff --git a/core/src/tools/builtin/filesystem/edit_file.common.ts b/core/src/tools/builtin/filesystem/edit_file.common.ts
index db70339d..4ea38ab1 100644
--- a/core/src/tools/builtin/filesystem/edit_file.common.ts
+++ b/core/src/tools/builtin/filesystem/edit_file.common.ts
@@ -2,6 +2,7 @@ import { createTwoFilesPatch } from 'diff'
import type { ToolRegistration } from '../../tool-service'
import { CREATE_FILE_TOOL_NAME } from './common'
import { READ_FILE_TOOL_NAME } from './read_file.common'
+import type { Diagnostic } from '../diagnostics/common'
export type EditFileToolDef = {
name: 'edit_file'
@@ -15,6 +16,7 @@ export type EditFileToolDef = {
| {
diff: string
lineRange?: [number, number]
+ diagnostics?: Diagnostic[]
}
}
@@ -62,9 +64,11 @@ export const editFileToolReg: ToolRegistration<EditFileToolDef> = {
source: 'builtin',
},
fn:
- import.meta.env.VITE_PLATFORM === 'node' || import.meta.env.VITE_PLATFORM === 'vscode'
+ import.meta.env.VITE_PLATFORM === 'node'
? import('./edit_file.node').then(({ nodeEditFileTool }) => nodeEditFileTool)
- : null,
+ : import.meta.env.VITE_PLATFORM === 'vscode'
+ ? import('./edit_file.vscode').then(({ vscodeEditFileTool }) => vscodeEditFileTool)
+ : null,
}
/**
diff --git a/core/src/tools/builtin/filesystem/edit_file.node.ts b/core/src/tools/builtin/filesystem/edit_file.node.ts
index 1bd9ff30..110c815e 100644
--- a/core/src/tools/builtin/filesystem/edit_file.node.ts
+++ b/core/src/tools/builtin/filesystem/edit_file.node.ts
@@ -50,37 +50,15 @@ export const nodeEditFileTool: NonNullable<(typeof editFileToolReg)['fn']> = (
await filesystem.writeFile(path, modifiedContent, signal)
})
- if (import.meta.env.VITE_PLATFORM === 'vscode') {
- // eslint-disable-next-line @typescript-eslint/no-require-imports
- const vscode = require('vscode') as typeof import('vscode')
-
- const visibleFileEditors = vscode.window.visibleTextEditors.filter(
- (e) => e.document.uri.fsPath === filePath && e.document.uri.scheme === 'file',
- )
- for (const editor of visibleFileEditors) {
- await vscode.window.showTextDocument(editor.document, {
- preserveFocus: true,
- preview: false,
- })
-
- // If the buffer is dirty, revert → VS Code reloads from disk
- if (editor.document.isDirty) {
- const choice = await vscode.window.showWarningMessage(
- `Amp made changes to '${args.path}'. Do you want to revert the file to the version on disk? Your unsaved changes will be lost.`,
- { modal: true },
- 'Reload',
- )
-
- if (choice === 'Reload') {
- await vscode.commands.executeCommand('workbench.action.files.revert')
- }
- }
- }
+ const result = {
+ diff: formattedDiff,
+ lineRange,
}
+
return {
status: 'done',
progress: {},
- result: { diff: formattedDiff, lineRange },
+ result,
files: [args.path],
}
} finally {
diff --git a/core/src/tools/builtin/filesystem/edit_file.vscode.ts b/core/src/tools/builtin/filesystem/edit_file.vscode.ts
new file mode 100644
index 00000000..3c3c96de
--- /dev/null
+++ b/core/src/tools/builtin/filesystem/edit_file.vscode.ts
@@ -0,0 +1,119 @@
+import { promiseFactoryToObservable } from '@sourcegraph/observable'
+import { Utils } from 'vscode-uri'
+import { getFileModTime } from '../../../threads/file-tracking/common'
+import { getDiagnosticsForFile } from '../diagnostics/vscode'
+import { checkDirURIIsFile, checkPathSafety } from '../node-helpers'
+import type { EditFileToolDef, editFileToolReg } from './edit_file.common'
+import { applyFileEdits } from './edit_file.common'
+import { recordEdit } from './undo_edit.node'
+
+export const vscodeEditFileTool: NonNullable<(typeof editFileToolReg)['fn']> = (
+ { args },
+ { dir, threadID, trackFileChange, filesystem },
+) => {
+ return promiseFactoryToObservable(async (signal) => {
+ checkEditArgs(args)
+ checkPathSafety(args.path)
+ checkDirURIIsFile(dir)
+
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
+ const vscode = require('vscode') as typeof import('vscode')
+
+ const filePath = Utils.joinPath(dir, args.path)
+
+ if (!filesystem.exclusiveWriter) {
+ const lastReadTime = getFileModTime(filePath.fsPath, threadID)
+ const currentMtime = await filesystem.getMtime(filePath.fsPath)
+ if (lastReadTime && currentMtime && lastReadTime !== currentMtime) {
+ return {
+ status: 'error' as const,
+ progress: {},
+ error: {
+ message: `The file '${args.path}' has been modified since you last read it. Please use read_file to view the current version before making edits.`,
+ },
+ }
+ }
+ }
+
+ // Find or open the document
+ const existingDoc = vscode.workspace.textDocuments.find(
+ (doc) => doc.uri.toString() === filePath.toString(),
+ )
+ const doc = existingDoc ?? (await vscode.workspace.openTextDocument(filePath))
+ const content = doc.getText()
+
+ const { modifiedContent, formattedDiff, lineRange } = await applyFileEdits(
+ args.path,
+ content,
+ args.old_str,
+ args.new_str,
+ )
+
+ // Record the edit for undo functionality
+ await recordEdit(args.path, content, modifiedContent)
+
+ await trackFileChange(filePath.fsPath, async () => {
+ await vscode.workspace.fs.writeFile(
+ filePath,
+ new Uint8Array(Buffer.from(modifiedContent, 'utf-8')),
+ )
+ })
+
+ const result: { diff: string; lineRange: [number, number]; diagnostics?: any[] } = {
+ diff: formattedDiff,
+ lineRange,
+ }
+
+ try {
+ // Add a small delay before requesting diagnostics to let the language server start analyzing
+ console.log(`[DEBUG] edit_file waiting 500ms before requesting diagnostics`)
+ await new Promise((resolve) => setTimeout(resolve, 500))
+
+ console.log(
+ `[DEBUG] edit_file requesting diagnostics for ${filePath.toString()} with 5000ms timeout`,
+ )
+ const diagnostics = await getDiagnosticsForFile(filePath, dir, 5000)
+ if (diagnostics && diagnostics.length > 0) {
+ console.log(`[DEBUG] edit_file received ${diagnostics.length} diagnostics`)
+ result.diagnostics = diagnostics
+ } else {
+ console.log(`[DEBUG] edit_file received no diagnostics, or diagnostics is null`)
+ }
+ } catch (error) {
+ // If we can't get diagnostics, just continue without them
+ console.error('Failed to get diagnostics:', error)
+ }
+
+ return {
+ status: 'done',
+ progress: {},
+ result,
+ files: [args.path],
+ }
+ })
+}
+
+function checkEditArgs(args: EditFileToolDef['args']): asserts args is EditFileToolDef['args'] {
+ if (typeof args !== 'object' || args === null) {
+ throw new Error('args must be an object. received instead: `' + JSON.stringify(args) + '`')
+ }
+ if (typeof args.path !== 'string') {
+ throw new Error(
+ 'path must be a string. received instead: `' + JSON.stringify(args.path) + '`',
+ )
+ }
+ if (typeof args.old_str !== 'string') {
+ throw new Error(
+ 'old_str must be a string. received instead: `' + JSON.stringify(args.old_str) + '`',
+ )
+ }
+ if (typeof args.new_str !== 'string') {
+ throw new Error(
+ 'new_str must be a string. received instead: `' + JSON.stringify(args.new_str) + '`',
+ )
+ }
+
+ if (args.old_str === args.new_str) {
+ throw new Error('old_str and new_str must be different from each other.')
+ }
+}
diff --git a/web/src/lib/components/thread/tool-uses/edit_file-tool-use.svelte b/web/src/lib/components/thread/tool-uses/edit_file-tool-use.svelte
index f2775307..1e150015 100644
--- a/web/src/lib/components/thread/tool-uses/edit_file-tool-use.svelte
+++ b/web/src/lib/components/thread/tool-uses/edit_file-tool-use.svelte
@@ -7,7 +7,10 @@
</script>
<script lang="ts">
+ import AlertCircle from '@lucide/svelte/icons/alert-circle'
+ import AlertTriangle from '@lucide/svelte/icons/alert-triangle'
import FileDiff from '@lucide/svelte/icons/file-diff'
+ import type { Diagnostic } from '@sourcegraph/amp-core/src/tools/builtin/diagnostics/common'
import type { EditFileToolDef } from '@sourcegraph/amp-core/src/tools/builtin/filesystem/edit_file.common'
import {
calculateEditFileDiffStat,
@@ -15,6 +18,7 @@
} from '@sourcegraph/amp-core/src/util/diff-stat'
import DiffStat from '../../diff-stat.svelte'
import Markdown from '../../markdown.svelte'
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'
import type { ToolUseProps } from '../steps/tool-use-step.svelte'
import ActionBlock from '../structure/action-row.svelte'
import FilePath from '../structure/file-path.svelte'
@@ -45,6 +49,28 @@
let diffEmpty = $derived(stat.added === 0 && stat.deleted === 0 && stat.changed === 0)
let path = $derived(toolUse.input?.path)
+
+ // Get diagnostics from result if available
+ let hasDiagnostics = $derived(
+ toolRun.status === 'done' &&
+ typeof toolRun.result === 'object' &&
+ 'diagnostics' in toolRun.result &&
+ Array.isArray(toolRun.result.diagnostics),
+ )
+
+ let diagnostics = $derived<Diagnostic[]>(
+ hasDiagnostics
+ ? toolRun.status === 'done' &&
+ typeof toolRun.result === 'object' &&
+ 'diagnostics' in toolRun.result
+ ? (toolRun.result.diagnostics as Diagnostic[])
+ : []
+ : [],
+ )
+
+ let errorCount = $derived(diagnostics.filter((d) => d.severity === 'error').length)
+
+ let warningCount = $derived(diagnostics.filter((d) => d.severity === 'warning').length)
</script>
<ActionBlock
@@ -86,6 +112,77 @@
<Markdown content={stripFilenamesFromDiffHeader(toolRun.result.diff)} />
</div>
{/if}
+
+ {#if hasDiagnostics && (errorCount > 0 || warningCount > 0)}
+ <div class="border-t border-border m-2 pt-2">
+ <Tooltip>
+ <TooltipTrigger class="flex items-center gap-2 text-xs cursor-help">
+ <span
+ class={errorCount > 0
+ ? 'italic text-destructive'
+ : warningCount > 0
+ ? 'text-warning'
+ : ''}
+ >
+ {#if errorCount > 0 && warningCount > 0}
+ Found {errorCount} diagnostic {errorCount === 1
+ ? 'error'
+ : 'errors'}, {warningCount}
+ {warningCount === 1 ? 'warning' : 'warnings'}
+ {:else if errorCount > 0}
+ Found {errorCount} diagnostic {errorCount === 1
+ ? 'error'
+ : 'errors'}
+ {:else if warningCount > 0}
+ Found {warningCount} diagnostic {warningCount === 1
+ ? 'warning'
+ : 'warnings'}
+ {:else}
+ Diagnostics
+ {/if}
+ </span>
+ </TooltipTrigger>
+
+ <TooltipContent
+ side="top"
+ sideOffset={5}
+ avoidCollisions
+ class="max-w-[400px] w-auto max-h-[300px] overflow-auto p-3"
+ >
+ <ul class="text-xs space-y-1">
+ {#each diagnostics as diagnostic, index (diagnostic.message + '-' + index)}
+ <li
+ class="flex items-start gap-1 pb-1 {index !==
+ diagnostics.length - 1
+ ? 'border-b border-border mb-1'
+ : ''}"
+ >
+ {#if diagnostic.severity === 'error'}
+ <AlertCircle
+ class="h-3 w-3 mt-0.5 shrink-0 text-destructive"
+ />
+ {:else if diagnostic.severity === 'warning'}
+ <AlertTriangle
+ class="h-3 w-3 mt-0.5 shrink-0 text-warning"
+ />
+ {/if}
+ <div>
+ <span class="text-foreground">{diagnostic.message}</span
+ >
+ {#if diagnostic.range && diagnostic.range.type === 'full'}
+ <div class="text-muted-foreground text-xs mt-0.5">
+ at line {diagnostic.range.start.line + 1},
+ column {diagnostic.range.start.character + 1}
+ </div>
+ {/if}
+ </div>
+ </li>
+ {/each}
+ </ul>
+ </TooltipContent>
+ </Tooltip>
+ </div>
+ {/if}
{/if}
{/snippet}
</ActionBlock>
diff --git a/web/src/routes/storybook/+page.svelte b/web/src/routes/storybook/+page.svelte
index 8cfc4434..cf7d2e64 100644
--- a/web/src/routes/storybook/+page.svelte
+++ b/web/src/routes/storybook/+page.svelte
@@ -49,6 +49,7 @@
import CodebaseSearchAgentStory from './tool-calls/codebase-search-agent-story.svelte'
import CreateFileStory from './tool-calls/create-file-story.svelte'
import EditFileStory from './tool-calls/edit-file-story.svelte'
+ import EditFileWithDiagnosticsStory from './tool-calls/edit-file-with-diagnostics-story.svelte'
import FormatFileStory from './tool-calls/format-file-story.svelte'
import GenericToolStory from './tool-calls/generic-tool-story.svelte'
import GetDiagnosticsStory from './tool-calls/get-diagnostics-story.svelte'
@@ -195,6 +196,10 @@
<EditFileStory />
</Story>
+ <Story title="Edit File Tool (with diagnostics)">
+ <EditFileWithDiagnosticsStory />
+ </Story>
+
<Story title="Create File Tool">
<CreateFileStory />
</Story>
diff --git a/web/src/routes/storybook/tool-calls/edit-file-with-diagnostics-story.svelte b/web/src/routes/storybook/tool-calls/edit-file-with-diagnostics-story.svelte
new file mode 100644
index 00000000..0bfcc52d
--- /dev/null
+++ b/web/src/routes/storybook/tool-calls/edit-file-with-diagnostics-story.svelte
@@ -0,0 +1,113 @@
+<script lang="ts">
+ import { type ToolUseProps } from '$lib/components/thread/steps/tool-use-step.svelte'
+ import EditFileToolUse from '$lib/components/thread/tool-uses/edit_file-tool-use.svelte'
+ import {
+ newThreadID,
+ newThreadToolUseID,
+ type ToolRunUserInput,
+ } from '@sourcegraph/amp-core/src/threads/thread'
+ import type { EditFileToolDef } from '@sourcegraph/amp-core/src/tools/builtin/filesystem/edit_file.common'
+ import type { ToolRun } from '@sourcegraph/amp-core/src/tools/tool-service'
+
+ let fakeHandleThreadDelta = async () => {
+ alert('Called handleThreadDelta')
+ }
+
+ function toolCallProps(
+ input: EditFileToolDef['args'],
+ invocation: ToolRun<EditFileToolDef>,
+ userInput?: ToolRunUserInput,
+ ): ToolUseProps<EditFileToolDef> {
+ return {
+ toolUse: {
+ id: newThreadToolUseID(),
+ type: 'tool_use',
+ name: 'edit_file',
+ input,
+ },
+ toolRun: invocation,
+ userInput,
+ handleThreadDelta: fakeHandleThreadDelta,
+ threadID: newThreadID(),
+ }
+ }
+</script>
+
+<h3>edit_file with diagnostics</h3>
+
+<h4>With diagnostics - error</h4>
+<EditFileToolUse
+ {...toolCallProps(
+ {
+ path: 'src/app.tsx',
+ old_str: 'function App() {\n return <div>Hello world</div>;\n}',
+ new_str:
+ 'function App() {\n const count: number = "hello";\n return <div>Hello world: {count}</div>;\n}',
+ },
+ {
+ status: 'done',
+ progress: {},
+ result: {
+ diff: '```diff\nIndex: src/app.tsx\n===================================================================\n--- src/app.tsx\toriginal\n+++ src/app.tsx\tmodified\n@@ -1,3 +1,4 @@\n function App() {\n- return <div>Hello world</div>;\n+ const count: number = "hello";\n+ return <div>Hello world: {count}</div>;\n }\n',
+ lineRange: [1, 4],
+ diagnostics: [
+ {
+ message: "Type 'string' is not assignable to type 'number'",
+ severity: 'error',
+ source: 'typescript',
+ path: 'src/app.tsx',
+ range: {
+ type: 'full',
+ start: { line: 1, character: 18 },
+ end: { line: 1, character: 25 },
+ },
+ },
+ ],
+ },
+ },
+ )}
+/>
+
+<h4>With diagnostics - warning and error</h4>
+<EditFileToolUse
+ {...toolCallProps(
+ {
+ path: 'src/utils.ts',
+ old_str: 'export function formatName(name) {\n return name.toUpperCase();\n}',
+ new_str:
+ 'export function formatName(name) {\n console.log("Formatting name");\n const formatted = name.toUpperCase();\n return formatted;\n}',
+ },
+ {
+ status: 'done',
+ progress: {},
+ result: {
+ diff: '```diff\nIndex: src/utils.ts\n===================================================================\n--- src/utils.ts\toriginal\n+++ src/utils.ts\tmodified\n@@ -1,3 +1,5 @@\n export function formatName(name) {\n- return name.toUpperCase();\n+ console.log("Formatting name");\n+ const formatted = name.toUpperCase();\n+ return formatted;\n }\n',
+ lineRange: [1, 5],
+ diagnostics: [
+ {
+ message: "Parameter 'name' implicitly has an 'any' type",
+ severity: 'error',
+ source: 'typescript',
+ path: 'src/utils.ts',
+ range: {
+ type: 'full',
+ start: { line: 0, character: 24 },
+ end: { line: 0, character: 28 },
+ },
+ },
+ {
+ message: 'Unexpected console statement',
+ severity: 'warning',
+ source: 'eslint',
+ path: 'src/utils.ts',
+ range: {
+ type: 'full',
+ start: { line: 1, character: 2 },
+ end: { line: 1, character: 32 },
+ },
+ },
+ ],
+ },
+ },
+ )}
+/>
%@@ -209,28 +209,21 @@
): Promise<Diagnostic[] | null> {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const vscode = require('vscode') as typeof import('vscode')
console.log(
`[DEBUG] getDiagnosticsForFile called for ${uri.toString()} with timeout ${timeoutMs}ms`,
)
const fileType = await uriFileType(uri)
if (fileType !== 'file') {
console.log(`[DEBUG] ${uri.toString()} is not a file, returning empty diagnostics`)
return []
}
const needsRefresh = await checkFileNeedsRefresh(uri, vscode)
console.log(`[DEBUG] ${uri.toString()} needsRefresh: ${needsRefresh}`)
await openOrRefreshDocument(uri, needsRefresh, vscode)
// Set up a promise that resolves when diagnostics change
const diagnosticsChanged = new Promise<void>((resolve) => {
const listener = vscode.languages.onDidChangeDiagnostics((e) => {
for (const changedUri of e.uris) {
if (changedUri.toString() === uri.toString()) {
console.log(`[DEBUG] Diagnostics changed for ${uri.toString()}`)
listener.dispose()
resolve()
break
}
@@ -235,11 +235,8 @@
// Create a timeout promise
const timeout = new Promise<null>((resolve) =>
setTimeout(() => {
console.log(
`[DEBUG] Diagnostics timeout reached for ${uri.toString()} after ${timeoutMs}ms`,
)
resolve(null)
}, timeoutMs),
)
@@ -247,13 +244,11 @@
const winner = await Promise.race([
diagnosticsChanged.then(() => 'diagnostics'),
timeout.then(() => 'timeout'),
])
console.log(`[DEBUG] Race won by: ${winner}`)
// If diagnostics event was triggered, wait a bit longer for results to populate
if (winner === 'diagnostics') {
console.log(`[DEBUG] Waiting additional 1000ms for diagnostics to populate`)
await new Promise((resolve) => setTimeout(resolve, 1000))
}
// Poll for diagnostics a few times if none are found initially