From 897d8d71ee1a33127dc33c868efd9458b404294f Mon Sep 17 00:00:00 2001 From: Svyat Sobol Date: Tue, 28 Jul 2020 15:14:20 +0300 Subject: [PATCH] #22: Add memo.collapseBacklinksPanelItems config prop --- package.json | 12 ++++++ src/extension.spec.ts | 6 +-- .../BacklinksTreeDataProvider.spec.ts | 38 +++++++++++++++++++ src/extensions/BacklinksTreeDataProvider.ts | 15 ++++---- src/extensions/completionProvider.ts | 8 +--- src/test/testUtils.ts | 32 +++++++++++++++- 6 files changed, 91 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 714da2ea..80179f0e 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,12 @@ "scope": "resource", "description": "The maximum height of the image preview", "type": "number" + }, + "memo.collapseBacklinksPanelItems": { + "default": false, + "scope": "resource", + "description": "Collapse backlinks panel items by default.", + "type": "boolean" } } }, @@ -96,6 +102,12 @@ } ] }, + "viewsWelcome": [ + { + "view": "memoBacklinksExplorer", + "contents": "No information to show" + } + ], "markdown.previewStyles": [ "./media/fontello/css/fontello.css", "./media/markdown.css" diff --git a/src/extension.spec.ts b/src/extension.spec.ts index fd937d33..64bfee07 100644 --- a/src/extension.spec.ts +++ b/src/extension.spec.ts @@ -1,13 +1,11 @@ import * as vscode from 'vscode'; -import { closeAllEditors } from './test/testUtils'; +import { closeEditorsAndCleanWorkspace } from './test/testUtils'; const MEMO_EXTENSION_ID = 'svsool.markdown-memo'; describe('extension', () => { - beforeEach(async () => { - await closeAllEditors(); - }); + beforeEach(closeEditorsAndCleanWorkspace); it('should find extension in extensions list', () => { expect(vscode.extensions.all.some((extension) => extension.id === MEMO_EXTENSION_ID)).toBe( diff --git a/src/extensions/BacklinksTreeDataProvider.spec.ts b/src/extensions/BacklinksTreeDataProvider.spec.ts index bf392751..d4bc6352 100644 --- a/src/extensions/BacklinksTreeDataProvider.spec.ts +++ b/src/extensions/BacklinksTreeDataProvider.spec.ts @@ -9,6 +9,8 @@ import { closeEditorsAndCleanWorkspace, getWorkspaceFolder, toPlainObject, + updateMemoConfigProperty, + getConfigProperty, } from '../test/testUtils'; const getChildren = async () => { @@ -298,4 +300,40 @@ describe('BacklinksTreeDataProvider()', () => { }, ]); }); + + it('should collapse parent items according to configuration', async () => { + const link = rndName(); + const name0 = rndName(); + const name1 = rndName(); + + await createFile(`${link}.md`); + await createFile(`a-${name0}.md`, `First note with backlink [[${link}]]`); + await createFile(`b-${name1}.md`, `Second note with backlink [[${link}]]`); + + const doc = await openTextDocument(`${link}.md`); + + await window.showTextDocument(doc); + + await updateMemoConfigProperty('collapseBacklinksPanelItems', true); + + expect((await getChildren()).every((child) => child.collapsibleState === 1)).toBe(true); + }); + + it('should expand parent items according to config', async () => { + const link = rndName(); + const name0 = rndName(); + const name1 = rndName(); + + await createFile(`${link}.md`); + await createFile(`a-${name0}.md`, `First note with backlink [[${link}]]`); + await createFile(`b-${name1}.md`, `Second note with backlink [[${link}]]`); + + const doc = await openTextDocument(`${link}.md`); + + await window.showTextDocument(doc); + + expect(getConfigProperty('collapseBacklinksPanelItems', null)).toBe(false); + + expect((await getChildren()).every((child) => child.collapsibleState === 2)).toBe(true); + }); }); diff --git a/src/extensions/BacklinksTreeDataProvider.ts b/src/extensions/BacklinksTreeDataProvider.ts index 12a6390f..728e60f0 100644 --- a/src/extensions/BacklinksTreeDataProvider.ts +++ b/src/extensions/BacklinksTreeDataProvider.ts @@ -8,6 +8,7 @@ import { getWorkspaceFolder, trimSlashes, sortPaths, + getConfigProperty, } from '../utils'; import { FoundRefT } from '../types'; @@ -40,12 +41,8 @@ export default class BacklinksTreeDataProvider implements vscode.TreeDataProvide if (!element) { const fsPath = vscode.window.activeTextEditor?.document.uri.fsPath; - const noInfoToShow = [ - new Backlink('No information to show', undefined, vscode.TreeItemCollapsibleState.None), - ]; - if (!fsPath || (fsPath && !containsMarkdownExt(fsPath))) { - return noInfoToShow; + return []; } const refFromFilename = path.parse(fsPath).name; @@ -58,14 +55,18 @@ export default class BacklinksTreeDataProvider implements vscode.TreeDataProvide const pathsSorted = sortPaths(Object.keys(referencesByPath), { shallowFirst: true }); if (!pathsSorted.length) { - return noInfoToShow; + return []; } + const collapsibleState = getConfigProperty('collapseBacklinksPanelItems', false) + ? vscode.TreeItemCollapsibleState.Collapsed + : vscode.TreeItemCollapsibleState.Expanded; + return pathsSorted.map((pathParam) => { const backlink = new Backlink( path.basename(pathParam), referencesByPath[pathParam], - vscode.TreeItemCollapsibleState.Expanded, + collapsibleState, ); backlink.description = `(${referencesByPath[pathParam].length}) ${trimSlashes( pathParam diff --git a/src/extensions/completionProvider.ts b/src/extensions/completionProvider.ts index 6bbafc83..adfd4c99 100644 --- a/src/extensions/completionProvider.ts +++ b/src/extensions/completionProvider.ts @@ -11,13 +11,7 @@ import { import path from 'path'; import groupBy from 'lodash.groupby'; -import { - getWorkspaceCache, - fsPathToRef, - containsImageExt, - containsOtherKnownExts, - getConfigProperty, -} from '../utils'; +import { getWorkspaceCache, fsPathToRef, containsImageExt, containsOtherKnownExts } from '../utils'; const padWithZero = (n: number): string => (n < 10 ? '0' + n : String(n)); diff --git a/src/test/testUtils.ts b/src/test/testUtils.ts index 06f65121..5c786a71 100644 --- a/src/test/testUtils.ts +++ b/src/test/testUtils.ts @@ -1,6 +1,6 @@ import rimraf from 'rimraf'; import path from 'path'; -import { workspace, Uri, commands } from 'vscode'; +import { workspace, Uri, commands, ConfigurationTarget } from 'vscode'; export { default as waitForExpect } from 'wait-for-expect'; import * as utils from '../utils'; @@ -11,9 +11,11 @@ const { getImgUrlForMarkdownPreview, getFileUrlForMarkdownPreview, escapeForRegExp, + getConfigProperty, } = utils; export { + getConfigProperty, getWorkspaceFolder, getImgUrlForMarkdownPreview, getFileUrlForMarkdownPreview, @@ -87,7 +89,33 @@ export const closeAllEditors = async () => { await delay(100); }; +const getDefaultConfigProperties = (): { + default?: any; + scope?: string; + description?: string; + type?: string; +}[] => { + return require('../../package.json').contributes.configuration.properties; +}; + +export const updateConfigProperty = async (property: string, value: unknown) => { + await workspace.getConfiguration().update(property, value, ConfigurationTarget.Workspace); +}; + +export const updateMemoConfigProperty = async (property: string, value: unknown) => + await updateConfigProperty(`memo.${property}`, value); + +const resetMemoConfigProps = async () => + await Promise.all( + Object.entries(getDefaultConfigProperties()).map(([propName, propConfig]) => + propConfig.default !== undefined + ? updateConfigProperty(propName, propConfig.default) + : undefined, + ), + ); + export const closeEditorsAndCleanWorkspace = async () => { + await resetMemoConfigProps(); await closeAllEditors(); cleanWorkspace(); await cleanWorkspaceCache(); @@ -96,4 +124,4 @@ export const closeEditorsAndCleanWorkspace = async () => { export const getWorkspaceCache = async (): Promise => (await commands.executeCommand('_memo.getWorkspaceCache')) as WorkspaceCache; -export const toPlainObject = (value: unknown) => JSON.parse(JSON.stringify(value)); +export const toPlainObject = (value: unknown): R => JSON.parse(JSON.stringify(value));