#191 consistently open terminal in mac

This commit is contained in:
neil 2023-02-11 09:19:35 +08:00
parent 1ca78c9613
commit 018e049716
2 changed files with 57 additions and 27 deletions

View file

@ -1,8 +1,8 @@
import { spawn, exec } from 'child_process';
import { spawn } from 'child_process';
import { clean } from 'semver';
import { promisify } from 'util';
const execPromise = promisify(exec);
import { getGuiPath } from './teaDir';
import fs from 'fs';
import path from 'path';
export async function installPackage(full_name: string) {
return await new Promise((resolve, reject) => {
@ -32,33 +32,59 @@ export async function installPackage(full_name: string) {
}
export async function openTerminal(cmd: string) {
let scriptPath = '';
try {
// TODO SECURITY: escape the cmd if possible or create whitelist of acceptable commands
return await exec(open(cmd));
scriptPath = await createCommandScriptFile(cmd);
let stdout = ``;
let stderr = ``;
await new Promise((resolve, reject) => {
const child = spawn('/usr/bin/osascript', [scriptPath]);
child.stdout.on('data', (data) => {
stdout += data.toString().trim();
});
child.stderr.on('data', (data) => {
stderr += data.toString().trim();
});
child.on('exit', () => {
console.log('exit:', stdout);
resolve(stdout);
});
child.on('error', () => {
reject(new Error(stderr));
});
});
} catch (error) {
console.error('root:', error);
} finally {
if (scriptPath) await fs.unlinkSync(scriptPath);
}
}
const open = (cmd) => `osascript -e '
if application "iTerm" is running then
tell application "iTerm"
tell current window
create tab with default profile
tell current session
write text "${cmd.replace(/"/g, '\\"')}"
end tell
end tell
end tell
else
activate application "iTerm"
delay 3
tell application "iTerm"
tell current window
tell current session
write text "${cmd.replace(/"/g, '\\"')}"
end tell
end tell
end tell
end if
'`;
const createCommandScriptFile = async (cmd: string): Promise<string> => {
const guiFolder = getGuiPath();
const tmpFilePath = path.join(guiFolder, `${+new Date()}.scpt`);
const command = `"${cmd.replace(/"/g, '\\"')}"`;
const script = `
tell application "iTerm"
activate
if application "iTerm" is running then
try
tell the first window to create tab with default profile
on error
create window with default profile
end try
end if
delay 0.1
tell the first window to tell current session to write text ${command}
end tell
`.trim();
await fs.writeFileSync(tmpFilePath, script, 'utf-8');
return tmpFilePath;
};

View file

@ -16,6 +16,10 @@ export const getTeaPath = () => {
return teaPath;
};
export const getGuiPath = () => {
return path.join(getTeaPath(), 'tea.xyz/gui');
};
export async function getInstalledPackages() {
const pkgsPath = getTeaPath();