ADR-0019 §9 sweep (3/3): ui.rs prose strings (caught in manual sanity)
Surprise gap from the post-sweep sanity check — `ui.rs` had a substantial set of TUI-rendered strings that the previous two sweep passes didn't cover. Caught by grepping for capitalised literals in `ui.rs` after running the binary smoke check. ## Migrated - **modal.*** — load picker title / empty state / path prompt; rebuild confirm title / "Continue?" prompt. (modal.path_entry's title comes from `save.*` since it's the save / save-as dialog.) - **save.*** — `save` no-op hint, modal titles for Save / Save as, modal prompt body. - **status.*** — status bar `Project:` label and the `(no project)` placeholder. - **panel.*** — `Tables` panel title, `(none yet)` placeholder for empty tables, `(no active hint)` placeholder for the hint panel. - **shortcut.*** — the bottom-bar keyboard hint labels (submit, confirm, cancel, yes, no, load, select, browse_path, back_to_list, switch, advanced_once, cancel_one_shot, quit). Each is a translatable label paired with a key name (Enter / Esc / Ctrl-C / etc.) at the call site. Keystroke names are deliberately left as literals — translating them would mean retraining users away from what their keyboard says. The `push_shortcut` closure's parameter type changed from `&'static str` to `&str` so it accepts the catalog-returned String. ## Deliberately left - **Echo prefix tags**: `[simple] `, `[advanced] `, `[system] `, `[error] `. Their column widths are hardcoded into the wrap-width calculation in `render_output_panel`; translating them would silently break alignment. Worth a follow-up pass if a future locale needs different prefixes (would need `mode.label()` and the echo-tag widths to live behind a single locale-aware function). - **Mode labels**: `SIMPLE` / `ADVANCED` / `Advanced:` rendered in the input panel border. Same alignment reasoning as the echo tags — also they're keywords (the user types `mode simple` to switch), so translating the display label without translating the command word would be confusing. Left as is. - **Visual decoration**: `[Y]`, `[N]`, `[TEMP] `, `>` cursor markers, `█` cursor block, `↑↓` arrow glyph, `›` selection marker. Universal symbols / labels rather than translatable prose. ## Catalog totals The catalog now has ~170 entries across 16 categories. `tests/engine_vocabulary_audit` passes — no engine vocabulary leaks anywhere user-reachable. ## Tally 610 tests passing (no change — pure refactor with identical-output catalog substitutions). Clippy clean with nursery lints. Release builds at 7.8 MB. ADR-0019 §9 is now genuinely complete.
This commit is contained in:
+8
-6
@@ -1130,15 +1130,17 @@ impl App {
|
|||||||
/// the named project is already persistent (ADR-0015 §11).
|
/// the named project is already persistent (ADR-0015 §11).
|
||||||
fn handle_save_command(&mut self, force_save_as: bool) -> Vec<Action> {
|
fn handle_save_command(&mut self, force_save_as: bool) -> Vec<Action> {
|
||||||
if !force_save_as && !self.project_is_temp {
|
if !force_save_as && !self.project_is_temp {
|
||||||
self.note_system(
|
self.note_system(crate::t!("save.already_saved"));
|
||||||
"already auto-saved; use `save as` to copy to a different location",
|
|
||||||
);
|
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let title = if force_save_as { "Save as" } else { "Save" };
|
let title = if force_save_as {
|
||||||
|
crate::t!("save.title_as")
|
||||||
|
} else {
|
||||||
|
crate::t!("save.title_save")
|
||||||
|
};
|
||||||
self.modal = Some(Modal::PathEntry(PathEntryModal {
|
self.modal = Some(Modal::PathEntry(PathEntryModal {
|
||||||
title: title.to_string(),
|
title,
|
||||||
prompt: "Name (under data dir/projects) or absolute path:".to_string(),
|
prompt: crate::t!("save.path_prompt"),
|
||||||
input: String::new(),
|
input: String::new(),
|
||||||
cursor: 0,
|
cursor: 0,
|
||||||
purpose: PathEntryPurpose::SaveAs,
|
purpose: PathEntryPurpose::SaveAs,
|
||||||
|
|||||||
@@ -148,10 +148,40 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
|
|||||||
// ---- Modal labels ----
|
// ---- Modal labels ----
|
||||||
("modal.generic_cancelled", &["title"]),
|
("modal.generic_cancelled", &["title"]),
|
||||||
("modal.load_cancelled", &[]),
|
("modal.load_cancelled", &[]),
|
||||||
|
("modal.load_picker_empty", &[]),
|
||||||
("modal.load_picker_nothing", &[]),
|
("modal.load_picker_nothing", &[]),
|
||||||
|
("modal.load_picker_path_prompt", &[]),
|
||||||
|
("modal.load_picker_title", &[]),
|
||||||
("modal.path_entry_empty_name", &[]),
|
("modal.path_entry_empty_name", &[]),
|
||||||
("modal.path_entry_empty_path", &[]),
|
("modal.path_entry_empty_path", &[]),
|
||||||
("modal.rebuild_cancelled", &[]),
|
("modal.rebuild_cancelled", &[]),
|
||||||
|
("modal.rebuild_confirm_prompt", &[]),
|
||||||
|
("modal.rebuild_confirm_title", &[]),
|
||||||
|
// ---- Status bar + panels ----
|
||||||
|
("panel.hint_empty", &[]),
|
||||||
|
("panel.tables_empty", &[]),
|
||||||
|
("panel.tables_title", &[]),
|
||||||
|
("status.no_project", &[]),
|
||||||
|
("status.project_label", &[]),
|
||||||
|
// ---- Save / save-as surfaces ----
|
||||||
|
("save.already_saved", &[]),
|
||||||
|
("save.path_prompt", &[]),
|
||||||
|
("save.title_as", &[]),
|
||||||
|
("save.title_save", &[]),
|
||||||
|
// ---- Shortcut hint labels ----
|
||||||
|
("shortcut.advanced_once", &[]),
|
||||||
|
("shortcut.back_to_list", &[]),
|
||||||
|
("shortcut.browse_path", &[]),
|
||||||
|
("shortcut.cancel", &[]),
|
||||||
|
("shortcut.cancel_one_shot", &[]),
|
||||||
|
("shortcut.confirm", &[]),
|
||||||
|
("shortcut.load", &[]),
|
||||||
|
("shortcut.no", &[]),
|
||||||
|
("shortcut.quit", &[]),
|
||||||
|
("shortcut.select", &[]),
|
||||||
|
("shortcut.submit", &[]),
|
||||||
|
("shortcut.switch", &[]),
|
||||||
|
("shortcut.yes", &[]),
|
||||||
// ---- mode / messages banners ----
|
// ---- mode / messages banners ----
|
||||||
("messages.set_short", &[]),
|
("messages.set_short", &[]),
|
||||||
("messages.set_verbose", &[]),
|
("messages.set_verbose", &[]),
|
||||||
|
|||||||
@@ -309,6 +309,48 @@ modal:
|
|||||||
path_entry_empty_name: "path entry: empty name"
|
path_entry_empty_name: "path entry: empty name"
|
||||||
path_entry_empty_path: "path entry: empty path"
|
path_entry_empty_path: "path entry: empty path"
|
||||||
load_picker_nothing: "nothing to load"
|
load_picker_nothing: "nothing to load"
|
||||||
|
# Modal titles + body prose rendered by ui.rs.
|
||||||
|
load_picker_title: "Load project"
|
||||||
|
load_picker_empty: "(no projects in data directory)"
|
||||||
|
load_picker_path_prompt: "Path to project directory:"
|
||||||
|
rebuild_confirm_title: "Rebuild project"
|
||||||
|
rebuild_confirm_prompt: "Continue?"
|
||||||
|
|
||||||
|
# ---- Save / save-as command surfaces ---------------------------------
|
||||||
|
save:
|
||||||
|
# `save` on a named project is a no-op with a friendly hint.
|
||||||
|
already_saved: "already auto-saved; use `save as` to copy to a different location"
|
||||||
|
# Modal titles for `save` (on a temp) vs `save as`.
|
||||||
|
title_as: "Save as"
|
||||||
|
title_save: "Save"
|
||||||
|
# Prompt body for the path-entry modal opened by save / save as.
|
||||||
|
path_prompt: "Name (under data dir/projects) or absolute path:"
|
||||||
|
|
||||||
|
# ---- Status bar (project label) and panels ---------------------------
|
||||||
|
status:
|
||||||
|
no_project: "(no project)"
|
||||||
|
project_label: "Project: "
|
||||||
|
|
||||||
|
panel:
|
||||||
|
tables_title: "Tables"
|
||||||
|
tables_empty: "(none yet)"
|
||||||
|
hint_empty: "(no active hint)"
|
||||||
|
|
||||||
|
# ---- Shortcut hints (paired with key names in the bottom bar) -------
|
||||||
|
shortcut:
|
||||||
|
submit: "submit"
|
||||||
|
confirm: "confirm"
|
||||||
|
cancel: "cancel"
|
||||||
|
yes: "yes"
|
||||||
|
no: "no"
|
||||||
|
load: "load"
|
||||||
|
select: "select"
|
||||||
|
browse_path: "browse path"
|
||||||
|
back_to_list: "back to list"
|
||||||
|
switch: "switch"
|
||||||
|
advanced_once: "advanced once"
|
||||||
|
cancel_one_shot: "cancel one-shot"
|
||||||
|
quit: "quit"
|
||||||
|
|
||||||
# ---- mode / messages banners (app-level commands) -------------------
|
# ---- mode / messages banners (app-level commands) -------------------
|
||||||
mode:
|
mode:
|
||||||
|
|||||||
@@ -120,9 +120,12 @@ fn render_path_entry(
|
|||||||
text_lines.push(Line::from(""));
|
text_lines.push(Line::from(""));
|
||||||
text_lines.push(Line::from(vec![
|
text_lines.push(Line::from(vec![
|
||||||
Span::styled("Enter", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("Enter", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
Span::raw(" confirm "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.confirm"))),
|
||||||
Span::styled("Esc", Style::default().fg(theme.muted)),
|
Span::styled("Esc", Style::default().fg(theme.muted)),
|
||||||
Span::styled(" cancel", Style::default().fg(theme.muted)),
|
Span::styled(
|
||||||
|
format!(" {}", crate::t!("shortcut.cancel")),
|
||||||
|
Style::default().fg(theme.muted),
|
||||||
|
),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let paragraph = Paragraph::new(text_lines)
|
let paragraph = Paragraph::new(text_lines)
|
||||||
@@ -157,7 +160,10 @@ fn render_load_picker(
|
|||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.border_type(BorderType::Rounded)
|
.border_type(BorderType::Rounded)
|
||||||
.border_style(Style::default().fg(theme.fg))
|
.border_style(Style::default().fg(theme.fg))
|
||||||
.title(Line::from(vec![Span::styled(" Load project ", title_style)]))
|
.title(Line::from(vec![Span::styled(
|
||||||
|
format!(" {} ", crate::t!("modal.load_picker_title")),
|
||||||
|
title_style,
|
||||||
|
)]))
|
||||||
.style(Style::default().bg(theme.bg).fg(theme.fg));
|
.style(Style::default().bg(theme.bg).fg(theme.fg));
|
||||||
|
|
||||||
let mut text_lines: Vec<Line<'_>> = Vec::new();
|
let mut text_lines: Vec<Line<'_>> = Vec::new();
|
||||||
@@ -166,7 +172,7 @@ fn render_load_picker(
|
|||||||
match &m.sub_mode {
|
match &m.sub_mode {
|
||||||
LoadPickerSubMode::List => {
|
LoadPickerSubMode::List => {
|
||||||
if m.entries.is_empty() {
|
if m.entries.is_empty() {
|
||||||
text_lines.push(Line::from("(no projects in data directory)"));
|
text_lines.push(Line::from(crate::t!("modal.load_picker_empty")));
|
||||||
} else {
|
} else {
|
||||||
for (i, entry) in m.entries.iter().enumerate() {
|
for (i, entry) in m.entries.iter().enumerate() {
|
||||||
let marker = if i == m.selected { "›" } else { " " };
|
let marker = if i == m.selected { "›" } else { " " };
|
||||||
@@ -189,17 +195,20 @@ fn render_load_picker(
|
|||||||
text_lines.push(Line::from(""));
|
text_lines.push(Line::from(""));
|
||||||
text_lines.push(Line::from(vec![
|
text_lines.push(Line::from(vec![
|
||||||
Span::styled("↑↓", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("↑↓", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
Span::raw(" select "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.select"))),
|
||||||
Span::styled("Enter", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("Enter", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
Span::raw(" load "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.load"))),
|
||||||
Span::styled("b", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("b", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
Span::raw(" browse path "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.browse_path"))),
|
||||||
Span::styled("Esc", Style::default().fg(theme.muted)),
|
Span::styled("Esc", Style::default().fg(theme.muted)),
|
||||||
Span::styled(" cancel", Style::default().fg(theme.muted)),
|
Span::styled(
|
||||||
|
format!(" {}", crate::t!("shortcut.cancel")),
|
||||||
|
Style::default().fg(theme.muted),
|
||||||
|
),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
LoadPickerSubMode::PathEntry { input, cursor } => {
|
LoadPickerSubMode::PathEntry { input, cursor } => {
|
||||||
text_lines.push(Line::from("Path to project directory:"));
|
text_lines.push(Line::from(crate::t!("modal.load_picker_path_prompt")));
|
||||||
text_lines.push(Line::from(""));
|
text_lines.push(Line::from(""));
|
||||||
let cursor_marker = "█";
|
let cursor_marker = "█";
|
||||||
let display_input = if *cursor == input.len() {
|
let display_input = if *cursor == input.len() {
|
||||||
@@ -215,9 +224,12 @@ fn render_load_picker(
|
|||||||
text_lines.push(Line::from(""));
|
text_lines.push(Line::from(""));
|
||||||
text_lines.push(Line::from(vec![
|
text_lines.push(Line::from(vec![
|
||||||
Span::styled("Enter", Style::default().add_modifier(Modifier::BOLD)),
|
Span::styled("Enter", Style::default().add_modifier(Modifier::BOLD)),
|
||||||
Span::raw(" load "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.load"))),
|
||||||
Span::styled("Esc", Style::default().fg(theme.muted)),
|
Span::styled("Esc", Style::default().fg(theme.muted)),
|
||||||
Span::styled(" back to list", Style::default().fg(theme.muted)),
|
Span::styled(
|
||||||
|
format!(" {}", crate::t!("shortcut.back_to_list")),
|
||||||
|
Style::default().fg(theme.muted),
|
||||||
|
),
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,7 +274,10 @@ fn render_rebuild_confirm(summary: &str, theme: &Theme, frame: &mut Frame<'_>, a
|
|||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.border_type(BorderType::Rounded)
|
.border_type(BorderType::Rounded)
|
||||||
.border_style(Style::default().fg(theme.fg))
|
.border_style(Style::default().fg(theme.fg))
|
||||||
.title(Line::from(vec![Span::styled(" Rebuild project ", title_style)]))
|
.title(Line::from(vec![Span::styled(
|
||||||
|
format!(" {} ", crate::t!("modal.rebuild_confirm_title")),
|
||||||
|
title_style,
|
||||||
|
)]))
|
||||||
.style(Style::default().bg(theme.bg).fg(theme.fg));
|
.style(Style::default().bg(theme.bg).fg(theme.fg));
|
||||||
|
|
||||||
let mut text_lines: Vec<Line<'_>> = Vec::new();
|
let mut text_lines: Vec<Line<'_>> = Vec::new();
|
||||||
@@ -271,7 +286,7 @@ fn render_rebuild_confirm(summary: &str, theme: &Theme, frame: &mut Frame<'_>, a
|
|||||||
text_lines.push(Line::from(line));
|
text_lines.push(Line::from(line));
|
||||||
}
|
}
|
||||||
text_lines.push(Line::from(""));
|
text_lines.push(Line::from(""));
|
||||||
text_lines.push(Line::from("Continue?"));
|
text_lines.push(Line::from(crate::t!("modal.rebuild_confirm_prompt")));
|
||||||
text_lines.push(Line::from(""));
|
text_lines.push(Line::from(""));
|
||||||
text_lines.push(Line::from(vec![
|
text_lines.push(Line::from(vec![
|
||||||
Span::styled(
|
Span::styled(
|
||||||
@@ -280,16 +295,19 @@ fn render_rebuild_confirm(summary: &str, theme: &Theme, frame: &mut Frame<'_>, a
|
|||||||
.fg(theme.fg)
|
.fg(theme.fg)
|
||||||
.add_modifier(Modifier::BOLD),
|
.add_modifier(Modifier::BOLD),
|
||||||
),
|
),
|
||||||
Span::raw(" yes "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.yes"))),
|
||||||
Span::styled(
|
Span::styled(
|
||||||
"[N]",
|
"[N]",
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(theme.fg)
|
.fg(theme.fg)
|
||||||
.add_modifier(Modifier::BOLD),
|
.add_modifier(Modifier::BOLD),
|
||||||
),
|
),
|
||||||
Span::raw(" no "),
|
Span::raw(format!(" {} ", crate::t!("shortcut.no"))),
|
||||||
Span::styled("Esc", Style::default().fg(theme.muted)),
|
Span::styled("Esc", Style::default().fg(theme.muted)),
|
||||||
Span::styled(" cancel", Style::default().fg(theme.muted)),
|
Span::styled(
|
||||||
|
format!(" {}", crate::t!("shortcut.cancel")),
|
||||||
|
Style::default().fg(theme.muted),
|
||||||
|
),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let paragraph = Paragraph::new(text_lines)
|
let paragraph = Paragraph::new(text_lines)
|
||||||
@@ -332,8 +350,12 @@ fn render_project_label(app: &App, theme: &Theme, frame: &mut Frame<'_>, area: R
|
|||||||
.add_modifier(Modifier::BOLD);
|
.add_modifier(Modifier::BOLD);
|
||||||
let bar_style = Style::default().bg(theme.bg).fg(theme.muted);
|
let bar_style = Style::default().bg(theme.bg).fg(theme.muted);
|
||||||
|
|
||||||
let display = app.project_name.as_deref().unwrap_or("(no project)");
|
let no_project = crate::t!("status.no_project");
|
||||||
let mut spans: Vec<Span<'_>> = vec![Span::styled("Project: ", label_style)];
|
let display = app.project_name.as_deref().unwrap_or(no_project.as_str());
|
||||||
|
let mut spans: Vec<Span<'_>> = vec![Span::styled(
|
||||||
|
crate::t!("status.project_label"),
|
||||||
|
label_style,
|
||||||
|
)];
|
||||||
if app.project_is_temp {
|
if app.project_is_temp {
|
||||||
spans.push(Span::styled(
|
spans.push(Span::styled(
|
||||||
"[TEMP] ",
|
"[TEMP] ",
|
||||||
@@ -374,7 +396,7 @@ fn render_items_panel(app: &App, theme: &Theme, frame: &mut Frame<'_>, area: Rec
|
|||||||
.border_type(BorderType::Rounded)
|
.border_type(BorderType::Rounded)
|
||||||
.border_style(Style::default().fg(theme.border))
|
.border_style(Style::default().fg(theme.border))
|
||||||
.title(Span::styled(
|
.title(Span::styled(
|
||||||
" Tables ",
|
format!(" {} ", crate::t!("panel.tables_title")),
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(theme.fg)
|
.fg(theme.fg)
|
||||||
.add_modifier(Modifier::BOLD),
|
.add_modifier(Modifier::BOLD),
|
||||||
@@ -383,7 +405,7 @@ fn render_items_panel(app: &App, theme: &Theme, frame: &mut Frame<'_>, area: Rec
|
|||||||
|
|
||||||
if app.tables.is_empty() {
|
if app.tables.is_empty() {
|
||||||
let placeholder = Paragraph::new(Line::from(Span::styled(
|
let placeholder = Paragraph::new(Line::from(Span::styled(
|
||||||
"(none yet)",
|
crate::t!("panel.tables_empty"),
|
||||||
Style::default()
|
Style::default()
|
||||||
.fg(theme.muted)
|
.fg(theme.muted)
|
||||||
.add_modifier(Modifier::ITALIC),
|
.add_modifier(Modifier::ITALIC),
|
||||||
@@ -597,9 +619,10 @@ fn render_hint_panel(app: &App, theme: &Theme, frame: &mut Frame<'_>, area: Rect
|
|||||||
))
|
))
|
||||||
.style(Style::default().bg(theme.bg).fg(theme.fg));
|
.style(Style::default().bg(theme.bg).fg(theme.fg));
|
||||||
|
|
||||||
let body = app.hint.as_deref().unwrap_or("(no active hint)");
|
let empty_hint = crate::t!("panel.hint_empty");
|
||||||
|
let body = app.hint.as_deref().unwrap_or(empty_hint.as_str());
|
||||||
let paragraph = Paragraph::new(Line::from(Span::styled(
|
let paragraph = Paragraph::new(Line::from(Span::styled(
|
||||||
body,
|
body.to_string(),
|
||||||
Style::default().fg(theme.muted),
|
Style::default().fg(theme.muted),
|
||||||
)))
|
)))
|
||||||
.block(block)
|
.block(block)
|
||||||
@@ -619,29 +642,34 @@ fn render_status_bar(app: &App, theme: &Theme, frame: &mut Frame<'_>, area: Rect
|
|||||||
let separator = Span::styled(" · ", sep_style);
|
let separator = Span::styled(" · ", sep_style);
|
||||||
let mut spans: Vec<Span<'_>> = Vec::new();
|
let mut spans: Vec<Span<'_>> = Vec::new();
|
||||||
|
|
||||||
let push_shortcut = |spans: &mut Vec<Span<'_>>, key: &'static str, label: &'static str| {
|
let push_shortcut = |spans: &mut Vec<Span<'_>>, key: &'static str, label: &str| {
|
||||||
if !spans.is_empty() {
|
if !spans.is_empty() {
|
||||||
spans.push(separator.clone());
|
spans.push(separator.clone());
|
||||||
}
|
}
|
||||||
spans.push(Span::styled(key, key_style));
|
spans.push(Span::styled(key, key_style));
|
||||||
spans.push(Span::raw(" "));
|
spans.push(Span::raw(" "));
|
||||||
spans.push(Span::styled(label, label_style));
|
spans.push(Span::styled(label.to_string(), label_style));
|
||||||
};
|
};
|
||||||
|
|
||||||
push_shortcut(&mut spans, "Enter", "submit");
|
let submit = crate::t!("shortcut.submit");
|
||||||
|
push_shortcut(&mut spans, "Enter", &submit);
|
||||||
|
let switch = crate::t!("shortcut.switch");
|
||||||
|
let advanced_once = crate::t!("shortcut.advanced_once");
|
||||||
|
let cancel_one_shot = crate::t!("shortcut.cancel_one_shot");
|
||||||
|
let quit = crate::t!("shortcut.quit");
|
||||||
match app.effective_mode() {
|
match app.effective_mode() {
|
||||||
EffectiveMode::Simple => {
|
EffectiveMode::Simple => {
|
||||||
push_shortcut(&mut spans, ":", "advanced once");
|
push_shortcut(&mut spans, ":", &advanced_once);
|
||||||
push_shortcut(&mut spans, "mode advanced", "switch");
|
push_shortcut(&mut spans, "mode advanced", &switch);
|
||||||
}
|
}
|
||||||
EffectiveMode::AdvancedPersistent => {
|
EffectiveMode::AdvancedPersistent => {
|
||||||
push_shortcut(&mut spans, "mode simple", "switch");
|
push_shortcut(&mut spans, "mode simple", &switch);
|
||||||
}
|
}
|
||||||
EffectiveMode::AdvancedOneShot => {
|
EffectiveMode::AdvancedOneShot => {
|
||||||
push_shortcut(&mut spans, "Backspace", "cancel one-shot");
|
push_shortcut(&mut spans, "Backspace", &cancel_one_shot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
push_shortcut(&mut spans, "Ctrl-C", "quit");
|
push_shortcut(&mut spans, "Ctrl-C", &quit);
|
||||||
|
|
||||||
let paragraph = Paragraph::new(Line::from(spans)).style(bar_style);
|
let paragraph = Paragraph::new(Line::from(spans)).style(bar_style);
|
||||||
frame.render_widget(paragraph, area);
|
frame.render_widget(paragraph, area);
|
||||||
|
|||||||
Reference in New Issue
Block a user