Skip to content

Commit

Permalink
Merge pull request #3 from xlboy/refactor/improve-type-icon
Browse files Browse the repository at this point in the history
refactor: improve the icon next to the line of type code
  • Loading branch information
xlboy committed May 26, 2023
2 parents 5fa79ea + 8dff2c0 commit addde65
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 24 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
},
Expand Down
3 changes: 0 additions & 3 deletions res/col-icon.svg

This file was deleted.

Binary file added res/type-icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 33 additions & 10 deletions src/core/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ReadonlyDeep } from 'type-fest';
import vscode from 'vscode';
import fs from 'fs-extra';

import { log } from './log';

Expand All @@ -8,44 +9,66 @@ interface ExtensionConfig {
* @default true
*/
enabled: boolean;
/**
* @default `{$ExtensionRootPath}/res/type-icon.png`
*/
typeIconPath: string;
}

const defaultTypeIconPath = `${__dirname}/../res/type-icon.png`;

export class Config {
private static _instance: Config;
/** instance */
static get i(): Config {
return (Config._instance ??= new Config());
}

get(): ReadonlyDeep<ExtensionConfig> {
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<Function> = [];

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<ExtensionConfig> {
return this.config;
registerWatchCallback(fn: Function) {
this.watchCallbacks.push(fn);
}

private init() {
const config = vscode.workspace.getConfiguration('ts-type-hidden');

this.config = Object.freeze<ExtensionConfig>({
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());
});
}
}
47 changes: 36 additions & 11 deletions src/core/editor-context.ts
Original file line number Diff line number Diff line change
@@ -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>;

Expand All @@ -29,18 +31,13 @@ export class EditorContext {
}

private editors = new Map</* filePath */ string, EditorInfo>();
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);
}
Expand All @@ -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 =>
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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()
};
}
};
})();
}

0 comments on commit addde65

Please sign in to comment.