parent
223ae3ea9a
commit
391d8a1beb
12 changed files with 465 additions and 278 deletions
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"editor.defaultFormatter": "biomejs.biome"
|
||||||
|
}
|
30
biome.json
Normal file
30
biome.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||||
|
"vcs": {
|
||||||
|
"enabled": false,
|
||||||
|
"clientKind": "git",
|
||||||
|
"useIgnoreFile": false
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"ignoreUnknown": false,
|
||||||
|
"ignore": []
|
||||||
|
},
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"indentStyle": "tab"
|
||||||
|
},
|
||||||
|
"organizeImports": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"linter": {
|
||||||
|
"enabled": true,
|
||||||
|
"rules": {
|
||||||
|
"recommended": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"quoteStyle": "double"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
26
package.json
26
package.json
|
@ -19,15 +19,11 @@
|
||||||
"main": "./dist/extension",
|
"main": "./dist/extension",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run lint && webpack --mode production",
|
"build": "npm run lint && webpack --mode production",
|
||||||
"lint": "prettier --check . && eslint src --ext mjs,js,ts",
|
"lint": "npx @biomejs/biome check",
|
||||||
"format": "prettier --write . && eslint src --ext mjs,js,ts --fix"
|
"format": "npx @biomejs/biome format --write"
|
||||||
},
|
},
|
||||||
"activationEvents": [
|
"activationEvents": ["*"],
|
||||||
"*"
|
"extensionKind": ["ui"],
|
||||||
],
|
|
||||||
"extensionKind": [
|
|
||||||
"ui"
|
|
||||||
],
|
|
||||||
"contributes": {
|
"contributes": {
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
|
@ -165,17 +161,8 @@
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/iCrawl/discord-vscode/issues"
|
"url": "https://github.com/iCrawl/discord-vscode/issues"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": ["discord", "vscode", "rich", "presence", "rich presence", "rpc"],
|
||||||
"discord",
|
"categories": ["Other"],
|
||||||
"vscode",
|
|
||||||
"rich",
|
|
||||||
"presence",
|
|
||||||
"rich presence",
|
|
||||||
"rpc"
|
|
||||||
],
|
|
||||||
"categories": [
|
|
||||||
"Other"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/iCrawl/discord-vscode#readme",
|
"homepage": "https://github.com/iCrawl/discord-vscode#readme",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
"galleryBanner": {
|
"galleryBanner": {
|
||||||
|
@ -191,6 +178,7 @@
|
||||||
"utf-8-validate": "^5.0.9"
|
"utf-8-validate": "^5.0.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "^1.9.4",
|
||||||
"@types/lodash-es": "^4.17.6",
|
"@types/lodash-es": "^4.17.6",
|
||||||
"@types/node": "^17.0.41",
|
"@types/node": "^17.0.41",
|
||||||
"@types/vscode": "^1.67.0",
|
"@types/vscode": "^1.67.0",
|
||||||
|
|
141
src/activity.ts
141
src/activity.ts
|
@ -1,5 +1,12 @@
|
||||||
import { basename, parse, sep } from 'path';
|
import { basename, parse, sep } from "node:path";
|
||||||
import { debug, env, Selection, TextDocument, window, workspace } from 'vscode';
|
import {
|
||||||
|
type Selection,
|
||||||
|
type TextDocument,
|
||||||
|
debug,
|
||||||
|
env,
|
||||||
|
window,
|
||||||
|
workspace,
|
||||||
|
} from "vscode";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CONFIG_KEYS,
|
CONFIG_KEYS,
|
||||||
|
@ -13,9 +20,16 @@ import {
|
||||||
UNKNOWN_GIT_REPO_NAME,
|
UNKNOWN_GIT_REPO_NAME,
|
||||||
VSCODE_IMAGE_KEY,
|
VSCODE_IMAGE_KEY,
|
||||||
VSCODE_INSIDERS_IMAGE_KEY,
|
VSCODE_INSIDERS_IMAGE_KEY,
|
||||||
} from './constants';
|
} from "./constants";
|
||||||
import { log, LogLevel } from './logger';
|
import { LogLevel, log } from "./logger";
|
||||||
import { getConfig, getGit, resolveFileIcon, toLower, toTitle, toUpper } from './util';
|
import {
|
||||||
|
getConfig,
|
||||||
|
getGit,
|
||||||
|
resolveFileIcon,
|
||||||
|
toLower,
|
||||||
|
toTitle,
|
||||||
|
toUpper,
|
||||||
|
} from "./util";
|
||||||
|
|
||||||
interface ActivityPayload {
|
interface ActivityPayload {
|
||||||
details?: string | undefined;
|
details?: string | undefined;
|
||||||
|
@ -35,19 +49,32 @@ interface ActivityPayload {
|
||||||
instance?: boolean | undefined;
|
instance?: boolean | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fileDetails(_raw: string, document: TextDocument, selection: Selection) {
|
async function fileDetails(
|
||||||
|
_raw: string,
|
||||||
|
document: TextDocument,
|
||||||
|
selection: Selection,
|
||||||
|
) {
|
||||||
let raw = _raw.slice();
|
let raw = _raw.slice();
|
||||||
|
|
||||||
if (raw.includes(REPLACE_KEYS.TotalLines)) {
|
if (raw.includes(REPLACE_KEYS.TotalLines)) {
|
||||||
raw = raw.replace(REPLACE_KEYS.TotalLines, document.lineCount.toLocaleString());
|
raw = raw.replace(
|
||||||
|
REPLACE_KEYS.TotalLines,
|
||||||
|
document.lineCount.toLocaleString(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw.includes(REPLACE_KEYS.CurrentLine)) {
|
if (raw.includes(REPLACE_KEYS.CurrentLine)) {
|
||||||
raw = raw.replace(REPLACE_KEYS.CurrentLine, (selection.active.line + 1).toLocaleString());
|
raw = raw.replace(
|
||||||
|
REPLACE_KEYS.CurrentLine,
|
||||||
|
(selection.active.line + 1).toLocaleString(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw.includes(REPLACE_KEYS.CurrentColumn)) {
|
if (raw.includes(REPLACE_KEYS.CurrentColumn)) {
|
||||||
raw = raw.replace(REPLACE_KEYS.CurrentColumn, (selection.active.character + 1).toLocaleString());
|
raw = raw.replace(
|
||||||
|
REPLACE_KEYS.CurrentColumn,
|
||||||
|
(selection.active.character + 1).toLocaleString(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw.includes(REPLACE_KEYS.FileSize)) {
|
if (raw.includes(REPLACE_KEYS.FileSize)) {
|
||||||
|
@ -70,7 +97,9 @@ async function fileDetails(_raw: string, document: TextDocument, selection: Sele
|
||||||
|
|
||||||
raw = raw.replace(
|
raw = raw.replace(
|
||||||
REPLACE_KEYS.FileSize,
|
REPLACE_KEYS.FileSize,
|
||||||
`${originalSize > 1000 ? size.toFixed(2) : size}${FILE_SIZES[currentDivision]}`,
|
`${originalSize > 1000 ? size.toFixed(2) : size}${
|
||||||
|
FILE_SIZES[currentDivision]
|
||||||
|
}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +109,8 @@ async function fileDetails(_raw: string, document: TextDocument, selection: Sele
|
||||||
if (git?.repositories.length) {
|
if (git?.repositories.length) {
|
||||||
raw = raw.replace(
|
raw = raw.replace(
|
||||||
REPLACE_KEYS.GitBranch,
|
REPLACE_KEYS.GitBranch,
|
||||||
git.repositories.find((repo) => repo.ui.selected)?.state.HEAD?.name ?? FAKE_EMPTY,
|
git.repositories.find((repo) => repo.ui.selected)?.state.HEAD?.name ??
|
||||||
|
FAKE_EMPTY,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
raw = raw.replace(REPLACE_KEYS.GitBranch, UNKNOWN_GIT_BRANCH);
|
raw = raw.replace(REPLACE_KEYS.GitBranch, UNKNOWN_GIT_BRANCH);
|
||||||
|
@ -93,8 +123,8 @@ async function fileDetails(_raw: string, document: TextDocument, selection: Sele
|
||||||
REPLACE_KEYS.GitRepoName,
|
REPLACE_KEYS.GitRepoName,
|
||||||
git.repositories
|
git.repositories
|
||||||
.find((repo) => repo.ui.selected)
|
.find((repo) => repo.ui.selected)
|
||||||
?.state.remotes[0].fetchUrl?.split('/')[1]
|
?.state.remotes[0].fetchUrl?.split("/")[1]
|
||||||
.replace('.git', '') ?? FAKE_EMPTY,
|
.replace(".git", "") ?? FAKE_EMPTY,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
raw = raw.replace(REPLACE_KEYS.GitRepoName, UNKNOWN_GIT_REPO_NAME);
|
raw = raw.replace(REPLACE_KEYS.GitRepoName, UNKNOWN_GIT_REPO_NAME);
|
||||||
|
@ -104,7 +134,11 @@ async function fileDetails(_raw: string, document: TextDocument, selection: Sele
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function details(idling: CONFIG_KEYS, editing: CONFIG_KEYS, debugging: CONFIG_KEYS) {
|
async function details(
|
||||||
|
idling: CONFIG_KEYS,
|
||||||
|
editing: CONFIG_KEYS,
|
||||||
|
debugging: CONFIG_KEYS,
|
||||||
|
) {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
let raw = (config[idling] as string).replace(REPLACE_KEYS.Empty, FAKE_EMPTY);
|
let raw = (config[idling] as string).replace(REPLACE_KEYS.Empty, FAKE_EMPTY);
|
||||||
|
|
||||||
|
@ -114,12 +148,18 @@ async function details(idling: CONFIG_KEYS, editing: CONFIG_KEYS, debugging: CON
|
||||||
const split = dir.split(sep);
|
const split = dir.split(sep);
|
||||||
const dirName = split[split.length - 1];
|
const dirName = split[split.length - 1];
|
||||||
|
|
||||||
const noWorkspaceFound = config[CONFIG_KEYS.LowerDetailsNoWorkspaceFound].replace(REPLACE_KEYS.Empty, FAKE_EMPTY);
|
const noWorkspaceFound = config[
|
||||||
const workspaceFolder = workspace.getWorkspaceFolder(window.activeTextEditor.document.uri);
|
CONFIG_KEYS.LowerDetailsNoWorkspaceFound
|
||||||
|
].replace(REPLACE_KEYS.Empty, FAKE_EMPTY);
|
||||||
|
const workspaceFolder = workspace.getWorkspaceFolder(
|
||||||
|
window.activeTextEditor.document.uri,
|
||||||
|
);
|
||||||
const workspaceFolderName = workspaceFolder?.name ?? noWorkspaceFound;
|
const workspaceFolderName = workspaceFolder?.name ?? noWorkspaceFound;
|
||||||
const workspaceName = workspace.name?.replace(REPLACE_KEYS.VSCodeWorkspace, EMPTY) ?? workspaceFolderName;
|
const workspaceName =
|
||||||
|
workspace.name?.replace(REPLACE_KEYS.VSCodeWorkspace, EMPTY) ??
|
||||||
|
workspaceFolderName;
|
||||||
const workspaceAndFolder = `${workspaceName}${
|
const workspaceAndFolder = `${workspaceName}${
|
||||||
workspaceFolderName === FAKE_EMPTY ? '' : ` - ${workspaceFolderName}`
|
workspaceFolderName === FAKE_EMPTY ? "" : ` - ${workspaceFolderName}`
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
const fileIcon = resolveFileIcon(window.activeTextEditor.document);
|
const fileIcon = resolveFileIcon(window.activeTextEditor.document);
|
||||||
|
@ -132,15 +172,27 @@ async function details(idling: CONFIG_KEYS, editing: CONFIG_KEYS, debugging: CON
|
||||||
|
|
||||||
if (workspaceFolder) {
|
if (workspaceFolder) {
|
||||||
const { name } = workspaceFolder;
|
const { name } = workspaceFolder;
|
||||||
const relativePath = workspace.asRelativePath(window.activeTextEditor.document.fileName).split(sep);
|
const relativePath = workspace
|
||||||
|
.asRelativePath(window.activeTextEditor.document.fileName)
|
||||||
|
.split(sep);
|
||||||
relativePath.splice(-1, 1);
|
relativePath.splice(-1, 1);
|
||||||
raw = raw.replace(REPLACE_KEYS.FullDirName, `${name}${sep}${relativePath.join(sep)}`);
|
raw = raw.replace(
|
||||||
|
REPLACE_KEYS.FullDirName,
|
||||||
|
`${name}${sep}${relativePath.join(sep)}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
raw = await fileDetails(raw, window.activeTextEditor.document, window.activeTextEditor.selection);
|
raw = await fileDetails(
|
||||||
|
raw,
|
||||||
|
window.activeTextEditor.document,
|
||||||
|
window.activeTextEditor.selection,
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(LogLevel.Error, `Failed to generate file details: ${error as string}`);
|
log(
|
||||||
|
LogLevel.Error,
|
||||||
|
`Failed to generate file details: ${error as string}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
raw = raw
|
raw = raw
|
||||||
.replace(REPLACE_KEYS.FileName, fileName)
|
.replace(REPLACE_KEYS.FileName, fileName)
|
||||||
|
@ -163,10 +215,13 @@ export async function activity(previous: ActivityPayload = {}) {
|
||||||
const appName = env.appName;
|
const appName = env.appName;
|
||||||
const defaultSmallImageKey = debug.activeDebugSession
|
const defaultSmallImageKey = debug.activeDebugSession
|
||||||
? DEBUG_IMAGE_KEY
|
? DEBUG_IMAGE_KEY
|
||||||
: appName.includes('Insiders')
|
: appName.includes("Insiders")
|
||||||
? VSCODE_INSIDERS_IMAGE_KEY
|
? VSCODE_INSIDERS_IMAGE_KEY
|
||||||
: VSCODE_IMAGE_KEY;
|
: VSCODE_IMAGE_KEY;
|
||||||
const defaultSmallImageText = config[CONFIG_KEYS.SmallImage].replace(REPLACE_KEYS.AppName, appName);
|
const defaultSmallImageText = config[CONFIG_KEYS.SmallImage].replace(
|
||||||
|
REPLACE_KEYS.AppName,
|
||||||
|
appName,
|
||||||
|
);
|
||||||
const defaultLargeImageText = config[CONFIG_KEYS.LargeImageIdling];
|
const defaultLargeImageText = config[CONFIG_KEYS.LargeImageIdling];
|
||||||
const removeDetails = config[CONFIG_KEYS.RemoveDetails];
|
const removeDetails = config[CONFIG_KEYS.RemoveDetails];
|
||||||
const removeLowerDetails = config[CONFIG_KEYS.RemoveLowerDetails];
|
const removeLowerDetails = config[CONFIG_KEYS.RemoveLowerDetails];
|
||||||
|
@ -177,8 +232,14 @@ export async function activity(previous: ActivityPayload = {}) {
|
||||||
let state: ActivityPayload = {
|
let state: ActivityPayload = {
|
||||||
details: removeDetails
|
details: removeDetails
|
||||||
? undefined
|
? undefined
|
||||||
: await details(CONFIG_KEYS.DetailsIdling, CONFIG_KEYS.DetailsEditing, CONFIG_KEYS.DetailsDebugging),
|
: await details(
|
||||||
startTimestamp: config[CONFIG_KEYS.RemoveTimestamp] ? undefined : previous.startTimestamp ?? Date.now(),
|
CONFIG_KEYS.DetailsIdling,
|
||||||
|
CONFIG_KEYS.DetailsEditing,
|
||||||
|
CONFIG_KEYS.DetailsDebugging,
|
||||||
|
),
|
||||||
|
startTimestamp: config[CONFIG_KEYS.RemoveTimestamp]
|
||||||
|
? undefined
|
||||||
|
: (previous.startTimestamp ?? Date.now()),
|
||||||
largeImageKey: IDLE_IMAGE_KEY,
|
largeImageKey: IDLE_IMAGE_KEY,
|
||||||
largeImageText: defaultLargeImageText,
|
largeImageText: defaultLargeImageText,
|
||||||
smallImageKey: defaultSmallImageKey,
|
smallImageKey: defaultSmallImageKey,
|
||||||
|
@ -196,18 +257,25 @@ export async function activity(previous: ActivityPayload = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!removeRemoteRepository && git?.repositories.length) {
|
if (!removeRemoteRepository && git?.repositories.length) {
|
||||||
let repo = git.repositories.find((repo) => repo.ui.selected)?.state.remotes[0]?.fetchUrl;
|
let repo = git.repositories.find((repo) => repo.ui.selected)?.state
|
||||||
|
.remotes[0]?.fetchUrl;
|
||||||
|
|
||||||
if (repo) {
|
if (repo) {
|
||||||
if (repo.startsWith('git@') || repo.startsWith('ssh://')) {
|
if (repo.startsWith("git@") || repo.startsWith("ssh://")) {
|
||||||
repo = repo.replace('ssh://', '').replace(':', '/').replace('git@', 'https://').replace('.git', '');
|
repo = repo
|
||||||
|
.replace("ssh://", "")
|
||||||
|
.replace(":", "/")
|
||||||
|
.replace("git@", "https://")
|
||||||
|
.replace(".git", "");
|
||||||
} else {
|
} else {
|
||||||
repo = repo.replace(/(https:\/\/)([^@]*)@(.*?$)/, '$1$3').replace('.git', '');
|
repo = repo
|
||||||
|
.replace(/(https:\/\/)([^@]*)@(.*?$)/, "$1$3")
|
||||||
|
.replace(".git", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
...state,
|
...state,
|
||||||
buttons: [{ label: 'View Repository', url: repo }],
|
buttons: [{ label: "View Repository", url: repo }],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +292,11 @@ export async function activity(previous: ActivityPayload = {}) {
|
||||||
...state,
|
...state,
|
||||||
details: removeDetails
|
details: removeDetails
|
||||||
? undefined
|
? undefined
|
||||||
: await details(CONFIG_KEYS.DetailsIdling, CONFIG_KEYS.DetailsEditing, CONFIG_KEYS.DetailsDebugging),
|
: await details(
|
||||||
|
CONFIG_KEYS.DetailsIdling,
|
||||||
|
CONFIG_KEYS.DetailsEditing,
|
||||||
|
CONFIG_KEYS.DetailsDebugging,
|
||||||
|
),
|
||||||
state: removeLowerDetails
|
state: removeLowerDetails
|
||||||
? undefined
|
? undefined
|
||||||
: await details(
|
: await details(
|
||||||
|
@ -248,7 +320,10 @@ export async function activity(previous: ActivityPayload = {}) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
log(LogLevel.Trace, `VSCode language id: ${window.activeTextEditor.document.languageId}`);
|
log(
|
||||||
|
LogLevel.Trace,
|
||||||
|
`VSCode language id: ${window.activeTextEditor.document.languageId}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
106
src/constants.ts
106
src/constants.ts
|
@ -1,61 +1,63 @@
|
||||||
import LANG from './data/languages.json';
|
import LANG from "./data/languages.json";
|
||||||
|
|
||||||
export const CLIENT_ID = '383226320970055681' as const;
|
export const CLIENT_ID = "383226320970055681" as const;
|
||||||
|
|
||||||
export const KNOWN_EXTENSIONS: { [key: string]: { image: string } } = LANG.KNOWN_EXTENSIONS;
|
export const KNOWN_EXTENSIONS: { [key: string]: { image: string } } =
|
||||||
export const KNOWN_LANGUAGES: { language: string; image: string }[] = LANG.KNOWN_LANGUAGES;
|
LANG.KNOWN_EXTENSIONS;
|
||||||
|
export const KNOWN_LANGUAGES: { language: string; image: string }[] =
|
||||||
|
LANG.KNOWN_LANGUAGES;
|
||||||
|
|
||||||
export const EMPTY = '' as const;
|
export const EMPTY = "" as const;
|
||||||
export const FAKE_EMPTY = '\u200b\u200b' as const;
|
export const FAKE_EMPTY = "\u200b\u200b" as const;
|
||||||
export const FILE_SIZES = [' bytes', 'KB', 'MB', 'GB', 'TB'] as const;
|
export const FILE_SIZES = [" bytes", "KB", "MB", "GB", "TB"] as const;
|
||||||
|
|
||||||
export const IDLE_IMAGE_KEY = 'vscode-big' as const;
|
export const IDLE_IMAGE_KEY = "vscode-big" as const;
|
||||||
export const DEBUG_IMAGE_KEY = 'debug' as const;
|
export const DEBUG_IMAGE_KEY = "debug" as const;
|
||||||
export const VSCODE_IMAGE_KEY = 'vscode' as const;
|
export const VSCODE_IMAGE_KEY = "vscode" as const;
|
||||||
export const VSCODE_INSIDERS_IMAGE_KEY = 'vscode-insiders' as const;
|
export const VSCODE_INSIDERS_IMAGE_KEY = "vscode-insiders" as const;
|
||||||
|
|
||||||
export const UNKNOWN_GIT_BRANCH = 'Unknown' as const;
|
export const UNKNOWN_GIT_BRANCH = "Unknown" as const;
|
||||||
export const UNKNOWN_GIT_REPO_NAME = 'Unknown' as const;
|
export const UNKNOWN_GIT_REPO_NAME = "Unknown" as const;
|
||||||
|
|
||||||
export const enum REPLACE_KEYS {
|
export enum REPLACE_KEYS {
|
||||||
Empty = '{empty}',
|
Empty = "{empty}",
|
||||||
FileName = '{file_name}',
|
FileName = "{file_name}",
|
||||||
DirName = '{dir_name}',
|
DirName = "{dir_name}",
|
||||||
FullDirName = '{full_dir_name}',
|
FullDirName = "{full_dir_name}",
|
||||||
Workspace = '{workspace}',
|
Workspace = "{workspace}",
|
||||||
VSCodeWorkspace = '(Workspace)',
|
VSCodeWorkspace = "(Workspace)",
|
||||||
WorkspaceFolder = '{workspace_folder}',
|
WorkspaceFolder = "{workspace_folder}",
|
||||||
WorkspaceAndFolder = '{workspace_and_folder}',
|
WorkspaceAndFolder = "{workspace_and_folder}",
|
||||||
LanguageLowerCase = '{lang}',
|
LanguageLowerCase = "{lang}",
|
||||||
LanguageTitleCase = '{Lang}',
|
LanguageTitleCase = "{Lang}",
|
||||||
LanguageUpperCase = '{LANG}',
|
LanguageUpperCase = "{LANG}",
|
||||||
TotalLines = '{total_lines}',
|
TotalLines = "{total_lines}",
|
||||||
CurrentLine = '{current_line}',
|
CurrentLine = "{current_line}",
|
||||||
CurrentColumn = '{current_column}',
|
CurrentColumn = "{current_column}",
|
||||||
FileSize = '{file_size}',
|
FileSize = "{file_size}",
|
||||||
AppName = '{app_name}',
|
AppName = "{app_name}",
|
||||||
GitRepoName = '{git_repo_name}',
|
GitRepoName = "{git_repo_name}",
|
||||||
GitBranch = '{git_branch}',
|
GitBranch = "{git_branch}",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CONFIG_KEYS {
|
export enum CONFIG_KEYS {
|
||||||
Enabled = 'enabled',
|
Enabled = "enabled",
|
||||||
DetailsIdling = 'detailsIdling',
|
DetailsIdling = "detailsIdling",
|
||||||
DetailsEditing = 'detailsEditing',
|
DetailsEditing = "detailsEditing",
|
||||||
DetailsDebugging = 'detailsDebugging',
|
DetailsDebugging = "detailsDebugging",
|
||||||
LowerDetailsIdling = 'lowerDetailsIdling',
|
LowerDetailsIdling = "lowerDetailsIdling",
|
||||||
LowerDetailsEditing = 'lowerDetailsEditing',
|
LowerDetailsEditing = "lowerDetailsEditing",
|
||||||
LowerDetailsDebugging = 'lowerDetailsDebugging',
|
LowerDetailsDebugging = "lowerDetailsDebugging",
|
||||||
LowerDetailsNoWorkspaceFound = 'lowerDetailsNoWorkspaceFound',
|
LowerDetailsNoWorkspaceFound = "lowerDetailsNoWorkspaceFound",
|
||||||
LargeImageIdling = 'largeImageIdling',
|
LargeImageIdling = "largeImageIdling",
|
||||||
LargeImage = 'largeImage',
|
LargeImage = "largeImage",
|
||||||
SmallImage = 'smallImage',
|
SmallImage = "smallImage",
|
||||||
SuppressNotifications = 'suppressNotifications',
|
SuppressNotifications = "suppressNotifications",
|
||||||
WorkspaceExcludePatterns = 'workspaceExcludePatterns',
|
WorkspaceExcludePatterns = "workspaceExcludePatterns",
|
||||||
SwapBigAndSmallImage = 'swapBigAndSmallImage',
|
SwapBigAndSmallImage = "swapBigAndSmallImage",
|
||||||
RemoveDetails = 'removeDetails',
|
RemoveDetails = "removeDetails",
|
||||||
RemoveLowerDetails = 'removeLowerDetails',
|
RemoveLowerDetails = "removeLowerDetails",
|
||||||
RemoveTimestamp = 'removeTimestamp',
|
RemoveTimestamp = "removeTimestamp",
|
||||||
RemoveRemoteRepository = 'removeRemoteRepository',
|
RemoveRemoteRepository = "removeRemoteRepository",
|
||||||
IdleTimeout = 'idleTimeout',
|
IdleTimeout = "idleTimeout",
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,11 +82,15 @@
|
||||||
".asmx": { "image": "asp" },
|
".asmx": { "image": "asp" },
|
||||||
".aspx": { "image": "asp" },
|
".aspx": { "image": "asp" },
|
||||||
".axd": { "image": "asp" },
|
".axd": { "image": "asp" },
|
||||||
"/\\.(l?a|[ls]?o|out|s|a51|asm|axf|elf|prx|puff|z80)$/i": { "image": "assembly" },
|
"/\\.(l?a|[ls]?o|out|s|a51|asm|axf|elf|prx|puff|z80)$/i": {
|
||||||
|
"image": "assembly"
|
||||||
|
},
|
||||||
".agc": { "image": "assembly" },
|
".agc": { "image": "assembly" },
|
||||||
".ko": { "image": "assembly" },
|
".ko": { "image": "assembly" },
|
||||||
".lst": { "image": "assembly" },
|
".lst": { "image": "assembly" },
|
||||||
"/\\.((c([+px]{2}?)?-?)?objdump|bsdiff|bin|dat|pak|pdb)$/i": { "image": "assembly" },
|
"/\\.((c([+px]{2}?)?-?)?objdump|bsdiff|bin|dat|pak|pdb)$/i": {
|
||||||
|
"image": "assembly"
|
||||||
|
},
|
||||||
".d-objdump": { "image": "assembly" },
|
".d-objdump": { "image": "assembly" },
|
||||||
"/\\.gcode|\\.gco/i": { "image": "assembly" },
|
"/\\.gcode|\\.gco/i": { "image": "assembly" },
|
||||||
"/\\.rpy[bc]$/i": { "image": "assembly" },
|
"/\\.rpy[bc]$/i": { "image": "assembly" },
|
||||||
|
@ -150,7 +154,9 @@
|
||||||
".dm": { "image": "dm" },
|
".dm": { "image": "dm" },
|
||||||
".dme": { "image": "dm" },
|
".dme": { "image": "dm" },
|
||||||
".dmm": { "image": "dm" },
|
".dmm": { "image": "dm" },
|
||||||
"/^(Dockerfile|docker-compose)|\\.docker(file|ignore)$/i": { "image": "docker" },
|
"/^(Dockerfile|docker-compose)|\\.docker(file|ignore)$/i": {
|
||||||
|
"image": "docker"
|
||||||
|
},
|
||||||
"/^docker-sync\\.yml$/i": { "image": "docker" },
|
"/^docker-sync\\.yml$/i": { "image": "docker" },
|
||||||
".editorconfig": { "image": "editorconfig" },
|
".editorconfig": { "image": "editorconfig" },
|
||||||
".ejs": { "image": "ejs" },
|
".ejs": { "image": "ejs" },
|
||||||
|
@ -274,13 +280,19 @@
|
||||||
"/^pkginfo$/": { "image": "manifest" },
|
"/^pkginfo$/": { "image": "manifest" },
|
||||||
"/^mime\\.types$/i": { "image": "manifest" },
|
"/^mime\\.types$/i": { "image": "manifest" },
|
||||||
"/^METADATA\\.pb$/": { "image": "manifest" },
|
"/^METADATA\\.pb$/": { "image": "manifest" },
|
||||||
"/[\\/\\\\](?:magic[\\/\\\\]Magdir|file[\\/\\\\]magic)[\\/\\\\][-.\\w]+$/i": { "image": "manifest" },
|
"/[\\/\\\\](?:magic[\\/\\\\]Magdir|file[\\/\\\\]magic)[\\/\\\\][-.\\w]+$/i": {
|
||||||
"/(\\\\|\\/)dev[-\\w]+\\1(?:[^\\\\\\/]+\\1)*(?!DESC|NOTES)(?:[A-Z][-A-Z]*)(?:\\.in)?$/": { "image": "manifest" },
|
"image": "manifest"
|
||||||
|
},
|
||||||
|
"/(\\\\|\\/)dev[-\\w]+\\1(?:[^\\\\\\/]+\\1)*(?!DESC|NOTES)(?:[A-Z][-A-Z]*)(?:\\.in)?$/": {
|
||||||
|
"image": "manifest"
|
||||||
|
},
|
||||||
"lib/icons/.icondb.js": { "image": "manifest" },
|
"lib/icons/.icondb.js": { "image": "manifest" },
|
||||||
"/\\.git[\\/\\\\](.*[\\/\\\\])?(HEAD|ORIG_HEAD|packed-refs|logs[\\/\\\\](.+[\\/\\\\])?[^\\/\\\\]+)$/": {
|
"/\\.git[\\/\\\\](.*[\\/\\\\])?(HEAD|ORIG_HEAD|packed-refs|logs[\\/\\\\](.+[\\/\\\\])?[^\\/\\\\]+)$/": {
|
||||||
"image": "manifest"
|
"image": "manifest"
|
||||||
},
|
},
|
||||||
"/\\.(md|mdown|markdown|mkd|mkdown|mdwn|mkdn|rmd|ron|pmd)$/i": { "image": "markdown" },
|
"/\\.(md|mdown|markdown|mkd|mkdown|mdwn|mkdn|rmd|ron|pmd)$/i": {
|
||||||
|
"image": "markdown"
|
||||||
|
},
|
||||||
".mdx": { "image": "markdownx" },
|
".mdx": { "image": "markdownx" },
|
||||||
".marko": { "image": "marko" },
|
".marko": { "image": "marko" },
|
||||||
".nim": { "image": "nim" },
|
".nim": { "image": "nim" },
|
||||||
|
@ -329,7 +341,9 @@
|
||||||
".psm1": { "image": "powershell" },
|
".psm1": { "image": "powershell" },
|
||||||
".ps1xml": { "image": "powershell" },
|
".ps1xml": { "image": "powershell" },
|
||||||
".prettierignore": { "image": "prettier" },
|
".prettierignore": { "image": "prettier" },
|
||||||
"/\\.prettier((rc)|(\\.(toml|yml|yaml|json|js))?$){2}/i": { "image": "prettier" },
|
"/\\.prettier((rc)|(\\.(toml|yml|yaml|json|js))?$){2}/i": {
|
||||||
|
"image": "prettier"
|
||||||
|
},
|
||||||
"prettier.config.js": { "image": "prettier" },
|
"prettier.config.js": { "image": "prettier" },
|
||||||
"prisma.yml": { "image": "prisma" },
|
"prisma.yml": { "image": "prisma" },
|
||||||
".pde": { "image": "processing" },
|
".pde": { "image": "processing" },
|
||||||
|
@ -359,7 +373,9 @@
|
||||||
"/\\.(r|Rprofile|rsx|rd)$/i": { "image": "r" },
|
"/\\.(r|Rprofile|rsx|rd)$/i": { "image": "r" },
|
||||||
".rkt": { "image": "racket" },
|
".rkt": { "image": "racket" },
|
||||||
"/\\.res?i?$/i": { "image": "reasonml" },
|
"/\\.res?i?$/i": { "image": "reasonml" },
|
||||||
"/\\.(rb|ru|ruby|erb|gemspec|god|mspec|pluginspec|podspec|rabl|rake|opal)$/i": { "image": "ruby" },
|
"/\\.(rb|ru|ruby|erb|gemspec|god|mspec|pluginspec|podspec|rabl|rake|opal)$/i": {
|
||||||
|
"image": "ruby"
|
||||||
|
},
|
||||||
"/^\\.?(irbrc|gemrc|pryrc|ruby-(gemset|version))$/i": { "image": "ruby" },
|
"/^\\.?(irbrc|gemrc|pryrc|ruby-(gemset|version))$/i": { "image": "ruby" },
|
||||||
"/^(Appraisals|(Rake|[bB]uild|Cap|Danger|Deliver|Fast|Guard|Jar|Maven|Pod|Puppet|Snap)file(\\.lock)?)$/": {
|
"/^(Appraisals|(Rake|[bB]uild|Cap|Danger|Deliver|Fast|Guard|Jar|Maven|Pod|Puppet|Snap)file(\\.lock)?)$/": {
|
||||||
"image": "ruby"
|
"image": "ruby"
|
||||||
|
@ -377,13 +393,19 @@
|
||||||
},
|
},
|
||||||
"/\\.(ksh|mksh|pdksh)$/i": { "image": "shell" },
|
"/\\.(ksh|mksh|pdksh)$/i": { "image": "shell" },
|
||||||
".sh-session": { "image": "shell" },
|
".sh-session": { "image": "shell" },
|
||||||
"/\\.zsh(-theme|_history)?$|^\\.?(antigen|zpreztorc|zlogin|zlogout|zprofile|zshenv|zshrc)$/i": { "image": "shell" },
|
"/\\.zsh(-theme|_history)?$|^\\.?(antigen|zpreztorc|zlogin|zlogout|zprofile|zshenv|zshrc)$/i": {
|
||||||
|
"image": "shell"
|
||||||
|
},
|
||||||
"/\\.fish$|^\\.fishrc$/i": { "image": "shell" },
|
"/\\.fish$|^\\.fishrc$/i": { "image": "shell" },
|
||||||
"/^\\.?(login|profile)$/": { "image": "shell" },
|
"/^\\.?(login|profile)$/": { "image": "shell" },
|
||||||
".inputrc": { "image": "shell" },
|
".inputrc": { "image": "shell" },
|
||||||
".tmux": { "image": "shell" },
|
".tmux": { "image": "shell" },
|
||||||
"/^(configure|config\\.(guess|rpath|status|sub)|depcomp|libtool|compile)$/": { "image": "shell" },
|
"/^(configure|config\\.(guess|rpath|status|sub)|depcomp|libtool|compile)$/": {
|
||||||
"/^\\/(private\\/)?etc\\/([^\\/]+\\/)*(profile$|nanorc$|rc\\.|csh\\.)/i": { "image": "shell" },
|
"image": "shell"
|
||||||
|
},
|
||||||
|
"/^\\/(private\\/)?etc\\/([^\\/]+\\/)*(profile$|nanorc$|rc\\.|csh\\.)/i": {
|
||||||
|
"image": "shell"
|
||||||
|
},
|
||||||
"/^\\.?cshrc$/i": { "image": "shell" },
|
"/^\\.?cshrc$/i": { "image": "shell" },
|
||||||
".profile": { "image": "shell" },
|
".profile": { "image": "shell" },
|
||||||
".tcsh": { "image": "shell" },
|
".tcsh": { "image": "shell" },
|
||||||
|
|
140
src/extension.ts
140
src/extension.ts
|
@ -1,28 +1,40 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
||||||
|
|
||||||
const { Client } = require('discord-rpc'); // eslint-disable-line
|
const { Client } = require("discord-rpc"); // eslint-disable-line
|
||||||
import { commands, ExtensionContext, StatusBarAlignment, StatusBarItem, window, workspace, debug } from 'vscode';
|
import throttle from "lodash-es/throttle";
|
||||||
import throttle from 'lodash-es/throttle';
|
import {
|
||||||
|
type ExtensionContext,
|
||||||
|
StatusBarAlignment,
|
||||||
|
type StatusBarItem,
|
||||||
|
commands,
|
||||||
|
debug,
|
||||||
|
window,
|
||||||
|
workspace,
|
||||||
|
} from "vscode";
|
||||||
|
|
||||||
import { activity } from './activity';
|
import { activity } from "./activity";
|
||||||
import { CLIENT_ID, CONFIG_KEYS } from './constants';
|
import { CLIENT_ID, CONFIG_KEYS } from "./constants";
|
||||||
import { log, LogLevel } from './logger';
|
import { LogLevel, log } from "./logger";
|
||||||
import { getConfig, getGit } from './util';
|
import { getConfig, getGit } from "./util";
|
||||||
|
|
||||||
const statusBarIcon: StatusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
|
const statusBarIcon: StatusBarItem = window.createStatusBarItem(
|
||||||
statusBarIcon.text = '$(pulse) Connecting to Discord...';
|
StatusBarAlignment.Left,
|
||||||
|
);
|
||||||
|
statusBarIcon.text = "$(pulse) Connecting to Discord...";
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
let rpc = new Client({ transport: 'ipc' });
|
let rpc = new Client({ transport: "ipc" });
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
|
||||||
let state = {};
|
let state = {};
|
||||||
let idle: NodeJS.Timeout | undefined;
|
let idle: NodeJS.Timeout | undefined;
|
||||||
let listeners: { dispose: () => any }[] = [];
|
let listeners: { dispose: () => void }[] = [];
|
||||||
|
|
||||||
export function cleanUp() {
|
export function cleanUp() {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
listeners.forEach((listener) => listener.dispose());
|
for (const listener of listeners) {
|
||||||
|
listener.dispose();
|
||||||
|
}
|
||||||
listeners = [];
|
listeners = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,50 +46,70 @@ async function sendActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function login() {
|
async function login() {
|
||||||
log(LogLevel.Info, 'Creating discord-rpc client');
|
log(LogLevel.Info, "Creating discord-rpc client");
|
||||||
rpc = new Client({ transport: 'ipc' });
|
rpc = new Client({ transport: "ipc" });
|
||||||
|
|
||||||
rpc.on('ready', () => {
|
rpc.on("ready", () => {
|
||||||
log(LogLevel.Info, 'Successfully connected to Discord');
|
log(LogLevel.Info, "Successfully connected to Discord");
|
||||||
cleanUp();
|
cleanUp();
|
||||||
|
|
||||||
statusBarIcon.text = '$(globe) Connected to Discord';
|
statusBarIcon.text = "$(globe) Connected to Discord";
|
||||||
statusBarIcon.tooltip = 'Connected to Discord';
|
statusBarIcon.tooltip = "Connected to Discord";
|
||||||
|
|
||||||
void sendActivity();
|
void sendActivity();
|
||||||
const onChangeActiveTextEditor = window.onDidChangeActiveTextEditor(() => sendActivity());
|
const onChangeActiveTextEditor = window.onDidChangeActiveTextEditor(() =>
|
||||||
const onChangeTextDocument = workspace.onDidChangeTextDocument(throttle(() => sendActivity(), 2000));
|
sendActivity(),
|
||||||
const onStartDebugSession = debug.onDidStartDebugSession(() => sendActivity());
|
);
|
||||||
const onTerminateDebugSession = debug.onDidTerminateDebugSession(() => sendActivity());
|
const onChangeTextDocument = workspace.onDidChangeTextDocument(
|
||||||
|
throttle(() => sendActivity(), 2000),
|
||||||
|
);
|
||||||
|
const onStartDebugSession = debug.onDidStartDebugSession(() =>
|
||||||
|
sendActivity(),
|
||||||
|
);
|
||||||
|
const onTerminateDebugSession = debug.onDidTerminateDebugSession(() =>
|
||||||
|
sendActivity(),
|
||||||
|
);
|
||||||
|
|
||||||
listeners.push(onChangeActiveTextEditor, onChangeTextDocument, onStartDebugSession, onTerminateDebugSession);
|
listeners.push(
|
||||||
|
onChangeActiveTextEditor,
|
||||||
|
onChangeTextDocument,
|
||||||
|
onStartDebugSession,
|
||||||
|
onTerminateDebugSession,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
rpc.on('disconnected', () => {
|
rpc.on("disconnected", () => {
|
||||||
cleanUp();
|
cleanUp();
|
||||||
rpc.destroy();
|
rpc.destroy();
|
||||||
statusBarIcon.text = '$(pulse) Reconnect to Discord';
|
statusBarIcon.text = "$(pulse) Reconnect to Discord";
|
||||||
statusBarIcon.command = 'discord.reconnect';
|
statusBarIcon.command = "discord.reconnect";
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await rpc.login({ clientId: CLIENT_ID });
|
await rpc.login({ clientId: CLIENT_ID });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log(LogLevel.Error, `Encountered following error while trying to login:\n${error as string}`);
|
log(
|
||||||
|
LogLevel.Error,
|
||||||
|
`Encountered following error while trying to login:\n${error as string}`,
|
||||||
|
);
|
||||||
cleanUp();
|
cleanUp();
|
||||||
rpc.destroy();
|
rpc.destroy();
|
||||||
if (!config[CONFIG_KEYS.SuppressNotifications]) {
|
if (!config[CONFIG_KEYS.SuppressNotifications]) {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
if (error?.message?.includes('ENOENT')) void window.showErrorMessage('No Discord client detected');
|
if (error?.message?.includes("ENOENT"))
|
||||||
else void window.showErrorMessage(`Couldn't connect to Discord via RPC: ${error as string}`);
|
void window.showErrorMessage("No Discord client detected");
|
||||||
|
else
|
||||||
|
void window.showErrorMessage(
|
||||||
|
`Couldn't connect to Discord via RPC: ${error as string}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
statusBarIcon.text = '$(pulse) Reconnect to Discord';
|
statusBarIcon.text = "$(pulse) Reconnect to Discord";
|
||||||
statusBarIcon.command = 'discord.reconnect';
|
statusBarIcon.command = "discord.reconnect";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function activate(context: ExtensionContext) {
|
export async function activate(context: ExtensionContext) {
|
||||||
log(LogLevel.Info, 'Discord Presence activated');
|
log(LogLevel.Info, "Discord Presence activated");
|
||||||
|
|
||||||
let isWorkspaceExcluded = false;
|
let isWorkspaceExcluded = false;
|
||||||
for (const pattern of config[CONFIG_KEYS.WorkspaceExcludePatterns]) {
|
for (const pattern of config[CONFIG_KEYS.WorkspaceExcludePatterns]) {
|
||||||
|
@ -93,52 +125,62 @@ export async function activate(context: ExtensionContext) {
|
||||||
const enable = async (update = true) => {
|
const enable = async (update = true) => {
|
||||||
if (update) {
|
if (update) {
|
||||||
try {
|
try {
|
||||||
await config.update('enabled', true);
|
await config.update("enabled", true);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
log(LogLevel.Info, 'Enable: Cleaning up old listeners');
|
log(LogLevel.Info, "Enable: Cleaning up old listeners");
|
||||||
cleanUp();
|
cleanUp();
|
||||||
statusBarIcon.text = '$(pulse) Connecting to Discord...';
|
statusBarIcon.text = "$(pulse) Connecting to Discord...";
|
||||||
statusBarIcon.show();
|
statusBarIcon.show();
|
||||||
log(LogLevel.Info, 'Enable: Attempting to recreate login');
|
log(LogLevel.Info, "Enable: Attempting to recreate login");
|
||||||
void login();
|
void login();
|
||||||
};
|
};
|
||||||
|
|
||||||
const disable = async (update = true) => {
|
const disable = async (update = true) => {
|
||||||
if (update) {
|
if (update) {
|
||||||
try {
|
try {
|
||||||
await config.update('enabled', false);
|
await config.update("enabled", false);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
log(LogLevel.Info, 'Disable: Cleaning up old listeners');
|
log(LogLevel.Info, "Disable: Cleaning up old listeners");
|
||||||
cleanUp();
|
cleanUp();
|
||||||
void rpc?.destroy();
|
void rpc?.destroy();
|
||||||
log(LogLevel.Info, 'Disable: Destroyed the rpc instance');
|
log(LogLevel.Info, "Disable: Destroyed the rpc instance");
|
||||||
statusBarIcon.hide();
|
statusBarIcon.hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
const enabler = commands.registerCommand('discord.enable', async () => {
|
const enabler = commands.registerCommand("discord.enable", async () => {
|
||||||
await disable();
|
await disable();
|
||||||
await enable();
|
await enable();
|
||||||
await window.showInformationMessage('Enabled Discord Presence for this workspace');
|
await window.showInformationMessage(
|
||||||
|
"Enabled Discord Presence for this workspace",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const disabler = commands.registerCommand('discord.disable', async () => {
|
const disabler = commands.registerCommand("discord.disable", async () => {
|
||||||
await disable();
|
await disable();
|
||||||
await window.showInformationMessage('Disabled Discord Presence for this workspace');
|
await window.showInformationMessage(
|
||||||
|
"Disabled Discord Presence for this workspace",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const reconnecter = commands.registerCommand('discord.reconnect', async () => {
|
const reconnecter = commands.registerCommand(
|
||||||
|
"discord.reconnect",
|
||||||
|
async () => {
|
||||||
await disable(false);
|
await disable(false);
|
||||||
await enable(false);
|
await enable(false);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const disconnect = commands.registerCommand('discord.disconnect', async () => {
|
const disconnect = commands.registerCommand(
|
||||||
|
"discord.disconnect",
|
||||||
|
async () => {
|
||||||
await disable(false);
|
await disable(false);
|
||||||
statusBarIcon.text = '$(pulse) Reconnect to Discord';
|
statusBarIcon.text = "$(pulse) Reconnect to Discord";
|
||||||
statusBarIcon.command = 'discord.reconnect';
|
statusBarIcon.command = "discord.reconnect";
|
||||||
statusBarIcon.show();
|
statusBarIcon.show();
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
context.subscriptions.push(enabler, disabler, reconnecter, disconnect);
|
context.subscriptions.push(enabler, disabler, reconnecter, disconnect);
|
||||||
|
|
||||||
|
|
146
src/git.d.ts
vendored
146
src/git.d.ts
vendored
|
@ -12,8 +12,8 @@
|
||||||
* --------------------------------------------------------------------------------------------
|
* --------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Uri, Event, Disposable, ProviderResult } from 'vscode';
|
import type { Disposable, Event, ProviderResult, Uri } from "vscode";
|
||||||
export { ProviderResult } from 'vscode';
|
export { ProviderResult } from "vscode";
|
||||||
|
|
||||||
export interface Git {
|
export interface Git {
|
||||||
readonly path: string;
|
readonly path: string;
|
||||||
|
@ -23,15 +23,15 @@ export interface InputBox {
|
||||||
value: string;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum ForcePushMode {
|
export enum ForcePushMode {
|
||||||
Force,
|
Force = "Force",
|
||||||
ForceWithLease,
|
ForceWithLease = "ForceWithLease",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum RefType {
|
export enum RefType {
|
||||||
Head,
|
Head = "Head",
|
||||||
RemoteHead,
|
RemoteHead = "RemoteHead",
|
||||||
Tag,
|
Tag = "Tag",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Ref {
|
export interface Ref {
|
||||||
|
@ -75,26 +75,26 @@ export interface Remote {
|
||||||
readonly isReadOnly: boolean;
|
readonly isReadOnly: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum Status {
|
export enum Status {
|
||||||
INDEX_MODIFIED,
|
INDEX_MODIFIED = "INDEX_MODIFIED",
|
||||||
INDEX_ADDED,
|
INDEX_ADDED = "INDEX_ADDED",
|
||||||
INDEX_DELETED,
|
INDEX_DELETED = "INDEX_DELETED",
|
||||||
INDEX_RENAMED,
|
INDEX_RENAMED = "INDEX_RENAMED",
|
||||||
INDEX_COPIED,
|
INDEX_COPIED = "INDEX_COPIED",
|
||||||
|
|
||||||
MODIFIED,
|
MODIFIED = "MODIFIED",
|
||||||
DELETED,
|
DELETED = "DELETED",
|
||||||
UNTRACKED,
|
UNTRACKED = "UNTRACKED",
|
||||||
IGNORED,
|
IGNORED = "IGNORED",
|
||||||
INTENT_TO_ADD,
|
INTENT_TO_ADD = "INTENT_TO_ADD",
|
||||||
|
|
||||||
ADDED_BY_US,
|
ADDED_BY_US = "ADDED_BY_US",
|
||||||
ADDED_BY_THEM,
|
ADDED_BY_THEM = "ADDED_BY_THEM",
|
||||||
DELETED_BY_US,
|
DELETED_BY_US = "DELETED_BY_US",
|
||||||
DELETED_BY_THEM,
|
DELETED_BY_THEM = "DELETED_BY_THEM",
|
||||||
BOTH_ADDED,
|
BOTH_ADDED = "BOTH_ADDED",
|
||||||
BOTH_DELETED,
|
BOTH_DELETED = "BOTH_DELETED",
|
||||||
BOTH_MODIFIED,
|
BOTH_MODIFIED = "BOTH_MODIFIED",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Change {
|
export interface Change {
|
||||||
|
@ -138,7 +138,7 @@ export interface LogOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CommitOptions {
|
export interface CommitOptions {
|
||||||
all?: boolean | 'tracked';
|
all?: boolean | "tracked";
|
||||||
amend?: boolean;
|
amend?: boolean;
|
||||||
signoff?: boolean;
|
signoff?: boolean;
|
||||||
signCommit?: boolean;
|
signCommit?: boolean;
|
||||||
|
@ -173,8 +173,13 @@ export interface Repository {
|
||||||
setConfig(key: string, value: string): Promise<string>;
|
setConfig(key: string, value: string): Promise<string>;
|
||||||
getGlobalConfig(key: string): Promise<string>;
|
getGlobalConfig(key: string): Promise<string>;
|
||||||
|
|
||||||
getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number }>;
|
getObjectDetails(
|
||||||
detectObjectType(object: string): Promise<{ mimetype: string; encoding?: string }>;
|
treeish: string,
|
||||||
|
path: string,
|
||||||
|
): Promise<{ mode: string; object: string; size: number }>;
|
||||||
|
detectObjectType(
|
||||||
|
object: string,
|
||||||
|
): Promise<{ mimetype: string; encoding?: string }>;
|
||||||
buffer(ref: string, path: string): Promise<Buffer>;
|
buffer(ref: string, path: string): Promise<Buffer>;
|
||||||
show(ref: string, path: string): Promise<string>;
|
show(ref: string, path: string): Promise<string>;
|
||||||
getCommit(ref: string): Promise<Commit>;
|
getCommit(ref: string): Promise<Commit>;
|
||||||
|
@ -215,7 +220,12 @@ export interface Repository {
|
||||||
fetch(options?: FetchOptions): Promise<void>;
|
fetch(options?: FetchOptions): Promise<void>;
|
||||||
fetch(remote?: string, ref?: string, depth?: number): Promise<void>;
|
fetch(remote?: string, ref?: string, depth?: number): Promise<void>;
|
||||||
pull(unshallow?: boolean): Promise<void>;
|
pull(unshallow?: boolean): Promise<void>;
|
||||||
push(remoteName?: string, branchName?: string, setUpstream?: boolean, force?: ForcePushMode): Promise<void>;
|
push(
|
||||||
|
remoteName?: string,
|
||||||
|
branchName?: string,
|
||||||
|
setUpstream?: boolean,
|
||||||
|
force?: ForcePushMode,
|
||||||
|
): Promise<void>;
|
||||||
|
|
||||||
blame(path: string): Promise<string>;
|
blame(path: string): Promise<string>;
|
||||||
log(options?: LogOptions): Promise<Commit[]>;
|
log(options?: LogOptions): Promise<Commit[]>;
|
||||||
|
@ -256,7 +266,7 @@ export interface PushErrorHandler {
|
||||||
): Promise<boolean>;
|
): Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type APIState = 'uninitialized' | 'initialized';
|
export type APIState = "uninitialized" | "initialized";
|
||||||
|
|
||||||
export interface PublishEvent {
|
export interface PublishEvent {
|
||||||
repository: Repository;
|
repository: Repository;
|
||||||
|
@ -299,40 +309,40 @@ export interface GitExtension {
|
||||||
getAPI(version: 1): API;
|
getAPI(version: 1): API;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum GitErrorCodes {
|
export enum GitErrorCodes {
|
||||||
BadConfigFile = 'BadConfigFile',
|
BadConfigFile = "BadConfigFile",
|
||||||
AuthenticationFailed = 'AuthenticationFailed',
|
AuthenticationFailed = "AuthenticationFailed",
|
||||||
NoUserNameConfigured = 'NoUserNameConfigured',
|
NoUserNameConfigured = "NoUserNameConfigured",
|
||||||
NoUserEmailConfigured = 'NoUserEmailConfigured',
|
NoUserEmailConfigured = "NoUserEmailConfigured",
|
||||||
NoRemoteRepositorySpecified = 'NoRemoteRepositorySpecified',
|
NoRemoteRepositorySpecified = "NoRemoteRepositorySpecified",
|
||||||
NotAGitRepository = 'NotAGitRepository',
|
NotAGitRepository = "NotAGitRepository",
|
||||||
NotAtRepositoryRoot = 'NotAtRepositoryRoot',
|
NotAtRepositoryRoot = "NotAtRepositoryRoot",
|
||||||
Conflict = 'Conflict',
|
Conflict = "Conflict",
|
||||||
StashConflict = 'StashConflict',
|
StashConflict = "StashConflict",
|
||||||
UnmergedChanges = 'UnmergedChanges',
|
UnmergedChanges = "UnmergedChanges",
|
||||||
PushRejected = 'PushRejected',
|
PushRejected = "PushRejected",
|
||||||
RemoteConnectionError = 'RemoteConnectionError',
|
RemoteConnectionError = "RemoteConnectionError",
|
||||||
DirtyWorkTree = 'DirtyWorkTree',
|
DirtyWorkTree = "DirtyWorkTree",
|
||||||
CantOpenResource = 'CantOpenResource',
|
CantOpenResource = "CantOpenResource",
|
||||||
GitNotFound = 'GitNotFound',
|
GitNotFound = "GitNotFound",
|
||||||
CantCreatePipe = 'CantCreatePipe',
|
CantCreatePipe = "CantCreatePipe",
|
||||||
PermissionDenied = 'PermissionDenied',
|
PermissionDenied = "PermissionDenied",
|
||||||
CantAccessRemote = 'CantAccessRemote',
|
CantAccessRemote = "CantAccessRemote",
|
||||||
RepositoryNotFound = 'RepositoryNotFound',
|
RepositoryNotFound = "RepositoryNotFound",
|
||||||
RepositoryIsLocked = 'RepositoryIsLocked',
|
RepositoryIsLocked = "RepositoryIsLocked",
|
||||||
BranchNotFullyMerged = 'BranchNotFullyMerged',
|
BranchNotFullyMerged = "BranchNotFullyMerged",
|
||||||
NoRemoteReference = 'NoRemoteReference',
|
NoRemoteReference = "NoRemoteReference",
|
||||||
InvalidBranchName = 'InvalidBranchName',
|
InvalidBranchName = "InvalidBranchName",
|
||||||
BranchAlreadyExists = 'BranchAlreadyExists',
|
BranchAlreadyExists = "BranchAlreadyExists",
|
||||||
NoLocalChanges = 'NoLocalChanges',
|
NoLocalChanges = "NoLocalChanges",
|
||||||
NoStashFound = 'NoStashFound',
|
NoStashFound = "NoStashFound",
|
||||||
LocalChangesOverwritten = 'LocalChangesOverwritten',
|
LocalChangesOverwritten = "LocalChangesOverwritten",
|
||||||
NoUpstreamBranch = 'NoUpstreamBranch',
|
NoUpstreamBranch = "NoUpstreamBranch",
|
||||||
IsInSubmodule = 'IsInSubmodule',
|
IsInSubmodule = "IsInSubmodule",
|
||||||
WrongCase = 'WrongCase',
|
WrongCase = "WrongCase",
|
||||||
CantLockRef = 'CantLockRef',
|
CantLockRef = "CantLockRef",
|
||||||
CantRebaseMultipleBranches = 'CantRebaseMultipleBranches',
|
CantRebaseMultipleBranches = "CantRebaseMultipleBranches",
|
||||||
PatchDoesNotApply = 'PatchDoesNotApply',
|
PatchDoesNotApply = "PatchDoesNotApply",
|
||||||
NoPathFound = 'NoPathFound',
|
NoPathFound = "NoPathFound",
|
||||||
UnknownPath = 'UnknownPath',
|
UnknownPath = "UnknownPath",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
import { window } from 'vscode';
|
import dayjs from "dayjs";
|
||||||
import dayjs from 'dayjs';
|
import { window } from "vscode";
|
||||||
|
|
||||||
const outputChannel = window.createOutputChannel('Discord Presence');
|
const outputChannel = window.createOutputChannel("Discord Presence");
|
||||||
|
|
||||||
export const enum LogLevel {
|
export enum LogLevel {
|
||||||
Trace = 'TRACE',
|
Trace = "TRACE",
|
||||||
Debug = 'DEBUG',
|
Debug = "DEBUG",
|
||||||
Info = 'INFO',
|
Info = "INFO",
|
||||||
Warn = 'WARN',
|
Warn = "WARN",
|
||||||
Error = 'ERROR',
|
Error = "ERROR",
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(level: string, message: string) {
|
function send(level: string, message: string) {
|
||||||
outputChannel.appendLine(`[${dayjs().format('DD/MM/YYYY HH:mm:ss')} - ${level}] ${message}`);
|
outputChannel.appendLine(
|
||||||
|
`[${dayjs().format("DD/MM/YYYY HH:mm:ss")} - ${level}] ${message}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function log(level: LogLevel, message: string | Error) {
|
export function log(level: LogLevel, message: string | Error) {
|
||||||
if (typeof message === 'string') {
|
if (typeof message === "string") {
|
||||||
send(level, message);
|
send(level, message);
|
||||||
} else if (message instanceof Error) {
|
} else if (message instanceof Error) {
|
||||||
send(level, message.message);
|
send(level, message.message);
|
||||||
|
@ -24,7 +26,7 @@ export function log(level: LogLevel, message: string | Error) {
|
||||||
if (message.stack) {
|
if (message.stack) {
|
||||||
send(level, message.stack);
|
send(level, message.stack);
|
||||||
}
|
}
|
||||||
} else if (typeof message === 'object') {
|
} else if (typeof message === "object") {
|
||||||
try {
|
try {
|
||||||
const json = JSON.stringify(message, null, 2);
|
const json = JSON.stringify(message, null, 2);
|
||||||
send(level, json);
|
send(level, json);
|
||||||
|
|
39
src/util.ts
39
src/util.ts
|
@ -1,9 +1,14 @@
|
||||||
import { basename } from 'path';
|
import { basename } from "node:path";
|
||||||
import { TextDocument, workspace, extensions, WorkspaceConfiguration } from 'vscode';
|
import {
|
||||||
|
type TextDocument,
|
||||||
|
type WorkspaceConfiguration,
|
||||||
|
extensions,
|
||||||
|
workspace,
|
||||||
|
} from "vscode";
|
||||||
|
|
||||||
import { KNOWN_EXTENSIONS, KNOWN_LANGUAGES } from './constants';
|
import { KNOWN_EXTENSIONS, KNOWN_LANGUAGES } from "./constants";
|
||||||
import type { API, GitExtension } from './git';
|
import type { API, GitExtension } from "./git";
|
||||||
import { log, LogLevel } from './logger';
|
import { LogLevel, log } from "./logger";
|
||||||
|
|
||||||
let git: API | null | undefined;
|
let git: API | null | undefined;
|
||||||
|
|
||||||
|
@ -30,14 +35,17 @@ type WorkspaceExtensionConfiguration = WorkspaceConfiguration & {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getConfig() {
|
export function getConfig() {
|
||||||
return workspace.getConfiguration('discord') as WorkspaceExtensionConfiguration;
|
return workspace.getConfiguration(
|
||||||
|
"discord",
|
||||||
|
) as WorkspaceExtensionConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const toLower = (str: string) => str.toLocaleLowerCase();
|
export const toLower = (str: string) => str.toLocaleLowerCase();
|
||||||
|
|
||||||
export const toUpper = (str: string) => str.toLocaleUpperCase();
|
export const toUpper = (str: string) => str.toLocaleUpperCase();
|
||||||
|
|
||||||
export const toTitle = (str: string) => toLower(str).replace(/^\w/, (c) => toUpper(c));
|
export const toTitle = (str: string) =>
|
||||||
|
toLower(str).replace(/^\w/, (c) => toUpper(c));
|
||||||
|
|
||||||
export function resolveFileIcon(document: TextDocument) {
|
export function resolveFileIcon(document: TextDocument) {
|
||||||
const filename = basename(document.fileName);
|
const filename = basename(document.fileName);
|
||||||
|
@ -54,14 +62,16 @@ export function resolveFileIcon(document: TextDocument) {
|
||||||
const regex = new RegExp(match[1], match[2]);
|
const regex = new RegExp(match[1], match[2]);
|
||||||
return regex.test(filename);
|
return regex.test(filename);
|
||||||
});
|
});
|
||||||
const findKnownLanguage = KNOWN_LANGUAGES.find((key) => key.language === document.languageId);
|
const findKnownLanguage = KNOWN_LANGUAGES.find(
|
||||||
|
(key) => key.language === document.languageId,
|
||||||
|
);
|
||||||
const fileIcon = findKnownExtension
|
const fileIcon = findKnownExtension
|
||||||
? KNOWN_EXTENSIONS[findKnownExtension]
|
? KNOWN_EXTENSIONS[findKnownExtension]
|
||||||
: findKnownLanguage
|
: findKnownLanguage
|
||||||
? findKnownLanguage.image
|
? findKnownLanguage.image
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return typeof fileIcon === 'string' ? fileIcon : fileIcon?.image ?? 'text';
|
return typeof fileIcon === "string" ? fileIcon : (fileIcon?.image ?? "text");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGit() {
|
export async function getGit() {
|
||||||
|
@ -70,16 +80,19 @@ export async function getGit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log(LogLevel.Debug, 'Loading git extension');
|
log(LogLevel.Debug, "Loading git extension");
|
||||||
const gitExtension = extensions.getExtension<GitExtension>('vscode.git');
|
const gitExtension = extensions.getExtension<GitExtension>("vscode.git");
|
||||||
if (!gitExtension?.isActive) {
|
if (!gitExtension?.isActive) {
|
||||||
log(LogLevel.Trace, 'Git extension not activated, activating...');
|
log(LogLevel.Trace, "Git extension not activated, activating...");
|
||||||
await gitExtension?.activate();
|
await gitExtension?.activate();
|
||||||
}
|
}
|
||||||
git = gitExtension?.exports.getAPI(1);
|
git = gitExtension?.exports.getAPI(1);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
git = null;
|
git = null;
|
||||||
log(LogLevel.Error, `Failed to load git extension, is git installed?; ${error as string}`);
|
log(
|
||||||
|
LogLevel.Error,
|
||||||
|
`Failed to load git extension, is git installed?; ${error as string}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return git;
|
return git;
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
|
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||||
const TerserPlugin = require('terser-webpack-plugin');
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
const path = require('path');
|
const path = require("node:path");
|
||||||
|
|
||||||
/** @type {import('webpack').Configuration} */
|
/** @type {import('webpack').Configuration} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
target: 'node',
|
target: "node",
|
||||||
entry: './src/extension.ts',
|
entry: "./src/extension.ts",
|
||||||
output: {
|
output: {
|
||||||
filename: 'extension.js',
|
filename: "extension.js",
|
||||||
libraryTarget: 'commonjs2',
|
libraryTarget: "commonjs2",
|
||||||
path: path.resolve(process.cwd(), 'dist'),
|
path: path.resolve(process.cwd(), "dist"),
|
||||||
},
|
},
|
||||||
devtool: 'source-map',
|
devtool: "source-map",
|
||||||
externals: {
|
externals: {
|
||||||
vscode: 'commonjs vscode',
|
vscode: "commonjs vscode",
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['.ts', '.js', '.json'],
|
extensions: [".ts", ".js", ".json"],
|
||||||
},
|
},
|
||||||
plugins: [new CleanWebpackPlugin()],
|
plugins: [new CleanWebpackPlugin()],
|
||||||
optimization: {
|
optimization: {
|
||||||
|
@ -42,7 +42,7 @@ module.exports = {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.ts$/,
|
test: /\.ts$/,
|
||||||
use: 'ts-loader',
|
use: "ts-loader",
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue