Skip to content

Commit

Permalink
extension: Show StyLua version in status bar item
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnnyMorganz committed Dec 30, 2023
1 parent 7e4d214 commit 2cf5e80
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 41 deletions.
2 changes: 2 additions & 0 deletions stylua-vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ To view the changelog of the StyLua binary, see [here](https://github.com/Johnny
- Added configuration option `stylua.configPath` to provide a direct path to a `stylua.toml` file. Note: this will override any workspace config lookup
- Added configuration option `stylua.verify` to pass `--verify` to StyLua CLI when formatting a file. This enforces output verification
- Added command `StyLua: Select Version` to customize which version of StyLua to install. This command updates the `stylua.targetReleaseVersion` setting
- Added a new language status bar item to display StyLua information
- Current StyLua version will now be shown in the status bar item

### Changed

Expand Down
45 changes: 34 additions & 11 deletions stylua-vscode/src/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,45 @@ import { createWriteStream } from "fs";
import { executeStylua } from "./stylua";
import { GitHub, GitHubRelease } from "./github";

interface StyluaInfo {
path: string;
version: string | undefined;
}

const getStyluaVersion = async (path: string, cwd?: string) => {
try {
const currentVersion = (
await executeStylua(path, ["--version"], cwd)
)?.trim();
return currentVersion.substring("stylua ".length);
} catch (err) {
return undefined;
}
};

export class StyluaDownloader {
constructor(
private readonly storageDirectory: vscode.Uri,
private readonly github: GitHub
) {}

public async ensureStyluaExists(cwd?: string): Promise<string | undefined> {
public async ensureStyluaExists(
cwd?: string
): Promise<StyluaInfo | undefined> {
const path = await this.getStyluaPath();

if (path === undefined) {
await vscode.workspace.fs.createDirectory(this.storageDirectory);
await this.downloadStyLuaVisual(util.getDesiredVersion());
return await this.getStyluaPath();
const path = await this.getStyluaPath();
if (path) {
return {
path,
version: await getStyluaVersion(path),
};
} else {
return;
}
} else {
if (!(await util.fileExists(path))) {
vscode.window.showErrorMessage(
Expand All @@ -27,22 +53,19 @@ export class StyluaDownloader {
return;
}

const currentVersion = await getStyluaVersion(path);

if (
!vscode.workspace.getConfiguration("stylua").get("disableVersionCheck")
) {
try {
const currentVersion = (
await executeStylua(path, ["--version"], cwd)
)?.trim();
const desiredVersion = util.getDesiredVersion();
const release = await this.github.getRelease(desiredVersion);
if (
currentVersion !==
`stylua ${
release.tagName.startsWith("v")
? release.tagName.substr(1)
: release.tagName
}`
(release.tagName.startsWith("v")
? release.tagName.substr(1)
: release.tagName)
) {
this.openUpdatePrompt(release);
}
Expand All @@ -65,7 +88,7 @@ export class StyluaDownloader {
}
}

return path;
return { path, version: currentVersion };
}
}

Expand Down
97 changes: 67 additions & 30 deletions stylua-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { GitHub } from "./github";
import { StyluaDownloader } from "./download";
import { getDesiredVersion } from "./util";

const documentSelector = ["lua", "luau"];

/**
* Convert a Position within a Document to a byte offset.
* Required as `document.offsetAt(position)` returns a char offset, causing inconsistencies when sending over to StyLua
Expand All @@ -23,6 +25,55 @@ const byteOffset = (
return Buffer.byteLength(text);
};

class StatusInfo implements vscode.Disposable {
statusItem: vscode.LanguageStatusItem;
version: string | undefined;

constructor() {
this.statusItem = vscode.languages.createLanguageStatusItem(
"stylua",
documentSelector
);
this.statusItem.name = "StyLua";
this.statusItem.command = {
title: "Show Output",
command: "stylua.showOutputChannel",
};
this.updateReady();
}

setVersion(version: string | undefined) {
this.version = version;
this.updateReady();
}

getStyluaText() {
return this.version ? `StyLua (${this.version})` : "StyLua";
}

updateReady() {
this.statusItem.text = `$(check) ${this.getStyluaText()}`;
this.statusItem.detail = "Ready";
this.statusItem.severity = vscode.LanguageStatusSeverity.Information;
}

updateFormatSuccess() {
this.statusItem.text = `$(check) ${this.getStyluaText()}`;
this.statusItem.detail = "File formatted successfully";
this.statusItem.severity = vscode.LanguageStatusSeverity.Information;
}

updateFormatFailure() {
this.statusItem.text = `${this.getStyluaText()}`;
this.statusItem.detail = "Failed to format file";
this.statusItem.severity = vscode.LanguageStatusSeverity.Error;
}

dispose() {
this.statusItem.dispose();
}
}

export async function activate(context: vscode.ExtensionContext) {
console.log("stylua activated");

Expand All @@ -31,6 +82,7 @@ export async function activate(context: vscode.ExtensionContext) {
});
outputChannel.info("StyLua activated");

const statusItem = new StatusInfo();
const github = new GitHub();
context.subscriptions.push(github);

Expand All @@ -39,13 +91,18 @@ export async function activate(context: vscode.ExtensionContext) {
let cwdForVersionDetection =
vscode.workspace.workspaceFolders?.[0].uri.fsPath;

let styluaBinaryPath: string | undefined =
await downloader.ensureStyluaExists(cwdForVersionDetection);
let styluaBinaryPath = await downloader.ensureStyluaExists(
cwdForVersionDetection
);
statusItem.setVersion(styluaBinaryPath?.version);

context.subscriptions.push(
vscode.commands.registerCommand("stylua.reinstall", async () => {
await downloader.downloadStyLuaVisual(getDesiredVersion());
styluaBinaryPath = await downloader.getStyluaPath();
styluaBinaryPath = await downloader.ensureStyluaExists(
cwdForVersionDetection
);
statusItem.setVersion(styluaBinaryPath?.version);
})
);

Expand Down Expand Up @@ -90,7 +147,7 @@ export async function activate(context: vscode.ExtensionContext) {
const updateConfigValue = selectedVersion.label.includes("latest")
? "latest"
: selectedVersion.label;
await downloader.downloadStyLuaVisual(selectedVersion.label);
await downloader.downloadStyLuaVisual(updateConfigValue);
vscode.workspace
.getConfiguration("stylua")
.update(
Expand All @@ -108,24 +165,11 @@ export async function activate(context: vscode.ExtensionContext) {
styluaBinaryPath = await downloader.ensureStyluaExists(
cwdForVersionDetection
);
statusItem.setVersion(styluaBinaryPath?.version);
}
})
);

const documentSelector = ["lua", "luau"];

const languageStatusItem = vscode.languages.createLanguageStatusItem(
"stylua",
documentSelector
);
languageStatusItem.name = "StyLua";
languageStatusItem.text = "$(check) StyLua";
languageStatusItem.detail = "Ready";
languageStatusItem.command = {
title: "Show Output",
command: "stylua.showOutputChannel",
};

let disposable = vscode.languages.registerDocumentRangeFormattingEditProvider(
documentSelector,
{
Expand Down Expand Up @@ -162,7 +206,7 @@ export async function activate(context: vscode.ExtensionContext) {

try {
const formattedText = await formatCode(
styluaBinaryPath,
styluaBinaryPath.path,
text,
cwd,
byteOffset(document, range.start),
Expand All @@ -180,15 +224,10 @@ export async function activate(context: vscode.ExtensionContext) {
fullDocumentRange,
formattedText
);
languageStatusItem.text = "$(check) StyLua";
languageStatusItem.detail = "File formatted successfully";
languageStatusItem.severity =
vscode.LanguageStatusSeverity.Information;
statusItem.updateFormatSuccess();
return [format];
} catch (err) {
languageStatusItem.text = "StyLua";
languageStatusItem.detail = "Failed to format file";
languageStatusItem.severity = vscode.LanguageStatusSeverity.Error;
statusItem.updateFormatFailure();
outputChannel.error(err as string);
return [];
}
Expand All @@ -197,12 +236,10 @@ export async function activate(context: vscode.ExtensionContext) {
);

context.subscriptions.push(disposable);
context.subscriptions.push(languageStatusItem);
context.subscriptions.push(statusItem);
context.subscriptions.push(
vscode.window.onDidChangeActiveTextEditor((editor) => {
languageStatusItem.text = "$(check) StyLua";
languageStatusItem.detail = "Ready";
languageStatusItem.severity = vscode.LanguageStatusSeverity.Information;
statusItem.updateReady();
})
);
}
Expand Down

0 comments on commit 2cf5e80

Please sign in to comment.