@@ -3,7 +3,14 @@ import { vesper } from './theme';
33import { Renderer } from './renderer/Renderer' ;
44import { getPosFromMouse } from './mouse' ;
55import { Selection , hasDiagnosticSelection } from "./selection" ;
6- import { Completion , CompletionRequest , DefinitionRequest , DefinitionResponse , HoverRequest } from "./lsp" ;
6+ import {
7+ Completion ,
8+ CompletionRequest ,
9+ DefinitionRequest ,
10+ DefinitionResponse ,
11+ HoverRequest ,
12+ ReferencesRequest ,
13+ } from "./lsp" ;
714import {
815 Action , ActionContext , ActionResult ,
916 executeAction , handlePasteText ,
@@ -71,6 +78,7 @@ export class AnycodeEditor {
7178 private completionProvider : ( ( request : CompletionRequest ) => Promise < Completion [ ] > ) | null = null ;
7279 private hoverProvider : ( ( request : HoverRequest ) => Promise < string | null > ) | null = null ;
7380 private goToDefinitionProvider : ( ( request : DefinitionRequest ) => Promise < DefinitionResponse > ) | null = null ;
81+ private referencesPeekProvider : ( ( request : ReferencesRequest ) => Promise < void > ) | null = null ;
7482 private onCursorChangeCallback : ( ( newCursor : Position , oldCursor : Position ) => void ) | null = null ;
7583 private hoverDebounceTimer : number | null = null ;
7684 private hoverRequestToken = 0 ;
@@ -238,9 +246,16 @@ export class AnycodeEditor {
238246
239247 public async init ( ) {
240248 await this . code . init ( ) ;
241- if ( ! this . readOnly ) {
242- this . setupEventListeners ( ) ;
249+ if ( this . readOnly ) {
250+ this . setupReadOnlyEventListeners ( ) ;
251+ return ;
243252 }
253+ this . setupEventListeners ( ) ;
254+ }
255+
256+ private setupReadOnlyEventListeners ( ) {
257+ this . handleScroll = this . handleScroll . bind ( this ) ;
258+ this . container . addEventListener ( "scroll" , this . handleScroll ) ;
244259 }
245260
246261 public getContainer ( ) : HTMLDivElement {
@@ -257,12 +272,46 @@ export class AnycodeEditor {
257272 this . renderer . renderCursor ( line , column ) ;
258273 }
259274
275+ public setSelectionRange (
276+ startLine : number ,
277+ startColumn : number ,
278+ endLine : number ,
279+ endColumn : number ,
280+ center : boolean = false ,
281+ ) : void {
282+ const startOffset = this . code . getOffset ( startLine , startColumn ) ;
283+ const endOffset = this . code . getOffset ( endLine , endColumn ) ;
284+ this . selection = new Selection ( startOffset , endOffset ) ;
285+ this . offset = endOffset ;
286+
287+ if ( center ) {
288+ this . renderer . focusCenter ( this . getEditorState ( ) ) ;
289+ } else {
290+ this . renderer . focus ( this . getEditorState ( ) ) ;
291+ }
292+
293+ const applySelection = ( ) => {
294+ if ( ! this . selection || this . selection . isEmpty ( ) ) return ;
295+ this . renderer . renderSelection ( this . code , this . selection ) ;
296+ } ;
297+
298+ // First pass immediately, then reinforce after possible virtualized re-render.
299+ applySelection ( ) ;
300+ requestAnimationFrame ( ( ) => {
301+ applySelection ( ) ;
302+ requestAnimationFrame ( ( ) => {
303+ applySelection ( ) ;
304+ } ) ;
305+ } ) ;
306+ }
307+
260308 public requestFocus ( line : number , column : number , center : boolean = false ) : void {
261- if ( this . readOnly ) return ;
262309 this . needFocus = true ;
263310 const offset = this . code . getOffset ( line , column ) ;
264311 this . offset = offset ;
265- this . codeContent . focus ( ) ;
312+ if ( ! this . readOnly ) {
313+ this . codeContent . focus ( ) ;
314+ }
266315
267316 if ( center ) this . renderer . focusCenter ( this . getEditorState ( ) ) ;
268317 else this . renderer . focus ( this . getEditorState ( ) ) ;
@@ -308,6 +357,12 @@ export class AnycodeEditor {
308357 this . goToDefinitionProvider = goToDefinitionProvider ;
309358 }
310359
360+ public setReferencesPeekProvider (
361+ referencesPeekProvider : ( request : ReferencesRequest ) => Promise < void >
362+ ) {
363+ this . referencesPeekProvider = referencesPeekProvider ;
364+ }
365+
311366 public setOnCursorChange ( callback : ( newState : Position , oldState : Position ) => void ) {
312367 this . onCursorChangeCallback = callback ;
313368 }
@@ -462,6 +517,11 @@ export class AnycodeEditor {
462517 this . isCompletionOpen = false ;
463518 }
464519
520+ if ( e . altKey ) {
521+ this . openReferencesPeek ( pos . row , pos . col ) . catch ( console . error ) ;
522+ return ;
523+ }
524+
465525 if ( e . metaKey || e . ctrlKey ) {
466526 this . goToDefinition ( pos . row , pos . col ) . catch ( console . error ) ;
467527 }
@@ -486,6 +546,25 @@ export class AnycodeEditor {
486546 }
487547 }
488548
549+ private async openReferencesPeek ( row : number , col : number ) : Promise < void > {
550+ if ( ! this . referencesPeekProvider ) {
551+ console . warn ( 'References peek provider not set' ) ;
552+ return ;
553+ }
554+
555+ try {
556+ const referencesRequest : ReferencesRequest = {
557+ file : this . code . filename ,
558+ row : row ,
559+ column : col
560+ } ;
561+
562+ await this . referencesPeekProvider ( referencesRequest ) ;
563+ } catch ( error ) {
564+ console . error ( 'Failed to get references:' , error ) ;
565+ }
566+ }
567+
489568 private handleMouseUp ( e : MouseEvent ) {
490569 // console.log('handleMouseUp ', this.selection);
491570 this . isMouseSelecting = false ;
@@ -1349,5 +1428,4 @@ export class AnycodeEditor {
13491428
13501429 this . renderer . verifyDiffs ( this . diffs ) ;
13511430 }
1352-
13531431}
0 commit comments