diff options
Diffstat (limited to 'idatui/pane.py')
| -rw-r--r-- | idatui/pane.py | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/idatui/pane.py b/idatui/pane.py index e34b822..53afef3 100644 --- a/idatui/pane.py +++ b/idatui/pane.py @@ -131,15 +131,20 @@ def spawn(args) -> int: if not os.environ.get("TMUX"): print("error: not inside tmux (spawn creates a tmux pane)", file=sys.stderr) return 2 - if not args.open: - print("error: pass --open <binary>", file=sys.stderr) + if not args.open and not getattr(args, "project", None): + print("error: pass --open <binary> or --project <file>", file=sys.stderr) return 2 sock = args.sock or os.path.join(_sockdir(), f"idatui-{secrets.token_hex(3)}.sock") - target = os.path.abspath(os.path.expanduser(args.open)) - if not os.path.exists(target): + project = (os.path.abspath(os.path.expanduser(args.project)) + if getattr(args, "project", None) else None) + target = os.path.abspath(os.path.expanduser(args.open)) if args.open else None + if target is not None and not os.path.exists(target): print(f"error: no such binary: {target}", file=sys.stderr) return 2 + if project is not None and target is None and not os.path.exists(project): + print(f"error: no such project: {project}", file=sys.stderr) + return 2 # Reap workers leaked by previously-stopped/crashed panes so we don't spawn # into a full IDA_MCP_MAX_WORKERS (which makes the new TUI hang forever, @@ -151,7 +156,15 @@ def spawn(args) -> int: # the command the pane runs: the launcher spawns a private idalib worker for # this binary and becomes the TUI, so kill-pane tears the whole thing down. - inner = [args.python, "-m", "idatui.launch", target, "--rpc", sock] + if project is not None: + # launch takes: --project FILE [binaries...]; extra binaries are added to + # the project (and a missing project file is created from them). + inner = [args.python, "-m", "idatui.launch", "--project", project] + if target is not None: + inner.append(target) + inner += ["--rpc", sock] + else: + inner = [args.python, "-m", "idatui.launch", target, "--rpc", sock] cmd = f"cd {REPO!r} && exec " + " ".join(_q(a) for a in inner) split = ["split-window", "-v" if args.vertical else "-h", @@ -166,8 +179,8 @@ def spawn(args) -> int: split.append(cmd) pane = _tmux(*split) - row = {"sock": sock, "pane": pane, "target": target, - "kind": "open", "started": time.time()} + row = {"sock": sock, "pane": pane, "target": project or target, + "kind": "project" if project else "open", "started": time.time()} reg = [r for r in _load_registry() if r.get("sock") != sock] reg.append(row) _save_registry(reg) @@ -301,8 +314,11 @@ def main(argv: list[str]) -> int: sub = p.add_subparsers(dest="cmd", required=True) sp = sub.add_parser("spawn", help="open a TUI pane and wait until ready") - sp.add_argument("--open", metavar="PATH", required=True, + sp.add_argument("--open", metavar="PATH", help="binary to open (its dir must be writable)") + sp.add_argument("--project", metavar="FILE", + help="project file to open instead of a single binary; " + "any --open paths are added to it (created if absent)") sp.add_argument("--sock", help="RPC socket path (default: auto in $XDG_RUNTIME_DIR)") sp.add_argument("--python", default=DEFAULT_PY, help=f"python for the TUI ({DEFAULT_PY})") sp.add_argument("--vertical", action="store_true", help="split vertically (stacked)") |
