Skip to content

Commit db0d0e6

Browse files
committed
refactor: refactor the whole thing
1 parent 71d1aba commit db0d0e6

File tree

3 files changed

+157
-54
lines changed

3 files changed

+157
-54
lines changed

.vscode/launch.json

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,32 @@
33
// Hover to view descriptions of existing attributes.
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
{
6-
"version": "0.2.0",
7-
"configurations": [
8-
{
9-
"name": "Run Extension",
10-
"type": "extensionHost",
11-
"request": "launch",
12-
"args": [
13-
"--extensionDevelopmentPath=${workspaceFolder}"
14-
],
15-
"outFiles": [
16-
"${workspaceFolder}/dist/**/*.js"
17-
],
18-
"preLaunchTask": "${defaultBuildTask}"
19-
},
20-
{
21-
"name": "Extension Tests",
22-
"type": "extensionHost",
23-
"request": "launch",
24-
"args": [
25-
"--extensionDevelopmentPath=${workspaceFolder}",
26-
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
27-
],
28-
"outFiles": [
29-
"${workspaceFolder}/out/**/*.js",
30-
"${workspaceFolder}/dist/**/*.js"
31-
],
32-
"preLaunchTask": "tasks: watch-tests"
33-
}
34-
]
6+
"version": "0.2.0",
7+
"configurations": [
8+
{
9+
"name": "Run Extension",
10+
"type": "extensionHost",
11+
"request": "launch",
12+
"args": [
13+
"--extensionDevelopmentPath=${workspaceFolder}",
14+
"--disable-extensions"
15+
],
16+
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
17+
"preLaunchTask": "${defaultBuildTask}"
18+
},
19+
{
20+
"name": "Extension Tests",
21+
"type": "extensionHost",
22+
"request": "launch",
23+
"args": [
24+
"--extensionDevelopmentPath=${workspaceFolder}",
25+
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
26+
],
27+
"outFiles": [
28+
"${workspaceFolder}/out/**/*.js",
29+
"${workspaceFolder}/dist/**/*.js"
30+
],
31+
"preLaunchTask": "tasks: watch-tests"
32+
}
33+
]
3534
}

