Skip to content
This repository was archived by the owner on Sep 23, 2025. It is now read-only.

Commit 8155807

Browse files
committed
Extract placement resolution logic into separate function
- Add resolveDialecticUrlPlacement() function for pure placement resolution - Refactor openDialecticUrl() to use resolveDialecticUrlPlacement() + navigation - Enables reuse of placement logic for comments (resolve → place comment → navigate) - Clean separation of concerns: resolution vs navigation - Fix searchInFile API usage with proper SearchOptions object
1 parent 34391fd commit 8155807

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

extension/src/fileNavigation.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as vscode from 'vscode';
2+
import * as path from 'path';
23
import { parseDialecticUrl, DialecticUrl } from './dialecticUrl';
34
import { searchInFile, getBestSearchResult, formatSearchResults, needsDisambiguation } from './searchEngine';
45

@@ -9,6 +10,115 @@ interface PlacementState {
910
wasAmbiguous: boolean; // Whether this item had multiple possible locations
1011
}
1112

13+
/**
14+
* Resolve a dialectic URL to a precise location, using placement memory and user disambiguation
15+
* Returns the resolved location without navigating to it
16+
*/
17+
export async function resolveDialecticUrlPlacement(
18+
dialecticUrl: string,
19+
outputChannel: vscode.OutputChannel,
20+
baseUri?: vscode.Uri,
21+
placementMemory?: Map<string, PlacementState>
22+
): Promise<{ line: number; column: number; document: vscode.TextDocument } | null> {
23+
try {
24+
// Parse the dialectic URL to extract components
25+
const parsed = parseDialecticUrl(dialecticUrl);
26+
if (!parsed) {
27+
vscode.window.showErrorMessage(`Invalid dialectic URL: ${dialecticUrl}`);
28+
return null;
29+
}
30+
31+
outputChannel.appendLine(`Resolving dialectic URL: ${dialecticUrl}`);
32+
outputChannel.appendLine(`Parsed components: ${JSON.stringify(parsed, null, 2)}`);
33+
34+
// Resolve the file path
35+
let resolvedPath = parsed.path;
36+
if (baseUri && !path.isAbsolute(parsed.path)) {
37+
resolvedPath = path.resolve(baseUri.fsPath, parsed.path);
38+
}
39+
40+
outputChannel.appendLine(`Resolved file path: ${resolvedPath}`);
41+
42+
// Open the document
43+
const fileUri = vscode.Uri.file(resolvedPath);
44+
const document = await vscode.workspace.openTextDocument(fileUri);
45+
let targetLine = 1;
46+
let targetColumn = 1;
47+
48+
// Handle regex search if present
49+
if (parsed.regex) {
50+
try {
51+
const searchResults = await searchInFile(fileUri, { regexPattern: parsed.regex });
52+
outputChannel.appendLine(`Search results: ${formatSearchResults(searchResults)}`);
53+
54+
if (searchResults.length === 0) {
55+
vscode.window.showWarningMessage(`Regex pattern "${parsed.regex}" not found in ${parsed.path}`);
56+
// Fall back to line parameter if regex fails
57+
if (parsed.line) {
58+
targetLine = parsed.line.startLine;
59+
targetColumn = parsed.line.startColumn || 1;
60+
}
61+
} else {
62+
// Check if we have a stored placement
63+
const linkKey = `link:${dialecticUrl}`;
64+
const placementState = placementMemory?.get(linkKey);
65+
66+
if (placementState?.isPlaced && placementState.chosenLocation) {
67+
// Use stored placement
68+
const storedChoice = placementState.chosenLocation;
69+
targetLine = storedChoice.line;
70+
targetColumn = storedChoice.column;
71+
} else if (searchResults.length === 1) {
72+
// Auto-place single results (pre-disambiguated)
73+
const singleResult = searchResults[0];
74+
targetLine = singleResult.line;
75+
targetColumn = singleResult.column;
76+
77+
// Store the auto-placement
78+
placementMemory?.set(linkKey, {
79+
isPlaced: true,
80+
chosenLocation: singleResult,
81+
wasAmbiguous: false
82+
});
83+
} else {
84+
// Multiple results - show disambiguation
85+
const selectedResult = await showSearchDisambiguation(searchResults, parsed.regex, document);
86+
if (selectedResult) {
87+
targetLine = selectedResult.line;
88+
targetColumn = selectedResult.column;
89+
90+
// Store the choice
91+
placementMemory?.set(linkKey, {
92+
isPlaced: true,
93+
chosenLocation: selectedResult,
94+
wasAmbiguous: true
95+
});
96+
} else {
97+
// User cancelled disambiguation
98+
return null;
99+
}
100+
}
101+
}
102+
} catch (error) {
103+
outputChannel.appendLine(`Error during regex search: ${error}`);
104+
vscode.window.showErrorMessage(`Error searching for pattern "${parsed.regex}": ${error}`);
105+
return null;
106+
}
107+
} else if (parsed.line) {
108+
// Direct line navigation
109+
targetLine = parsed.line.startLine;
110+
targetColumn = parsed.line.startColumn || 1;
111+
}
112+
113+
return { line: targetLine, column: targetColumn, document };
114+
115+
} catch (error) {
116+
outputChannel.appendLine(`Error resolving dialectic URL: ${error}`);
117+
vscode.window.showErrorMessage(`Failed to resolve dialectic URL: ${error}`);
118+
return null;
119+
}
120+
}
121+
12122
/**
13123
* Open a file location specified by a dialectic URL
14124
* Full implementation with regex search support extracted from reviewWebview

0 commit comments

Comments
 (0)