Skip to content

feat: file browser for Import and Export Config - #663

Open
harishkarthiktk wants to merge 1 commit into
sirmalloc:mainfrom
harishkarthiktk:feat-import-file-picker
Open

harishkarthiktk wants to merge 1 commit into
sirmalloc:mainfrom
harishkarthiktk:feat-import-file-picker

Conversation

@harishkarthiktk

Copy link
Copy Markdown
Contributor

Import and Export Config used to be bare text fields: the full path had to be typed exactly, pasted paths with quotes failed, relative paths silently resolved against the launch directory, and export would quietly mkdir -p the target folder and overwrite any existing file.

Therefore, I wanted a simple file picker for the import and export options.

Both dialogs now use an arrow-key file browser built on ink-file-picker (pinned to 0.3.2, bundled like the other dev dependencies).

Import

  • Opens in the launch directory and lists folders plus .json files (case-insensitive). Enter opens a folder or picks a file; Left / Backspace goes up; typing filters.
  • Ctrl+T switches to a typed-path bar pre-filled with the current folder; a folder path jumps the browser there. Ctrl+O toggles hidden files.

Export

  • Same browser plus an editable "File name:" field, starting in ~ with ccstatusline-config.json. Tab moves between list and name field, Ctrl+S saves into the current folder, Enter on an existing .json targets it, and Ctrl+T types a full path. ".json" is appended when missing; empty names, path separators, NUL bytes and names over 255 bytes get an inline error.
  • Writing is now explicit: an existing file asks "Overwrite it?" (naming the real file when the target is a symlink), a missing folder asks "Create it and export?", and dangling symlinks, devices and pipes are refused. exportConfig takes { createDir, overwrite } and writes with the 'wx' flag unless the overwrite was confirmed, so a file that appears between the check and the write is never clobbered. A declined prompt or any failure returns to the dialog with folder and name kept.

Implementation

  • Library patch (patches/[email protected], registered in patchedDependencies): the list container had no flexDirection, so Ink laid entries out in one truncated row. The patch also makes the focus marker configurable, labels the header "Folder:", fixes the filter-mode footer text, and types theme as partial overrides to match the runtime merge.
  • src/tui/components/file-picker-common.tsx holds the shared theme (green ▶ like the other menus), a [Key] action hint bar matching the library footer, the .json filter and path helpers.
  • The dialogs only report a chosen path. App resolves it and classifies it with the pure helpers in src/utils/export-target.ts, then runs the confirm flows. Extra shortcuts use Ctrl combos because the picker treats every printable key as type-ahead. Both dialogs guard against double submission, and the confirm action ignores a second Yes.
  • normalizeImportPath is renamed normalizeUserPath (trim, strip quotes, expand ~, resolve) and is used by both directions.

Tests: new ImportConfigDialog, ExportConfigDialog and export-target suites, plus config tests for path normalization and the new export options. Lint is clean and the full suite passes.

bun.lock also picks up bun's dedupe of @typescript-eslint 8.67 -> 8.70 (dev-only lint tooling).

Import and Export Config used to be bare text fields: the full path had
to be typed exactly, pasted paths with quotes failed, relative paths
silently resolved against the launch directory, and export would quietly
mkdir -p the target folder and overwrite any existing file.

Both dialogs now use an arrow-key file browser built on ink-file-picker
(pinned to 0.3.2, bundled like the other dev dependencies).

Import
- Opens in the launch directory and lists folders plus .json files
  (case-insensitive). Enter opens a folder or picks a file; Left /
  Backspace goes up; typing filters.
- Ctrl+T switches to a typed-path bar pre-filled with the current
  folder; a folder path jumps the browser there. Ctrl+O toggles hidden
  files.

Export
- Same browser plus an editable "File name:" field, starting in ~ with
  ccstatusline-config.json. Tab moves between list and name field,
  Ctrl+S saves into the current folder, Enter on an existing .json
  targets it, and Ctrl+T types a full path. ".json" is appended when
  missing; empty names, path separators, NUL bytes and names over 255
  bytes get an inline error.
- Writing is now explicit: an existing file asks "Overwrite it?" (naming
  the real file when the target is a symlink), a missing folder asks
  "Create it and export?", and dangling symlinks, devices and pipes are
  refused. exportConfig takes { createDir, overwrite } and writes with
  the 'wx' flag unless the overwrite was confirmed, so a file that
  appears between the check and the write is never clobbered. A declined
  prompt or any failure returns to the dialog with folder and name kept.

Implementation
- Library patch (patches/[email protected], registered in
  patchedDependencies): the list container had no flexDirection, so Ink
  laid entries out in one truncated row. The patch also makes the focus
  marker configurable, labels the header "Folder:", fixes the
  filter-mode footer text, and types `theme` as partial overrides to
  match the runtime merge.
- src/tui/components/file-picker-common.tsx holds the shared theme
  (green ▶ like the other menus), a [Key] action hint bar matching the
  library footer, the .json filter and path helpers.
- The dialogs only report a chosen path. App resolves it and classifies
  it with the pure helpers in src/utils/export-target.ts, then runs the
  confirm flows. Extra shortcuts use Ctrl combos because the picker
  treats every printable key as type-ahead. Both dialogs guard against
  double submission, and the confirm action ignores a second Yes.
- normalizeImportPath is renamed normalizeUserPath (trim, strip quotes,
  expand ~, resolve) and is used by both directions.

Tests: new ImportConfigDialog, ExportConfigDialog and export-target
suites, plus config tests for path normalization and the new export
options. Lint is clean and the full suite passes.

bun.lock also picks up bun's dedupe of @typescript-eslint 8.67 -> 8.70
(dev-only lint tooling).
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.

1 participant