@@ -5,9 +5,15 @@ import {
5
5
_Connection ,
6
6
TextDocumentPositionParams ,
7
7
CodeActionParams ,
8
- DefinitionParams
8
+ DefinitionParams ,
9
+ SymbolKind ,
10
+ Location ,
11
+ Position ,
12
+ Range ,
13
+ DocumentSymbol
9
14
} from 'vscode-languageserver/node'
10
15
import { TextDocument } from 'vscode-languageserver-textdocument'
16
+ import { URI } from 'vscode-uri'
11
17
import { TextDocumentWrapper } from './TextDocumentWrapper'
12
18
13
19
export class LanguageServer {
@@ -18,7 +24,13 @@ export class LanguageServer {
18
24
19
25
connection . onInitialize ( ( ) => this . onInitialize ( ) )
20
26
21
- connection . onDefinition ( params => this . onDefinition ( params ) )
27
+ connection . onDefinition ( params => {
28
+ if ( ! params . textDocument . uri . endsWith ( 'dvc.yaml' ) ) {
29
+ return null
30
+ }
31
+
32
+ return this . onDefinition ( params )
33
+ } )
22
34
23
35
this . documents . listen ( connection )
24
36
@@ -41,26 +53,89 @@ export class LanguageServer {
41
53
return new TextDocumentWrapper ( doc )
42
54
}
43
55
56
+ private getFilePathLocations (
57
+ symbolUnderCursor : DocumentSymbol ,
58
+ allDocs : TextDocument [ ]
59
+ ) {
60
+ if ( symbolUnderCursor . kind !== SymbolKind . File ) {
61
+ return [ ]
62
+ }
63
+
64
+ const filePath = symbolUnderCursor . name
65
+
66
+ const matchingFiles = allDocs . filter ( doc =>
67
+ URI . file ( doc . uri ) . fsPath . endsWith ( filePath )
68
+ )
69
+
70
+ return matchingFiles . map ( doc => {
71
+ const uri = doc . uri
72
+ const start = Position . create ( 0 , 0 )
73
+ const end = doc . positionAt ( doc . getText ( ) . length - 1 )
74
+ const range = Range . create ( start , end )
75
+
76
+ return Location . create ( uri , range )
77
+ } )
78
+ }
79
+
80
+ private getLocationsFromOtherDocuments (
81
+ symbolUnderCursor : DocumentSymbol ,
82
+ allDocs : TextDocument [ ]
83
+ ) {
84
+ const locationsAccumulator = [ ]
85
+
86
+ for ( const txtDoc of allDocs ) {
87
+ const finder = this . wrap ( txtDoc )
88
+ const locations = finder . findLocationsFor ( symbolUnderCursor )
89
+ locationsAccumulator . push ( ...locations )
90
+ }
91
+
92
+ return locationsAccumulator
93
+ }
94
+
44
95
private onDefinition ( params : DefinitionParams ) {
45
96
const document = this . getDvcTextDocument ( params )
46
97
const symbolUnderCursor = document ?. symbolAt ( params . position )
47
98
48
- if ( symbolUnderCursor ) {
99
+ if ( document && symbolUnderCursor ) {
49
100
const allDocs = this . documents . all ( )
50
101
const locationsAccumulator = [ ]
51
102
52
- for ( const txtDoc of allDocs ) {
53
- const finder = this . wrap ( txtDoc )
54
- const locations = finder . findLocationsFor ( symbolUnderCursor )
55
- locationsAccumulator . push ( ...locations )
103
+ const fileLocations = this . getFilePathLocations (
104
+ symbolUnderCursor ,
105
+ allDocs
106
+ )
107
+
108
+ locationsAccumulator . push ( ...fileLocations )
109
+
110
+ const locationsFromOtherDocuments = this . getLocationsFromOtherDocuments (
111
+ symbolUnderCursor ,
112
+ allDocs
113
+ )
114
+
115
+ locationsAccumulator . push ( ...locationsFromOtherDocuments )
116
+
117
+ const externalLocations = locationsAccumulator . filter (
118
+ location => location . uri !== document . uri
119
+ )
120
+
121
+ if ( externalLocations . length > 0 ) {
122
+ return this . arrayOrSingleResponse ( externalLocations )
56
123
}
57
124
58
- return locationsAccumulator ?? [ ]
125
+ return this . arrayOrSingleResponse ( locationsAccumulator )
59
126
}
60
127
61
128
return null
62
129
}
63
130
131
+ private arrayOrSingleResponse < T > ( elements : T [ ] ) {
132
+ if ( elements . length === 1 ) {
133
+ return elements [ 0 ]
134
+ }
135
+
136
+ return elements
137
+ }
138
+
64
139
private onInitialize ( ) {
65
140
const serverCapabilities : ServerCapabilities = {
66
141
definitionProvider : true
0 commit comments