Skip to content

feat: open external files from browser via "i" key #178

Description

@oobagi

Problem

Opening external files (e.g. ~/.zshrc, config files) currently requires exiting
the TUI and running notebook ~/.zshrc from the CLI. This breaks flow — the whole
point of the TUI is staying in it.

Context

The plumbing already exists:

  • openFile() in cmd/file.go handles reading, editing, saving, and permission
    preservation for arbitrary files
  • recents.RecordExternal() tracks external files in the Recent section after opening
  • Input mode (startCreate, startRename in browser.go) provides a status-bar
    text prompt pattern with Enter/Esc handling and cursor blink
  • External files already render in recents via format.ShortenHome() and can be
    re-opened from there

The new feature would wire these together: i → input prompt → validate path → open file.

Possible approaches

Approach A: Reuse inputMode directly

  • How: Add startImport() following the startCreate()/startRename() pattern.
    Set inputPrompt = "Open file:", resolve path in inputAction callback, then
    set m.selected with FilePath and quit to the browse loop.
  • Pros: Minimal new code, fully consistent with existing UX
  • Cons: No tab-completion for paths (can be added later)
  • Files: internal/browser/browser.go (key handler + startImport), help overlay

Approach B: Selection-based with path in Selection

  • How: Same as A but instead of opening inline, return a Selection{FilePath: path}
    so the browse.go loop handles opening via existing openFile() path
  • Pros: Keeps editor launch in one place (browse.go), external files return to L0
    correctly via existing FromRecent logic
  • Cons: None significant — this is the cleaner version of A
  • Files: internal/browser/browser.go, cmd/browse.go (already handles FilePath)

Approach B is recommended — it reuses the browse loop's existing external file handling.

Tasks

  • Add startImport() method using the inputMode pattern
  • Bind i key at L0 (confirm unbound — currently unused)
  • In the input action: expand ~, resolve to absolute path, validate file exists
    and is readable, return Selection{FilePath: path, FromRecent: true}
  • Add i Open file to browser help overlay
  • Add test for import flow (input mode → path → selection)

Test plan

  • Press i at L0 → status bar shows "Open file:" prompt
  • Enter valid path (absolute, relative, ~/...) → file opens in editor
  • Save and quit editor → file appears in Recent section
  • Enter nonexistent path → inline error, stays in browser
  • Enter unreadable path → inline error with OS message
  • Esc during prompt → cancels cleanly, no side effects
  • Existing external file re-opening from recents still works

Scope

Type: feature
Size: small

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions