diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73e0b53..2560237 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,8 @@ env: CARGO_TERM_COLOR: always jobs: - version-badge: - name: Version Badge + version-check: + name: Version Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -26,6 +26,29 @@ jobs: exit 1 fi echo "Version badge matches: $CARGO_VERSION" + - name: Check demo GIF matches Cargo.toml version + run: | + CARGO_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') + DEMO_FILE="demo/demo-${CARGO_VERSION}.gif" + if [ ! -f "$DEMO_FILE" ]; then + echo "Demo GIF missing: $DEMO_FILE" + echo "Run: ./demo/generate.sh" + exit 1 + fi + # Check only one demo GIF exists + DEMO_COUNT=$(find demo -name 'demo-*.gif' | wc -l) + if [ "$DEMO_COUNT" -ne 1 ]; then + echo "Expected exactly 1 demo GIF, found $DEMO_COUNT:" + find demo -name 'demo-*.gif' + echo "Remove old demo files before committing" + exit 1 + fi + # Check README references the correct demo + if ! grep -q "demo/demo-${CARGO_VERSION}.gif" README.md; then + echo "README does not reference demo/demo-${CARGO_VERSION}.gif" + exit 1 + fi + echo "Demo version matches: $CARGO_VERSION" check: name: Check diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml new file mode 100644 index 0000000..5d8d670 --- /dev/null +++ b/.github/workflows/demo.yml @@ -0,0 +1,79 @@ +name: Demo + +on: + pull_request: + branches: + - main + +permissions: + contents: write + +jobs: + generate-demo: + name: Generate Demo + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check if demo needs regeneration + id: check + run: | + VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/') + DEMO_FILE="demo/demo-${VERSION}.gif" + if [ -f "$DEMO_FILE" ]; then + echo "Demo already exists for version $VERSION" + echo "needs_regen=false" >> $GITHUB_OUTPUT + else + echo "Demo missing for version $VERSION" + echo "needs_regen=true" >> $GITHUB_OUTPUT + echo "version=$VERSION" >> $GITHUB_OUTPUT + fi + + - name: Install dependencies + if: steps.check.outputs.needs_regen == 'true' + run: | + sudo apt-get update + sudo apt-get install -y ffmpeg ttyd + + - name: Install vhs + if: steps.check.outputs.needs_regen == 'true' + run: | + curl -fsSL -o vhs.deb https://github.com/charmbracelet/vhs/releases/download/v0.10.0/vhs_0.10.0_amd64.deb + sudo dpkg -i vhs.deb + + - name: Install Rust + if: steps.check.outputs.needs_regen == 'true' + uses: dtolnay/rust-toolchain@stable + + - name: Build f + if: steps.check.outputs.needs_regen == 'true' + run: cargo build --release -p f + + - name: Generate demo + if: steps.check.outputs.needs_regen == 'true' + run: | + VERSION=${{ steps.check.outputs.version }} + export PATH="$PWD/target/release:$PATH" + + # Remove old demos + rm -f demo/demo-*.gif + + # Generate new demo + cd demo + vhs demo.tape -o "demo-${VERSION}.gif" + + # Update README + cd .. + sed -i "s|demo/demo-[0-9]*\.[0-9]*\.[0-9]*\.gif|demo/demo-${VERSION}.gif|g" README.md + + - name: Commit and push + if: steps.check.outputs.needs_regen == 'true' + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add demo/*.gif README.md + git commit -m "Generate demo for v${{ steps.check.outputs.version }}" + git push diff --git a/README.md b/README.md index 2602e28..1933549 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ A keyboard-driven git file manager for the terminal. +![demo](demo/demo-0.1.0.gif) + ## The Problem When working with git, common workflows like staging files, viewing diffs, and editing changed files require typing full file paths repeatedly. Tab completion helps, but with many changed files it's still slow. diff --git a/crates/f/src/f.rs b/crates/f/src/f.rs index a1bf764..7d9affa 100644 --- a/crates/f/src/f.rs +++ b/crates/f/src/f.rs @@ -140,7 +140,13 @@ fn exec_git(args: &[&str]) -> ! { fn exec_editor(path: &str, config: &Config) -> ! { let editor = get_editor(config); - let err = Command::new(&editor).arg(path).exec(); + // Run through shell to support EDITOR with arguments (e.g., "vim -u NONE") + let err = Command::new("sh") + .arg("-c") + .arg(format!("{} \"$1\"", editor)) + .arg("sh") // $0 + .arg(path) // $1 + .exec(); eprintln!("Failed to exec {}: {}", editor, err); process::exit(1); } @@ -512,7 +518,12 @@ mod interactive { } 'e' => { let editor = config.editor(); - let _ = Command::new(&editor).arg(&file.abs_path).exec(); + let _ = Command::new("sh") + .arg("-c") + .arg(format!("{} \"$1\"", editor)) + .arg("sh") + .arg(&file.abs_path) + .exec(); } _ => {} } diff --git a/demo/demo-0.1.0.gif b/demo/demo-0.1.0.gif new file mode 100644 index 0000000..ba132c2 Binary files /dev/null and b/demo/demo-0.1.0.gif differ diff --git a/demo/demo.tape b/demo/demo.tape new file mode 100644 index 0000000..3a674db --- /dev/null +++ b/demo/demo.tape @@ -0,0 +1,142 @@ +# VHS Demo Tape for f +# Run with: vhs demo/demo.tape + +Output demo.gif +Output demo.ascii +Set FontSize 16 +Set Width 900 +Set Height 500 +Set Theme "Catppuccin Mocha" +Set TypingSpeed 50ms + +# Setup: create a temp git repo with some changes +Hide +Type "export PS1='> '" +Enter +Sleep 100ms +Type "cd $(mktemp -d)" +Enter +Sleep 100ms +Type "git init -q && git config user.email 'demo@example.com' && git config user.name 'Demo'" +Enter +Sleep 100ms +Type "echo 'hello' > greeting.txt" +Enter +Type "git add . && git commit -q -m 'init'" +Enter +Sleep 100ms +Type "echo 'hello world' > greeting.txt" +Enter +Type "echo 'new file' > notes.txt" +Enter +Type "echo 'config' > config.toml" +Enter +Type "git add config.toml" +Enter +Sleep 100ms +Type "clear" +Enter +Sleep 300ms +Show + +# Demo: List changed files +Type "# List changed files with stable IDs" +Enter +Sleep 500ms +Type "f" +Enter +Sleep 2s + +Type "clear" +Enter +Sleep 300ms + +# Demo: View diff by ID +Type "# View diff for a file" +Enter +Sleep 500ms +Type "f d d" +Enter +Sleep 2s + +Type "clear" +Enter +Sleep 300ms + +# Demo: Edit file by ID +Type "# Edit a file in $EDITOR" +Enter +Sleep 500ms +Type "export EDITOR='vi -u NONE'" +Enter +Sleep 300ms +Type "f d e" +Enter +Sleep 1s +# vim: Go to end, open line above, type, save +Type "G" +Sleep 300ms +Type "o" +Sleep 300ms +Type "some changes here" +Sleep 500ms +Escape +Sleep 300ms +Type ":wq" +Enter +Sleep 1s + +# Show status after edit +Type "f" +Enter +Sleep 2s + +Type "clear" +Enter +Sleep 300ms + +# Demo: Stage a file using ID +Type "# Stage a file by ID" +Enter +Sleep 500ms +Type "f d a" +Enter +Sleep 1s + +# Show updated status +Type "f" +Enter +Sleep 2s + +Type "clear" +Enter +Sleep 300ms + +# Demo: Stage remaining files +Type "# Stage another file (autoselect top of list)" +Enter +Sleep 500ms +Type "f a" +Enter +Sleep 1s + +Type "f" +Enter +Sleep 2s + +Type "clear" +Enter +Sleep 300ms + +# Demo: Commit +Type "# Commit staged changes" +Enter +Sleep 500ms +Type "f c update greeting and add notes" +Enter +Sleep 1s + +# Final status +Type "f" +Enter +Sleep 2s diff --git a/demo/generate.sh b/demo/generate.sh new file mode 100755 index 0000000..2b40b78 --- /dev/null +++ b/demo/generate.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Get version from Cargo.toml +VERSION=$(grep '^version = ' "$PROJECT_ROOT/Cargo.toml" | head -1 | sed 's/version = "\(.*\)"/\1/') + +if [[ -z "$VERSION" ]]; then + echo "Error: Could not extract version from Cargo.toml" + exit 1 +fi + +OUTPUT_FILE="$SCRIPT_DIR/demo-${VERSION}.gif" + +echo "Generating demo for version $VERSION..." +echo "Output: $OUTPUT_FILE" + +# Remove old demo GIFs +find "$SCRIPT_DIR" -name 'demo-*.gif' -delete 2>/dev/null || true + +# Build the project first so demo uses current version +cargo build --release -p f --quiet + +# Add to PATH for vhs +export PATH="$PROJECT_ROOT/target/release:$PATH" + +# Generate the demo +cd "$SCRIPT_DIR" +vhs demo.tape -o "demo-${VERSION}.gif" + +# Update README to reference new demo +sed -i "s|demo/demo-[0-9]*\.[0-9]*\.[0-9]*\.gif|demo/demo-${VERSION}.gif|g" "$PROJECT_ROOT/README.md" + +echo "Demo generated: $OUTPUT_FILE" +echo "README.md updated to reference demo/demo-${VERSION}.gif"