From 484e9e6d9235276eabd7f63ef5155c5555e00748 Mon Sep 17 00:00:00 2001 From: Han Yeong-woo Date: Thu, 21 Sep 2023 05:42:18 +0900 Subject: [PATCH 1/7] Fold visible editors --- src/decorator.ts | 12 ++++++------ src/extension.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/decorator.ts b/src/decorator.ts index 9f3ec21..6ec3501 100644 --- a/src/decorator.ts +++ b/src/decorator.ts @@ -16,12 +16,10 @@ export class Decorator { EndLine: number = 0; /** - * To set/update the current working text editor. - * It's neccessary to call this method when the active editor changes - * because somethimes it return as undefined. + * To set/update the current visible text editor. * @param textEditor TextEditor */ - activeEditor(textEditor: TextEditor) { + editor(textEditor: TextEditor) { if (!textEditor) return; this.CurrentEditor = textEditor; this.startLine(textEditor.visibleRanges[0].start.line); @@ -72,7 +70,9 @@ export class Decorator { } updateDecorations() { - if (!this.SupportedLanguages.includes(this.CurrentEditor.document.languageId)) { + const currentLangId = this.CurrentEditor.document.languageId + + if (!this.SupportedLanguages.includes(currentLangId)) { return; } @@ -110,7 +110,7 @@ export class Decorator { continue; } - /* Checking if the range is selected by the user. + /* Checking if the range is selected by the user. first check is for single selection, second is for multiple cursor selections. or if the user has enabled the unfoldOnLineSelect option. */ if (this.CurrentEditor.selection.contains(range) || diff --git a/src/extension.ts b/src/extension.ts index 4afd10d..b11e60b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,9 +13,9 @@ export function activate(context: ExtensionContext) { elimit.Lead(); function triggerUpdateDecorations(): void { - const textEditor = window.activeTextEditor; - if (!textEditor) return; - decorator.activeEditor(textEditor); + for (const textEditor of window.visibleTextEditors) { + decorator.editor(textEditor); + } } const toggleCommand = commands.registerCommand(Commands.InlineFoldToggle, () => { @@ -26,8 +26,8 @@ export function activate(context: ExtensionContext) { Cache.ClearCache(); }); - const activeTextEditor = window.onDidChangeActiveTextEditor((e) => { - if (!e) return; + const changeVisibleTextEditors = window.onDidChangeVisibleTextEditors((editors) => { + if (editors.length < 1) return; elimit.Trail(); }); @@ -64,7 +64,7 @@ export function activate(context: ExtensionContext) { context.subscriptions.push(changeText); context.subscriptions.push(toggleCommand); context.subscriptions.push(changeSelection); - context.subscriptions.push(activeTextEditor); + context.subscriptions.push(changeVisibleTextEditors); context.subscriptions.push(clearCacheCommand); context.subscriptions.push(changeVisibleRange); context.subscriptions.push(changeConfiguration); From 4b7833cfdaaa98dc3031e5a261b92037f40d9f10 Mon Sep 17 00:00:00 2001 From: Han Yeong-woo Date: Thu, 21 Sep 2023 05:51:28 +0900 Subject: [PATCH 2/7] Refactor CacheClass --- src/cache.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cache.ts b/src/cache.ts index 85f4eb5..f517273 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -11,13 +11,18 @@ class CacheClass { StateCache: Map = new Map(); // Get the autoFold setting - autoFold() { + private autoFold() { return ExtSettings.Get(Settings.autoFold); } + // Get the togglePerFile setting + private togglePerFile() { + return ExtSettings.Get(Settings.togglePerFile) + } + // Set the state of the extension set State(_state: boolean) { - if (ExtSettings.Get(Settings.togglePerFile)) { + if (this.togglePerFile()) { this.StateCache.set(window.activeTextEditor?.document.uri.path, _state); } else { this.StateCache.set("global", _state); @@ -26,7 +31,7 @@ class CacheClass { // Get the state of the extension get State(): boolean { - if (ExtSettings.Get(Settings.togglePerFile)) { + if (this.togglePerFile()) { return this.StateCache.get(window.activeTextEditor?.document.uri.path) ?? this.autoFold(); } else { return this.StateCache.get("global") ?? this.autoFold(); @@ -47,4 +52,4 @@ class CacheClass { } // We will use singleton pattern to make sure that we only have one instance of the state -export const Cache = CacheClass.Instance; \ No newline at end of file +export const Cache = CacheClass.Instance; From f65b0282d40c3d3b538ffcb33ffd6ca135b1cfd2 Mon Sep 17 00:00:00 2001 From: Han Yeong-woo Date: Thu, 21 Sep 2023 07:10:56 +0900 Subject: [PATCH 3/7] Working toggle fold for visible editors --- src/cache.ts | 23 +++++++++++------------ src/decorator.ts | 10 +--------- src/extension.ts | 7 ++++--- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/cache.ts b/src/cache.ts index f517273..1ccfbb1 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -1,4 +1,3 @@ -import { window } from "vscode"; import { Settings } from "./enums"; import { ExtSettings } from "./settings"; @@ -8,7 +7,7 @@ class CacheClass { this._instance = this._instance ? this._instance : new CacheClass(); return this._instance; } - StateCache: Map = new Map(); + CacheMap = new Map(); // Get the autoFold setting private autoFold() { @@ -21,31 +20,31 @@ class CacheClass { } // Set the state of the extension - set State(_state: boolean) { + public SetShouldFold(key: string | undefined, shouldToggle: boolean) { if (this.togglePerFile()) { - this.StateCache.set(window.activeTextEditor?.document.uri.path, _state); + this.CacheMap.set(key, shouldToggle); } else { - this.StateCache.set("global", _state); + this.CacheMap.set("global", shouldToggle); } } // Get the state of the extension - get State(): boolean { + public ShouldFold(key: string | undefined): boolean { if (this.togglePerFile()) { - return this.StateCache.get(window.activeTextEditor?.document.uri.path) ?? this.autoFold(); + return this.CacheMap.get(key) ?? this.autoFold(); } else { - return this.StateCache.get("global") ?? this.autoFold(); + return this.CacheMap.get("global") ?? this.autoFold(); } } // Toggle the state of the extension - public ToggleState() { - this.State = !this.State; + public ToggleShouldFold(key: string) { + this.SetShouldFold(key, !this.ShouldFold(key)) } // Clear the state cache - public ClearCache() { - this.StateCache.clear(); + public Clear() { + this.CacheMap.clear(); } constructor () { } diff --git a/src/decorator.ts b/src/decorator.ts index 6ec3501..2f6b181 100644 --- a/src/decorator.ts +++ b/src/decorator.ts @@ -51,14 +51,6 @@ export class Decorator { } } - /** - * Set the active state of the decorator (used for command) - */ - toggle() { - Cache.ToggleState(); - this.updateDecorations(); - } - /** * This method gets triggered when the extension settings are changed * @param extConfs: Workspace configs @@ -100,7 +92,7 @@ export class Decorator { /* Checking if the toggle command is active or not. without conflicts with default state settings. If it is not active, it will remove all decorations. */ - if (!Cache.State) { + if (!Cache.ShouldFold(this.CurrentEditor.document.uri.path)) { this.CurrentEditor.setDecorations(plainDecorationType, []); break; } diff --git a/src/extension.ts b/src/extension.ts index b11e60b..304fdc2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,11 +19,12 @@ export function activate(context: ExtensionContext) { } const toggleCommand = commands.registerCommand(Commands.InlineFoldToggle, () => { - decorator.toggle(); + Cache.ToggleShouldFold(window.activeTextEditor?.document.uri.path) + triggerUpdateDecorations() }); const clearCacheCommand = commands.registerCommand(Commands.InlineFoldClearCache, () => { - Cache.ClearCache(); + Cache.Clear(); }); const changeVisibleTextEditors = window.onDidChangeVisibleTextEditors((editors) => { @@ -53,7 +54,7 @@ export function activate(context: ExtensionContext) { const changeConfiguration = workspace.onDidChangeConfiguration((event) => { if (event.affectsConfiguration(Settings.identifier)) { if (!event.affectsConfiguration(Settings.autoFold)) { - Cache.ClearCache(); + Cache.Clear(); } decorator.updateConfigs(workspace.getConfiguration(Settings.identifier)); } From 1f03e9e0e7604397b497613ecd9e4e44b6d850e0 Mon Sep 17 00:00:00 2001 From: Han Yeong-woo Date: Thu, 21 Sep 2023 08:50:11 +0900 Subject: [PATCH 4/7] Respect language-specific settings --- src/cache.ts | 24 ++++++++++++------------ src/decoration.ts | 21 ++++++++++----------- src/decorator.ts | 12 ++++++------ src/extension.ts | 2 +- src/settings.ts | 22 +++++++++------------- 5 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/cache.ts b/src/cache.ts index 1ccfbb1..575a7af 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -10,18 +10,18 @@ class CacheClass { CacheMap = new Map(); // Get the autoFold setting - private autoFold() { - return ExtSettings.Get(Settings.autoFold); + private autoFold(langId?: string) { + return ExtSettings.Get(Settings.autoFold, langId); } // Get the togglePerFile setting - private togglePerFile() { - return ExtSettings.Get(Settings.togglePerFile) + private togglePerFile(langId?: string) { + return ExtSettings.Get(Settings.togglePerFile, langId) } // Set the state of the extension - public SetShouldFold(key: string | undefined, shouldToggle: boolean) { - if (this.togglePerFile()) { + public SetShouldFold(key: string | undefined, shouldToggle: boolean, langId?: string) { + if (this.togglePerFile(langId)) { this.CacheMap.set(key, shouldToggle); } else { this.CacheMap.set("global", shouldToggle); @@ -29,17 +29,17 @@ class CacheClass { } // Get the state of the extension - public ShouldFold(key: string | undefined): boolean { - if (this.togglePerFile()) { - return this.CacheMap.get(key) ?? this.autoFold(); + public ShouldFold(key: string | undefined, langId?: string): boolean { + if (this.togglePerFile(langId)) { + return this.CacheMap.get(key) ?? this.autoFold(langId); } else { - return this.CacheMap.get("global") ?? this.autoFold(); + return this.CacheMap.get("global") ?? this.autoFold(langId); } } // Toggle the state of the extension - public ToggleShouldFold(key: string) { - this.SetShouldFold(key, !this.ShouldFold(key)) + public ToggleShouldFold(key: string | undefined, langId?: string) { + this.SetShouldFold(key, !this.ShouldFold(key, langId), langId) } // Clear the state cache diff --git a/src/decoration.ts b/src/decoration.ts index f6fab80..a0fc510 100644 --- a/src/decoration.ts +++ b/src/decoration.ts @@ -11,7 +11,7 @@ import { ExtSettings } from "./settings"; * on demand. */ export class DecoratorTypeOptions { - private cache = new Map(); + private cache = new Map(); public ClearCache() { this.cache.forEach((decOp) => { @@ -20,21 +20,21 @@ export class DecoratorTypeOptions { this.cache.clear(); } - public UnfoldDecorationType = (): TextEditorDecorationType => { + public UnfoldDecorationType = (langId?: string): TextEditorDecorationType => { return window.createTextEditorDecorationType({ rangeBehavior: DecorationRangeBehavior.ClosedOpen, - opacity: ExtSettings.Get(Settings.unfoldedOpacity).toString() + opacity: ExtSettings.Get(Settings.unfoldedOpacity, langId).toString() }) } - public MatchedDecorationType = (): TextEditorDecorationType => { + public MatchedDecorationType = (langId?: string): TextEditorDecorationType => { return window.createTextEditorDecorationType({ before: { - contentText: ExtSettings.Get(Settings.maskChar), - color: ExtSettings.Get(Settings.maskColor), + contentText: ExtSettings.Get(Settings.maskChar, langId), + color: ExtSettings.Get(Settings.maskColor, langId), }, after: { - contentText: ExtSettings.Get(Settings.after), + contentText: ExtSettings.Get(Settings.after, langId), }, textDecoration: "none; display: none;" }); @@ -43,16 +43,15 @@ export class DecoratorTypeOptions { public PlainDecorationType = (): TextEditorDecorationType => window.createTextEditorDecorationType({}) - public MaskDecorationTypeCache(): TextEditorDecorationType { - const langId = window.activeTextEditor.document.languageId; + public MaskDecorationTypeCache(langId?: string): TextEditorDecorationType { if (this.cache.has(langId)) { return this.cache.get(langId) as TextEditorDecorationType; } - const decorationType = this.MatchedDecorationType(); + const decorationType = this.MatchedDecorationType(langId); this.cache.set(langId, decorationType); return decorationType; } constructor () { } -} \ No newline at end of file +} diff --git a/src/decorator.ts b/src/decorator.ts index 2f6b181..4fa2fee 100644 --- a/src/decorator.ts +++ b/src/decorator.ts @@ -68,13 +68,13 @@ export class Decorator { return; } - const regEx: RegExp = ExtSettings.Regex(); - const unFoldOnLineSelect = ExtSettings.Get(Settings.unfoldOnLineSelect); + const regEx: RegExp = ExtSettings.Regex(currentLangId); + const unFoldOnLineSelect = ExtSettings.Get(Settings.unfoldOnLineSelect, currentLangId); const text = this.CurrentEditor.document.getText(); - const regexGroup: number = ExtSettings.Get(Settings.regexGroup) as number | 1; - const matchDecorationType = this.DTOs.MaskDecorationTypeCache(); + const regexGroup: number = ExtSettings.Get(Settings.regexGroup, currentLangId) as number | 1; + const matchDecorationType = this.DTOs.MaskDecorationTypeCache(currentLangId); const plainDecorationType = this.DTOs.PlainDecorationType(); - const unfoldDecorationType = this.DTOs.UnfoldDecorationType(); + const unfoldDecorationType = this.DTOs.UnfoldDecorationType(currentLangId); const foldRanges: DecorationOptions[] = []; const unfoldRanges: Range[] = []; @@ -92,7 +92,7 @@ export class Decorator { /* Checking if the toggle command is active or not. without conflicts with default state settings. If it is not active, it will remove all decorations. */ - if (!Cache.ShouldFold(this.CurrentEditor.document.uri.path)) { + if (!Cache.ShouldFold(this.CurrentEditor.document.uri.path, currentLangId)) { this.CurrentEditor.setDecorations(plainDecorationType, []); break; } diff --git a/src/extension.ts b/src/extension.ts index 304fdc2..1e2f21e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,7 +19,7 @@ export function activate(context: ExtensionContext) { } const toggleCommand = commands.registerCommand(Commands.InlineFoldToggle, () => { - Cache.ToggleShouldFold(window.activeTextEditor?.document.uri.path) + Cache.ToggleShouldFold(window.activeTextEditor?.document.uri.path, window.activeTextEditor?.document.languageId) triggerUpdateDecorations() }); diff --git a/src/settings.ts b/src/settings.ts index e67727c..98bfcd1 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -24,15 +24,11 @@ class ExtensionSettings { * @param _section The extension's identifier * @returns Workspace's configuration for the extension */ - private getPerLanguage(_section: string) { - // Check if the window has an active editor (document file) - if (!window.activeTextEditor) return; - // Get the current active editor languageid - const language_Id = window.activeTextEditor.document.languageId; + private getPerLanguage(_section: string, languageId: string) { // Get the configuration of the active language id - const lang_config: WorkspaceConfiguration = workspace.getConfiguration(Settings.identifier, { languageId: language_Id }); + const langConfig: WorkspaceConfiguration = workspace.getConfiguration(Settings.identifier, { languageId}); // return the configuration for the given section - return lang_config.get(_section); + return langConfig.get(_section); } /** @@ -58,13 +54,13 @@ class ExtensionSettings { * @param _section : the key of the configuration * @returns Language's scoped configuration or fall back to global configuration */ - public Get(_section: Settings): T { + public Get(_section: Settings, langId?: string): T { // Try to get language scope configuration, otherwise fallback to global configuration const getGlobal = this.configs.get(Settings.useGlobal) - if (getGlobal) { - return this.configs.get(_section) as T + if (getGlobal || langId === undefined) { + return this.configs.get(_section) as T; } - return (this.getPerLanguage(_section) as T) ?? (this.configs.get(_section) as T); + return this.getPerLanguage(_section, langId); } /** @@ -79,8 +75,8 @@ class ExtensionSettings { return supported; } - public Regex(): RegExp { - return RegExp(this.Get(Settings.regex), this.Get(Settings.regexFlags)); + public Regex(langId?: string): RegExp { + return RegExp(this.Get(Settings.regex, langId), this.Get(Settings.regexFlags, langId)); } constructor () { } From e4457365fbf5b0960c6c10c6c7a353b7a0255b5f Mon Sep 17 00:00:00 2001 From: Mohammed Alamri Date: Thu, 21 Sep 2023 09:38:57 +0300 Subject: [PATCH 5/7] Format --- src/settings.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/settings.ts b/src/settings.ts index 98bfcd1..66b1068 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,4 +1,4 @@ -import { window, workspace, WorkspaceConfiguration } from "vscode"; +import { workspace, WorkspaceConfiguration } from "vscode"; import { Settings } from "./enums"; class ExtensionSettings { @@ -26,7 +26,7 @@ class ExtensionSettings { */ private getPerLanguage(_section: string, languageId: string) { // Get the configuration of the active language id - const langConfig: WorkspaceConfiguration = workspace.getConfiguration(Settings.identifier, { languageId}); + const langConfig: WorkspaceConfiguration = workspace.getConfiguration(Settings.identifier, { languageId }); // return the configuration for the given section return langConfig.get(_section); } From 5bec68748b0b6d1c5ea92178c72fbd29c9ca9a02 Mon Sep 17 00:00:00 2001 From: Mohammed Alamri Date: Thu, 21 Sep 2023 10:35:14 +0300 Subject: [PATCH 6/7] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bc39ab..9fc47b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@
+> ### v0.2.5: +- feat: trigger folding when the editor is not active by [@nix6839](https://github.com/nix6839) + > ### v0.2.4: - fix: [#108](https://github.com/moalamri/vscode-inline-fold/issues/108) - fix: [#112](https://github.com/moalamri/vscode-inline-fold/issues/112) From 20d88d517eee0b621071e537c6b6cf8247828f69 Mon Sep 17 00:00:00 2001 From: Mohammed Alamri Date: Thu, 21 Sep 2023 10:35:46 +0300 Subject: [PATCH 7/7] Update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 58a8477..de34c5c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Inline fold", "description": "A custom decorator that \"fold\" matching content in single line", "icon": "res/icon.png", - "version": "0.2.4", + "version": "0.2.5", "publisher": "moalamri", "homepage": "https://github.com/moalamri/vscode-inline-fold", "bugs": "https://github.com/moalamri/vscode-inline-fold/issues",