feat: input history recall via Up/Down arrows and /history command#265
Open
mmacedoeu wants to merge 14 commits into
Open
feat: input history recall via Up/Down arrows and /history command#265mmacedoeu wants to merge 14 commits into
mmacedoeu wants to merge 14 commits into
Conversation
- Add input_history ring buffer (max 100) and input_history_index to App - Up arrow in empty input recalls previous submitted inputs - Down arrow navigates forward through history, clearing at the end - Any manual edit (typing, backspace) cancels history browsing - Consecutive duplicate inputs are not stored - /history lists all stored inputs with indices - /history input N loads entry N into the input box - Works in both local and remote TUI modes - Help overlay updated with new keybindings and /history command - 13 unit tests covering all history operations Closes 1jehuang#264
…overage - Up arrow now works when already browsing history (not just from empty input) - Same fix applied to both local and remote key handlers - reset_input_history_browse added to insert_input_text, undo_input_change, and remember_input_undo_state for comprehensive coverage - Removed redundant reset calls from individual key handlers - Added tests for multi-press Up navigation, Down when not browsing - 15 total tests passing
… indicator - /history clear: wipe all entries - /history search <term>: case-insensitive search with match count - /history delete N: remove specific entry - Non-consecutive dedup: re-inserting existing text moves it to the end - Persistent history: saved to ~/.jcode/input-history.json, loaded on startup - Status bar indicator: shows '📋 history N/M' while browsing - input_history_browse_status() added to TuiState trait - 20 unit tests passing (7 new)
…/history input N Round 1: save_input_history now deletes file when history is empty so /clear doesn't leave stale data on disk. Round 2: Update help overlay, autocomplete description, and add /history to command_accepts_args. Remove duplicate inherent input_history_browse_status method in favor of trait impl. Round 3: Better error messages for /history delete and /history input when history is empty. Add catch-all for unknown /history subcommands. Remove double clone. Round 4: Add missing sync_model_picker_preview_from_input() call on /history input N. Round 5: Save undo state before /history input N replaces input.
- Added HistorySearchState struct to App with query, match_index, saved_input, saved_cursor - Added search methods: start, char, backspace, next, accept, cancel, find_match - Added handle_history_search_key free function for key dispatch during search - Wired Ctrl+R in both local and remote key handlers to start search - Search mode intercepts all keys before normal input handling - Case-insensitive substring matching, backwards from most recent entry - Ctrl+R cycles to next older match, Enter accepts, Esc cancels - Added input_history_search_status to TuiState trait with impls - UI renders (reverse-i-search) prompt in notification bar and input hint - 13 unit tests covering start, search, cycle, accept, cancel, edge cases
- Add reset_tab_completion + sync_model_picker_preview guards on accept/cancel - Fix undo snapshot to capture pre-search input instead of post-find_match state - Use reset_input_history_browse() in start_input_history_search - Fix Alt+char captured as search input (check both CTRL and ALT modifiers) - Update help overlay: Ctrl+R now means 'Search input history' - Update tool recovery message: refer to /fix instead of Ctrl+R - Replace unwrap() with if-let in cancel_input_history_search - Add 2 undo snapshot regression tests
Add InputHistoryConfig to jcode-config-types with max_entries field. Supports [input_history] config section and JCODE_INPUT_HISTORY_MAX env var override. Defaults to 100 entries (hardcoded fallback).
- Add #[serde(default = "default_max_entries")] so max_entries defaults
to 100 when [input_history] section present but field omitted
- Add deserialize_clamped_usize to clamp TOML/env values to 1..=10000
- Clamp JCODE_INPUT_HISTORY_MAX env var to 1..=10_000
- Add missing JCODE_ACP_{,TOOL_}PROFILE to CONFIG_ENV_KEYS
- Add 5 new config tests for serde default, clamping edge cases
- Command suggestions intercepted Down during history browsing when the history entry started with '/' (e.g. /commit). Skip suggestion key handling when input_history_index is active. - Down-past-end of history cleared input instead of restoring the original pre-browse text. Added input_history_pre_browse to save and restore the input that was present when Up first entered browse mode. - Ctrl+R search mode ignored Down arrow entirely. Now Down accepts the current search match and exits search, allowing continued Down navigation through history. - Ctrl+R search mode ignored Up arrow for cycling older matches.
The '(reverse-i-search) Type to search...' hint was rendered as the first line inside the input area, pushing the matched history content below the visible region. The search query and match info are already displayed in the notification bar above, making this hint redundant.
- Notification bar: simplified to '🔍 match 3/10' instead of the dense '(reverse-i-search)'foo': 3/10' format. - Input area: shows the search query on its own line with a cursor block, above the matched history entry rendered with the normal prompt. Clear visual separation between what you search and what was found.
- HistorySearchState now stores a matches list and selected index instead of a single match_index. - Up/Down arrows navigate the match list, Ctrl+R cycles down. - Input area renders all matching entries (up to 8) with selection highlight (▸ for selected, dimmed for others). - Empty query shows all history entries for browsing. - Notification bar shows '🔍 match N/M' counter. - TuiState trait exposes input_history_search_matches() for rendering.
The search results were rendered inside the input area at the bottom of the screen, getting cut off. Now they render as a bordered floating popup above the input area with: - Search query line with cursor block - Separator line - Up to 8 results with selection highlight (▸ for selected, dimmed rest) - Scroll window tracks the selected item - Rounded border with 'History Search' title
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds input history recall to the TUI, addressing #264. Users can now press Up arrow in an empty input box to recall previously submitted inputs, and Down arrow to navigate forward.
What's new
Keybindings
Any manual edit (typing, backspace) cancels history browsing and returns to normal editing.
Slash commands
/historyor/history input/history input NBehavior
Files changed (9 files, +326 lines)
src/tui/app.rsinput_history,input_history_indexfieldssrc/tui/app/tui_lifecycle.rssrc/tui/app/state_ui_runtime.rspush_input_history,input_history_up/down,reset_input_history_browsemethodssrc/tui/app/input.rstake_prepared_inputrecords toosrc/tui/app/remote/key_handling.rssrc/tui/app/state_ui_input_helpers.rs/historyin autocompletesrc/tui/app/commands.rs/history input [N]command handlersrc/tui/ui_overlays.rs/historysrc/tui/app/tests/remote_startup_input_02/part_01.rsTests
All 13 new tests pass:
test_submit_input_records_input_historytest_submit_input_deduplicates_consecutive_entriestest_submit_input_does_not_record_emptytest_input_history_up_recalls_last_input(including boundary at index 0)test_input_history_down_navigates_forward(including clear at end)test_input_history_down_does_nothing_when_not_browsingtest_text_input_resets_history_browsetest_backspace_resets_history_browsetest_history_command_lists_entriestest_history_command_emptytest_history_input_n_loads_entrytest_history_input_n_rejects_invalid_indextest_input_history_up_empty_historyCloses #264