From 0a206ebd8d8e7e1a3b2063c12bb153d69efd0be7 Mon Sep 17 00:00:00 2001 From: retrozinndev Date: Sun, 11 May 2025 22:03:51 -0300 Subject: [PATCH] :sparkles: ags(runner/plugins/shell): better shell plugin --- ags/runner/plugins/shell.ts | 69 +++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/ags/runner/plugins/shell.ts b/ags/runner/plugins/shell.ts index ba10df2..89a6a63 100644 --- a/ags/runner/plugins/shell.ts +++ b/ags/runner/plugins/shell.ts @@ -1,18 +1,59 @@ import { ResultWidget, ResultWidgetProps } from "../../widget/runner/ResultWidget"; -import AstalHyprland from "gi://AstalHyprland"; -import { GLib } from "astal"; +import { Gio, GLib } from "astal"; import { Runner } from "../Runner"; +import { Notifications } from "../../scripts/notifications"; -export const PluginShell = { - prefix: '!', - handle: (command: string): ResultWidget => { - const shell = GLib.getenv("SHELL") || "/usr/bin/env sh"; +export const PluginShell = (() => { - return new ResultWidget({ - onClick: () => AstalHyprland.get_default().dispatch("exec", `${shell} -c '${command}'`), - title: `Run: \`${command}\``, - description: shell, - icon: "utilities-terminal-symbolic" - } as ResultWidgetProps) - } -} as Runner.Plugin; + const shell = GLib.getenv("SHELL") ?? "/bin/sh"; + const procLauncher = Gio.SubprocessLauncher.new( + Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE); + + procLauncher.set_cwd(GLib.get_home_dir()); + + return { + prefix: '!', + prioritize: true, + handle: (input: string): ResultWidget => { + let showOutputNotif: boolean = false; + if(input.startsWith('!')) { + input = input.replace('!', ""); + showOutputNotif = true; + } + + const command = input ? GLib.shell_parse_argv(input) : undefined; + + return new ResultWidget({ + onClick: () => { + if(!command || !command[0]) return; + + const proc = procLauncher.spawnv([ shell, "-c", `${input}` ]); + proc.communicate_utf8_async(null, null, (_, asyncResult) => { + const [ success, stdout, stderr ] = proc.communicate_utf8_finish(asyncResult); + + if(!success || stderr) { + Notifications.getDefault().sendNotification({ + appName: shell, + summary: "Command error", + body: `An error occurred on \`${input}\`. Stderr: ${stderr}` + }); + + return; + } + + if(!showOutputNotif) return; + + Notifications.getDefault().sendNotification({ + appName: shell, + summary: "Command output", + body: stdout + }); + }); + }, + title: `Run ${input ? ` \`${input}\`` : `with ${shell.split('/')[shell.split('/').length-1]}`}`, + description: (input || showOutputNotif) && `${input ? `${shell}\t` : ""}${ showOutputNotif ? "(showing output on notification)" : "" }`, + icon: "utilities-terminal-symbolic" + } as ResultWidgetProps) + } + } as Runner.Plugin +})();