components: fix shortcut section order
Tests / Test on ${{ matrix.build }} (linux-amd64, ubuntu-latest, stable, x86_64-unknown-linux-gnu) (push) Successful in 8m2s
Details
Tests / Test on ${{ matrix.build }} (linux-amd64, ubuntu-latest, stable, x86_64-unknown-linux-gnu) (push) Successful in 8m2s
Details
Shortcut sections are shown in order, sorted by focus--as if widgets are stacked vertically by the order you've opened them. In some widgets that order was wrong. Also, when a parent widget retrieved its child shortcuts, sometimes it overwrote children sections if they both have them. This commit adds a sealed trait ExtendShortcutsMaps that instead of overriding them, it merges them with the child map having the priority. Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/284/head
parent
f193bdf685
commit
96f0b3e6b4
|
@ -75,6 +75,29 @@ impl std::fmt::UpperHex for ComponentId {
|
|||
pub type ShortcutMap = IndexMap<&'static str, Key>;
|
||||
pub type ShortcutMaps = IndexMap<&'static str, ShortcutMap>;
|
||||
|
||||
mod private {
|
||||
pub trait Sealed {}
|
||||
}
|
||||
impl private::Sealed for ShortcutMaps {}
|
||||
|
||||
pub trait ExtendShortcutsMaps: private::Sealed {
|
||||
fn extend_shortcuts(&mut self, other: Self);
|
||||
}
|
||||
|
||||
impl ExtendShortcutsMaps for ShortcutMaps {
|
||||
fn extend_shortcuts(&mut self, mut other: Self) {
|
||||
other.retain(|k, v| {
|
||||
if let Some(m) = self.get_mut(k) {
|
||||
m.extend(v.iter().map(|(k, v)| (*k, v.clone())));
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
self.extend(other.into_iter());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum PageMovement {
|
||||
Up(usize),
|
||||
|
|
|
@ -29,7 +29,9 @@ use melib::{backends::EnvelopeHashBatch, Address};
|
|||
use smallvec::SmallVec;
|
||||
|
||||
use super::*;
|
||||
use crate::{conf::accounts::JobRequest, types::segment_tree::SegmentTree};
|
||||
use crate::{
|
||||
components::ExtendShortcutsMaps, conf::accounts::JobRequest, types::segment_tree::SegmentTree,
|
||||
};
|
||||
|
||||
// [ref:TODO]: emoji_text_presentation_selector should be printed along with the chars
|
||||
// before it but not as a separate Cell
|
||||
|
@ -2152,17 +2154,18 @@ impl Component for Listing {
|
|||
}
|
||||
|
||||
fn shortcuts(&self, context: &Context) -> ShortcutMaps {
|
||||
let mut map = if let Some(s) = self.status.as_ref() {
|
||||
let mut map = ShortcutMaps::default();
|
||||
if self.focus != ListingFocus::Menu && self.component.unfocused() {
|
||||
map.extend_shortcuts(self.view.shortcuts(context));
|
||||
}
|
||||
map.extend_shortcuts(if let Some(s) = self.status.as_ref() {
|
||||
s.shortcuts(context)
|
||||
} else {
|
||||
self.component.shortcuts(context)
|
||||
};
|
||||
});
|
||||
let mut config_map = context.settings.shortcuts.listing.key_values();
|
||||
if self.focus != ListingFocus::Menu {
|
||||
config_map.remove("open_mailbox");
|
||||
if self.component.unfocused() {
|
||||
map.extend(self.view.shortcuts(context).into_iter());
|
||||
}
|
||||
}
|
||||
map.insert(Shortcuts::LISTING, config_map);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ use std::collections::HashSet;
|
|||
use indexmap::IndexMap;
|
||||
|
||||
pub use self::tables::*;
|
||||
use crate::{jobs::JobId, melib::text_processing::TextProcessing};
|
||||
use crate::{components::ExtendShortcutsMaps, jobs::JobId, melib::text_processing::TextProcessing};
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SearchPattern {
|
||||
|
@ -854,8 +854,7 @@ impl Tabbed {
|
|||
dirty: true,
|
||||
id: ComponentId::default(),
|
||||
};
|
||||
ret.help_curr_views
|
||||
.extend(ret.shortcuts(context).into_iter());
|
||||
ret.help_curr_views.extend_shortcuts(ret.shortcuts(context));
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -937,6 +936,18 @@ impl Tabbed {
|
|||
new.realize(self.id().into(), context);
|
||||
self.children.push(new);
|
||||
}
|
||||
|
||||
fn update_help_curr_views(&mut self, context: &Context) {
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
children_maps.extend_shortcuts(self.shortcuts(context));
|
||||
if let Some(i) = children_maps
|
||||
.get_index_of(Shortcuts::GENERAL)
|
||||
.filter(|i| i + 1 != children_maps.len())
|
||||
{
|
||||
children_maps.move_index(i, children_maps.len().saturating_sub(1));
|
||||
}
|
||||
self.help_curr_views = children_maps;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Tabbed {
|
||||
|
@ -990,11 +1001,16 @@ impl Component for Tabbed {
|
|||
|
||||
if (self.show_shortcuts && self.dirty) || must_redraw_shortcuts {
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
let our_map = self.shortcuts(context);
|
||||
children_maps.extend(our_map.into_iter());
|
||||
children_maps.extend_shortcuts(self.shortcuts(context));
|
||||
if children_maps.is_empty() {
|
||||
return;
|
||||
}
|
||||
if let Some(i) = children_maps
|
||||
.get_index_of(Shortcuts::GENERAL)
|
||||
.filter(|i| i + 1 != children_maps.len())
|
||||
{
|
||||
children_maps.move_index(i, children_maps.len().saturating_sub(1));
|
||||
}
|
||||
if (children_maps == self.help_curr_views) && must_redraw_shortcuts {
|
||||
let dialog_area = align_area(
|
||||
area,
|
||||
|
@ -1021,7 +1037,10 @@ impl Component for Tabbed {
|
|||
None,
|
||||
);
|
||||
write_string_to_grid(
|
||||
"Press ? to close",
|
||||
&format!(
|
||||
"Press {} to close",
|
||||
children_maps[Shortcuts::GENERAL]["toggle_help"]
|
||||
),
|
||||
grid,
|
||||
self.theme_default.fg,
|
||||
self.theme_default.bg,
|
||||
|
@ -1097,7 +1116,7 @@ impl Component for Tabbed {
|
|||
}
|
||||
let mut max_length = 6;
|
||||
let mut max_width =
|
||||
"Press ? to close, use COMMAND \"search\" to find shortcuts".len() + 3;
|
||||
"Press XXXX to close, use COMMAND \"search\" to find shortcuts".len() + 3;
|
||||
|
||||
let mut max_first_column_width = 3;
|
||||
|
||||
|
@ -1200,7 +1219,10 @@ impl Component for Tabbed {
|
|||
None,
|
||||
);
|
||||
write_string_to_grid(
|
||||
"Press ? to close",
|
||||
&format!(
|
||||
"Press {} to close",
|
||||
self.help_curr_views[Shortcuts::GENERAL]["toggle_help"]
|
||||
),
|
||||
grid,
|
||||
self.theme_default.fg,
|
||||
self.theme_default.bg,
|
||||
|
@ -1363,9 +1385,7 @@ impl Component for Tabbed {
|
|||
self.children[self.cursor_pos]
|
||||
.process_event(&mut UIEvent::VisibilityChange(false), context);
|
||||
self.cursor_pos = no % self.children.len();
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
children_maps.extend(self.shortcuts(context));
|
||||
self.help_curr_views = children_maps;
|
||||
self.update_help_curr_views(context);
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::UpdateStatus(
|
||||
|
@ -1381,9 +1401,7 @@ impl Component for Tabbed {
|
|||
self.children[self.cursor_pos]
|
||||
.process_event(&mut UIEvent::VisibilityChange(false), context);
|
||||
self.cursor_pos = (self.cursor_pos + 1) % self.children.len();
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
children_maps.extend(self.shortcuts(context));
|
||||
self.help_curr_views = children_maps;
|
||||
self.update_help_curr_views(context);
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::UpdateStatus(
|
||||
|
@ -1414,9 +1432,7 @@ impl Component for Tabbed {
|
|||
.process_event(&mut UIEvent::VisibilityChange(false), context);
|
||||
self.cursor_pos = self.children.len() - 1;
|
||||
self.children[self.cursor_pos].set_dirty(true);
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
children_maps.extend(self.shortcuts(context));
|
||||
self.help_curr_views = children_maps;
|
||||
self.update_help_curr_views(context);
|
||||
return true;
|
||||
}
|
||||
UIEvent::Action(Tab(Close)) => {
|
||||
|
@ -1425,9 +1441,7 @@ impl Component for Tabbed {
|
|||
}
|
||||
let id = self.children[self.cursor_pos].id();
|
||||
self.children[self.cursor_pos].kill(id, context);
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
children_maps.extend(self.shortcuts(context));
|
||||
self.help_curr_views = children_maps;
|
||||
self.update_help_curr_views(context);
|
||||
self.set_dirty(true);
|
||||
return true;
|
||||
}
|
||||
|
@ -1442,9 +1456,7 @@ impl Component for Tabbed {
|
|||
self.children.remove(c_idx);
|
||||
self.cursor_pos = 0;
|
||||
self.set_dirty(true);
|
||||
let mut children_maps = self.children[self.cursor_pos].shortcuts(context);
|
||||
children_maps.extend(self.shortcuts(context));
|
||||
self.help_curr_views = children_maps;
|
||||
self.update_help_curr_views(context);
|
||||
return true;
|
||||
} else {
|
||||
log::debug!(
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
*/
|
||||
|
||||
use super::*;
|
||||
use crate::terminal::cells::boundaries::{
|
||||
HORZ_BOUNDARY, VERT_BOUNDARY, _LIGHT_DOWN_AND_HORIZONTAL, _LIGHT_UP_AND_HORIZONTAL,
|
||||
use crate::{
|
||||
components::ExtendShortcutsMaps,
|
||||
terminal::cells::boundaries::{
|
||||
HORZ_BOUNDARY, VERT_BOUNDARY, _LIGHT_DOWN_AND_HORIZONTAL, _LIGHT_UP_AND_HORIZONTAL,
|
||||
},
|
||||
};
|
||||
|
||||
/// A horizontally split in half container.
|
||||
|
@ -106,7 +109,7 @@ impl Component for HSplit {
|
|||
|
||||
fn shortcuts(&self, context: &Context) -> ShortcutMaps {
|
||||
let mut top_map = self.top.shortcuts(context);
|
||||
top_map.extend(self.bottom.shortcuts(context).into_iter());
|
||||
top_map.extend_shortcuts(self.bottom.shortcuts(context));
|
||||
top_map
|
||||
}
|
||||
|
||||
|
@ -243,7 +246,7 @@ impl Component for VSplit {
|
|||
|
||||
fn shortcuts(&self, context: &Context) -> ShortcutMaps {
|
||||
let mut right_map = self.right.shortcuts(context);
|
||||
right_map.extend(self.left.shortcuts(context).into_iter());
|
||||
right_map.extend_shortcuts(self.left.shortcuts(context));
|
||||
right_map
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue