Skip to content

Commit b8919f1

Browse files
committed
refactor: decorator
1 parent aa77e84 commit b8919f1

File tree

1 file changed

+134
-128
lines changed

1 file changed

+134
-128
lines changed

src/decorator.ts

Lines changed: 134 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from "vscode";
22
import { genMarkdownString, getColorTokenValue } from "./utils";
33

4-
interface DecorationItem {
4+
interface LineDecorationItem {
55
line: number;
66
disposable: vscode.TextEditorDecorationType;
77
}
@@ -12,18 +12,15 @@ export default function setupChangeEvent(
1212
) {
1313
let timeout: NodeJS.Timer | undefined = undefined;
1414
let activeEditor = vscode.window.activeTextEditor;
15-
const fullTokenKeys = Object.keys(fullToken);
16-
const fileDecorationMap = new Map<string, DecorationItem[]>();
17-
const openedFileNameSet = new Set<string>();
18-
let lineCount = 0;
15+
const fileDecorationMap = new Map<
16+
string,
17+
Map<number, vscode.TextEditorDecorationType[]>
18+
>();
19+
let fileLineCount = 0;
1920

2021
if (activeEditor) {
21-
lineCount = activeEditor.document.lineCount;
22-
const isOpened = checkOpenedFile(activeEditor.document.fileName);
23-
24-
if (!isOpened) {
25-
triggerUpdateDecorations();
26-
}
22+
fileLineCount = activeEditor.document.lineCount;
23+
triggerUpdateDecorations();
2724
}
2825

2926
vscode.workspace.onDidChangeTextDocument(
@@ -33,7 +30,7 @@ export default function setupChangeEvent(
3330
}
3431

3532
const startLine = event.contentChanges[0].range.start.line;
36-
let endLine = event.contentChanges[0].range.end.line;
33+
const endLine = event.contentChanges[0].range.end.line;
3734

3835
if (activeEditor && event.document === activeEditor.document) {
3936
/**
@@ -43,7 +40,7 @@ export default function setupChangeEvent(
4340
const throttle =
4441
event.reason !== undefined
4542
? false
46-
: event.document.lineCount - lineCount >= 0;
43+
: event.document.lineCount - fileLineCount >= 0;
4744
triggerUpdateDecorations(throttle, true, startLine, endLine);
4845
}
4946
},
@@ -53,14 +50,18 @@ export default function setupChangeEvent(
5350

5451
vscode.window.onDidChangeActiveTextEditor(
5552
(editor) => {
53+
console.log("Active Editor!", editor?.document.fileName);
5654
activeEditor = editor;
5755
if (editor) {
58-
lineCount = editor.document.lineCount;
59-
const isOpened = checkOpenedFile(editor.document.fileName);
56+
const fileName = editor.document.fileName;
57+
fileLineCount = editor.document.lineCount;
6058

61-
if (!isOpened) {
62-
triggerUpdateDecorations();
59+
if (fileDecorationMap.has(fileName)) {
60+
clearDecoration(fileName);
61+
fileDecorationMap.set(fileName, new Map());
6362
}
63+
64+
triggerUpdateDecorations();
6465
}
6566
},
6667
null,
@@ -79,132 +80,137 @@ export default function setupChangeEvent(
7980
}
8081
if (throttle) {
8182
timeout = setTimeout(() => {
82-
updateDecorations(isEdit, startLine, endLine);
83+
updateDecorations(startLine, endLine);
8384
}, 500);
8485
} else {
85-
updateDecorations(isEdit, startLine, endLine);
86+
updateDecorations(startLine, endLine);
8687
}
8788
}
8889

89-
function updateDecorations(
90-
isEdit: boolean,
91-
startLine?: number,
92-
endLine?: number
93-
) {
90+
function updateDecorations(startLine?: number, endLine?: number) {
9491
if (activeEditor) {
95-
console.log("!!!!!!update!!!!", startLine, endLine);
96-
const text = activeEditor.document.getText();
97-
const fileName = activeEditor.document.fileName;
98-
99-
if (!fileDecorationMap.has(fileName)) {
100-
fileDecorationMap.set(fileName, []);
101-
}
92+
if (startLine && endLine) {
93+
console.log("editing", startLine, endLine);
94+
const currentLineCount = activeEditor.document.lineCount;
95+
const diffLine = currentLineCount - fileLineCount;
96+
const fileName = activeEditor.document.fileName;
97+
console.log("diffLine", diffLine);
98+
99+
if (diffLine < 0) {
100+
const lines = getLines(startLine, endLine);
101+
return clearDecoration(fileName, lines);
102+
}
102103

103-
const currentFileDecorations = fileDecorationMap.get(fileName) || [];
104-
const currentLineCount = activeEditor.document.lineCount;
105-
const diffLine = currentLineCount - lineCount;
106-
console.log("diffLine", diffLine);
107-
lineCount = currentLineCount;
108-
109-
/**
110-
* Dispose the line decoration between start and end
111-
*/
112-
if (
113-
startLine &&
114-
endLine &&
115-
currentFileDecorations.length &&
116-
diffLine <= 0
117-
) {
118-
for (let i = startLine; i <= endLine; i++) {
119-
for (let j = 0; j < currentFileDecorations.length; j++) {
120-
if (currentFileDecorations[j].line === i) {
121-
currentFileDecorations[j].disposable.dispose();
122-
console.log("dispose", i);
123-
currentFileDecorations.splice(j--, 1);
124-
}
125-
}
104+
if (diffLine === 0) {
105+
clearDecoration(fileName, [startLine]);
126106
}
127107
}
128108

129-
// if (diffLine > 0) {
130-
// return;
131-
// }
109+
setupDecoration(startLine, endLine);
110+
}
111+
}
132112

133-
fullTokenKeys.forEach((key: string) => {
134-
if (!activeEditor) {
135-
return;
136-
}
113+
function setupDecoration(startLine?: number, endLine?: number) {
114+
console.log("!!!!!!updating!!!!!", startLine, endLine);
115+
const fileName = activeEditor!.document.fileName;
116+
const text = activeEditor!.document.getText();
117+
const fullTokenKeys = Object.keys(fullToken);
118+
const lineDecorationMap = new Map<
119+
number,
120+
vscode.TextEditorDecorationType[]
121+
>();
122+
123+
if (!fileDecorationMap.has(fileName)) {
124+
fileDecorationMap.set(fileName, new Map());
125+
}
137126

138-
const regEx = new RegExp(`\\b(${key})\\b(?!-)`, "g");
139-
140-
let match;
141-
while ((match = regEx.exec(text))) {
142-
const valueDecorations: vscode.DecorationOptions[] = [];
143-
let decorationType: vscode.TextEditorDecorationType;
144-
145-
/**
146-
* TIPS:
147-
* Actually, they are always at the same line.
148-
*/
149-
const startPos = activeEditor.document.positionAt(match.index);
150-
const endPos = activeEditor.document.positionAt(
151-
match.index + match[0].length
152-
);
153-
const currentLine = startPos.line;
154-
155-
if (
156-
!isEdit ||
157-
// diffLine > 0 ||
158-
(startLine &&
159-
endLine &&
160-
currentLine >= startLine &&
161-
currentLine <= endLine)
162-
) {
163-
const value = String(fullToken[key]);
164-
const colorSpan = genMarkdownString(value);
165-
const markDownString = new vscode.MarkdownString(
166-
`<h3>antd design token: ${match[0]}</h3>${colorSpan}<code>${value}</code><br></br>`
167-
);
168-
markDownString.supportHtml = true;
169-
markDownString.isTrusted = true;
170-
171-
const decoration = {
172-
range: new vscode.Range(startPos, endPos),
173-
hoverMessage: markDownString,
174-
};
175-
176-
const colorValue = getColorTokenValue(fullToken[key]);
177-
valueDecorations.push(decoration);
178-
179-
decorationType = vscode.window.createTextEditorDecorationType({
180-
after: {
181-
contentText: colorValue ? `**` : `(${String(fullToken[key])})`,
182-
backgroundColor: colorValue || "",
183-
margin: "0 0 0 4px;",
184-
color: colorValue || "#1890ff",
185-
fontWeight: "bolder",
186-
},
187-
});
188-
189-
currentFileDecorations.push({
190-
line: currentLine,
191-
disposable: decorationType,
192-
});
193-
console.log("setDecorations", currentLine);
194-
activeEditor.setDecorations(decorationType, valueDecorations);
195-
}
196-
}
197-
});
198-
fileDecorationMap.set(fileName, currentFileDecorations);
127+
fullTokenKeys.forEach((key: string) => {
128+
const regEx = new RegExp(`\\b(${key})\\b(?!-)`, "g");
129+
let match;
130+
131+
while ((match = regEx.exec(text))) {
132+
const valueDecorations: vscode.DecorationOptions[] = [];
133+
let decorationType: vscode.TextEditorDecorationType;
134+
135+
/**
136+
* TIPS:
137+
* Actually, they are always at the same line.
138+
*/
139+
const startPos = activeEditor!.document.positionAt(match.index);
140+
const endPos = activeEditor!.document.positionAt(
141+
match.index + match[0].length
142+
);
143+
const currentLine = startPos.line;
144+
const value = String(fullToken[key]);
145+
const colorSpan = genMarkdownString(value);
146+
const markDownString = new vscode.MarkdownString(
147+
`<h3>antd design token: ${match[0]}</h3>${colorSpan}<code>${value}</code><br></br>`
148+
);
149+
markDownString.supportHtml = true;
150+
markDownString.isTrusted = true;
151+
152+
const decoration = {
153+
range: new vscode.Range(startPos, endPos),
154+
hoverMessage: markDownString,
155+
};
156+
157+
const colorValue = getColorTokenValue(fullToken[key]);
158+
valueDecorations.push(decoration);
159+
160+
decorationType = vscode.window.createTextEditorDecorationType({
161+
after: {
162+
contentText: colorValue ? `**` : `${String(fullToken[key])}`,
163+
backgroundColor: colorValue || "",
164+
margin: "0 0 0 5px;",
165+
color: colorValue || "#b37feb",
166+
fontWeight: "bolder",
167+
},
168+
});
169+
170+
const lineValue = lineDecorationMap.get(currentLine);
171+
lineDecorationMap.set(
172+
currentLine,
173+
lineValue ? lineValue.concat([decorationType]) : [decorationType]
174+
);
175+
console.log("setDecorations", currentLine);
176+
activeEditor!.setDecorations(decorationType, valueDecorations);
177+
}
178+
});
179+
180+
fileDecorationMap.set(fileName, lineDecorationMap);
181+
console.log(fileDecorationMap);
182+
}
183+
184+
function clearDecoration(fileName: string, lines?: number[]) {
185+
const lineDecorationMap = fileDecorationMap.get(fileName);
186+
if (lineDecorationMap) {
187+
if (lines) {
188+
lines.forEach((line) => {
189+
console.log("dispose line", line);
190+
lineDecorationMap.get(line)?.forEach(dispose);
191+
});
192+
} else {
193+
lineDecorationMap.forEach((value) => {
194+
value.forEach(dispose);
195+
});
196+
}
199197
}
200198
}
201199

202-
function checkOpenedFile(fileName: string): boolean {
203-
if (openedFileNameSet.has(fileName)) {
204-
return true;
205-
} else {
206-
openedFileNameSet.add(fileName);
207-
return false;
200+
function dispose(disposable: vscode.TextEditorDecorationType) {
201+
disposable.dispose();
202+
}
203+
204+
function getLines(start: number, end: number): number[] {
205+
const result: number[] = [];
206+
207+
if (start > end) {
208+
return [];
209+
}
210+
211+
for (let i = start; i <= end; i++) {
212+
result.push(i);
208213
}
214+
return result;
209215
}
210216
}

0 commit comments

Comments
 (0)