From 389757d7e22f7dd2e425bf8167d878ea3cdecc43 Mon Sep 17 00:00:00 2001 From: Frangu Vlad Date: Mon, 30 Apr 2018 12:28:20 +0300 Subject: [PATCH] rewrite: generateDetails, add support for line numbers and file sizes and much more (#58) --- package.json | 10 ++--- src/extension.ts | 111 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 100 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 8e30ef4..3d58b84 100644 --- a/package.json +++ b/package.json @@ -63,12 +63,12 @@ "discord.detailsEditing": { "type": "string", "default": "Editing {filename}", - "description": "Custom string for the details section of the rich presence\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any." + "description": "Custom string for the details section of the rich presence\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{dirname}' will get replaced with the folder name that has the current file.\n\t- '{fulldirname}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{currentline}' will get replaced with the current line number.\n\t- '{totallines}' will get replaced with the total line number.\n\t- '{filesize}' will get replaced with the current file's size." }, "discord.detailsDebugging": { "type": "string", "default": "Editing {filename}", - "description": "Custom string for the details section of the rich presence when debugging\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any." + "description": "Custom string for the details section of the rich presence when debugging\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{dirname}' will get replaced with the folder name that has the current file.\n\t- '{fulldirname}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{currentline}' will get replaced with the current line number.\n\t- '{totallines}' will get replaced with the total line number.\n\t- '{filesize}' will get replaced with the current file's size." }, "discord.detailsIdle": { "type": "string", @@ -78,12 +78,12 @@ "discord.lowerDetailsEditing": { "type": "string", "default": "Workspace: {workspace}", - "description": "Custom string for the state section of the rich presence\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any." + "description": "Custom string for the state section of the rich presence\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{dirname}' will get replaced with the folder name that has the current file.\n\t- '{fulldirname}' will get replaced with the full directory name without the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{currentline}' will get replaced with the current line number.\n\t- '{totallines}' will get replaced with the total line number.\n\t- '{filesize}' will get replaced with the current file's size." }, "discord.lowerDetailsDebugging": { "type": "string", "default": "Debugging: {workspace}", - "description": "Custom string for the state section of the rich presence when debugging\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{workspace}' will be replaced with the current workspace name, if any." + "description": "Custom string for the state section of the rich presence when debugging\n\t- '{null}' will be replaced with an empty space.\n\t- '{filename}' will be replaced with the current file name.\n\t- '{dirname}' will get replaced with the folder name that has the current file.\n\t- '{fulldirname}' will get replaced with the full directory name without the current file name..\n\t- '{workspace}' will be replaced with the current workspace name, if any.\n\t- '{currentline}' will get replaced with the current line number.\n\t- '{totallines}' will get replaced with the total line number.\n\t- '{filesize}' will get replaced with the current file's size." }, "discord.lowerDetailsIdle": { "type": "string", @@ -93,7 +93,7 @@ "discord.lowerDetailsNotFound": { "type": "string", "default": "No workspace.", - "description": "Custom string for the state section of the rich presence when no workspace is found.\nIf set to '{null}', this will be an empty space." + "description": "Custom string for the state section of the rich presence when no workspace is found.\nIf set to '{null}', this will be an empty space.\n\t- '{currentline}' will get replaced with the current line number.\n\t- '{totallines}' will get replaced with the total line number.\n\t- '{filesize}' will get replaced with the current file's size." }, "discord.largeImage": { "type": "string", diff --git a/src/extension.ts b/src/extension.ts index da24e01..a2b1db3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,6 @@ // Import the required functions & object types from various packages. import { Client } from 'discord-rpc'; -import { basename, extname } from 'path'; +import { basename, extname, parse, sep } from 'path'; import { setInterval, clearInterval } from 'timers'; import { commands, @@ -14,6 +14,7 @@ import { workspace, WorkspaceFolder } from 'vscode'; +import { statSync } from 'fs'; const lang = require('./data/languages.json'); const knownExtentions: { [x: string]: { image: string } } = lang.knownExtentions; @@ -259,26 +260,104 @@ function setActivity(workspaceElapsedTime: boolean = false): void { } function generateDetails(debugging, editing, idling): string { + let string: string = config.get(idling); + const emptySpaces = '\u200b\u200b'; + const fileName: string = window.activeTextEditor ? basename(window.activeTextEditor.document.fileName) : null; + let dirName: string = null; + if (window.activeTextEditor) { + const { dir } = parse(window.activeTextEditor.document.fileName); + const split = dir.split(sep); + dirName = split[split.length - 1]; + } const checkState: boolean = window.activeTextEditor - ? Boolean(workspace.getWorkspaceFolder(window.activeTextEditor.document.uri)) - : false; + ? Boolean(workspace.getWorkspaceFolder(window.activeTextEditor.document.uri)) + : false; + const workspaceFolder: WorkspaceFolder = checkState ? workspace.getWorkspaceFolder(window.activeTextEditor.document.uri) : null; - const emptyDebugState: boolean = config.get(debugging) === '{null}'; - const emptyEditingState: boolean = config.get(editing) === '{null}'; + let fullDirName: string = null; + if (workspaceFolder) { + const { name } = workspaceFolder; + const relativePath = workspace.asRelativePath(window.activeTextEditor.document.fileName).split(sep); + relativePath.splice(-1, 1); + fullDirName = `${name}${sep}${relativePath.join(sep)}`; + } - return window.activeTextEditor - ? debug.activeDebugSession - ? emptyDebugState - ? '\u200b\u200b' - : config.get(debugging) + if (window.activeTextEditor) { + if (debug.activeDebugSession) { + let rawString = config.get(debugging); + const { totalLines, size, currentLine } = getFileDetails(rawString); + rawString = rawString + .replace('{null}', emptySpaces) .replace('{filename}', fileName) - .replace('{workspace}', checkState ? workspaceFolder.name : config.get('lowerDetailsNotFound')) - : emptyEditingState - ? '\u200b\u200b' - : config.get(editing) + .replace('{dirname}', dirName) + .replace('{fulldirname}', fullDirName) + .replace('{workspace}', + checkState ? + workspaceFolder.name : + config.get('lowerDetailsNotFound').replace('{null}', emptySpaces) + ); + if (totalLines) rawString = rawString.replace('{totallines}', totalLines); + if (size) rawString = rawString.replace('{filesize}', size); + if (currentLine) rawString = rawString.replace('{currentline}', currentLine); + string = rawString; + } else { + let rawString = config.get(editing); + const { totalLines, size, currentLine } = getFileDetails(rawString); + rawString = rawString + .replace('{null}', emptySpaces) .replace('{filename}', fileName) - .replace('{workspace}', checkState ? workspaceFolder.name : config.get('lowerDetailsNotFound')) - : config.get(idling); + .replace('{dirname}', dirName) + .replace('{fulldirname}', fullDirName) + .replace('{workspace}', + checkState ? + workspaceFolder.name : + config.get('lowerDetailsNotFound').replace('{null}', emptySpaces) + ); + if (totalLines) rawString = rawString.replace('{totallines}', totalLines); + if (size) rawString = rawString.replace('{filesize}', size); + if (currentLine) rawString = rawString.replace('{currentline}', currentLine); + string = rawString; + } + } + + return string; } + +function getFileDetails(rawString): FileDetail { + const obj = { + size: null, + totalLines: null, + currentLine: null, + }; + if (!rawString) return obj; + if (rawString.includes('{totallines}')) { + obj.totalLines = window.activeTextEditor.document.lineCount.toLocaleString(); + } + if (rawString.includes('{currentline}')) { + obj.currentLine = (window.activeTextEditor.selection.active.line + 1).toLocaleString(); + } + if (rawString.includes('{filesize}')) { + const sizes = ['bytes', 'kb', 'mb', 'gb', 'tb']; + let currentDivision = 0; + let { size } = statSync(window.activeTextEditor.document.fileName); + const originalSize = size; + if (originalSize > 1000) { + size = size / 1000; + currentDivision++; + while (size > 1000) { + currentDivision++; + size = size / 1000; + } + } + obj.size = `${originalSize > 1000 ? size.toFixed(2) : size}${sizes[currentDivision]}`; + } + return obj; +} + +type FileDetail = { + size: string | null, + totalLines: string | null, + currentLine: string | null, +};