@@ -5,19 +5,29 @@ import { useEffect, useRef } from 'react';
5
5
interface ParsedAggregateStages {
6
6
name : string ;
7
7
startLine : number ;
8
- startCharacter : number ;
9
- length : number ;
8
+ startColumn : number ;
9
+ startOffset : number ;
10
+ endOffset : number ;
10
11
}
11
12
12
13
class CodeLensVisitor implements JSONVisitor {
13
14
private _currentLevel : number ;
14
15
private _stages : ParsedAggregateStages [ ] ;
16
+ private _seperators : number [ ] ;
15
17
private _hasError : boolean ;
18
+ private _startLine : number ;
19
+ private _startColumn : number ;
20
+ private _startOffset : number ;
21
+ private _stageName ?: string ;
16
22
17
23
constructor ( ) {
18
24
this . _hasError = false ;
19
25
this . _currentLevel = 0 ;
20
26
this . _stages = [ ] ;
27
+ this . _seperators = [ ] ;
28
+ this . _startLine = 0 ;
29
+ this . _startOffset = 0 ;
30
+ this . _startColumn = 0 ;
21
31
}
22
32
23
33
onObjectBegin = (
@@ -31,6 +41,13 @@ class CodeLensVisitor implements JSONVisitor {
31
41
return false ;
32
42
}
33
43
this . _currentLevel += 1 ;
44
+
45
+ if ( this . _currentLevel === 1 ) {
46
+ this . _startLine = startLine ;
47
+ this . _startOffset = offset ;
48
+ this . _startColumn = startCharacter ;
49
+ }
50
+ return ;
34
51
} ;
35
52
36
53
onObjectProperty = (
@@ -39,37 +56,55 @@ class CodeLensVisitor implements JSONVisitor {
39
56
length : number ,
40
57
startLine : number ,
41
58
startCharacter : number ,
42
- pathSupplier : ( ) => JSONPath ,
59
+ _pathSupplier : ( ) => JSONPath ,
43
60
) => {
44
61
if ( this . _currentLevel === 1 ) {
45
- this . _stages . push ( {
46
- name : property ,
47
- startLine : startLine ,
48
- startCharacter : startCharacter ,
49
- length : length ,
50
- } ) ;
62
+ this . _stageName = property ;
51
63
}
52
64
} ;
53
65
54
- onObjectEnd = ( offset : number , length : number , startLine : number , startCharacter : number ) => {
66
+ onObjectEnd = ( offset : number , _length : number , _startLine : number , _startCharacter : number ) => {
67
+ if ( ! this . _stageName ) {
68
+ this . _hasError = true ;
69
+ } else {
70
+ if ( this . _currentLevel === 1 ) {
71
+ this . _stages . push ( {
72
+ name : this . _stageName ,
73
+ startLine : this . _startLine ,
74
+ startOffset : this . _startOffset ,
75
+ startColumn : this . _startColumn ,
76
+ endOffset : offset ,
77
+ } ) ;
78
+ }
79
+ }
55
80
this . _currentLevel -= 1 ;
56
81
} ;
57
82
58
- onError = ( error : ParseErrorCode , offset : number , length : number , startLine : number , startCharacter : number ) => {
83
+ onSeparator = ( character : string , offset : number , _length : number , _startLine : number , _startCharacter : number ) => {
84
+ if ( character === ',' && this . _currentLevel === 0 ) {
85
+ this . _seperators . push ( offset )
86
+ }
87
+ }
88
+
89
+ onError = ( _error : ParseErrorCode , _offset : number , _length : number , _startLine : number , _startCharacter : number ) => {
59
90
this . _hasError = true ;
60
91
} ;
61
92
62
93
public get stages ( ) : ParsedAggregateStages [ ] {
63
94
return this . _stages ;
64
95
}
65
96
97
+ public get seperators ( ) : number [ ] {
98
+ return this . _seperators ;
99
+ }
100
+
66
101
public get hasError ( ) : boolean {
67
102
return this . _hasError ;
68
103
}
69
104
}
70
105
71
106
class CodeLensProvider implements monacoTypes . languages . CodeLensProvider {
72
- constructor ( private readonly editor : MonacoEditor ) { }
107
+ constructor ( private readonly editor : MonacoEditor , private readonly updateTextCommandId : string ) { }
73
108
74
109
provideCodeLenses (
75
110
model : monacoTypes . editor . ITextModel ,
@@ -79,6 +114,8 @@ class CodeLensProvider implements monacoTypes.languages.CodeLensProvider {
79
114
return null ;
80
115
}
81
116
117
+ const lenses : monacoTypes . languages . CodeLens [ ] = [ ]
118
+
82
119
const text = model . getValue ( ) ;
83
120
const visitor = new CodeLensVisitor ( ) ;
84
121
visit ( text , visitor ) ;
@@ -88,20 +125,53 @@ class CodeLensProvider implements monacoTypes.languages.CodeLensProvider {
88
125
}
89
126
90
127
const stages = visitor . stages ;
91
- return {
92
- lenses : stages . map ( ( stage ) => ( {
93
- range : {
94
- startLineNumber : stage . startLine ,
95
- startColumn : stage . startCharacter ,
96
- endLineNumber : stage . startLine ,
97
- endColumn : stage . startCharacter + stage . length ,
128
+ const seperators = visitor . seperators ;
129
+
130
+ for ( let i = 0 ; i < stages . length ; i ++ ) {
131
+ const stage = stages [ i ] ;
132
+
133
+ const range = {
134
+ startLineNumber : stage . startLine + 1 ,
135
+ startColumn : stage . startColumn ,
136
+ endLineNumber : stage . startLine + 2 ,
137
+ endColumn : stage . startColumn
138
+ }
139
+
140
+ lenses . push ( {
141
+ range,
142
+ // @ts -ignore
143
+ command : {
144
+ title : `Stage ${ stage . name } `
98
145
} ,
146
+ } ) ;
147
+
148
+ // Remove text from start - end
149
+ let start , end ;
150
+
151
+ if ( i == 0 ) {
152
+ start = stage . startOffset ;
153
+ end = seperators . length > 0 ? seperators [ 0 ] + 1 : stage . endOffset + 1 ;
154
+ } else if ( i == stages . length - 1 ) {
155
+ start = seperators [ seperators . length - 1 ] ;
156
+ end = stage . endOffset + 1 ;
157
+ } else {
158
+ start = stage . startOffset ;
159
+ end = seperators . length > 0 ? seperators [ i ] + 1 : stage . endOffset + 1 ;
160
+ }
161
+
162
+ lenses . push ( {
163
+ range,
99
164
command : {
100
- id : 'mongodb.aggregate.stage' ,
101
- title : `Stage: ${ stage . name } ` ,
165
+ id : this . updateTextCommandId ,
166
+ title : "Delete" ,
167
+ arguments : [ text . slice ( 0 , start ) + text . slice ( end ) ]
102
168
} ,
103
- } ) ) ,
104
- dispose : ( ) => { } ,
169
+ } ) ;
170
+ }
171
+
172
+ return {
173
+ lenses : lenses ,
174
+ dispose : ( ) => { } ,
105
175
} ;
106
176
}
107
177
@@ -122,8 +192,8 @@ export function useCodeLens() {
122
192
} ;
123
193
} , [ ] ) ;
124
194
125
- return ( editor : MonacoEditor , monaco : Monaco ) => {
126
- const provider = new CodeLensProvider ( editor ) ;
195
+ return ( editor : MonacoEditor , monaco : Monaco , updateTextCommandId : string ) => {
196
+ const provider = new CodeLensProvider ( editor , updateTextCommandId ) ;
127
197
const { dispose } = monaco . languages . registerCodeLensProvider ( 'json' , provider ) ;
128
198
codeLensDisposeFun . current = dispose ;
129
199
} ;
0 commit comments