Skip to content

OMNIS-33: Add the options editor to the TUI - #43

Merged
JtheGunner merged 10 commits into
mainfrom
feat/OMNIS-33-options-editor
Oct 7, 2026
Merged

JtheGunner merged 10 commits into
mainfrom
feat/OMNIS-33-options-editor

Conversation

@JtheGunner

Copy link
Copy Markdown
Owner

YouTrack: https://youtrack.xn--wrm-hoa.li/issue/OMNIS-33 (sub-task of OMNIS-14, the last functional one)

In omnishell tui, the key o opens an options screen for the selected module. Bool options switch with Space, enum options cycle with the left and right arrows, and string and int options are typed (pre-filled with the current value) and saved with Enter. Every value goes through the existing modedit.SetOption, so it is validated against the module's option schema exactly like omnishell set, and a rejected value is never written. No new dependencies.

Changes

  • modedit: new Editor.Options(id) returns a module's options sorted by key, with type, help, allowed values, pattern, default and current value. It reads only config.toml and the manifest (a test makes any package-manager call panic), so it is cheap enough to call after every write. A value that config.toml holds but the schema rejects (a hand edit) is shown as written and flagged (invalid).
  • tui: Backend gains Options and SetOption. The model reads and writes in tea.Cmds (Update still does no I/O), one write at a time; keys other than Ctrl-C are ignored while a write is pending. A rejected string or int keeps the typed text and shows the reason on the status line, so a typo is corrected instead of retyped. List options are shown, dimmed, and not editable here (the detail points to omnishell set). The header's change count now includes options whose value differs from the first value the screen showed.
  • tui view: option table with scrolling, a detail pane (help, type, current value, default, allowed values, pattern, a note when the module is not enabled), and a typing cell that scrolls so the end of the input and the cursor stay visible. The browser footer reads esc clear instead of esc clear filter to fit o options into 80 columns, which changes one line in six existing golden files.
  • All option text from a backend, and all typed text, goes through sanitize.
  • cli: the backend adapter shortens config.Error to its message. README, CHANGELOG, CLAUDE.md and the tui --help text describe the screen; the implementation plan is under docs/superpowers.

Commits

  • docs: add implementation plan for the options editor in the TUI (OMNIS-33)
  • feat: list a module's options with their current values in modedit
  • feat: let the tui backend read and write module options
  • feat: add the options screen to the tui model
  • feat: draw the options screen in the tui
  • docs: describe the options editor in the omnishell tui
  • fix: show the full option value and keep the cursor in view while editing
  • fix: leave the filter typing mode when the options screen opens
  • fix: drop option results that arrive for another screen or module
  • test: leave the options screen before marking a write as pending

The last commit repairs a test I got wrong in the commit before it (it set the pending flag before leaving the screen, which the screen deliberately ignores); that earlier commit is red on its own, the branch tip is green.

Review findings fixed before this PR

  • A string value wider than the value column (for example the 32-character fzf.default_opts) was not shown in full anywhere, and while typing, the input and cursor scrolled out of the column, so it was edited blind. The detail pane now shows the whole value over up to two lines, and the typing cell scrolls on the left (also with wide characters, where cutting in the middle of a character used to leave the cursor one cell too far right).
  • A / pressed while the options were loading left the browser in filter-typing mode after Esc, so q was typed into the filter. Fixed, with a test.
  • Option results that arrive for another screen or module are dropped, mirroring the plan screen's stale-answer check. This cannot happen today because of the pending flag; the guard keeps it that way if a key is added later.

Test plan

  • make vet and make test (race detector) pass locally.
  • golangci-lint v2.13.2 (the CI version, via go run) reports 0 issues.
  • CGO_ENABLED=0 go build ./cmd/omnishell succeeds for linux/amd64, linux/arm64, linux/armv6, linux/armv7, darwin/amd64 and darwin/arm64.
  • With the real binary in a pseudo-terminal (throwaway HOME): switching tmux.auto_attach writes auto_attach = false; typing a value the pattern rejects shows the reason and writes nothing; a valid value is saved; extending the long fzf.default_opts saves it and omnishell validate accepts the file. An independent review ran the same kind of checks and also wrote a range of awkward strings (quotes, backslashes, U+2028, emoji, #, [modules.x]) through SetOption; every one loads again.
  • CI: vet, race tests, golangci-lint, govulncheck and the build matrix pass.
  • Reviewer: with a scratch HOME (never a real config), run omnishell init, then omnishell tui. Press o on a module with options (for example fzf or tmux) and check Space on a bool, the arrows on an enum, and Enter on a string, including a value the pattern rejects (the text must stay for correction) and a long value.

Known gaps (not in this PR)

  • The rendering of the long-value editing cell is covered by View() tests, not by a real terminal emulator.
  • After a failed re-read that follows a successful write, the rows are stale until the next successful read (by design, as with toggling).
  • The omnishell tui --help text has one line longer than 80 columns, and one CHANGELOG line is longer than the file's wrap width.
  • Existing behaviour on main: omnishell set can write a config.toml that no command can load when the value contains BEL (0x07) or VT (0x0b), because config.tomlLiteral uses strconv.Quote, which emits \a and \v that TOML does not have. The TUI is not affected, because sanitize replaces control characters before they reach SetOption.

@JtheGunner
JtheGunner merged commit 6f8790d into main Oct 7, 2026
4 checks passed
@JtheGunner
JtheGunner deleted the feat/OMNIS-33-options-editor branch October 7, 2026 12:25
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