src/decoration-manager.ts

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export default class DecorationManager {
1010
>;
1111
private timeout: NodeJS.Timer | undefined = undefined;
1212
private fileName: string = "";
13-
private fileLineCount: number = 0;
1413

1514
constructor($activeEditor: vscode.TextEditor | undefined, $fullToken: any) {
1615
this.activeEditor = $activeEditor;
@@ -21,16 +20,19 @@ export default class DecorationManager {
2120
setActiveEditor(editor: vscode.TextEditor) {
2221
this.activeEditor = editor;
2322
this.fileName = editor.document.fileName;
24-
this.fileLineCount = editor.document.lineCount;
2523
}
2624

2725
triggerUpdateDecorations(
2826
throttle: boolean = false,
2927
isEdit: boolean = false,
28+
diffLine: number = 0,
3029
startLine?: number,
3130
endLine?: number
3231
) {
3332
console.log("fileName", this.fileName);
33+
/**
34+
* Active editor changed event
35+
*/
3436
if (!isEdit) {
3537
if (this.fileDecorationMap.has(this.fileName)) {
3638
this.clearCurrentFileDecoration();
@@ -45,41 +47,43 @@ export default class DecorationManager {
4547

4648
if (throttle) {
4749
this.timeout = setTimeout(() => {
48-
this.setupDecorations(startLine, endLine);
50+
this.setupDecorations(diffLine, startLine, endLine);
4951
}, 500);
5052
} else {
51-
this.setupDecorations(startLine, endLine);
53+
this.setupDecorations(diffLine, startLine, endLine);
5254
}
5355
}
5456

55-
setupDecorations(startLine?: number, endLine?: number) {
57+
setupDecorations(diffLine: number, startLine?: number, endLine?: number) {
5658
if (startLine && endLine) {
57-
console.log("editing", startLine, endLine);
58-
const currentLineCount = this.activeEditor!.document.lineCount;
59-
const diffLine = currentLineCount - this.fileLineCount;
6059
console.log("diffLine", diffLine);
6160

61+
const lines = this.getLines(startLine, endLine);
6262
if (diffLine < 0) {
63-
const lines = this.getLines(startLine, endLine);
64-
return this.clearCurrentFileDecoration(lines);
63+
this.clearCurrentFileDecoration(lines);
64+
this.updateFileDecorationMap(diffLine, startLine);
6565
}
6666

6767
if (diffLine === 0) {
6868
this.clearCurrentFileDecoration([startLine]);
69+
this.setDecorations([startLine]);
6970
}
70-
}
7171

72-
this.setDecorations();
72+
if (diffLine > 0) {
73+
this.updateFileDecorationMap(diffLine, startLine);
74+
this.setDecorations(lines);
75+
}
76+
} else {
77+
this.setDecorations();
78+
}
7379
}
7480

75-
setDecorations() {
81+
setDecorations(sepecificLines?: number[]) {
7682
console.log("!!!!!!updating!!!!!");
7783
const text = this.activeEditor!.document.getText();
7884
const fullTokenKeys = Object.keys(this.fullToken);
79-
const lineDecorationMap = new Map<
80-
number,
81-
vscode.TextEditorDecorationType[]
82-
>();
85+
const lineDecorationMap: Map<number, vscode.TextEditorDecorationType[]> =
86+
this.fileDecorationMap.get(this.fileName) || new Map();
8387

8488
if (!this.fileDecorationMap.has(this.fileName)) {
8589
this.fileDecorationMap.set(this.fileName, new Map());
@@ -94,7 +98,12 @@ export default class DecorationManager {
9498
match.index
9599
).line;
96100

97-
this.setDecoration(match, key, lineDecorationMap);
101+
if (
102+
!sepecificLines ||
103+
(sepecificLines && sepecificLines.includes(currentLine))
104+
) {
105+
this.setDecoration(match, key, lineDecorationMap);
106+
}
98107
}
99108
});
100109

@@ -104,12 +113,15 @@ export default class DecorationManager {
104113

105114
clearCurrentFileDecoration(lines?: number[]) {
106115
const lineDecorationMapItem = this.fileDecorationMap.get(this.fileName);
107-
108-
if (lineDecorationMapItem) {
116+
console.log("lineDecorationMapItem", lineDecorationMapItem);
117+
if (lineDecorationMapItem?.size) {
109118
if (lines) {
110119
lines.forEach((line) => {
111120
console.log("dispose line", line);
112-
lineDecorationMapItem.get(line)?.forEach(this.dispose);
121+
if (lineDecorationMapItem.has(line)) {
122+
lineDecorationMapItem.get(line)?.forEach(this.dispose);
123+
lineDecorationMapItem.delete(line);
124+
}
113125
});
114126
} else {
115127
lineDecorationMapItem.forEach((value) => {
@@ -182,4 +194,27 @@ export default class DecorationManager {
182194
// console.log("setDecorations", currentLine);
183195
this.activeEditor!.setDecorations(decorationType, valueDecorations);
184196
}
197+
198+
updateFileDecorationMap(diffLine: number, startLine: number) {
199+
const lineDecorationMapItem = this.fileDecorationMap.get(this.fileName);
200+
const newMap: Map<number, vscode.TextEditorDecorationType[]> = new Map();
201+
console.log("before: ", lineDecorationMapItem);
202+
console.log("startLine", startLine);
203+
204+
if (lineDecorationMapItem?.size) {
205+
lineDecorationMapItem.forEach((value, key) => {
206+
if (key >= startLine) {
207+
newMap.set(
208+
diffLine > 0 ? key + diffLine : key - Math.abs(diffLine),
209+
lineDecorationMapItem.get(key)!
210+
);
211+
} else {
212+
newMap.set(key, lineDecorationMapItem.get(key)!);
213+
}
214+
});
215+
}
216+
217+
console.log("after: ", newMap);
218+
this.fileDecorationMap.set(this.fileName, newMap);
219+
}
185220
}

src/listener.ts

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ export default function setupEventListener(
55
context: vscode.ExtensionContext,
66
fullToken: any
77
) {
8+
let diffLine: number = 0;
9+
let fileLineCount: number = 0;
810
let activeEditor = vscode.window.activeTextEditor;
911
const decorationManager = new DecorationManager(activeEditor, fullToken);
1012

1113
if (activeEditor) {
14+
fileLineCount = activeEditor.document.lineCount;
1215
decorationManager.setActiveEditor(activeEditor);
1316
decorationManager.triggerUpdateDecorations();
1417
}
@@ -19,14 +22,23 @@ export default function setupEventListener(
1922
return;
2023
}
2124

22-
const startLine = event.contentChanges[0].range.start.line;
23-
const endLine = event.contentChanges[0].range.end.line;
24-
2525
if (activeEditor && event.document === activeEditor.document) {
26+
console.log("change", event.contentChanges[0]);
27+
28+
diffLine = activeEditor.document.lineCount - fileLineCount;
29+
fileLineCount = activeEditor.document.lineCount;
30+
31+
const [startLine, endLine] = getStartEndLine(
32+
event.document,
33+
event.contentChanges[0]
34+
);
35+
36+
console.log("editing", startLine, endLine);
2637
decorationManager.setActiveEditor(activeEditor);
2738
decorationManager.triggerUpdateDecorations(
39+
diffLine === 0,
2840
true,
29-
true,
41+
diffLine,
3042
startLine,
3143
endLine
3244
);
@@ -40,11 +52,68 @@ export default function setupEventListener(
4052
(editor) => {
4153
activeEditor = editor;
4254
if (editor) {
55+
fileLineCount = editor.document.lineCount || 0;
4356
decorationManager.setActiveEditor(editor);
4457
decorationManager.triggerUpdateDecorations();
4558
}
4659
},
4760
null,
4861
context.subscriptions
4962
);
63+
64+
function getStartEndLine(
65+
document: vscode.TextDocument,
66+
change: vscode.TextDocumentContentChangeEvent
67+
) {
68+
const newLines = change.text.split("\n").length;
69+
let startLine = change.range.start.line;
70+
let endLine = change.range.end.line;
71+
const startLinePos = document.lineAt(startLine);
72+
73+
const isStartLineEmpty = startLinePos.isEmptyOrWhitespace;
74+
const startLineLastPos = new vscode.Position(
75+
startLine,
76+
Math.max(startLinePos.text.length, 0)
77+
);
78+
const isStartLineLastPos = startLineLastPos.isEqual(change.range.start);
79+
80+
console.log("original", startLine, endLine);
81+
console.log("isStartLineEmpty", isStartLineEmpty);
82+
console.log("isStartLineLastPos", isStartLineLastPos);
83+
84+
/**
85+
* paste multiple lines
86+
* there are some `\n` in `text`, but currentChange[0].range is always a single line
87+
*/
88+
if (newLines > 1 && !change.text.startsWith("\n")) {
89+
endLine = startLine + newLines - 1;
90+
}
91+
92+
/**
93+
* cmd + x
94+
*/
95+
if (
96+
change.range.start.character === 0 &&
97+
change.range.end.character === 0
98+
) {
99+
endLine -= 1;
100+
}
101+
102+
/**
103+
* enter
104+
*/
105+
if (!isStartLineEmpty && diffLine === 1) {
106+
startLine += 1;
107+
endLine += 1;
108+
}
109+
110+
/**
111+
* delete to the end of the previous line
112+
*/
113+
if (!isStartLineEmpty && isStartLineLastPos && diffLine < 0) {
114+
startLine += 1;
115+
}
116+
117+
return [startLine, endLine];
118+
}
50119
}

0 commit comments

Comments
 (0)