Skip to content

fix(tui): Fixed a bug that caused tui to be stuck in filepath picker box#395

Merged
junaid2005p merged 1 commit intomainfrom
tui-filepath-bug
Apr 20, 2026
Merged

fix(tui): Fixed a bug that caused tui to be stuck in filepath picker box#395
junaid2005p merged 1 commit intomainfrom
tui-filepath-bug

Conversation

@junaid2005p
Copy link
Copy Markdown
Collaborator

@junaid2005p junaid2005p commented Apr 20, 2026

Greptile Summary

This PR replaces three independent boolean browsing flags (SettingsFileBrowsing, ExtensionFileBrowsing, catMgrFileBrowsing) with a single FilePickerOrigin enum, adds a centralised openDirectoryPicker helper, and ensures focusInput(2) is called on picker return — fixing the root cause of the "stuck in file picker" bug. New tests cover open, cancel, confirm, and root-directory edge cases.

Confidence Score: 5/5

Safe to merge; all remaining findings are minor style suggestions with no correctness impact.

The bug fix is well-targeted: the enum refactor eliminates the flag-management scatter, and adding focusInput(2) on picker dismissal directly addresses the stuck-input regression. Both open code paths and cancel paths are handled symmetrically. The only findings are a P2 implicit default case and a P2 test naming inconsistency — neither affects runtime behaviour.

No files require special attention.

Important Files Changed

Filename Overview
internal/tui/helpers.go Replaces three boolean browsing flags with a FilePickerOrigin switch; adds openDirectoryPicker helper to centralise setup. Logic is correct; FilePickerOriginAdd handled implicitly by default.
internal/tui/model.go Introduces FilePickerOrigin enum and filepickerOrigin field; removes SettingsFileBrowsing, ExtensionFileBrowsing, and catMgrFileBrowsing booleans. Clean structural improvement.
internal/tui/update_filepicker.go Cancel handler migrated to origin-based switch with proper state restoration for all origins including the new default (InputState) path. Correct.
internal/tui/update_input.go Tab on input[2] now calls openDirectoryPicker with FilePickerOriginAdd and preserves the original path for cancel restoration. Fixes the stuck-in-picker regression.
internal/tui/update_settings.go Browse shortcut delegates to openDirectoryPicker(FilePickerOriginSettings). Removes SettingsFileBrowsing flag usage. No issues.
internal/tui/update_category.go Tab on path field delegates to openDirectoryPicker(FilePickerOriginCategory). Removes catMgrFileBrowsing flag usage. No issues.
internal/tui/update_test.go New tests cover the browse-open, esc-cancel, enter-confirm, root-dir-stay-open flows; uses unwrapRootModel helper. Test name TestUpdate_FilePickerUseDirReturnsToAddInput misleadingly uses Enter key instead of the UseDir (.) key.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[InputState / SettingsState / ExtensionState / CategoryState] -->|Tab / Browse key| B[openDirectoryPicker\nsets filepickerOrigin + state=FilePickerState]
    B --> C{FilePickerState}
    C -->|UseDir / Enter selects path| D[handleFilePickerSelection]
    C -->|Escape / Cancel| E[updateFilePicker cancel switch]
    D --> F{filepickerOrigin}
    E --> F
    F -->|OriginSettings| G[SettingsState\nset DefaultDownloadDir]
    F -->|OriginExtension| H[ExtensionConfirmationState\nset inputs2 + focusInput 2]
    F -->|OriginCategory| I[CategoryManagerState\nset catMgrInputs3 + focus]
    F -->|OriginAdd / default| J[InputState\nset inputs2 + focusInput 2]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: internal/tui/helpers.go
Line: 92-98

Comment:
**`FilePickerOriginAdd` silently handled by `default`**

`FilePickerOriginAdd` is defined in the enum but never explicitly cased in this switch (or in the cancel switch in `update_filepicker.go`). It currently falls through to `default`, which is correct, but it means adding a new origin in the future could accidentally inherit the "go to InputState" behaviour without any compile-time signal. An explicit case makes the intent clear and makes the switch exhaustive for all declared origins.

