on master help sign in
Better sorting in picker in case of ties (#5169)
e6a2df8Alex Kladov
helix-term/src/ui/mod.rs+2−1
@@ -207,13 +207,14 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi
207
207
208 // Cap the number of files if we aren't in a git project, preventing
208 // Cap the number of files if we aren't in a git project, preventing
209 // hangs when using the picker in your home directory
209 // hangs when using the picker in your home directory
210− let files: Vec<_> = if root.join(".git").exists() {
210+ let mut files: Vec<PathBuf> = if root.join(".git").exists() {
211 files.collect()
211 files.collect()
212 } else {
212 } else {
213 // const MAX: usize = 8192;
213 // const MAX: usize = 8192;
214 const MAX: usize = 100_000;
214 const MAX: usize = 100_000;
215 files.take(MAX).collect()
215 files.take(MAX).collect()
216 };
216 };
217+ files.sort();
217
218
218 log::debug!("file_picker init {:?}", Instant::now().duration_since(now));
219 log::debug!("file_picker init {:?}", Instant::now().duration_since(now));
219
220
helix-term/src/ui/picker.rs+13−6
@@ -12,7 +12,10 @@ use tui::{
12use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
12use fuzzy_matcher::skim::SkimMatcherV2 as Matcher;
13use tui::widgets::Widget;
13use tui::widgets::Widget;
14
14
15+use std::{
16+ cmp::{self, Ordering},
15−use std::{cmp::Ordering, time::Instant};
17+ time::Instant,
18+};
16use std::{collections::HashMap, io::Read, path::PathBuf};
19use std::{collections::HashMap, io::Read, path::PathBuf};
17
20
18use crate::ui::{Prompt, PromptEvent};
21use crate::ui::{Prompt, PromptEvent};
@@ -344,11 +347,17 @@ impl<T: Item + 'static> Component for FilePicker<T> {
344
347
345#[derive(PartialEq, Eq, Debug)]
348#[derive(PartialEq, Eq, Debug)]
346struct PickerMatch {
349struct PickerMatch {
347− index: usize,
348 score: i64,
350 score: i64,
351+ index: usize,
349 len: usize,
352 len: usize,
350}
353}
351
354
355+impl PickerMatch {
356+ fn key(&self) -> impl Ord {
357+ (cmp::Reverse(self.score), self.len, self.index)
358+ }
359+}
360+
352impl PartialOrd for PickerMatch {
361impl PartialOrd for PickerMatch {
353 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
362 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
354 Some(self.cmp(other))
363 Some(self.cmp(other))
@@ -357,10 +366,7 @@ impl PartialOrd for PickerMatch {
357
366
358impl Ord for PickerMatch {
367impl Ord for PickerMatch {
359 fn cmp(&self, other: &Self) -> Ordering {
368 fn cmp(&self, other: &Self) -> Ordering {
360− self.score
369+ self.key().cmp(&other.key())
361− .cmp(&other.score)
362− .reverse()
363− .then_with(|| self.len.cmp(&other.len))
364 }
370 }
365}
371}
366
372
@@ -502,6 +508,7 @@ impl<T: Item> Picker<T> {
502 })
508 })
503 }),
509 }),
504 );
510 );
511+
505 self.matches.sort_unstable();
512 self.matches.sort_unstable();
506 }
513 }
507
514