(vault: string, args: ParsedArgs)
| 47 | } |
| 48 | |
| 49 | export async function cmdOpen(vault: string, args: ParsedArgs): Promise<void> { |
| 50 | if (args.positionals.length === 0) { |
| 51 | throw new Error('zn open needs a file path. Usage: zn open <file.md> [more.md ...]') |
| 52 | } |
| 53 | |
| 54 | let absPaths: string[] = [] |
| 55 | let unresolved: string | null = null |
| 56 | |
| 57 | for (const target of args.positionals) { |
| 58 | const abs = await resolveTarget(vault, target) |
| 59 | if (!abs) { |
| 60 | unresolved = target |
| 61 | break |
| 62 | } |
| 63 | absPaths.push(abs) |
| 64 | } |
| 65 | |
| 66 | if (unresolved !== null) { |
| 67 | // An unquoted path with spaces arrives as several tokens — re-join |
| 68 | // everything and try once more as a single file before giving up. |
| 69 | const joined = args.positionals.join(' ') |
| 70 | const abs = args.positionals.length > 1 ? await resolveTarget(vault, joined) : null |
| 71 | if (abs) { |
| 72 | absPaths = [abs] |
| 73 | } else { |
| 74 | const locations = [path.resolve(unresolved), vault ? path.resolve(vault, unresolved) : null] |
| 75 | .filter((location): location is string => location !== null) |
| 76 | .join(' or ') |
| 77 | const hint = |
| 78 | args.positionals.length > 1 ? ` (also tried as one path: ${JSON.stringify(joined)})` : '' |
| 79 | throw new Error(`No such file: ${unresolved} (looked in ${locations})${hint}`) |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | for (const abs of absPaths) assertMarkdown(abs) |
| 84 | |
| 85 | // Re-launch our own binary in GUI mode. The CLI wrapper set |
| 86 | // ELECTRON_RUN_AS_NODE so this process runs as plain Node, so we must |
| 87 | // drop it for the child or it would start as Node too instead of the app. |
| 88 | const env = { ...process.env } |
| 89 | delete env.ELECTRON_RUN_AS_NODE |
| 90 | const child = spawn(process.execPath, absPaths, { |
| 91 | detached: true, |
| 92 | stdio: 'ignore', |
| 93 | env |
| 94 | }) |
| 95 | child.unref() |
| 96 | |
| 97 | emitOk( |
| 98 | absPaths.length === 1 |
| 99 | ? `Opening ${absPaths[0]} in ZenNotes` |
| 100 | : `Opening ${absPaths.length} files in ZenNotes` |
| 101 | ) |
| 102 | } |
no test coverage detected