diff --git a/alex/fish/functions/latest-file.fish b/alex/fish/functions/latest-file.fish index c31ccea..149fffc 100644 --- a/alex/fish/functions/latest-file.fish +++ b/alex/fish/functions/latest-file.fish @@ -1,20 +1,51 @@ function bind_at + # 1. Get the list of files (Sorted by time, newest first) + # -p adds '/' to dirs so we can filter them out with grep -v + set -l files (command ls -tAp | string match -v '*/') + + # 2. Get the current token on the command line set -l token (commandline -t) - if string match -q -- "*@" "$token" - commandline -f backward-delete-char - set -l newest_file - for f in (command ls -tA) - if test -f "$f" - set newest_file "$f" - break - end + + # --- CYCLE MODE --- + # Check if the current token matches a file in our list. + # If it does, we assume you're hitting @ again to "scroll" back in time. + set -l found_index 0 + for i in (seq (count $files)) + # We compare against the escaped version because that's what sits on the command line + if test "$token" = (string escape -- $files[$i]) + set found_index $i + break end - if test -n "$newest_file" - commandline -i (string escape -- "$newest_file") - else - commandline -i "@" - end - else - commandline -i "@" end + + if test $found_index -gt 0 + # Found it! Calculate the next index (wrapping around if needed) + set -l next_index (math $found_index + 1) + if test $next_index -gt (count $files) + set next_index 1 + end + + # Replace the current token with the next file + set -l next_file (string escape -- $files[$next_index]) + commandline -t -- $next_file + return + end + + # --- TRIGGER MODE (@@) --- + # If it wasn't a file, check if we just finished typing "@@" + if string match -q -- "*@" "$token" + commandline -f backward-delete-char # Delete the last @ + + # Insert the very first (newest) file + if test (count $files) -gt 0 + commandline -i (string escape -- $files[1]) + else + commandline -i "@" # No files? fallback + end + return + end + + # --- DEFAULT MODE --- + # Just insert an @ literally + commandline -i "@" end