Skip to content

Commit 8034089

Browse files
committed
Add delete function in codelense
1 parent d6bf8ac commit 8034089

File tree

2 files changed

+102
-26
lines changed

2 files changed

+102
-26
lines changed

src/components/QueryEditorRaw.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ export function QueryEditorRaw({ query, onBlur, language, width, height, fontSiz
3737
setupValidationFn(editor, monaco);
3838
setupAutocompleteFn(editor, monaco);
3939
setupHoverFn(editor, monaco);
40-
setupCodeLensFn(editor, monaco);
40+
41+
const updateTextCommandId = editor.addCommand(0, (_ctx, ...args) => {
42+
const text = args[0];
43+
onBlur?.(text);
44+
});
45+
46+
setupCodeLensFn(editor, monaco, updateTextCommandId!);
4147
}}
4248
height={height || '240px'}
4349
width={width ? `${width - 2}px` : undefined}

src/editor/codelens.ts

Lines changed: 95 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,29 @@ import { useEffect, useRef } from 'react';
55
interface ParsedAggregateStages {
66
name: string;
77
startLine: number;
8-
startCharacter: number;
9-
length: number;
8+
startColumn: number;
9+
startOffset: number;
10+
endOffset: number;
1011
}
1112

1213
class CodeLensVisitor implements JSONVisitor {
1314
private _currentLevel: number;
1415
private _stages: ParsedAggregateStages[];
16+
private _seperators: number[];
1517
private _hasError: boolean;
18+
private _startLine: number;
19+
private _startColumn: number;
20+
private _startOffset: number;
21+
private _stageName?: string;
1622

1723
constructor() {
1824
this._hasError = false;
1925
this._currentLevel = 0;
2026
this._stages = [];
27+
this._seperators = [];
28+
this._startLine = 0;
29+
this._startOffset = 0;
30+
this._startColumn = 0;
2131
}
2232

2333
onObjectBegin = (
@@ -31,6 +41,13 @@ class CodeLensVisitor implements JSONVisitor {
3141
return false;
3242
}
3343
this._currentLevel += 1;
44+
45+
if (this._currentLevel === 1) {
46+
this._startLine = startLine;
47+
this._startOffset = offset;
48+
this._startColumn = startCharacter;
49+
}
50+
return;
3451
};
3552

3653
onObjectProperty = (
@@ -39,37 +56,55 @@ class CodeLensVisitor implements JSONVisitor {
3956
length: number,
4057
startLine: number,
4158
startCharacter: number,
42-
pathSupplier: () => JSONPath,
59+
_pathSupplier: () => JSONPath,
4360
) => {
4461
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;
5163
}
5264
};
5365

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+
}
5580
this._currentLevel -= 1;
5681
};
5782

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) => {
5990
this._hasError = true;
6091
};
6192

6293
public get stages(): ParsedAggregateStages[] {
6394
return this._stages;
6495
}
6596

97+
public get seperators(): number[] {
98+
return this._seperators;
99+
}
100+
66101
public get hasError(): boolean {
67102
return this._hasError;
68103
}
69104
}
70105

71106
class CodeLensProvider implements monacoTypes.languages.CodeLensProvider {
72-
constructor(private readonly editor: MonacoEditor) {}
107+
constructor(private readonly editor: MonacoEditor, private readonly updateTextCommandId: string) { }
73108

74109
provideCodeLenses(
75110
model: monacoTypes.editor.ITextModel,
@@ -79,6 +114,8 @@ class CodeLensProvider implements monacoTypes.languages.CodeLensProvider {
79114
return null;
80115
}
81116

117+
const lenses: monacoTypes.languages.CodeLens[] = []
118+
82119
const text = model.getValue();
83120
const visitor = new CodeLensVisitor();
84121
visit(text, visitor);
@@ -88,20 +125,53 @@ class CodeLensProvider implements monacoTypes.languages.CodeLensProvider {
88125
}
89126

90127
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}`
98145
},
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,
99164
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)]
102168
},
103-
})),
104-
dispose: () => {},
169+
});
170+
}
171+
172+
return {
173+
lenses: lenses,
174+
dispose: () => { },
105175
};
106176
}
107177

@@ -122,8 +192,8 @@ export function useCodeLens() {
122192
};
123193
}, []);
124194

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);
127197
const { dispose } = monaco.languages.registerCodeLensProvider('json', provider);
128198
codeLensDisposeFun.current = dispose;
129199
};

0 commit comments

Comments
 (0)