# SPDX-FileCopyrightText: ☭ 2022 Emery Hemingway # SPDX-License-Identifier: Unlicense import std/[asyncdispatch, deques, re, streams, strutils, osproc] import preserves import syndicate import ./protocol bootDataspace("main") do (root: Ref; turn: var Turn): var actions: seq[tuple[regex: Regex; cmd: string; args: seq[string]]] children: Deque[Process] connectStdio(root, turn) onPublish(turn, root, ?ActionHandler) do (pat: string; cmd: seq[string]): # TODO: during if cmd.len < 2: stderr.writeLine "ignoring ", $cmd, " for ", pat else: var act = (re(pat, {reIgnoreCase, reStudy}), cmd[0], cmd[1..cmd.high],) actions.add act onPublish(turn, root, ?ListenOn[Ref]) do (a: Assertion): let ds = unembed a onMessage(turn, ds, ?XdgOpen) do (uris: seq[string]): while children.len > 0 and not children.peekFirst.running: var child = children.popFirst() if child.peekExitCode != 0: stderr.writeLine child.errorStream.readAll close child # TODO check children on a timer? for uri in uris: var matched: bool for act in actions: if match(uri, act.regex): matched = true var args = newSeq[string](act.args.len) for i, arg in act.args: args[i] = replace(arg, "\\1", uri) var child = startProcess( command = act.cmd, args = args, options = {}) children.addLast child if not matched: stderr.writeLine "no actions matched for ", uri runForever()