From 7b68497b701f9af9f63d45e63728b5d2c944695f Mon Sep 17 00:00:00 2001
From: Derek Stavis <dekestavis@gmail.com>
Date: Sun, 28 Feb 2016 21:14:30 -0300
Subject: [PATCH] autoload: rewrite for conformance and performance

Rewrite autoload, split the big function into two smaller ones,
doing only option parsing at main function.

The algorithm is also rewritten in two steps for both path
inclusion an exclusion functions: 1) use auxiliary lists to store
valid function and completion paths, 2) bulk insert or remove just
once in the variable.
---
 lib/autoload.fish | 90 +++++++++++++++++++++++++----------------------
 1 file changed, 48 insertions(+), 42 deletions(-)

diff --git a/lib/autoload.fish b/lib/autoload.fish
index c5312eb..6f297f1 100644
--- a/lib/autoload.fish
+++ b/lib/autoload.fish
@@ -1,58 +1,64 @@
-# SYNOPSIS
-#   autoload <path>...
-#   autoload -e <path>...
-#
-# OVERVIEW
-#   Manipulate autoloading path components.
-#
-#   If called without options, the paths passed as arguments are added to
-#   $fish_function_path. All paths ending with `completions` are correctly
-#   added to $fish_complete_path. Returns 0 if one or more paths exist. If all
-#   paths are missing, returns != 0.
-#
-#   When called with -e, the paths passed as arguments are removed from
-#   $fish_function_path. All arguments ending with `completions` are correctly
-#   removed from $fish_complete_path. Returns 0 if one or more paths erased. If
-#   no paths were erased, returns != 0.
-
-function autoload -d "Manipulate autoloading path components"
+function autoload
   set -l paths $argv
-
   switch "$argv[1]"
   case '-e' '--erase'
-    set erase
-
-    if test (count $argv) -ge 2
-      set paths $argv[2..-1]
-    else
-      echo "usage: autoload $argv[1] <path>..." 1>&2
-      return 1
-    end
+    test (count $argv) -ge 2
+      and __autoload_erase $argv[2..-1]
+      or echo "usage: autoload $argv[1] <path>..." 1>&2
   case "-*" "--*"
     echo "autoload: invalid option $argv[1]"
     return 1
+  case '*'
+    test (count $argv) -ge 1
+      and __autoload_insert $argv
+      or echo "usage: autoload <path>..." 1>&2
   end
+end
 
-  for path in $paths
-    not test -d "$path"; and continue
+function __autoload_insert
+  set -l function_path
+  set -l complete_path
 
-    set -l dest fish_function_path
+  for path in $argv
+    not test -d "$path"; and continue
 
-    if test (basename "$path") = completions
-      set dest fish_complete_path
-    end
+    set -l IFS '/'
+    echo $path | read -la components
 
-    if set -q erase
-      if set -l index (contains -i -- $path $$dest)
-        set -e {$dest}[$index]
-        set return_success
-      end
+    if test "$components[-1]" = completions
+      contains -- $path $fish_complete_path
+        or set complete_path $complete_path $path
     else
-      set return_success
-      contains -- "$path" $$dest; and continue
-      set $dest "$path" $$dest
+      contains -- $path $fish_function_path
+        or set function_path $function_path $path
     end
   end
 
-  set -q return_success
+  test "$function_path"
+    and set fish_function_path $fish_function_path[1] $function_path $fish_function_path[2..-1]
+  test "$complete_path"
+    and set fish_complete_path $fish_complete_path[1] $complete_path $fish_complete_path[2..-1]
+
+  return 0
+end
+
+function __autoload_erase
+  set -l function_indexes
+  set -l complete_indexes
+
+  for path in $argv
+    set -l IFS '/'
+    echo $path | read -la components
+
+    test "$components[-1]" = completions
+      and set complete_indexes $complete_indexes (contains -i $path $fish_complete_path)
+      or  set function_indexes $function_indexes (contains -i $path $fish_function_path)
+  end
+
+  test -n "$function_indexes"
+    and set -e fish_function_path[$function_indexes]
+  test -n "$complete_indexes"
+    and set -e fish_complete_path[$complete_indexes]
+
+  return 0
 end
-- 
GitLab