feat(tui): redesign chrome with unified key hints and help overlay
Introduce one key-hint grammar across every view: bold key, dim label, priority-ordered hints that drop from the end instead of ellipsizing. The month footer becomes a single split status bar with a friendly selected date, the '?' mega-line becomes a real keyboard shortcut panel, and the editor, agenda, search, picker, detail, and delete frames share the same chips. Notifications carry check/warning marks. Adds a live PTY smoke test covering view interaction and terminal state restoration on q and Ctrl-C exits.
This commit is contained in:
@@ -41,6 +41,21 @@ nocal::Event make_event(std::string uid, std::string title, const nocal::Date st
|
||||
return event;
|
||||
}
|
||||
|
||||
std::string strip_ansi(const std::string& input)
|
||||
{
|
||||
std::string output;
|
||||
for (std::size_t index = 0; index < input.size();) {
|
||||
if (input[index] == '\x1b' && index + 1 < input.size() && input[index + 1] == '[') {
|
||||
index += 2;
|
||||
while (index < input.size() && input[index] != 'm') ++index;
|
||||
if (index < input.size()) ++index;
|
||||
} else {
|
||||
output += input[index++];
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
nocal::tui::ScreenState screen_for(const nocal::Date day, const int width = 100,
|
||||
const int height = 32)
|
||||
{
|
||||
@@ -313,9 +328,11 @@ void test_delete_cancel_confirm_and_rollback()
|
||||
app.dispatch(nocal::tui::Action::next_event);
|
||||
app.dispatch(nocal::tui::Action::delete_event);
|
||||
check(app.delete_confirmation_active(), "delete requires an explicit confirmation step");
|
||||
const auto confirmation = nocal::tui::render_month(events, app.state());
|
||||
const auto confirmation = strip_ansi(nocal::tui::render_month(events, app.state()));
|
||||
check(confirmation.find("Delete target") != std::string::npos &&
|
||||
confirmation.find("y confirm") != std::string::npos,
|
||||
confirmation.find("y confirm") != std::string::npos &&
|
||||
confirmation.find("n cancel") != std::string::npos &&
|
||||
confirmation.find("Esc cancel") != std::string::npos,
|
||||
"delete confirmation names the appointment and shows its keys");
|
||||
app.handle_input("n");
|
||||
check(!app.delete_confirmation_active() && events.size() == 2 && save_calls == 0,
|
||||
@@ -545,8 +562,9 @@ void test_history_is_unavailable_in_modal_states()
|
||||
footer_state.focused_event_id = "modal-history";
|
||||
const auto month_frame = nocal::tui::render_month(events, footer_state);
|
||||
check(month_frame.find("u undo") != std::string::npos &&
|
||||
month_frame.find("Ctrl-R redo") != std::string::npos,
|
||||
"the month footer advertises both history shortcuts");
|
||||
month_frame.find("Enter read") != std::string::npos &&
|
||||
month_frame.find("Tab next") != std::string::npos,
|
||||
"the month footer shows focused hints");
|
||||
app.dispatch(nocal::tui::Action::delete_event);
|
||||
app.handle_input("u");
|
||||
check(app.delete_confirmation_active() && app.state().notification_is_error &&
|
||||
@@ -658,6 +676,10 @@ void test_timed_event_details()
|
||||
std::string::npos,
|
||||
"the reader renders the event description");
|
||||
check(frame.find("Esc back") != std::string::npos, "the reader footer explains how to close it");
|
||||
// Verify the new chip grammar: hints left, ordinal right
|
||||
check(frame.find("Tab") != std::string::npos, "reader footer contains Tab hint");
|
||||
check(frame.find("del") != std::string::npos, "reader footer contains del hint");
|
||||
check(frame.find("1/") != std::string::npos, "reader footer contains ordinal");
|
||||
}
|
||||
|
||||
void test_all_day_and_multiday_details()
|
||||
|
||||
Reference in New Issue
Block a user