listing: add set operations to range select actions

Add symmetric difference (default), union, difference and intersection
modifiers for selecting ranges. That way you can quickly construct the
selection set you need.
jmap-eventsource
Manos Pitsidianakis 2020-10-21 14:30:44 +03:00
parent 05ef863a45
commit 594a2bd0dd
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
7 changed files with 365 additions and 60 deletions

View File

@ -43,6 +43,20 @@ pub use self::plain::*;
mod offline;
pub use self::offline::*;
#[derive(Debug, Copy, PartialEq, Clone)]
pub enum Modifier {
SymmetricDifference,
Union,
Difference,
Intersection,
}
impl Default for Modifier {
fn default() -> Self {
Modifier::SymmetricDifference
}
}
#[derive(Debug, Default, Clone)]
pub struct DataColumns {
pub columns: [CellBuffer; 12],
@ -372,7 +386,12 @@ pub trait ListingTrait: Component {
_context: &Context,
) {
}
fn set_command_modifier(&mut self, _is_active: bool) {}
fn unfocused(&self) -> bool;
fn set_modifier_active(&mut self, _new_val: bool) {}
fn set_modifier_command(&mut self, _new_val: Option<Modifier>) {}
fn modifier_command(&self) -> Option<Modifier> {
None
}
fn set_movement(&mut self, mvm: PageMovement);
}
@ -711,14 +730,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -764,14 +783,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -887,14 +906,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -910,14 +929,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -933,14 +952,14 @@ impl Component for Listing {
1
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
mult
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -956,14 +975,14 @@ impl Component for Listing {
1
} else if let Ok(mult) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
mult
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -1022,6 +1041,31 @@ impl Component for Listing {
}
return true;
}
UIEvent::Input(ref key)
if !self.component.unfocused()
&& shortcut!(key == shortcuts[Listing::DESCRIPTION]["union_modifier"])
&& self.component.modifier_command().is_some() =>
{
self.component.set_modifier_command(Some(Modifier::Union));
}
UIEvent::Input(ref key)
if !self.component.unfocused()
&& shortcut!(key == shortcuts[Listing::DESCRIPTION]["diff_modifier"])
&& self.component.modifier_command().is_some() =>
{
self.component
.set_modifier_command(Some(Modifier::Difference));
}
UIEvent::Input(ref key)
if !self.component.unfocused()
&& shortcut!(
key == shortcuts[Listing::DESCRIPTION]["intersection_modifier"]
)
&& self.component.modifier_command().is_some() =>
{
self.component
.set_modifier_command(Some(Modifier::Intersection));
}
_ => {}
}
} else if self.focus == ListingFocus::Menu {
@ -1055,14 +1099,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -1109,14 +1153,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -1165,14 +1209,14 @@ impl Component for Listing {
1
} else if let Ok(amount) = self.cmd_buf.parse::<usize>() {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
amount
} else {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -1240,7 +1284,7 @@ impl Component for Listing {
}
UIEvent::Input(Key::Esc) | UIEvent::Input(Key::Alt('')) if !self.cmd_buf.is_empty() => {
self.cmd_buf.clear();
self.component.set_command_modifier(false);
self.component.set_modifier_active(false);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufClear));
@ -1248,7 +1292,7 @@ impl Component for Listing {
}
UIEvent::Input(Key::Char(c)) if c >= '0' && c <= '9' => {
self.cmd_buf.push(c);
self.component.set_command_modifier(true);
self.component.set_modifier_active(true);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::BufSet(

View File

@ -19,7 +19,6 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use super::EntryStrings;
use super::*;
use crate::components::PageMovement;
use crate::jobs::JoinHandle;
@ -153,7 +152,7 @@ pub struct CompactListing {
movement: Option<PageMovement>,
modifier_active: bool,
modifier_command: Option<char>,
modifier_command: Option<Modifier>,
id: ComponentId,
}
@ -595,7 +594,9 @@ impl ListingTrait for CompactListing {
self.highlight_line(grid, new_area, *idx, context);
context.dirty_areas.push_back(new_area);
}
if !self.force_draw {
return;
}
} else if self.cursor_pos != self.new_cursor_pos {
self.cursor_pos = self.new_cursor_pos;
}
@ -852,8 +853,20 @@ impl ListingTrait for CompactListing {
}
}
fn set_command_modifier(&mut self, is_active: bool) {
self.modifier_active = is_active;
fn unfocused(&self) -> bool {
self.unfocused
}
fn set_modifier_active(&mut self, new_val: bool) {
self.modifier_active = new_val;
}
fn set_modifier_command(&mut self, new_val: Option<Modifier>) {
self.modifier_command = new_val;
}
fn modifier_command(&self) -> Option<Modifier> {
self.modifier_command
}
fn set_movement(&mut self, mvm: PageMovement) {
@ -1406,8 +1419,7 @@ impl Component for CompactListing {
let (upper_left, bottom_right) = area;
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
if let Some('s') = self.modifier_command.take() {
self.set_command_modifier(false);
if let Some(modifier) = self.modifier_command.take() {
if let Some(mvm) = self.movement.as_ref() {
match mvm {
PageMovement::Up(amount) => {
@ -1415,16 +1427,47 @@ impl Component for CompactListing {
..=self.new_cursor_pos.2
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (0..self.new_cursor_pos.2.saturating_sub(*amount))
.chain((self.new_cursor_pos.2 + 2)..self.length)
{
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::PageUp(multiplier) => {
for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
..=self.new_cursor_pos.2
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
}
@ -1433,9 +1476,30 @@ impl Component for CompactListing {
..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (0..self.new_cursor_pos.2).chain(
(std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
+ 1)..self.length,
) {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::PageDown(multiplier) => {
for c in self.new_cursor_pos.2
@ -1445,28 +1509,88 @@ impl Component for CompactListing {
)
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (0..self.new_cursor_pos.2).chain(
(std::cmp::min(
self.new_cursor_pos.2 + rows * multiplier + 1,
self.length,
) + 1)..self.length,
) {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::Right(_) | PageMovement::Left(_) => {}
PageMovement::Home => {
for c in 0..=self.new_cursor_pos.2 {
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (self.new_cursor_pos.2 + 1)..self.length {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::End => {
for c in self.new_cursor_pos.2..self.length {
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in 0..self.new_cursor_pos.2 {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
}
}
self.force_draw = true;
}
if !self.row_updates.is_empty() {
while let Some(row) = self.row_updates.pop() {
@ -1540,12 +1664,10 @@ impl Component for CompactListing {
}
UIEvent::Input(ref key)
if !self.unfocused
&& shortcut!(
key == shortcuts[CompactListing::DESCRIPTION]["select_entry"]
) =>
&& shortcut!(key == shortcuts[Listing::DESCRIPTION]["select_entry"]) =>
{
if self.modifier_active {
self.modifier_command = Some('s');
if self.modifier_active && self.modifier_command.is_none() {
self.modifier_command = Some(Modifier::default());
} else {
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2);
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
@ -1783,6 +1905,8 @@ impl Component for CompactListing {
let config_map = context.settings.shortcuts.compact_listing.key_values();
map.insert(CompactListing::DESCRIPTION, config_map);
let config_map = context.settings.shortcuts.listing.key_values();
map.insert(Listing::DESCRIPTION, config_map);
map
}

View File

@ -120,7 +120,7 @@ pub struct ConversationsListing {
movement: Option<PageMovement>,
modifier_active: bool,
modifier_command: Option<char>,
modifier_command: Option<Modifier>,
id: ComponentId,
}
@ -868,8 +868,20 @@ impl ListingTrait for ConversationsListing {
}
}
fn set_command_modifier(&mut self, is_active: bool) {
self.modifier_active = is_active;
fn unfocused(&self) -> bool {
self.unfocused
}
fn set_modifier_active(&mut self, new_val: bool) {
self.modifier_active = new_val;
}
fn set_modifier_command(&mut self, new_val: Option<Modifier>) {
self.modifier_command = new_val;
}
fn modifier_command(&self) -> Option<Modifier> {
self.modifier_command
}
fn set_movement(&mut self, mvm: PageMovement) {
@ -1260,8 +1272,7 @@ impl Component for ConversationsListing {
}
let (upper_left, bottom_right) = area;
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 3;
if let Some('s') = self.modifier_command.take() {
self.set_command_modifier(false);
if let Some(modifier) = self.modifier_command.take() {
if let Some(mvm) = self.movement.as_ref() {
match mvm {
PageMovement::Up(amount) => {
@ -1269,16 +1280,47 @@ impl Component for ConversationsListing {
..=self.new_cursor_pos.2
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (0..self.new_cursor_pos.2.saturating_sub(*amount))
.chain((self.new_cursor_pos.2 + 2)..self.length)
{
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::PageUp(multiplier) => {
for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
..=self.new_cursor_pos.2
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
}
@ -1287,9 +1329,30 @@ impl Component for ConversationsListing {
..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (0..self.new_cursor_pos.2).chain(
(std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
+ 1)..self.length,
) {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::PageDown(multiplier) => {
for c in self.new_cursor_pos.2
@ -1299,24 +1362,83 @@ impl Component for ConversationsListing {
)
{
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (0..self.new_cursor_pos.2).chain(
(std::cmp::min(
self.new_cursor_pos.2 + rows * multiplier + 1,
self.length,
) + 1)..self.length,
) {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::Right(_) | PageMovement::Left(_) => {}
PageMovement::Home => {
for c in 0..=self.new_cursor_pos.2 {
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in (self.new_cursor_pos.2 + 1)..self.length {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
PageMovement::End => {
for c in self.new_cursor_pos.2..self.length {
let thread = self.get_thread_under_cursor(c);
match modifier {
Modifier::SymmetricDifference => {
self.selection.entry(thread).and_modify(|e| *e = !*e);
}
Modifier::Union => {
self.selection.entry(thread).and_modify(|e| *e = true);
}
Modifier::Difference => {
self.selection.entry(thread).and_modify(|e| *e = false);
}
Modifier::Intersection => {}
}
self.row_updates.push(thread);
}
if modifier == Modifier::Intersection {
for c in 0..self.new_cursor_pos.2 {
let thread = self.get_thread_under_cursor(c);
self.selection.entry(thread).and_modify(|e| *e = false);
self.row_updates.push(thread);
}
}
}
}
}
@ -1402,12 +1524,10 @@ impl Component for ConversationsListing {
}
UIEvent::Input(ref key)
if !self.unfocused
&& shortcut!(
key == shortcuts[ConversationsListing::DESCRIPTION]["select_entry"]
) =>
&& shortcut!(key == shortcuts[Listing::DESCRIPTION]["select_entry"]) =>
{
if self.modifier_active {
self.modifier_command = Some('s');
if self.modifier_active && self.modifier_command.is_none() {
self.modifier_command = Some(Modifier::default());
} else {
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2);
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
@ -1631,6 +1751,8 @@ impl Component for ConversationsListing {
let config_map = context.settings.shortcuts.compact_listing.key_values();
map.insert(ConversationsListing::DESCRIPTION, config_map);
let config_map = context.settings.shortcuts.listing.key_values();
map.insert(Listing::DESCRIPTION, config_map);
map
}

View File

@ -79,6 +79,10 @@ impl ListingTrait for OfflineListing {
fn draw_list(&mut self, _: &mut CellBuffer, _: Area, _: &mut Context) {}
fn unfocused(&self) -> bool {
false
}
fn set_movement(&mut self, _: PageMovement) {}
}

View File

@ -703,6 +703,10 @@ impl ListingTrait for PlainListing {
}
}
fn unfocused(&self) -> bool {
self.unfocused
}
fn set_movement(&mut self, mvm: PageMovement) {
self.movement = Some(mvm);
self.set_dirty(true);
@ -1182,9 +1186,7 @@ impl Component for PlainListing {
}
UIEvent::Input(ref key)
if !self.unfocused
&& shortcut!(
key == shortcuts[PlainListing::DESCRIPTION]["select_entry"]
) =>
&& shortcut!(key == shortcuts[Listing::DESCRIPTION]["select_entry"]) =>
{
let env_hash = self.get_env_under_cursor(self.cursor_pos.2, context);
self.selection.entry(env_hash).and_modify(|e| *e = !*e);
@ -1388,6 +1390,8 @@ impl Component for PlainListing {
let config_map = context.settings.shortcuts.compact_listing.key_values();
map.insert(PlainListing::DESCRIPTION, config_map);
let config_map = context.settings.shortcuts.listing.key_values();
map.insert(Listing::DESCRIPTION, config_map);
map
}

View File

@ -734,6 +734,10 @@ impl ListingTrait for ThreadListing {
}
}
fn unfocused(&self) -> bool {
self.unfocused
}
fn set_movement(&mut self, mvm: PageMovement) {
self.movement = Some(mvm);
self.set_dirty(true);

View File

@ -160,8 +160,7 @@ shortcut_key_values! { "compact-listing",
/// Shortcut listing for a mail listing in compact mode.
pub struct CompactListingShortcuts {
exit_thread |> "Exit thread view." |> Key::Char('i'),
open_thread |> "Open thread." |> Key::Char('\n'),
select_entry |> "Select thread entry." |> Key::Char('v')
open_thread |> "Open thread." |> Key::Char('\n')
}
}
@ -181,6 +180,10 @@ shortcut_key_values! { "listing",
search |> "Search within list of e-mails." |> Key::Char('/'),
refresh |> "Manually request a mailbox refresh." |> Key::F(5),
set_seen |> "Set thread as seen." |> Key::Char('n'),
union_modifier |> "Union modifier." |> Key::Ctrl('u'),
diff_modifier |> "Difference modifier." |> Key::Ctrl('d'),
intersection_modifier |> "Intersection modifier." |> Key::Ctrl('i'),
select_entry |> "Select thread entry." |> Key::Char('v'),
toggle_menu_visibility |> "Toggle visibility of side menu in mail list." |> Key::Char('`')
}
}