Skip to content

fix: support absolute paths in Output and Screenshot commands#742

Open
tmchow wants to merge 1 commit intocharmbracelet:mainfrom
tmchow:fix/741-output-absolute-paths
Open

fix: support absolute paths in Output and Screenshot commands#742
tmchow wants to merge 1 commit intocharmbracelet:mainfrom
tmchow:fix/741-output-absolute-paths

Conversation

@tmchow
Copy link
Copy Markdown

@tmchow tmchow commented Apr 4, 2026

Summary

Output /tmp/demo.gif fails with parser errors because the lexer treats / as a regex delimiter. The path /tmp/demo.gif tokenizes as REGEX("tmp") + STRING("demo.gif") instead of a single path token, and parseOutput() rejects the unexpected REGEX.

This also breaks the template that vhs new generates, which uses an absolute Output path.

Fixes #741

Root Cause

In lexer/lexer.go, case '/' always creates a REGEX token via readRegex('/'). The parser expects STRING after Output but sees REGEX, producing: "Expected file path after output."

The fix is in the parser, not the lexer. The / character is genuinely ambiguous (regex vs path), but the parser knows the context: after Output/Screenshot, a path is expected. After Wait, a regex is expected.

Changes

Added parsePathArgument() in parser/parser.go that accepts both STRING tokens (relative paths, existing behavior) and REGEX + STRING sequences (absolute paths like /tmp/demo.gif). Both parseOutput() and parseScreenshot() use this shared helper.

Testing

Added TestParseAbsolutePaths covering:

  • Output /tmp/demo.gif (absolute GIF)
  • Output /tmp/demo.mp4 (absolute MP4)
  • Output /home/user/recordings/demo.webm (deep absolute path)
  • Output /frames/ (absolute directory output)
  • Output examples/out.gif (relative path, unchanged)
  • Output frames/ (relative directory, unchanged)
  • Screenshot /tmp/screenshot.png (absolute screenshot)
  • Screenshot examples/screenshot.png (relative screenshot, unchanged)

All 51 existing tests pass. go vet and gofumpt clean.

Before

$ vhs new test.tape && vhs test.tape

 60 │ Output /tmp/test.gif
      ^^^^^^ Expected file path after output
 60 │ Output /tmp/test.gif
             ^^^ Invalid command: tmp

parser: 3 error(s)

After

$ vhs new test.tape && vhs test.tape
Creating /tmp/test.gif...

Note: This contribution was developed with AI assist w/ Codex.

Compound Engineering

The lexer treats `/` as a regex delimiter, so `Output /tmp/demo.gif`
tokenizes as REGEX("tmp") + STRING("demo.gif") and the parser rejects
it. This also breaks the `vhs new` template which generates absolute
Output paths.

Add a shared parsePathArgument helper that reconstructs absolute paths
from the REGEX + STRING token sequence when the parser expects a file
path. Relative paths still use the existing STRING token path.

Fixes charmbracelet#741

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tmchow tmchow requested a review from a team as a code owner April 4, 2026 05:43
@tmchow tmchow requested review from aymanbagabas and meowgorithm and removed request for a team April 4, 2026 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Output command fails to parse absolute file paths

1 participant