use super::*;
use ratada::shortcut_hints;
use crate::keymap::{Action, Keymap};
use crate::tui::bindings::{GLOBAL_ACTIONS, HELP_SECTIONS};
use crate::tui::help::Section;
pub(super) const GLOBAL_GROUP: &str = "Global";
pub(super) const NAVIGATION_GROUP: &str = "Navigation";
const NAVIGATION_ROWS: &[(&[Action], &str)] = &[
(
&[Action::TabGit, Action::TabFiles],
"Git Repos / Files (press again for that kind's archive)",
),
(&[Action::Up, Action::Down], "move cursor (wraps)"),
(&[Action::Top, Action::Bottom], "top / bottom"),
(&[Action::PageUp, Action::PageDown], "page up / down"),
(
&[Action::HalfPageUp, Action::HalfPageDown],
"half page up / down",
),
(&[Action::ToggleSelect], "toggle the selection"),
(
&[Action::ExtendUp, Action::ExtendDown],
"extend the selection by a row",
),
(
&[Action::ExtendPageUp, Action::ExtendPageDown],
"extend the selection by a page",
),
];
const STRUCTURAL_ROWS: &[(&str, &str)] = &[
("Tab / Shift+Tab", "cycle the two active tabs"),
("Esc", "clear the selection"),
];
pub(super) fn global_group(keymap: &Keymap) -> Section {
let mut hints = keymap.hints(GLOBAL_ACTIONS);
hints.extend(shortcut_hints::global_bindings());
(GLOBAL_GROUP.to_string(), hints)
}
pub(super) fn navigation_group(keymap: &Keymap) -> Section {
let mut hints: Vec<(String, String)> = Vec::new();
for (actions, description) in NAVIGATION_ROWS {
let keys = keys_of(keymap, actions);
if !keys.is_empty() {
hints.push((keys, (*description).to_string()));
}
}
hints.extend(
STRUCTURAL_ROWS
.iter()
.map(|(key, text)| ((*key).to_string(), (*text).to_string())),
);
(NAVIGATION_GROUP.to_string(), hints)
}
pub(super) fn keys_of(keymap: &Keymap, actions: &[Action]) -> String {
actions
.iter()
.flat_map(|&action| keymap.keys_for(action))
.collect::<Vec<String>>()
.join("/")
}
impl App {
pub(super) fn hint_groups(&self) -> Vec<(String, Vec<(String, String)>)> {
let keymap = &self.keymap;
let compact = [
(&[Action::Up, Action::Down][..], "move"),
(&[Action::Top, Action::Bottom][..], "top/bottom"),
(&[Action::PageUp, Action::PageDown][..], "page"),
(&[Action::HalfPageUp, Action::HalfPageDown][..], "half"),
];
let navigation = (
NAVIGATION_GROUP.to_string(),
compact
.into_iter()
.map(|(actions, text)| {
(keys_of(keymap, actions), text.to_string())
})
.filter(|(keys, _)| !keys.is_empty())
.collect(),
);
let mut groups = vec![navigation];
for (label, actions) in crate::tui::bindings::hint_groups(self.tab) {
let hints = keymap.hints(actions);
if !hints.is_empty() {
groups.push(((*label).to_string(), hints));
}
}
groups.push(global_group(keymap));
groups
}
pub(super) fn help_sections(&self) -> Vec<Section> {
let keymap = &self.keymap;
let mut sections = vec![navigation_group(keymap)];
for (title, rows) in HELP_SECTIONS {
let hints: Vec<(String, String)> = rows
.iter()
.filter_map(|(action, description)| {
let keys = keymap.keys_for(*action).join("/");
(!keys.is_empty())
.then(|| (keys, (*description).to_string()))
})
.collect();
if !hints.is_empty() {
sections.push(((*title).to_string(), hints));
}
}
sections.push(global_group(keymap));
sections
}
}