Command::Move: Add support for extreme moves
This patch adds a 'MoveAmount' enum that permits movements by integer values or to abstract extremes which loosely translate to "top" for up direction, "bottom" for down direction, etc. The goal behind the effort is to add support for buttons like "Home" and "End". The new enum has a 'Default' impl that yields a value of integer movement by 1 field. This replaces the previous 'Option' wrap, that in fact served the same purpose, with the value of '1' scattered around different places in code. Along with the enum, new commands have been defined to make use of it: - "move top" - "move bottom" - "move leftmost" - "move rightmost"
This commit is contained in:
committed by
Henrik Friedrichsen
parent
1b0ac4d5cc
commit
07be9dc48d
@@ -28,6 +28,19 @@ pub enum MoveMode {
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Display, Clone, Serialize, Deserialize, Debug)]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum MoveAmount {
|
||||
Integer(i32),
|
||||
Extreme,
|
||||
}
|
||||
|
||||
impl Default for MoveAmount {
|
||||
fn default() -> Self {
|
||||
MoveAmount::Integer(1)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Display, Clone, Serialize, Deserialize, Debug)]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
pub enum ShiftMode {
|
||||
@@ -84,7 +97,7 @@ pub enum Command {
|
||||
Back,
|
||||
Open(TargetMode),
|
||||
Goto(GotoMode),
|
||||
Move(MoveMode, Option<i32>),
|
||||
Move(MoveMode, MoveAmount),
|
||||
Shift(ShiftMode, Option<i32>),
|
||||
Search(String),
|
||||
Help,
|
||||
@@ -124,7 +137,15 @@ impl fmt::Display for Command {
|
||||
Command::Back => "back".to_string(),
|
||||
Command::Open(mode) => format!("open {}", mode),
|
||||
Command::Goto(mode) => format!("goto {}", mode),
|
||||
Command::Move(mode, amount) => format!("move {} {}", mode, amount.unwrap_or(1)),
|
||||
Command::Move(mode, MoveAmount::Extreme) => {
|
||||
format!("move {}", match mode {
|
||||
MoveMode::Up => "top",
|
||||
MoveMode::Down => "bottom",
|
||||
MoveMode::Left => "leftmost",
|
||||
MoveMode::Right => "rightmost",
|
||||
})
|
||||
},
|
||||
Command::Move(mode, MoveAmount::Integer(amount)) => format!("move {} {}", mode, amount),
|
||||
Command::Shift(mode, amount) => format!("shift {} {}", mode, amount.unwrap_or(1)),
|
||||
Command::Search(term) => format!("search {}", term),
|
||||
Command::Help => "help".to_string(),
|
||||
@@ -207,17 +228,33 @@ pub fn parse(input: &str) -> Option<Command> {
|
||||
.map(|mode| Command::Shift(mode, amount))
|
||||
}
|
||||
"move" => {
|
||||
let amount = args.get(1).and_then(|amount| amount.parse().ok());
|
||||
let cmd: Option<Command> = {
|
||||
args.get(0)
|
||||
.and_then(|extreme| match *extreme {
|
||||
"top" => Some(Command::Move(MoveMode::Up, MoveAmount::Extreme)),
|
||||
"bottom" => Some(Command::Move(MoveMode::Down, MoveAmount::Extreme)),
|
||||
"leftmost" => Some(Command::Move(MoveMode::Left, MoveAmount::Extreme)),
|
||||
"rightmost" => Some(Command::Move(MoveMode::Right, MoveAmount::Extreme)),
|
||||
_ => None
|
||||
})
|
||||
};
|
||||
|
||||
args.get(0)
|
||||
.and_then(|direction| match *direction {
|
||||
"up" => Some(MoveMode::Up),
|
||||
"down" => Some(MoveMode::Down),
|
||||
"left" => Some(MoveMode::Left),
|
||||
"right" => Some(MoveMode::Right),
|
||||
_ => None,
|
||||
})
|
||||
.map(|mode| Command::Move(mode, amount))
|
||||
cmd.or({
|
||||
let amount = args.get(1)
|
||||
.and_then(|amount| amount.parse().ok())
|
||||
.map(|amount| MoveAmount::Integer(amount))
|
||||
.unwrap_or_default();
|
||||
|
||||
args.get(0)
|
||||
.and_then(|direction| match *direction {
|
||||
"up" => Some(MoveMode::Up),
|
||||
"down" => Some(MoveMode::Down),
|
||||
"left" => Some(MoveMode::Left),
|
||||
"right" => Some(MoveMode::Right),
|
||||
_ => None,
|
||||
})
|
||||
.map(|mode| Command::Move(mode, amount))
|
||||
})
|
||||
}
|
||||
"goto" => args
|
||||
.get(0)
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::command::{parse, Command, GotoMode, MoveMode, SeekDirection, ShiftMode, TargetMode};
|
||||
use crate::command::{parse, Command, GotoMode, MoveAmount, MoveMode, SeekDirection, ShiftMode, TargetMode};
|
||||
use crate::library::Library;
|
||||
use crate::queue::{Queue, RepeatSetting};
|
||||
use crate::spotify::{Spotify, VOLUME_PERCENT};
|
||||
@@ -262,21 +262,23 @@ impl CommandManager {
|
||||
kb.insert("a".into(), Command::Goto(GotoMode::Album));
|
||||
kb.insert("A".into(), Command::Goto(GotoMode::Artist));
|
||||
|
||||
kb.insert("Up".into(), Command::Move(MoveMode::Up, None));
|
||||
kb.insert("Down".into(), Command::Move(MoveMode::Down, None));
|
||||
kb.insert("Left".into(), Command::Move(MoveMode::Left, None));
|
||||
kb.insert("Right".into(), Command::Move(MoveMode::Right, None));
|
||||
kb.insert("PageUp".into(), Command::Move(MoveMode::Up, Some(5)));
|
||||
kb.insert("PageDown".into(), Command::Move(MoveMode::Down, Some(5)));
|
||||
kb.insert("k".into(), Command::Move(MoveMode::Up, None));
|
||||
kb.insert("j".into(), Command::Move(MoveMode::Down, None));
|
||||
kb.insert("h".into(), Command::Move(MoveMode::Left, None));
|
||||
kb.insert("l".into(), Command::Move(MoveMode::Right, None));
|
||||
kb.insert("Up".into(), Command::Move(MoveMode::Up, Default::default()));
|
||||
kb.insert("Down".into(), Command::Move(MoveMode::Down, Default::default()));
|
||||
kb.insert("Left".into(), Command::Move(MoveMode::Left, Default::default()));
|
||||
kb.insert("Right".into(), Command::Move(MoveMode::Right, Default::default()));
|
||||
kb.insert("PageUp".into(), Command::Move(MoveMode::Up, MoveAmount::Integer(5)));
|
||||
kb.insert("PageDown".into(), Command::Move(MoveMode::Down, MoveAmount::Integer(5)));
|
||||
kb.insert("Home".into(), Command::Move(MoveMode::Up, MoveAmount::Extreme));
|
||||
kb.insert("End".into(), Command::Move(MoveMode::Down, MoveAmount::Extreme));
|
||||
kb.insert("k".into(), Command::Move(MoveMode::Up, Default::default()));
|
||||
kb.insert("j".into(), Command::Move(MoveMode::Down, Default::default()));
|
||||
kb.insert("h".into(), Command::Move(MoveMode::Left, Default::default()));
|
||||
kb.insert("l".into(), Command::Move(MoveMode::Right, Default::default()));
|
||||
|
||||
kb.insert("Ctrl+p".into(), Command::Move(MoveMode::Up, None));
|
||||
kb.insert("Ctrl+n".into(), Command::Move(MoveMode::Down, None));
|
||||
kb.insert("Ctrl+a".into(), Command::Move(MoveMode::Left, None));
|
||||
kb.insert("Ctrl+e".into(), Command::Move(MoveMode::Right, None));
|
||||
kb.insert("Ctrl+p".into(), Command::Move(MoveMode::Up, Default::default()));
|
||||
kb.insert("Ctrl+n".into(), Command::Move(MoveMode::Down, Default::default()));
|
||||
kb.insert("Ctrl+a".into(), Command::Move(MoveMode::Left, Default::default()));
|
||||
kb.insert("Ctrl+e".into(), Command::Move(MoveMode::Right, Default::default()));
|
||||
|
||||
kb.insert("Shift+Up".into(), Command::Shift(ShiftMode::Up, None));
|
||||
kb.insert("Shift+Down".into(), Command::Shift(ShiftMode::Down, None));
|
||||
|
||||
@@ -9,7 +9,7 @@ use cursive::view::ScrollBase;
|
||||
use cursive::{Cursive, Printer, Rect, Vec2};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::command::{Command, GotoMode, MoveMode, TargetMode};
|
||||
use crate::command::{Command, GotoMode, MoveAmount, MoveMode, TargetMode};
|
||||
use crate::commands::CommandResult;
|
||||
use crate::library::Library;
|
||||
use crate::queue::Queue;
|
||||
@@ -359,24 +359,25 @@ impl<I: ListItem + Clone> ViewExt for ListView<I> {
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
Command::Move(mode, amount) => {
|
||||
let amount = match amount {
|
||||
Some(amount) => *amount,
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
let len = self.content.read().unwrap().len();
|
||||
let last_idx = self.content.read().unwrap().len().saturating_sub(1);
|
||||
|
||||
match mode {
|
||||
MoveMode::Up if self.selected > 0 => {
|
||||
self.move_focus(-(amount as i32));
|
||||
match amount {
|
||||
MoveAmount::Extreme => self.move_focus_to(0),
|
||||
MoveAmount::Integer(amount) => self.move_focus(-(*amount)),
|
||||
}
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
MoveMode::Down if self.selected < len.saturating_sub(1) => {
|
||||
self.move_focus(amount as i32);
|
||||
MoveMode::Down if self.selected < last_idx => {
|
||||
match amount {
|
||||
MoveAmount::Extreme => self.move_focus_to(last_idx),
|
||||
MoveAmount::Integer(amount) => self.move_focus(*amount),
|
||||
}
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
MoveMode::Down
|
||||
if self.selected == len.saturating_sub(1) && self.can_paginate() =>
|
||||
if self.selected == last_idx && self.can_paginate() =>
|
||||
{
|
||||
self.pagination.call(&self.content);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use cursive::traits::View;
|
||||
use cursive::{Cursive, Printer, Vec2};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::command::{Command, MoveMode};
|
||||
use crate::command::{Command, MoveAmount, MoveMode};
|
||||
use crate::commands::CommandResult;
|
||||
use crate::traits::{IntoBoxedViewExt, ViewExt};
|
||||
|
||||
@@ -105,20 +105,21 @@ impl View for TabView {
|
||||
impl ViewExt for TabView {
|
||||
fn on_command(&mut self, s: &mut Cursive, cmd: &Command) -> Result<CommandResult, String> {
|
||||
if let Command::Move(mode, amount) = cmd {
|
||||
let amount = match amount {
|
||||
Some(amount) => *amount,
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
let len = self.tabs.len();
|
||||
let last_idx = self.tabs.len() - 1;
|
||||
|
||||
match mode {
|
||||
MoveMode::Left if self.selected > 0 => {
|
||||
self.move_focus(-(amount as i32));
|
||||
match amount {
|
||||
MoveAmount::Extreme => self.move_focus_to(0),
|
||||
MoveAmount::Integer(amount) => self.move_focus(-(*amount)),
|
||||
}
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
MoveMode::Right if self.selected < len - 1 => {
|
||||
self.move_focus(amount as i32);
|
||||
MoveMode::Right if self.selected < last_idx => {
|
||||
match amount {
|
||||
MoveAmount::Extreme => self.move_focus_to(last_idx),
|
||||
MoveAmount::Integer(amount) => self.move_focus(*amount),
|
||||
}
|
||||
return Ok(CommandResult::Consumed(None));
|
||||
}
|
||||
_ => {}
|
||||
|
||||
Reference in New Issue
Block a user