summaryrefslogtreecommitdiffstats
path: root/default-plugins/status-bar/src/tip/data/quicknav.rs
blob: 59b604a701628e22acdc4d9d2fa2c8d88e15f98d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use ansi_term::{unstyled_len, ANSIString, ANSIStrings, Style};

use crate::{action_key, action_key_group, style_key_with_modifier, LinePart};
use zellij_tile::prelude::{
    actions::{Action, Direction, ResizeDirection},
    *,
};

macro_rules! strings {
    ($ANSIStrings:expr) => {{
        let strings: &[ANSIString] = $ANSIStrings;

        let ansi_strings = ANSIStrings(strings);

        LinePart {
            part: format!("{}", ansi_strings),
            len: unstyled_len(&ansi_strings),
        }
    }};
}

pub fn quicknav_full(help: &ModeInfo) -> LinePart {
    let groups = add_keybinds(help);

    let mut bits = vec![Style::new().paint(" Tip: ")];
    bits.extend(groups.new_pane);
    bits.push(Style::new().paint(" => open new pane. "));
    bits.extend(groups.move_focus);
    bits.push(Style::new().paint(" => navigate between panes. "));
    bits.extend(groups.resize);
    bits.push(Style::new().paint(" => increase/decrease pane size."));
    strings!(&bits)
}

pub fn quicknav_medium(help: &ModeInfo) -> LinePart {
    let groups = add_keybinds(help);

    let mut bits = vec![Style::new().paint(" Tip: ")];
    bits.extend(groups.new_pane);
    bits.push(Style::new().paint(" => new pane. "));
    bits.extend(groups.move_focus);
    bits.push(Style::new().paint(" => navigate. "));
    bits.extend(groups.resize);
    bits.push(Style::new().paint(" => resize pane."));
    strings!(&bits)
}

pub fn quicknav_short(help: &ModeInfo) -> LinePart {
    let groups = add_keybinds(help);

    let mut bits = vec![Style::new().paint(" QuickNav: ")];
    bits.extend(groups.new_pane);
    bits.push(Style::new().paint(" / "));
    bits.extend(groups.move_focus);
    bits.push(Style::new().paint(" / "));
    bits.extend(groups.resize);
    strings!(&bits)
}

struct Keygroups<'a> {
    new_pane: Vec<ANSIString<'a>>,
    move_focus: Vec<ANSIString<'a>>,
    resize: Vec<ANSIString<'a>>,
}

fn add_keybinds(help: &ModeInfo) -> Keygroups {
    let normal_keymap = help.get_mode_keybinds();
    let new_pane_keys = action_key(&normal_keymap, &[Action::NewPane(None)]);
    let new_pane = if new_pane_keys.is_empty() {
        vec![Style::new().bold().paint("UNBOUND")]
    } else {
        style_key_with_modifier(&new_pane_keys, &help.style.colors)
    };

    let resize_keys = action_key_group(
        &normal_keymap,
        &[
            &[Action::Resize(ResizeDirection::Increase)],
            &[Action::Resize(ResizeDirection::Decrease)],
        ],
    );
    let resize = if resize_keys.is_empty() {
        vec![Style::new().bold().paint("UNBOUND")]
    } else {
        style_key_with_modifier(&resize_keys, &help.style.colors)
    };

    let move_focus_keys = action_key_group(
        &normal_keymap,
        &[
            &[Action::MoveFocus(Direction::Left)],
            &[Action::MoveFocusOrTab(Direction::Left)],
            &[Action::MoveFocus(Direction::Down)],
            &[Action::MoveFocus(Direction::Up)],
            &[Action::MoveFocus(Direction::Right)],
            &[Action::MoveFocusOrTab(Direction::Right)],
        ],
    );
    // Let's see if we have some pretty groups in common here
    let mut arrows = vec![];
    let mut letters = vec![];
    for key in move_focus_keys.into_iter() {
        let key_str = key.to_string();
        if key_str.contains('←')
            || key_str.contains('↓')
            || key_str.contains('↑')
            || key_str.contains('→')
        {
            arrows.push(key);
        } else {
            letters.push(key);
        }
    }
    let arrows = style_key_with_modifier(&arrows, &help.style.colors);
    let letters = style_key_with_modifier(&letters, &help.style.colors);
    let move_focus = if arrows.is_empty() && letters.is_empty() {
        vec![Style::new().bold().paint("UNBOUND")]
    } else if arrows.is_empty() || letters.is_empty() {
        arrows.into_iter().chain(letters.into_iter()).collect()
    } else {
        arrows
            .into_iter()
            .chain(vec![Style::new().paint(" or ")].into_iter())
            .chain(letters.into_iter())
            .collect()
    };

    Keygroups {
        new_pane,
        move_focus,
        resize,
    }
}