@@ -13,17 +13,135 @@ export async function viewOthers(): Promise<void> {
1313 return ;
1414 }
1515
16- const open = ( item ) => {
17- const uri = DocumentContentProvider . getUri ( item ) ;
18- vscode . window . showTextDocument ( uri ) ;
16+ const open = async ( item : string ) => {
17+ const colonidx : number = item . indexOf ( ":" ) ;
18+ if ( colonidx !== - 1 ) {
19+ // A location is appened to the name of the other document
20+ const options : vscode . TextDocumentShowOptions = { } ;
21+
22+ // Split the document name form the location
23+ let loc = item . slice ( colonidx + 1 ) ;
24+ item = item . slice ( 0 , colonidx ) ;
25+ const uri = DocumentContentProvider . getUri ( item ) ;
26+
27+ if ( item . endsWith ( ".cls" ) ) {
28+ // Locations in classes are of the format method+offset+namespace
29+ loc = loc . slice ( 0 , loc . lastIndexOf ( "+" ) ) ;
30+ let method = loc . slice ( 0 , loc . lastIndexOf ( "+" ) ) ;
31+
32+ // Properly delimit method name if it contains invalid characters
33+ if ( method . match ( / ( ^ ( [ A - Z a - z ] | % ) $ ) | ( ^ ( [ A - Z a - z ] | % ) ( [ A - Z a - z ] | \d | [ ^ \x20 - \x7F ] ) + $ ) / g) === null ) {
34+ method = '"' + method . replace ( / " / g, '""' ) + '"' ;
35+ }
36+
37+ // Find the location of the given method in the class
38+ const symbols : vscode . DocumentSymbol [ ] = await vscode . commands . executeCommand (
39+ "vscode.executeDocumentSymbolProvider" ,
40+ uri
41+ ) ;
42+ if ( symbols !== undefined ) {
43+ for ( const symbol of symbols [ 0 ] . children ) {
44+ if ( symbol . name === method ) {
45+ // This is symbol that the location is in
46+ const doc = await vscode . workspace . openTextDocument ( uri ) ;
47+
48+ // Need to find the actual start of the method
49+ for (
50+ let methodlinenum = symbol . selectionRange . start . line ;
51+ methodlinenum <= symbol . range . end . line ;
52+ methodlinenum ++
53+ ) {
54+ const methodlinetext : string = doc . lineAt ( methodlinenum ) . text . trim ( ) ;
55+ if ( methodlinetext . endsWith ( "{" ) ) {
56+ // This is the last line of the method definition, so count from here
57+ const selectionline : number = methodlinenum + + loc . slice ( loc . lastIndexOf ( "+" ) + 1 ) ;
58+ options . selection = new vscode . Range ( selectionline , 0 , selectionline , 0 ) ;
59+ break ;
60+ }
61+ }
62+ break ;
63+ }
64+ }
65+ }
66+ } else {
67+ if ( item . endsWith ( ".mac" ) ) {
68+ // Locations in MAC routines are of the format +offset+namespace
69+ loc = loc . slice ( 0 , loc . lastIndexOf ( "+" ) ) ;
70+ }
71+ // Locations in INT routines are of the format +offset
72+ const linenum : number = + loc . slice ( 1 ) ;
73+ options . selection = new vscode . Range ( linenum , 0 , linenum , 0 ) ;
74+ }
75+ vscode . window . showTextDocument ( uri , options ) ;
76+ } else {
77+ const uri = DocumentContentProvider . getUri ( item ) ;
78+ vscode . window . showTextDocument ( uri ) ;
79+ }
1980 } ;
2081
2182 const getOthers = ( info ) => {
2283 return info . result . content [ 0 ] . others ;
2384 } ;
85+
2486 const api = new AtelierAPI ( file . uri ) ;
87+ let indexarg : string = file . name ;
88+ const cursorpos : vscode . Position = vscode . window . activeTextEditor . selection . active ;
89+ const fileExt : string = file . name . split ( "." ) . pop ( ) . toLowerCase ( ) ;
90+
91+ if ( api . config . apiVersion >= 4 && ( fileExt === "cls" || fileExt === "mac" || fileExt === "int" ) ) {
92+ // Send the server the current position in the document appended to the name if it supports it
93+ let symbols : vscode . DocumentSymbol [ ] = await vscode . commands . executeCommand (
94+ "vscode.executeDocumentSymbolProvider" ,
95+ file . uri
96+ ) ;
97+ if ( symbols !== undefined ) {
98+ if ( fileExt === "cls" ) {
99+ symbols = symbols [ 0 ] . children ;
100+ }
101+
102+ let currentSymbol : vscode . DocumentSymbol ;
103+ for ( const symbol of symbols ) {
104+ if ( symbol . range . contains ( cursorpos ) ) {
105+ currentSymbol = symbol ;
106+ break ;
107+ }
108+ }
109+
110+ if (
111+ currentSymbol !== undefined &&
112+ currentSymbol . kind === vscode . SymbolKind . Method &&
113+ currentSymbol . detail . toLowerCase ( ) !== "query" &&
114+ currentSymbol . name . charAt ( 0 ) !== '"' &&
115+ currentSymbol . name . charAt ( currentSymbol . name . length - 1 ) !== '"'
116+ ) {
117+ // The current position is in a symbol that we can convert into a label+offset that the server understands
118+ let offset : number = cursorpos . line - currentSymbol . selectionRange . start . line ;
119+
120+ if ( fileExt === "cls" ) {
121+ // Need to find the actual start of the method
122+ const currentdoc : vscode . TextDocument = vscode . window . activeTextEditor . document ;
123+ for (
124+ let methodlinenum = currentSymbol . selectionRange . start . line ;
125+ methodlinenum <= currentSymbol . range . end . line ;
126+ methodlinenum ++
127+ ) {
128+ const methodlinetext : string = currentdoc . lineAt ( methodlinenum ) . text . trim ( ) ;
129+ if ( methodlinetext . endsWith ( "{" ) ) {
130+ // This is the last line of the method definition, so count from here
131+ offset = cursorpos . line - methodlinenum ;
132+ break ;
133+ }
134+ }
135+ }
136+
137+ offset = offset < 0 ? 0 : offset ;
138+ indexarg = indexarg + ":" + currentSymbol . name + "+" + offset ;
139+ }
140+ }
141+ }
142+
25143 return api
26- . actionIndex ( [ file . name ] )
144+ . actionIndex ( [ indexarg ] )
27145 . then ( ( info ) => {
28146 const listOthers = getOthers ( info ) || [ ] ;
29147 if ( ! listOthers . length ) {
0 commit comments