From 8dff2c0a9f25cd9517761275d23bad12ac18c6f8 Mon Sep 17 00:00:00 2001 From: xlboy Date: Fri, 26 May 2023 17:43:36 +0800 Subject: [PATCH] refactor: improve the icon next to the line of type code --- package.json | 4 ++++ res/col-icon.svg | 3 --- res/type-icon.png | Bin 0 -> 1904 bytes src/core/config.ts | 43 +++++++++++++++++++++++++-------- src/core/editor-context.ts | 47 ++++++++++++++++++++++++++++--------- 5 files changed, 73 insertions(+), 24 deletions(-) delete mode 100644 res/col-icon.svg create mode 100644 res/type-icon.png diff --git a/package.json b/package.json index 44c5c65..a0cd758 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,10 @@ "type": "boolean", "default": true, "description": "Enable this extension" + }, + "ts-type-hidden.typeIconPath": { + "type": "string", + "description": "The path to the Icon file next to a line of type code" } } }, diff --git a/res/col-icon.svg b/res/col-icon.svg deleted file mode 100644 index 670e49d..0000000 --- a/res/col-icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/res/type-icon.png b/res/type-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..285a0863b9650a55b9a39dd97e6e8f8d2f15aa42 GIT binary patch literal 1904 zcmZ`)`#TegA9icnWH}+yWM5${DaDW@i^V9jT$XFi?YLiZ8FDF?tudCbbzhaBU7cv%QKj?BR#<0vx6Hxm!d@M8= zRs8prk>5N{qx3Ixh*Y(DIzt|RCrAJF#{3JX`hE~5cREkG8(Y;{Be_>0LW+bXeEEfkkw+5|pM03wYi=f21e3-`oq~cl|J`Jh1RquFyZF z%N=p3?84b6MwVx0X6S)nthKG*qqfDR)VM7yEHse%uJ}Z;KQCS zRrBuDX*zLxwBuEsVS2VgkvB;-guN^%>C}Lc@u4=jnkPEZO+5aE03tggy5;z{r4z?k zJb^aT_Vb&@pzP02RE>2|qdR*!JV}%ElCcFJ1s3%>hR$hEw_mtDsD(7{WK?|eXrZ)*TO z$|sP%>Rr(wS$sx=R@dq(%@}E+W3etcV6XejpHv>-L}T1&zVND1ExM`uA=cfV(XttM z%S0jMcTzURUT;V{tUIDA3wG^caRHuXRb^K@dVcMhOJSv%AQo|ZbYrL-%AlAR-OS)1 z5M2??Y=%BG$q=8aRV1S?bfPs%J9Vh4hhO zO_zD=t;sVB_<_Qpt(D}YJ+5GVOAwn}VaGNE&BIk$%ba59T=V2cCI6nHdD0j%ps3~?0k{$yD8s0YGvN^J6A5mGc=J=~La?o@LVxgr0nCsJ zIn3+j7zO=sZ^SwKdjM@#n%PL^vpGNM5#-6Lm!8j|;%+i=kk(Q`h{2*cN2QPG;&7H9LckhvzRVm+pq7j(7R@yhokvZm^XC}IxT$K|p@I%Wl#w%#$;&upCi09p!Iq7L$834-Nk~i63yBzXkzfAqwRGi^ z8(Ne2T;8wonqEaYJErb{e**t>ginI}uoH8xsJS&}{s4TSPPy+-v45&IJze-c=y6phYGibMSKu*g^xi0FH<9d( z`3{I4Krr%D$P*t;=kHeEGrv@>>?VITQsU`_GTV+>%D#esON!;z=y`RZy}^whQb#gjb%0H@Uh0w)pNyi86cUJfUna*%NSz-l!@e9bS{hRa#& z!r9yfSm@eOKxoc3p>^J=d3zfnkOci z4ZAp`l)P(122*79hMJN7sfw9_;I}T3Y`IB{v_IQb;qtN4X osv4T;fBwDNe|3*f=8Mi>KmygI { + return Object.freeze(this.config); + } + + private sync() { + const config = vscode.workspace.getConfiguration('ts-type-hidden'); + + this.config = { + enabled: config.get('enabled', true), + typeIconPath: config.get('typeIconPath') || defaultTypeIconPath + } satisfies ExtensionConfig; + } + private config!: ExtensionConfig; + private watchCallbacks: Array = []; private constructor() { - this.init(); + this.sync(); + this.verify(); this.watch(); } update() { - this.init(); + this.sync(); log.appendLine(`Config updated: ${JSON.stringify(this.config, null, 2)} `); } - get(): ReadonlyDeep { - return this.config; + registerWatchCallback(fn: Function) { + this.watchCallbacks.push(fn); } - private init() { - const config = vscode.workspace.getConfiguration('ts-type-hidden'); - - this.config = Object.freeze({ - enabled: config.get('enabled', true) - }); + private verify() { + if (!fs.existsSync(this.config.typeIconPath)) { + vscode.window.showErrorMessage('`typeIconPath` is not a valid path'); + this.config.typeIconPath = defaultTypeIconPath; + } } private watch() { vscode.workspace.onDidChangeConfiguration(() => { this.update(); + this.verify(); + this.watchCallbacks.forEach(cb => cb()); }); } } diff --git a/src/core/editor-context.ts b/src/core/editor-context.ts index 572d1b3..f49251d 100644 --- a/src/core/editor-context.ts +++ b/src/core/editor-context.ts @@ -1,8 +1,10 @@ import vscode from 'vscode'; import { TypeAnalyzer, type AnalyzedType } from './helpers/type-analyzer'; import { debounce, isEqual } from 'lodash-es'; -import { log } from './log'; import { GlobalState } from './global-state'; +import { Config } from './config'; +import fs from 'fs-extra'; +import { log } from './log'; type FoldingRange = Record<'start' | 'end', /* lineNumber */ number>; @@ -29,18 +31,13 @@ export class EditorContext { } private editors = new Map(); - private readonly decorationType = { - hidden: vscode.window.createTextEditorDecorationType({ - textDecoration: 'opacity: 0; font-size: 0; display: none', - gutterIconPath: vscode.Uri.file(`${__dirname}/../res/col-icon.svg`), - gutterIconSize: 'contain' - }) - }; private curFocusedTypes: AnalyzedType[] = []; private constructor() { this.register(); this.initVisibleEditors(); + this.decoration.init(); + Config.i.registerWatchCallback(this.decoration.refreshIcon); if (GlobalState.i.isHiddenMode) this.hideType(true); } @@ -52,7 +49,7 @@ export class EditorContext { const activeEditorInfo = this.editors.get(activeEditorWindow.document.fileName); if (!activeEditorInfo) return; - const rangesToHide = activeEditorInfo.analyzedTypes + const typeRangesToHide = activeEditorInfo.analyzedTypes .filter(type => !this.curFocusedTypes.some(curFType => isEqual(type, curFType))) .map( type => @@ -62,7 +59,8 @@ export class EditorContext { ) ); - activeEditorWindow.setDecorations(this.decorationType.hidden, rangesToHide); + activeEditorWindow.setDecorations(this.decoration.get().hidden, typeRangesToHide); + activeEditorWindow.setDecorations(this.decoration.get().icon, typeRangesToHide); if (needToFold) { handleMultiLineFold.call(this, activeEditorWindow, activeEditorInfo); @@ -134,7 +132,8 @@ export class EditorContext { const activeEditor = vscode.window.activeTextEditor; if (activeEditor && this.utils.isTargetDocument(activeEditor.document)) { - activeEditor.setDecorations(this.decorationType.hidden, []); + activeEditor.setDecorations(this.decoration.get().hidden, []); + activeEditor.setDecorations(this.decoration.get().icon, []); const curEditorInfo = this.editors.get(activeEditor.document.fileName); if (curEditorInfo) { @@ -259,4 +258,30 @@ export class EditorContext { return foldingRanges; } }; + + private decoration = (() => { + let value: Record<'hidden' | 'icon', vscode.TextEditorDecorationType>; + + const createIcon = () => + vscode.window.createTextEditorDecorationType({ + gutterIconPath: vscode.Uri.file(Config.i.get().typeIconPath), + gutterIconSize: 'contain' + }); + + return { + get: () => value, + refreshIcon() { + value.icon.dispose(); + value.icon = createIcon(); + }, + init() { + value = { + hidden: vscode.window.createTextEditorDecorationType({ + textDecoration: 'opacity: 0; font-size: 0; display: none' + }), + icon: createIcon() + }; + } + }; + })(); }