Skip to content

Commit

Permalink
Feature go to current tag goes to previous tag (leftwm#208)
Browse files Browse the repository at this point in the history
* This commit does the following:

- fix a type preventing test suites from being run on `cargo test`. `[#cfg(tests)] becomes `[cfg(test)]`
- fix tests that stopped working after recent changes to tags

* new feature: going to current tag sends you to the tag viewed before it.
  • Loading branch information
PVautour authored Feb 23, 2021
1 parent aff8d7f commit a57c91a
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 10 deletions.
143 changes: 140 additions & 3 deletions src/handlers/command_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,20 @@ pub fn process(manager: &mut Manager, command: Command, val: Option<String>) ->

Command::GotoTag if val.is_none() => false,
Command::GotoTag if !is_num(&val) => false,
Command::GotoTag => goto_tag_handler::process(manager, to_num(&val)),
Command::GotoTag => {
let current_tag = manager.tag_index(manager.focused_tag(0).unwrap_or("".to_string()));
let previous_tag = manager.tag_index(manager.focused_tag(1).unwrap_or("".to_string()));
let input_tag = to_num(&val);

let destination_tag = match (current_tag, previous_tag, input_tag) {
(Some(ctag), Some(ptag), itag) if ctag + 1 == itag => ptag + 1, // if current tag is the same as the destination tag, go to the previous tag instead
(_, _, _) => input_tag, // go to the input tag tag
};
goto_tag_handler::process(manager, destination_tag)
}

Command::FocusNextTag => {
let current = manager.focused_tag();
let current = manager.focused_tag(0);
let current = current.unwrap();
let mut index = match manager.tags.iter().position(|x| x.id == current) {
Some(x) => x + 1,
Expand All @@ -46,7 +56,7 @@ pub fn process(manager: &mut Manager, command: Command, val: Option<String>) ->
}

Command::FocusPreviousTag => {
let current = manager.focused_tag();
let current = manager.focused_tag(0);
let current = current.unwrap();
let mut index = match manager.tags.iter().position(|x| x.id == current) {
Some(x) => x + 1,
Expand Down Expand Up @@ -451,3 +461,130 @@ fn to_num(val: &Option<String>) -> usize {
.and_then(|num| num.parse::<usize>().ok())
.unwrap_or_default()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn go_to_tag_should_return_false_if_no_screen_is_created() {
let mut manager = Manager::default();
// no screen creation here
assert_eq!(
process(&mut manager, Command::GotoTag, Some("6".to_string())),
false
);
assert_eq!(
process(&mut manager, Command::GotoTag, Some("2".to_string())),
false
);
assert_eq!(
process(&mut manager, Command::GotoTag, Some("15".to_string())),
false
);
}

#[test]
fn go_to_tag_should_create_at_least_one_tag_per_screen_no_more() {
let mut manager = Manager::default();
screen_create_handler::process(&mut manager, Screen::default());
screen_create_handler::process(&mut manager, Screen::default());
// no tag creation here but one tag per screen is created
assert!(process(
&mut manager,
Command::GotoTag,
Some("2".to_string())
));
assert!(process(
&mut manager,
Command::GotoTag,
Some("1".to_string())
));
// we only have one tag per screen created automatically
assert_eq!(
process(&mut manager, Command::GotoTag, Some("3".to_string())),
false
);
}

#[test]
fn go_to_tag_should_return_false_on_invalid_input() {
let mut manager = Manager::default();
screen_create_handler::process(&mut manager, Screen::default());
manager.tags = vec![
TagModel::new("A15"),
TagModel::new("B24"),
TagModel::new("C"),
TagModel::new("6D4"),
TagModel::new("E39"),
TagModel::new("F67"),
];
assert_eq!(
process(&mut manager, Command::GotoTag, Some("abc".to_string())),
false
);
assert_eq!(
process(&mut manager, Command::GotoTag, Some("ab45c".to_string())),
false
);
assert_eq!(process(&mut manager, Command::GotoTag, None), false);
}

#[test]
fn go_to_tag_should_go_to_tag_and_set_history() {
let mut manager = Manager::default();
manager.tags = vec![
TagModel::new("A15"),
TagModel::new("B24"),
TagModel::new("C"),
TagModel::new("6D4"),
TagModel::new("E39"),
TagModel::new("F67"),
];
screen_create_handler::process(&mut manager, Screen::default());
screen_create_handler::process(&mut manager, Screen::default());

assert!(process(
&mut manager,
Command::GotoTag,
Some("6".to_string())
));
let current_tag = manager.tag_index(manager.focused_tag(0).unwrap_or("".to_string()));
assert_eq!(current_tag, Some(5));
assert!(process(
&mut manager,
Command::GotoTag,
Some("2".to_string())
));
let current_tag = manager.tag_index(manager.focused_tag(0).unwrap_or("".to_string()));
assert_eq!(current_tag, Some(1));

assert!(process(
&mut manager,
Command::GotoTag,
Some("3".to_string())
));
let current_tag = manager.tag_index(manager.focused_tag(0).unwrap_or("".to_string()));
assert_eq!(current_tag, Some(2));

assert!(process(
&mut manager,
Command::GotoTag,
Some("4".to_string())
));
let current_tag = manager.tag_index(manager.focused_tag(0).unwrap_or("".to_string()));
assert_eq!(current_tag, Some(3));
assert_eq!(
manager.tag_index(manager.focused_tag(1).unwrap_or("".to_string())),
Some(2)
);
assert_eq!(
manager.tag_index(manager.focused_tag(2).unwrap_or("".to_string())),
Some(1)
);
assert_eq!(
manager.tag_index(manager.focused_tag(3).unwrap_or("".to_string())),
Some(5)
);
}
}
8 changes: 4 additions & 4 deletions src/handlers/focus_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub fn focus_last_window_that_exists(manager: &mut Manager) -> bool {
*/
pub fn focus_tag(manager: &mut Manager, tag: &str) -> bool {
//no new history for if no change
if let Some(t) = manager.focused_tag() {
if let Some(t) = manager.focused_tag(0) {
if t == tag {
return false;
}
Expand Down Expand Up @@ -235,7 +235,7 @@ mod tests {
screen_create_handler::process(&mut manager, Screen::default());
let expected = "Bla".to_owned();
focus_tag(&mut manager, &expected);
let accual = manager.focused_tag().unwrap();
let accual = manager.focused_tag(0).unwrap();
assert_eq!(accual, expected);
}

Expand Down Expand Up @@ -270,7 +270,7 @@ mod tests {
screen_create_handler::process(&mut manager, Screen::default());
let ws = manager.workspaces[1].clone();
focus_workspace(&mut manager, &ws);
let actual = manager.focused_tag().unwrap();
let actual = manager.focused_tag(0).unwrap();
assert_eq!("2", actual);
}

Expand All @@ -283,7 +283,7 @@ mod tests {
let mut window = Window::new(WindowHandle::MockHandle(1), None);
window.tag("2");
focus_window(&mut manager, &window, 0, 0);
let actual = manager.focused_tag().unwrap();
let actual = manager.focused_tag(0).unwrap();
assert_eq!("2", actual);
}

Expand Down
12 changes: 9 additions & 3 deletions src/models/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,15 @@ impl Manager {
Some(&mut self.workspaces[index])
}

/// Return the currently focused tag.
pub fn focused_tag(&self) -> Option<String> {
self.focused_tag_history.get(0).map(|t| t.to_string())
/// Return the currently focused tag if the offset is 0.
/// Offset is used to reach further down the history.
pub fn focused_tag(&self, offset: usize) -> Option<String> {
self.focused_tag_history.get(offset).map(|t| t.to_string())
}

/// Return the index of a given tag.
pub fn tag_index(&self, tag: String) -> Option<usize> {
Some(self.tags.iter().position(|t| t.id == tag)).unwrap_or(None)
}

/// Return the currently focused window.
Expand Down

0 comments on commit a57c91a

Please sign in to comment.