```suggestion
	case FilePickerOriginAdd:
		m.inputs[2].SetValue(path)
		m.focusInput(2)
		m.filepickerOrigin = FilePickerOriginNone
		m.state = InputState
		return m, nil
	default:
		m.inputs[2].SetValue(path)
		m.focusInput(2)
		m.filepickerOrigin = FilePickerOriginNone
		m.state = InputState
		return m, nil
	}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: internal/tui/update_test.go
Line: 956-990

Comment:
**Test name says "UseDir" but tests `Enter`, not the `UseDir` (`.`) key**

The `UseDir` key binding maps to `.` (period) and explicitly selects the current directory via `handleFilePickerSelection`. `Enter` is passed to the underlying filepicker component and relies on `DidSelectFile` returning true — a different code path. Naming the test `UseDirReturnsToAddInput` while sending `KeyEnter` is misleading; consider renaming it to `TestUpdate_FilePickerEnterConfirmsDirReturnsToAddInput` or testing the actual `.` key press to match the name.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(tui): Fixed a bug that caused tui to..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Comment thread internal/tui/helpers.go
Comment on lines +92 to 98
default:
m.inputs[2].SetValue(path)
m.focusInput(2)
m.filepickerOrigin = FilePickerOriginNone
m.state = InputState
return m, nil
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 FilePickerOriginAdd silently handled by default

FilePickerOriginAdd is defined in the enum but never explicitly cased in this switch (or in the cancel switch in update_filepicker.go). It currently falls through to default, which is correct, but it means adding a new origin in the future could accidentally inherit the "go to InputState" behaviour without any compile-time signal. An explicit case makes the intent clear and makes the switch exhaustive for all declared origins.

Suggested change
default:
m.inputs[2].SetValue(path)
m.focusInput(2)
m.filepickerOrigin = FilePickerOriginNone
m.state = InputState
return m, nil
}
case FilePickerOriginAdd:
m.inputs[2].SetValue(path)
m.focusInput(2)
m.filepickerOrigin = FilePickerOriginNone
m.state = InputState
return m, nil
default:
m.inputs[2].SetValue(path)
m.focusInput(2)
m.filepickerOrigin = FilePickerOriginNone
m.state = InputState
return m, nil
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/tui/helpers.go
Line: 92-98

Comment:
**`FilePickerOriginAdd` silently handled by `default`**

`FilePickerOriginAdd` is defined in the enum but never explicitly cased in this switch (or in the cancel switch in `update_filepicker.go`). It currently falls through to `default`, which is correct, but it means adding a new origin in the future could accidentally inherit the "go to InputState" behaviour without any compile-time signal. An explicit case makes the intent clear and makes the switch exhaustive for all declared origins.

```suggestion
	case FilePickerOriginAdd:
		m.inputs[2].SetValue(path)
		m.focusInput(2)
		m.filepickerOrigin = FilePickerOriginNone
		m.state = InputState
		return m, nil
	default:
		m.inputs[2].SetValue(path)
		m.focusInput(2)
		m.filepickerOrigin = FilePickerOriginNone
		m.state = InputState
		return m, nil
	}
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +956 to +990
updated, _ = m2.Update(tea.KeyPressMsg{Code: tea.KeyEscape})
m3 := unwrapRootModel(t, updated)

if got, want := m3.state, InputState; got != want {
t.Fatalf("state after esc = %v, want %v", got, want)
}
if got := m3.filepickerOrigin; got != FilePickerOriginNone {
t.Fatalf("filepickerOrigin after esc = %v, want none", got)
}
if got, want := m3.focusedInput, 2; got != want {
t.Fatalf("focusedInput after esc = %d, want %d", got, want)
}
if got, want := m3.inputs[2].Value(), browseDir; got != want {
t.Fatalf("path input after esc = %q, want %q", got, want)
}
}

func TestUpdate_FilePickerUseDirReturnsToAddInput(t *testing.T) {
browseDir := t.TempDir()

m := RootModel{
state: FilePickerState,
focusedInput: 2,
inputs: newInputModels(),
keys: Keys,
Settings: config.DefaultSettings(),
filepicker: newFilepicker(browseDir),
filepickerOrigin: FilePickerOriginAdd,
}
m.filepicker.CurrentDirectory = browseDir

updated, _ := m.Update(tea.KeyPressMsg{Code: tea.KeyEnter})
m2 := unwrapRootModel(t, updated)

if got, want := m2.state, InputState; got != want {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test name says "UseDir" but tests Enter, not the UseDir (.) key

The UseDir key binding maps to . (period) and explicitly selects the current directory via handleFilePickerSelection. Enter is passed to the underlying filepicker component and relies on DidSelectFile returning true — a different code path. Naming the test UseDirReturnsToAddInput while sending KeyEnter is misleading; consider renaming it to TestUpdate_FilePickerEnterConfirmsDirReturnsToAddInput or testing the actual . key press to match the name.

Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/tui/update_test.go
Line: 956-990

Comment:
**Test name says "UseDir" but tests `Enter`, not the `UseDir` (`.`) key**

The `UseDir` key binding maps to `.` (period) and explicitly selects the current directory via `handleFilePickerSelection`. `Enter` is passed to the underlying filepicker component and relies on `DidSelectFile` returning true — a different code path. Naming the test `UseDirReturnsToAddInput` while sending `KeyEnter` is misleading; consider renaming it to `TestUpdate_FilePickerEnterConfirmsDirReturnsToAddInput` or testing the actual `.` key press to match the name.

How can I resolve this? If you propose a fix, please make it concise.

@junaid2005p junaid2005p merged commit 99c6264 into main Apr 20, 2026
16 checks passed
@junaid2005p junaid2005p deleted the tui-filepath-bug branch April 20, 2026 07:49
@SuperCoolPencil SuperCoolPencil linked an issue Apr 20, 2026 that may be closed by this pull request
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.

Cannot exit the "choose a path" window

2 participants