hyper-launch-menu
Version:
Adds ability to launch other shells to hyper
196 lines (168 loc) • 4.25 kB
JavaScript
const process = require('process');
const { execFileSync } = require('child_process');
const fs = require('fs');
exports.detectShells = () => {
switch (process.platform) {
case "win32":
return detectShellsWin();
case "darwin":
return detectShellsMac();
case "linux":
return detectShellsLinux();
default:
return detectShellsUnix();
}
}
/**
* Windows
*/
function detectShellsWin() {
let def = getCmd();
def.default = true;
let shells = [def, getPowerShells()];
let bashes = getWinBash();
if (bashes) shells.push(bashes);
return shells;
}
function getCmd() {
return {
name: "CMD",
shell: process.env.ComSpec || "C:\\Windows\\System32\\cmd.exe",
args: ["--login"]
}
}
function getWinBash() {
let wsl = getWSLBash(); wsl.groupName = "WSL";
let git = getGitBash(); git.groupName = "Git";
return tryGroupList([wsl, git], "Bash")
}
function getGitBash() {
return {
name: "Git Bash",
shell: "C:\\Program Files\\Git\\bin\\bash.exe",
args: ["--login"]
}
}
function getWSLBash() {
return {
name: "WSL Bash",
shell: "C:\\Windows\\System32\\bash.exe",
args: ["--login"]
}
}
function getPowerShells() {
let ps = getPowerShell();
let pscore = getPSCore();
if (exists(pscore)) {
ps.name = "Windows";
pscore.name = "Core";
return {
name: "PowerShell",
group: [ps, pscore]
}
} else {
return ps;
}
}
function getPowerShell() {
return {
name: "PowerShell",
shell: "powershell.exe"
}
}
function getPSCore() {
return {
name: "PS-Core",
shell: "pwsh.exe"
}
}
/**
* Mac
*/
function detectShellsMac() {
// No idea about how Mac works
}
/**
* Linux / UNIX
*/
const defShellsFile = '/etc/shells';
function detectShellsLinux() {
let shells;
try {
shells = readShellsFromFile(defShellsFile)
} catch (error) {
console.log(error);
shells = [getBash(), getSh()]
}
// process.env.SHELL returns the default shell
for (const shell of shells) {
if (shell.shell === process.env.SHELL) {
shell.default = true;
break;
}
}
return shells;
}
// I dont know any Unix and non Linux shell.
// If you do, feel free to add more here.
function detectShellsUnix() {
return detectShellsLinux();
}
function getBash() {
return {
name: "bash",
shell: "/bin/bash"
}
}
function getSh() {
return {
name: "sh",
shell: "/bin/sh"
}
}
/**
* Helper functions
*/
function readShellsFromFile(filename) {
let lines = fs.readFileSync(filename, 'utf-8')
.split('\n')
.filter(line => line && !line.startsWith('#'));
let shells = [];
lines.forEach(line => {
let shell = {};
let index = line.lastIndexOf('/');
if (index >= 0) shell.name = line.slice(index + 1)
shell.shell = line;
shells.push(shell);
});
return shells;
}
function exists(shell) {
try {
execFileSync(shell.shell, shell.args);
return true;
} catch (error) {
return false;
}
}
// If more than one shell exists, makes a group.
// (if it has a groupName, it changes the name with the groupName only if it was made part of a group)
function tryGroupList(list, name) {
let valid = list.map(shell => exists(shell));
let validCount = valid.reduce((count, exists) => exists ? ++count : count, 0);
if (validCount > 1) {
list.forEach(shell => {
if ('groupName' in shell) {
shell.name = shell.groupName;
shell.groupName = undefined;
}
})
return {
name: name,
group: list
}
} else {
let index = valid.findIndex((exists) => exists)
return index < 0 ? null : list[index]
}
}