Skip to content

Commit

Permalink
fix: displaying duplicate command suggestions
Browse files Browse the repository at this point in the history
Fixes #955
  • Loading branch information
mikavilpas committed Apr 29, 2024
1 parent 3a09155 commit 7db2354
Showing 1 changed file with 61 additions and 8 deletions.
69 changes: 61 additions & 8 deletions yazi-core/src/which/commands/show.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::str::FromStr;
use std::{collections::HashMap, str::FromStr};

use yazi_config::{keymap::{Control, Key}, KEYMAP};
use yazi_config::{keymap::{Control, ControlCow, Key}, KEYMAP};
use yazi_shared::{event::Cmd, render, Layer};

use crate::which::{Which, WhichSorter};
Expand Down Expand Up @@ -45,16 +45,69 @@ impl Which {
pub fn show_with(&mut self, key: &Key, layer: Layer) {
self.layer = layer;
self.times = 1;
self.cands = KEYMAP
.get(layer)
.iter()
.filter(|c| c.on.len() > 1 && &c.on[0] == key)
.map(|c| c.into())
.collect();
self.cands = keymap_candidates(layer, key);

WhichSorter::default().sort(&mut self.cands);
self.visible = true;
self.silent = false;
render!();
}
}

fn keymap_candidates(layer: Layer, key: &Key) -> Vec<ControlCow> {
let mut results: HashMap<&Vec<Key>, ControlCow> = HashMap::new();

let matches = KEYMAP.get(layer).iter().filter(|c| c.on.len() > 1 && &c.on[0] == key);
for c in matches {
if !results.contains_key(&c.on) {
results.insert(&c.on, c.into());
}
}

results.into_values().collect()
}

#[cfg(test)]
mod tests {
use std::collections::HashMap;

use super::*;

fn key(char: char) -> Key {
Key { code: crossterm::event::KeyCode::Char(char), alt: false, ctrl: false, shift: false }
}

#[test]
fn test_candidates_removes_duplicates() {
// When there are duplicate mappings in the [manager] section's prepend_keymap
// and keymap definitions, only the mapping in the prepend_keymap section will
// match. We should only display that one as a suggestion to the user.
let first = Control {
on: vec![key('g'), key('c')],
run: vec![Cmd { name: "noop".to_string(), args: HashMap::new() }],
desc: Some("do nothing".to_string()),
};
let second = Control {
on: vec![key('g'), key('c')],
run: vec![Cmd { name: "noop".to_string(), args: HashMap::new() }],
desc: Some("do nothing 2".to_string()),
};

KEYMAP.init(yazi_config::keymap::Keymap {
tasks: vec![],
select: vec![],
input: vec![],
help: vec![],
completion: vec![],
manager: vec![first, second],
});

let cands = keymap_candidates(Layer::Manager, &key('g'));

// duplicates have been removed
assert_eq!(cands.len(), 1);

// the first one is kept
assert_eq!(cands[0].desc_or_run(), "do nothing");
}
}

0 comments on commit 7db2354

Please sign in to comment.