@@ -132,160 +132,45 @@ export async function openDialecticUrl(
132132 baseUri ?: vscode . Uri ,
133133 placementMemory ?: Map < string , PlacementState >
134134) : Promise < void > {
135- try {
136- // Parse the dialectic URL to extract components
137- const parsed = parseDialecticUrl ( dialecticUrl ) ;
138- if ( ! parsed ) {
139- vscode . window . showErrorMessage ( `Invalid dialectic URL: ${ dialecticUrl } ` ) ;
140- return ;
141- }
142-
143- outputChannel . appendLine ( `Opening dialectic URL: ${ dialecticUrl } ` ) ;
144- outputChannel . appendLine ( `Parsed: path=${ parsed . path } , regex=${ parsed . regex } , line=${ JSON . stringify ( parsed . line ) } ` ) ;
145-
146- // Resolve file path - simplified version for shared module
147- let fileUri : vscode . Uri ;
148- if ( baseUri && ! parsed . path . startsWith ( '/' ) ) {
149- fileUri = vscode . Uri . joinPath ( baseUri , parsed . path ) ;
150- } else {
151- fileUri = vscode . Uri . file ( parsed . path ) ;
152- }
153-
154- // Check if file exists
155- try {
156- const stat = await vscode . workspace . fs . stat ( fileUri ) ;
157- if ( stat . type === vscode . FileType . Directory ) {
158- outputChannel . appendLine ( `Revealing directory in Explorer: ${ fileUri . fsPath } ` ) ;
159- await vscode . commands . executeCommand ( 'revealInExplorer' , fileUri ) ;
160- return ;
161- }
162- } catch ( error ) {
163- const baseInfo = baseUri ? ` (base: ${ baseUri . fsPath } )` : '' ;
164- vscode . window . showErrorMessage ( `File not found: ${ parsed . path } ${ baseInfo } ` ) ;
165- return ;
166- }
167-
168- // Open the document
169- const document = await vscode . workspace . openTextDocument ( fileUri ) ;
170-
171- let targetLine = 1 ;
172- let targetColumn = 1 ;
173-
174- // Handle regex if specified
175- if ( parsed . regex ) {
176- try {
177- const searchResults = await searchInFile ( fileUri , {
178- regexPattern : parsed . regex ,
179- lineConstraint : parsed . line
180- } ) ;
181-
182- outputChannel . appendLine ( `Regex search results:\n${ formatSearchResults ( searchResults ) } ` ) ;
183-
184- if ( searchResults . length === 0 ) {
185- vscode . window . showWarningMessage ( `Regex pattern "${ parsed . regex } " not found in ${ parsed . path } ` ) ;
186- // Fall back to line parameter if regex fails
187- if ( parsed . line ) {
188- targetLine = parsed . line . startLine ;
189- targetColumn = parsed . line . startColumn || 1 ;
190- }
191- } else {
192- // Check if we have a stored placement
193- const linkKey = `link:${ dialecticUrl } ` ;
194- const placementState = placementMemory ?. get ( linkKey ) ;
195-
196- if ( placementState ?. isPlaced && placementState . chosenLocation ) {
197- // Use stored placement
198- const storedChoice = placementState . chosenLocation ;
199- targetLine = storedChoice . line ;
200- targetColumn = storedChoice . column ;
201- } else if ( searchResults . length === 1 ) {
202- // Auto-place single results (pre-disambiguated)
203- const singleResult = searchResults [ 0 ] ;
204- targetLine = singleResult . line ;
205- targetColumn = singleResult . column ;
206-
207- // Store the auto-placement
208- placementMemory ?. set ( linkKey , {
209- isPlaced : true ,
210- chosenLocation : singleResult ,
211- wasAmbiguous : false
212- } ) ;
213- } else {
214- // Multiple results - show disambiguation
215- const selectedResult = await showSearchDisambiguation ( searchResults , parsed . regex , document ) ;
216- if ( selectedResult ) {
217- targetLine = selectedResult . line ;
218- targetColumn = selectedResult . column ;
219-
220- // Store the choice
221- placementMemory ?. set ( linkKey , {
222- isPlaced : true ,
223- chosenLocation : selectedResult ,
224- wasAmbiguous : true
225- } ) ;
226- }
227- }
228- }
229- } catch ( error ) {
230- outputChannel . appendLine ( `Regex search failed: ${ error } ` ) ;
231- vscode . window . showErrorMessage ( `Regex search failed: ${ error } ` ) ;
232- // Fall back to line parameter if regex fails
233- if ( parsed . line ) {
234- targetLine = parsed . line . startLine ;
235- targetColumn = parsed . line . startColumn || 1 ;
236- }
237- }
238- } else if ( parsed . line ) {
239- // No regex, just use line parameter
240- targetLine = parsed . line . startLine ;
241- targetColumn = parsed . line . startColumn || 1 ;
242- }
135+ // Resolve the placement
136+ const resolved = await resolveDialecticUrlPlacement ( dialecticUrl , outputChannel , baseUri , placementMemory ) ;
137+ if ( ! resolved ) {
138+ return ; // Resolution failed or was cancelled
139+ }
243140
244- // Convert to 0-based for VSCode API and create selection
245- const line = Math . max ( 0 , targetLine - 1 ) ;
246- const column = Math . max ( 0 , targetColumn - 1 ) ;
247- const selection = new vscode . Range ( line , column , line , column ) ;
141+ const { range, document } = resolved ;
248142
249- const editor = await vscode . window . showTextDocument ( document , {
250- selection ,
251- viewColumn : vscode . ViewColumn . One ,
252- preview : false // Ensure final navigation creates a permanent tab
253- } ) ;
143+ // Navigate to the resolved location
144+ const editor = await vscode . window . showTextDocument ( document , {
145+ selection : range ,
146+ viewColumn : vscode . ViewColumn . One
147+ } ) ;
254148
255- // Explicitly set the cursor position after opening
256- editor . selection = new vscode . Selection ( line , column , line , column ) ;
257- editor . revealRange ( new vscode . Range ( line , column , line , column ) , vscode . TextEditorRevealType . InCenter ) ;
149+ // Add line decorations for better visibility
150+ const decorationRanges = createDecorationRanges (
151+ document ,
152+ undefined , // No line constraint for dialectic URLs
153+ range . start . line + 1 , // Convert back to 1-based for createDecorationRanges
154+ range . start . character + 1 ,
155+ undefined // No search result highlighting needed
156+ ) ;
258157
259- // Apply highlight decoration using the appropriate ranges
158+ if ( decorationRanges . length > 0 ) {
260159 const lineHighlightDecoration = vscode . window . createTextEditorDecorationType ( {
261160 backgroundColor : new vscode . ThemeColor ( 'editor.findMatchHighlightBackground' ) ,
262161 border : '1px solid' ,
263162 borderColor : new vscode . ThemeColor ( 'editor.findMatchBorder' )
264163 } ) ;
265164
266- const bestSearchResult = parsed . regex ?
267- ( await searchInFile ( fileUri , { regexPattern : parsed . regex , lineConstraint : parsed . line } ) )
268- . find ( r => r . line === targetLine && r . column === targetColumn ) : undefined ;
165+ editor . setDecorations ( lineHighlightDecoration , decorationRanges ) ;
269166
270- const decorationRanges = createDecorationRanges ( document , parsed . line , targetLine , targetColumn , bestSearchResult ) ;
271- if ( decorationRanges . length > 0 ) {
272- editor . setDecorations ( lineHighlightDecoration , decorationRanges ) ;
273-
274- // Remove highlight after 3 seconds
275- setTimeout ( ( ) => {
276- if ( vscode . window . activeTextEditor === editor ) {
277- editor . setDecorations ( lineHighlightDecoration , [ ] ) ;
278- }
279- lineHighlightDecoration . dispose ( ) ;
280- } , 3000 ) ;
281- }
282-
283- outputChannel . appendLine ( `Navigated to line ${ targetLine } , column ${ targetColumn } ` ) ;
284-
285- } catch ( error ) {
286- outputChannel . appendLine ( `Failed to open dialectic URL: ${ error } ` ) ;
287- vscode . window . showErrorMessage ( `Failed to open ${ dialecticUrl } - ${ error } ` ) ;
167+ // Clear decorations after a delay
168+ setTimeout ( ( ) => {
169+ lineHighlightDecoration . dispose ( ) ;
170+ } , 3000 ) ;
288171 }
172+
173+ outputChannel . appendLine ( `Successfully navigated to ${ document . fileName } :${ range . start . line + 1 } :${ range . start . character + 1 } ` ) ;
289174}
290175
291176/**
0 commit comments