mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-26 22:15:19 +03:00
feat(controls): add quick navigation (#260)
* feat(input): quick navigation * feat(ui): quick navigation * style(fmt): rustfmt
This commit is contained in:
parent
c25eb04de9
commit
65c75ebb95
@ -63,8 +63,8 @@ impl ZellijTile for State {
|
||||
let second_line = keybinds(&self.mode_info, cols);
|
||||
|
||||
// [48;5;238m is gray background, [0K is so that it fills the rest of the line
|
||||
// [48;5;16m is black background, [0K is so that it fills the rest of the line
|
||||
// [m is background reset, [0K is so that it clears the rest of the line
|
||||
println!("{}\u{1b}[48;5;238m\u{1b}[0K", first_line);
|
||||
println!("{}\u{1b}[48;5;16m\u{1b}[0K", second_line);
|
||||
println!("\u{1b}[m{}\u{1b}[0K", second_line);
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,122 @@ fn first_word_shortcut(is_first_shortcut: bool, letter: &str, description: &str)
|
||||
len,
|
||||
}
|
||||
}
|
||||
fn quicknav_full() -> LinePart {
|
||||
let text_first_part = " Tip: ";
|
||||
let alt = "Alt";
|
||||
let text_second_part = " + ";
|
||||
let new_pane_shortcut = "n";
|
||||
let text_third_part = " => open new pane. ";
|
||||
let second_alt = "Alt";
|
||||
let text_fourth_part = " + ";
|
||||
let brackets_navigation = "[]";
|
||||
let text_fifth_part = " or ";
|
||||
let hjkl_navigation = "hjkl";
|
||||
let text_sixths_part = " => navigate between panes.";
|
||||
let len = text_first_part.chars().count()
|
||||
+ alt.chars().count()
|
||||
+ text_second_part.chars().count()
|
||||
+ new_pane_shortcut.chars().count()
|
||||
+ text_third_part.chars().count()
|
||||
+ second_alt.chars().count()
|
||||
+ text_fourth_part.chars().count()
|
||||
+ brackets_navigation.chars().count()
|
||||
+ text_fifth_part.chars().count()
|
||||
+ hjkl_navigation.chars().count()
|
||||
+ text_sixths_part.chars().count();
|
||||
LinePart {
|
||||
part: format!(
|
||||
"{}{}{}{}{}{}{}{}{}{}{}",
|
||||
text_first_part,
|
||||
Style::new().fg(ORANGE).bold().paint(alt),
|
||||
text_second_part,
|
||||
Style::new().fg(GREEN).bold().paint(new_pane_shortcut),
|
||||
text_third_part,
|
||||
Style::new().fg(ORANGE).bold().paint(second_alt),
|
||||
text_fourth_part,
|
||||
Style::new().fg(GREEN).bold().paint(brackets_navigation),
|
||||
text_fifth_part,
|
||||
Style::new().fg(GREEN).bold().paint(hjkl_navigation),
|
||||
text_sixths_part,
|
||||
),
|
||||
len,
|
||||
}
|
||||
}
|
||||
|
||||
fn quicknav_medium() -> LinePart {
|
||||
let text_first_part = " Tip: ";
|
||||
let alt = "Alt";
|
||||
let text_second_part = " + ";
|
||||
let new_pane_shortcut = "n";
|
||||
let text_third_part = " => new pane. ";
|
||||
let second_alt = "Alt";
|
||||
let text_fourth_part = " + ";
|
||||
let brackets_navigation = "[]";
|
||||
let text_fifth_part = " or ";
|
||||
let hjkl_navigation = "hjkl";
|
||||
let text_sixths_part = " => navigate.";
|
||||
let len = text_first_part.chars().count()
|
||||
+ alt.chars().count()
|
||||
+ text_second_part.chars().count()
|
||||
+ new_pane_shortcut.chars().count()
|
||||
+ text_third_part.chars().count()
|
||||
+ second_alt.chars().count()
|
||||
+ text_fourth_part.chars().count()
|
||||
+ brackets_navigation.chars().count()
|
||||
+ text_fifth_part.chars().count()
|
||||
+ hjkl_navigation.chars().count()
|
||||
+ text_sixths_part.chars().count();
|
||||
LinePart {
|
||||
part: format!(
|
||||
"{}{}{}{}{}{}{}{}{}{}{}",
|
||||
text_first_part,
|
||||
Style::new().fg(ORANGE).bold().paint(alt),
|
||||
text_second_part,
|
||||
Style::new().fg(GREEN).bold().paint(new_pane_shortcut),
|
||||
text_third_part,
|
||||
Style::new().fg(ORANGE).bold().paint(second_alt),
|
||||
text_fourth_part,
|
||||
Style::new().fg(GREEN).bold().paint(brackets_navigation),
|
||||
text_fifth_part,
|
||||
Style::new().fg(GREEN).bold().paint(hjkl_navigation),
|
||||
text_sixths_part,
|
||||
),
|
||||
len,
|
||||
}
|
||||
}
|
||||
|
||||
fn quicknav_short() -> LinePart {
|
||||
let text_first_part = " QuickNav: ";
|
||||
let alt = "Alt";
|
||||
let text_second_part = " + ";
|
||||
let new_pane_shortcut = "n";
|
||||
let text_third_part = "/";
|
||||
let brackets_navigation = "[]";
|
||||
let text_fifth_part = "/";
|
||||
let hjkl_navigation = "hjkl";
|
||||
let len = text_first_part.chars().count()
|
||||
+ alt.chars().count()
|
||||
+ text_second_part.chars().count()
|
||||
+ new_pane_shortcut.chars().count()
|
||||
+ text_third_part.chars().count()
|
||||
+ brackets_navigation.chars().count()
|
||||
+ text_fifth_part.chars().count()
|
||||
+ hjkl_navigation.chars().count();
|
||||
LinePart {
|
||||
part: format!(
|
||||
"{}{}{}{}{}{}{}{}",
|
||||
text_first_part,
|
||||
Style::new().fg(ORANGE).bold().paint(alt),
|
||||
text_second_part,
|
||||
Style::new().fg(GREEN).bold().paint(new_pane_shortcut),
|
||||
text_third_part,
|
||||
Style::new().fg(GREEN).bold().paint(brackets_navigation),
|
||||
text_fifth_part,
|
||||
Style::new().fg(GREEN).bold().paint(hjkl_navigation),
|
||||
),
|
||||
len,
|
||||
}
|
||||
}
|
||||
|
||||
fn locked_interface_indication() -> LinePart {
|
||||
let locked_text = " -- INTERFACE LOCKED -- ";
|
||||
@ -99,7 +215,7 @@ fn select_pane_shortcut(is_first_shortcut: bool) -> LinePart {
|
||||
|
||||
fn full_shortcut_list(help: &ModeInfo) -> LinePart {
|
||||
match help.mode {
|
||||
InputMode::Normal => LinePart::default(),
|
||||
InputMode::Normal => quicknav_full(),
|
||||
InputMode::Locked => locked_interface_indication(),
|
||||
_ => {
|
||||
let mut line_part = LinePart::default();
|
||||
@ -118,7 +234,7 @@ fn full_shortcut_list(help: &ModeInfo) -> LinePart {
|
||||
|
||||
fn shortened_shortcut_list(help: &ModeInfo) -> LinePart {
|
||||
match help.mode {
|
||||
InputMode::Normal => LinePart::default(),
|
||||
InputMode::Normal => quicknav_medium(),
|
||||
InputMode::Locked => locked_interface_indication(),
|
||||
_ => {
|
||||
let mut line_part = LinePart::default();
|
||||
@ -137,7 +253,14 @@ fn shortened_shortcut_list(help: &ModeInfo) -> LinePart {
|
||||
|
||||
fn best_effort_shortcut_list(help: &ModeInfo, max_len: usize) -> LinePart {
|
||||
match help.mode {
|
||||
InputMode::Normal => LinePart::default(),
|
||||
InputMode::Normal => {
|
||||
let line_part = quicknav_short();
|
||||
if line_part.len <= max_len {
|
||||
line_part
|
||||
} else {
|
||||
LinePart::default()
|
||||
}
|
||||
}
|
||||
InputMode::Locked => {
|
||||
let line_part = locked_interface_indication();
|
||||
if line_part.len <= max_len {
|
||||
@ -157,7 +280,7 @@ fn best_effort_shortcut_list(help: &ModeInfo, max_len: usize) -> LinePart {
|
||||
break;
|
||||
}
|
||||
line_part.len += shortcut.len;
|
||||
line_part.part = format!("{}{}", line_part.part, shortcut,);
|
||||
line_part.part = format!("{}{}", line_part.part, shortcut);
|
||||
}
|
||||
let select_pane_shortcut = select_pane_shortcut(help.keybinds.is_empty());
|
||||
if line_part.len + select_pane_shortcut.len <= max_len {
|
||||
|
@ -21,9 +21,9 @@ pub mod boundary_type {
|
||||
|
||||
pub mod colors {
|
||||
use ansi_term::Colour::{self, Fixed};
|
||||
pub const WHITE: Colour = Fixed(255);
|
||||
pub const GREEN: Colour = Fixed(154);
|
||||
pub const GRAY: Colour = Fixed(238);
|
||||
pub const ORANGE: Colour = Fixed(166);
|
||||
}
|
||||
|
||||
pub type BoundaryType = &'static str; // easy way to refer to boundary_type above
|
||||
@ -768,7 +768,7 @@ impl Boundaries {
|
||||
let color = match color.is_some() {
|
||||
true => match input_mode {
|
||||
InputMode::Normal | InputMode::Locked => Some(colors::GREEN),
|
||||
_ => Some(colors::WHITE),
|
||||
_ => Some(colors::ORANGE),
|
||||
},
|
||||
false => None,
|
||||
};
|
||||
|
@ -1809,6 +1809,62 @@ impl Tab {
|
||||
}
|
||||
self.render();
|
||||
}
|
||||
pub fn focus_next_pane(&mut self) {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
return;
|
||||
}
|
||||
let active_pane_id = self.get_active_pane_id().unwrap();
|
||||
let mut panes: Vec<(&PaneId, &Box<dyn Pane>)> = self.get_selectable_panes().collect();
|
||||
panes.sort_by(|(_a_id, a_pane), (_b_id, b_pane)| {
|
||||
if a_pane.y() == b_pane.y() {
|
||||
a_pane.x().cmp(&b_pane.x())
|
||||
} else {
|
||||
a_pane.y().cmp(&b_pane.y())
|
||||
}
|
||||
});
|
||||
let first_pane = panes.get(0).unwrap();
|
||||
let active_pane_position = panes
|
||||
.iter()
|
||||
.position(|(id, _)| *id == &active_pane_id) // TODO: better
|
||||
.unwrap();
|
||||
if let Some(next_pane) = panes.get(active_pane_position + 1) {
|
||||
self.active_terminal = Some(*next_pane.0);
|
||||
} else {
|
||||
self.active_terminal = Some(*first_pane.0);
|
||||
}
|
||||
self.render();
|
||||
}
|
||||
pub fn focus_previous_pane(&mut self) {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
return;
|
||||
}
|
||||
let active_pane_id = self.get_active_pane_id().unwrap();
|
||||
let mut panes: Vec<(&PaneId, &Box<dyn Pane>)> = self.get_selectable_panes().collect();
|
||||
panes.sort_by(|(_a_id, a_pane), (_b_id, b_pane)| {
|
||||
if a_pane.y() == b_pane.y() {
|
||||
a_pane.x().cmp(&b_pane.x())
|
||||
} else {
|
||||
a_pane.y().cmp(&b_pane.y())
|
||||
}
|
||||
});
|
||||
let last_pane = panes.last().unwrap();
|
||||
let active_pane_position = panes
|
||||
.iter()
|
||||
.position(|(id, _)| *id == &active_pane_id) // TODO: better
|
||||
.unwrap();
|
||||
if active_pane_position == 0 {
|
||||
self.active_terminal = Some(*last_pane.0);
|
||||
} else {
|
||||
self.active_terminal = Some(*panes.get(active_pane_position - 1).unwrap().0);
|
||||
}
|
||||
self.render();
|
||||
}
|
||||
pub fn move_focus_left(&mut self) {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
|
@ -178,7 +178,9 @@ pub enum ScreenContext {
|
||||
ResizeRight,
|
||||
ResizeDown,
|
||||
ResizeUp,
|
||||
MoveFocus,
|
||||
SwitchFocus,
|
||||
FocusNextPane,
|
||||
FocusPreviousPane,
|
||||
MoveFocusLeft,
|
||||
MoveFocusDown,
|
||||
MoveFocusUp,
|
||||
@ -218,7 +220,9 @@ impl From<&ScreenInstruction> for ScreenContext {
|
||||
ScreenInstruction::ResizeRight => ScreenContext::ResizeRight,
|
||||
ScreenInstruction::ResizeDown => ScreenContext::ResizeDown,
|
||||
ScreenInstruction::ResizeUp => ScreenContext::ResizeUp,
|
||||
ScreenInstruction::MoveFocus => ScreenContext::MoveFocus,
|
||||
ScreenInstruction::SwitchFocus => ScreenContext::SwitchFocus,
|
||||
ScreenInstruction::FocusNextPane => ScreenContext::FocusNextPane,
|
||||
ScreenInstruction::FocusPreviousPane => ScreenContext::FocusPreviousPane,
|
||||
ScreenInstruction::MoveFocusLeft => ScreenContext::MoveFocusLeft,
|
||||
ScreenInstruction::MoveFocusDown => ScreenContext::MoveFocusDown,
|
||||
ScreenInstruction::MoveFocusUp => ScreenContext::MoveFocusUp,
|
||||
|
@ -24,8 +24,10 @@ pub enum Action {
|
||||
/// Resize focus pane in specified direction.
|
||||
Resize(Direction),
|
||||
/// Switch focus to next pane in specified direction.
|
||||
SwitchFocus(Direction),
|
||||
FocusNextPane,
|
||||
FocusPreviousPane,
|
||||
/// Move the focus pane in specified direction.
|
||||
SwitchFocus,
|
||||
MoveFocus(Direction),
|
||||
/// Scroll up in focus pane.
|
||||
ScrollUp,
|
||||
|
@ -26,6 +26,7 @@ struct InputHandler {
|
||||
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
send_app_instructions: SenderWithContext<AppInstruction>,
|
||||
should_exit: bool,
|
||||
}
|
||||
|
||||
impl InputHandler {
|
||||
@ -48,6 +49,7 @@ impl InputHandler {
|
||||
send_pty_instructions,
|
||||
send_plugin_instructions,
|
||||
send_app_instructions,
|
||||
should_exit: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,30 +62,29 @@ impl InputHandler {
|
||||
self.send_app_instructions.update(err_ctx);
|
||||
self.send_screen_instructions.update(err_ctx);
|
||||
let keybinds = self.config.keybinds.clone();
|
||||
'input_loop: loop {
|
||||
//@@@ I think this should actually just iterate over stdin directly
|
||||
let alt_left_bracket = vec![27, 91];
|
||||
loop {
|
||||
if self.should_exit {
|
||||
break;
|
||||
}
|
||||
let stdin_buffer = self.os_input.read_from_stdin();
|
||||
for key_result in stdin_buffer.events_and_raw() {
|
||||
match key_result {
|
||||
Ok((event, raw_bytes)) => match event {
|
||||
termion::event::Event::Key(key) => {
|
||||
let key = cast_termion_key(key);
|
||||
// FIXME this explicit break is needed because the current test
|
||||
// framework relies on it to not create dead threads that loop
|
||||
// and eat up CPUs. Do not remove until the test framework has
|
||||
// been revised. Sorry about this (@categorille)
|
||||
let mut should_break = false;
|
||||
for action in
|
||||
Keybinds::key_to_actions(&key, raw_bytes, &self.mode, &keybinds)
|
||||
{
|
||||
should_break |= self.dispatch_action(action);
|
||||
}
|
||||
if should_break {
|
||||
break 'input_loop;
|
||||
self.handle_key(&key, raw_bytes, &keybinds);
|
||||
}
|
||||
termion::event::Event::Unsupported(unsupported_key) => {
|
||||
// we have to do this because of a bug in termion
|
||||
// this should be a key event and not an unsupported event
|
||||
if unsupported_key == alt_left_bracket {
|
||||
let key = Key::Alt('[');
|
||||
self.handle_key(&key, raw_bytes, &keybinds);
|
||||
}
|
||||
}
|
||||
termion::event::Event::Mouse(_) | termion::event::Event::Unsupported(_) => {
|
||||
// Mouse and unsupported events aren't implemented yet,
|
||||
termion::event::Event::Mouse(_) => {
|
||||
// Mouse events aren't implemented yet,
|
||||
// use a NoOp untill then.
|
||||
}
|
||||
},
|
||||
@ -92,6 +93,14 @@ impl InputHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn handle_key(&mut self, key: &Key, raw_bytes: Vec<u8>, keybinds: &Keybinds) {
|
||||
for action in Keybinds::key_to_actions(&key, raw_bytes, &self.mode, &keybinds) {
|
||||
let should_exit = self.dispatch_action(action);
|
||||
if should_exit {
|
||||
self.should_exit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dispatches an [`Action`].
|
||||
///
|
||||
@ -144,9 +153,19 @@ impl InputHandler {
|
||||
};
|
||||
self.send_screen_instructions.send(screen_instr).unwrap();
|
||||
}
|
||||
Action::SwitchFocus(_) => {
|
||||
Action::SwitchFocus => {
|
||||
self.send_screen_instructions
|
||||
.send(ScreenInstruction::MoveFocus)
|
||||
.send(ScreenInstruction::SwitchFocus)
|
||||
.unwrap();
|
||||
}
|
||||
Action::FocusNextPane => {
|
||||
self.send_screen_instructions
|
||||
.send(ScreenInstruction::FocusNextPane)
|
||||
.unwrap();
|
||||
}
|
||||
Action::FocusPreviousPane => {
|
||||
self.send_screen_instructions
|
||||
.send(ScreenInstruction::FocusPreviousPane)
|
||||
.unwrap();
|
||||
}
|
||||
Action::MoveFocus(direction) => {
|
||||
|
@ -91,6 +91,14 @@ impl Keybinds {
|
||||
vec![Action::SwitchToMode(InputMode::Scroll)],
|
||||
);
|
||||
defaults.insert(Key::Ctrl('q'), vec![Action::Quit]);
|
||||
|
||||
defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
|
||||
defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
|
||||
defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
|
||||
defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
|
||||
}
|
||||
InputMode::Locked => {
|
||||
defaults.insert(
|
||||
@ -133,6 +141,14 @@ impl Keybinds {
|
||||
defaults.insert(Key::Down, vec![Action::Resize(Direction::Down)]);
|
||||
defaults.insert(Key::Up, vec![Action::Resize(Direction::Up)]);
|
||||
defaults.insert(Key::Right, vec![Action::Resize(Direction::Right)]);
|
||||
|
||||
defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
|
||||
defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
|
||||
defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
|
||||
defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
|
||||
}
|
||||
InputMode::Pane => {
|
||||
defaults.insert(
|
||||
@ -173,7 +189,7 @@ impl Keybinds {
|
||||
defaults.insert(Key::Up, vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Right, vec![Action::MoveFocus(Direction::Right)]);
|
||||
|
||||
defaults.insert(Key::Char('p'), vec![Action::SwitchFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Char('p'), vec![Action::SwitchFocus]);
|
||||
defaults.insert(Key::Char('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Char('d'), vec![Action::NewPane(Some(Direction::Down))]);
|
||||
defaults.insert(
|
||||
@ -182,6 +198,14 @@ impl Keybinds {
|
||||
);
|
||||
defaults.insert(Key::Char('x'), vec![Action::CloseFocus]);
|
||||
defaults.insert(Key::Char('f'), vec![Action::ToggleFocusFullscreen]);
|
||||
|
||||
defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
|
||||
defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
|
||||
defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
|
||||
defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
|
||||
}
|
||||
InputMode::Tab => {
|
||||
defaults.insert(
|
||||
@ -240,6 +264,13 @@ impl Keybinds {
|
||||
for i in '1'..='9' {
|
||||
defaults.insert(Key::Char(i), vec![Action::GoToTab(i.to_digit(10).unwrap())]);
|
||||
}
|
||||
defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
|
||||
defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
|
||||
defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
|
||||
defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
|
||||
}
|
||||
InputMode::Scroll => {
|
||||
defaults.insert(
|
||||
@ -272,6 +303,14 @@ impl Keybinds {
|
||||
|
||||
defaults.insert(Key::Down, vec![Action::ScrollDown]);
|
||||
defaults.insert(Key::Up, vec![Action::ScrollUp]);
|
||||
|
||||
defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
|
||||
defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
|
||||
defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
|
||||
defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
|
||||
}
|
||||
InputMode::RenameTab => {
|
||||
defaults.insert(Key::Char('\n'), vec![Action::SwitchToMode(InputMode::Tab)]);
|
||||
@ -286,6 +325,14 @@ impl Keybinds {
|
||||
Action::SwitchToMode(InputMode::Tab),
|
||||
],
|
||||
);
|
||||
|
||||
defaults.insert(Key::Alt('n'), vec![Action::NewPane(None)]);
|
||||
defaults.insert(Key::Alt('h'), vec![Action::MoveFocus(Direction::Left)]);
|
||||
defaults.insert(Key::Alt('j'), vec![Action::MoveFocus(Direction::Down)]);
|
||||
defaults.insert(Key::Alt('k'), vec![Action::MoveFocus(Direction::Up)]);
|
||||
defaults.insert(Key::Alt('l'), vec![Action::MoveFocus(Direction::Right)]);
|
||||
defaults.insert(Key::Alt('['), vec![Action::FocusPreviousPane]);
|
||||
defaults.insert(Key::Alt(']'), vec![Action::FocusNextPane]);
|
||||
}
|
||||
}
|
||||
ModeKeybinds(defaults)
|
||||
|
@ -326,9 +326,15 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
ScreenInstruction::ResizeUp => {
|
||||
screen.get_active_tab_mut().unwrap().resize_up();
|
||||
}
|
||||
ScreenInstruction::MoveFocus => {
|
||||
ScreenInstruction::SwitchFocus => {
|
||||
screen.get_active_tab_mut().unwrap().move_focus();
|
||||
}
|
||||
ScreenInstruction::FocusNextPane => {
|
||||
screen.get_active_tab_mut().unwrap().focus_next_pane();
|
||||
}
|
||||
ScreenInstruction::FocusPreviousPane => {
|
||||
screen.get_active_tab_mut().unwrap().focus_previous_pane();
|
||||
}
|
||||
ScreenInstruction::MoveFocusLeft => {
|
||||
screen.get_active_tab_mut().unwrap().move_focus_left();
|
||||
}
|
||||
@ -589,7 +595,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
}
|
||||
ApiCommand::MoveFocus => {
|
||||
send_screen_instructions
|
||||
.send(ScreenInstruction::MoveFocus)
|
||||
.send(ScreenInstruction::FocusNextPane)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ pub enum ScreenInstruction {
|
||||
ResizeRight,
|
||||
ResizeDown,
|
||||
ResizeUp,
|
||||
MoveFocus,
|
||||
SwitchFocus,
|
||||
FocusNextPane,
|
||||
FocusPreviousPane,
|
||||
MoveFocusLeft,
|
||||
MoveFocusDown,
|
||||
MoveFocusUp,
|
||||
|
Loading…
Reference in New Issue
Block a user