From eb6fb63e748bc465996cec8b07241590c4bab68b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wojciech=20K=C4=99pka?=
 <46892771+wojciechkepka@users.noreply.github.com>
Date: Sat, 26 Jun 2021 04:09:17 +0200
Subject: [PATCH] Sort files in file picker by access, modification and
 creation date (#336)

* Sort files in file picker by access date

* Fallback file time to modified then created then UNIX_EPOCH

* Use `sort_by_key`

* Refactor
---
 helix-term/src/ui/mod.rs | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs
index 14dc9169..a6adbe8d 100644
--- a/helix-term/src/ui/mod.rs
+++ b/helix-term/src/ui/mod.rs
@@ -76,11 +76,22 @@ pub fn regex_prompt(
 
 pub fn file_picker(root: PathBuf) -> Picker<PathBuf> {
     use ignore::Walk;
+    use std::time;
     let files = Walk::new(root.clone()).filter_map(|entry| match entry {
         Ok(entry) => {
             // filter dirs, but we might need special handling for symlinks!
             if !entry.file_type().map_or(false, |entry| entry.is_dir()) {
-                Some(entry.into_path())
+                let time = if let Ok(metadata) = entry.metadata() {
+                    metadata
+                        .accessed()
+                        .or_else(|_| metadata.modified())
+                        .or_else(|_| metadata.created())
+                        .unwrap_or(time::UNIX_EPOCH)
+                } else {
+                    time::UNIX_EPOCH
+                };
+
+                Some((entry.into_path(), time))
             } else {
                 None
             }
@@ -88,13 +99,17 @@ pub fn file_picker(root: PathBuf) -> Picker<PathBuf> {
         Err(_err) => None,
     });
 
-    let files = if root.join(".git").is_dir() {
+    let mut files: Vec<_> = if root.join(".git").is_dir() {
         files.collect()
     } else {
         const MAX: usize = 8192;
         files.take(MAX).collect()
     };
 
+    files.sort_by_key(|file| file.1);
+
+    let files = files.into_iter().map(|(path, _)| path).collect();
+
     Picker::new(
         files,
         move |path: &PathBuf| {