@@ -2,7 +2,7 @@
 
 __git-bug_debug()
 {
-    if [[ -n ${BASH_COMP_DEBUG_FILE:-} ]]; then
+    if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then
         echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
     fi
 }
@@ -29,7 +29,7 @@ __git-bug_get_completion_results() {
     lastChar=${lastParam:$((${#lastParam}-1)):1}
     __git-bug_debug "lastParam ${lastParam}, lastChar ${lastChar}"
 
-    if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then
+    if [[ -z ${cur} && ${lastChar} != = ]]; then
         # If the last parameter is complete (there is a space following it)
         # We add an extra empty parameter so we can indicate this to the go method.
         __git-bug_debug "Adding extra empty parameter"
@@ -39,7 +39,7 @@ __git-bug_get_completion_results() {
     # When completing a flag with an = (e.g., git-bug -n=<TAB>)
     # bash focuses on the part after the =, so we need to remove
     # the flag part from $cur
-    if [[ "${cur}" == -*=* ]]; then
+    if [[ ${cur} == -*=* ]]; then
         cur="${cur#*=}"
     fi
 
@@ -51,7 +51,7 @@ __git-bug_get_completion_results() {
     directive=${out##*:}
     # Remove the directive
     out=${out%:*}
-    if [ "${directive}" = "${out}" ]; then
+    if [[ ${directive} == "${out}" ]]; then
         # There is not directive specified
         directive=0
     fi
@@ -65,22 +65,36 @@ __git-bug_process_completion_results() {
     local shellCompDirectiveNoFileComp=4
     local shellCompDirectiveFilterFileExt=8
     local shellCompDirectiveFilterDirs=16
+    local shellCompDirectiveKeepOrder=32
 
-    if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then
+    if (((directive & shellCompDirectiveError) != 0)); then
         # Error code.  No completion.
         __git-bug_debug "Received error from custom completion go code"
         return
     else
-        if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then
-            if [[ $(type -t compopt) = "builtin" ]]; then
+        if (((directive & shellCompDirectiveNoSpace) != 0)); then
+            if [[ $(type -t compopt) == builtin ]]; then
                 __git-bug_debug "Activating no space"
                 compopt -o nospace
             else
                 __git-bug_debug "No space directive not supported in this version of bash"
             fi
         fi
-        if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then
-            if [[ $(type -t compopt) = "builtin" ]]; then
+        if (((directive & shellCompDirectiveKeepOrder) != 0)); then
+            if [[ $(type -t compopt) == builtin ]]; then
+                # no sort isn't supported for bash less than < 4.4
+                if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then
+                    __git-bug_debug "No sort directive not supported in this version of bash"
+                else
+                    __git-bug_debug "Activating keep order"
+                    compopt -o nosort
+                fi
+            else
+                __git-bug_debug "No sort directive not supported in this version of bash"
+            fi
+        fi
+        if (((directive & shellCompDirectiveNoFileComp) != 0)); then
+            if [[ $(type -t compopt) == builtin ]]; then
                 __git-bug_debug "Activating no file completion"
                 compopt +o default
             else
@@ -94,7 +108,7 @@ __git-bug_process_completion_results() {
     local activeHelp=()
     __git-bug_extract_activeHelp
 
-    if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
+    if (((directive & shellCompDirectiveFilterFileExt) != 0)); then
         # File extension filtering
         local fullFilter filter filteringCmd
 
@@ -107,13 +121,12 @@ __git-bug_process_completion_results() {
         filteringCmd="_filedir $fullFilter"
         __git-bug_debug "File filtering command: $filteringCmd"
         $filteringCmd
-    elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then
+    elif (((directive & shellCompDirectiveFilterDirs) != 0)); then
         # File completion for directories only
 
-        # Use printf to strip any trailing newline
         local subdir
-        subdir=$(printf "%s" "${completions[0]}")
-        if [ -n "$subdir" ]; then
+        subdir=${completions[0]}
+        if [[ -n $subdir ]]; then
             __git-bug_debug "Listing directories in $subdir"
             pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
         else
@@ -128,7 +141,7 @@ __git-bug_process_completion_results() {
     __git-bug_handle_special_char "$cur" =
 
     # Print the activeHelp statements before we finish
-    if [ ${#activeHelp[*]} -ne 0 ]; then
+    if ((${#activeHelp[*]} != 0)); then
         printf "\n";
         printf "%s\n" "${activeHelp[@]}"
         printf "\n"
@@ -152,17 +165,17 @@ __git-bug_extract_activeHelp() {
     local endIndex=${#activeHelpMarker}
 
     while IFS='' read -r comp; do
-        if [ "${comp:0:endIndex}" = "$activeHelpMarker" ]; then
+        if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then
             comp=${comp:endIndex}
             __git-bug_debug "ActiveHelp found: $comp"
-            if [ -n "$comp" ]; then
+            if [[ -n $comp ]]; then
                 activeHelp+=("$comp")
             fi
         else
             # Not an activeHelp line but a normal completion
             completions+=("$comp")
         fi
-    done < <(printf "%s\n" "${out}")
+    done <<<"${out}"
 }
 
 __git-bug_handle_completion_types() {
@@ -218,7 +231,7 @@ __git-bug_handle_standard_completion_case() {
     done < <(printf "%s\n" "${completions[@]}")
 
     # If there is a single completion left, remove the description text
-    if [ ${#COMPREPLY[*]} -eq 1 ]; then
+    if ((${#COMPREPLY[*]} == 1)); then
         __git-bug_debug "COMPREPLY[0]: ${COMPREPLY[0]}"
         comp="${COMPREPLY[0]%%$tab*}"
         __git-bug_debug "Removed description from single completion, which is now: ${comp}"
@@ -235,8 +248,8 @@ __git-bug_handle_special_char()
     if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then
         local word=${comp%"${comp##*${char}}"}
         local idx=${#COMPREPLY[*]}
-        while [[ $((--idx)) -ge 0 ]]; do
-            COMPREPLY[$idx]=${COMPREPLY[$idx]#"$word"}
+        while ((--idx >= 0)); do
+            COMPREPLY[idx]=${COMPREPLY[idx]#"$word"}
         done
     fi
 }
@@ -262,7 +275,7 @@ __git-bug_format_comp_descriptions()
 
             # Make sure we can fit a description of at least 8 characters
             # if we are to align the descriptions.
-            if [[ $maxdesclength -gt 8 ]]; then
+            if ((maxdesclength > 8)); then
                 # Add the proper number of spaces to align the descriptions
                 for ((i = ${#comp} ; i < longest ; i++)); do
                     comp+=" "
@@ -274,8 +287,8 @@ __git-bug_format_comp_descriptions()
 
             # If there is enough space for any description text,
             # truncate the descriptions that are too long for the shell width
-            if [ $maxdesclength -gt 0 ]; then
-                if [ ${#desc} -gt $maxdesclength ]; then
+            if ((maxdesclength > 0)); then
+                if ((${#desc} > maxdesclength)); then
                     desc=${desc:0:$(( maxdesclength - 1 ))}
                     desc+="…"
                 fi
@@ -296,9 +309,9 @@ __start_git-bug()
     # Call _init_completion from the bash-completion package
     # to prepare the arguments properly
     if declare -F _init_completion >/dev/null 2>&1; then
-        _init_completion -n "=:" || return
+        _init_completion -n =: || return
     else
-        __git-bug_init_completion -n "=:" || return
+        __git-bug_init_completion -n =: || return
     fi
 
     __git-bug_debug
  
  
  
    
    @@ -55,6 +55,60 @@ function __git_bug_perform_completion
     printf "%s\n" "$directiveLine"
 end
 
+# this function limits calls to __git_bug_perform_completion, by caching the result behind $__git_bug_perform_completion_once_result
+function __git_bug_perform_completion_once
+    __git_bug_debug "Starting __git_bug_perform_completion_once"
+
+    if test -n "$__git_bug_perform_completion_once_result"
+        __git_bug_debug "Seems like a valid result already exists, skipping __git_bug_perform_completion"
+        return 0
+    end
+
+    set --global __git_bug_perform_completion_once_result (__git_bug_perform_completion)
+    if test -z "$__git_bug_perform_completion_once_result"
+        __git_bug_debug "No completions, probably due to a failure"
+        return 1
+    end
+
+    __git_bug_debug "Performed completions and set __git_bug_perform_completion_once_result"
+    return 0
+end
+
+# this function is used to clear the $__git_bug_perform_completion_once_result variable after completions are run
+function __git_bug_clear_perform_completion_once_result
+    __git_bug_debug ""
+    __git_bug_debug "========= clearing previously set __git_bug_perform_completion_once_result variable =========="
+    set --erase __git_bug_perform_completion_once_result
+    __git_bug_debug "Succesfully erased the variable __git_bug_perform_completion_once_result"
+end
+
+function __git_bug_requires_order_preservation
+    __git_bug_debug ""
+    __git_bug_debug "========= checking if order preservation is required =========="
+
+    __git_bug_perform_completion_once
+    if test -z "$__git_bug_perform_completion_once_result"
+        __git_bug_debug "Error determining if order preservation is required"
+        return 1
+    end
+
+    set -l directive (string sub --start 2 $__git_bug_perform_completion_once_result[-1])
+    __git_bug_debug "Directive is: $directive"
+
+    set -l shellCompDirectiveKeepOrder 32
+    set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2)
+    __git_bug_debug "Keeporder is: $keeporder"
+
+    if test $keeporder -ne 0
+        __git_bug_debug "This does require order preservation"
+        return 0
+    end
+
+    __git_bug_debug "This doesn't require order preservation"
+    return 1
+end
+
+
 # This function does two things:
 # - Obtain the completions and store them in the global __git_bug_comp_results
 # - Return false if file completion should be performed
@@ -65,17 +119,17 @@ function __git_bug_prepare_completions
     # Start fresh
     set --erase __git_bug_comp_results
 
-    set -l results (__git_bug_perform_completion)
-    __git_bug_debug "Completion results: $results"
+    __git_bug_perform_completion_once
+    __git_bug_debug "Completion results: $__git_bug_perform_completion_once_result"
 
-    if test -z "$results"
+    if test -z "$__git_bug_perform_completion_once_result"
         __git_bug_debug "No completion, probably due to a failure"
         # Might as well do file completion, in case it helps
         return 1
     end
 
-    set -l directive (string sub --start 2 $results[-1])
-    set --global __git_bug_comp_results $results[1..-2]
+    set -l directive (string sub --start 2 $__git_bug_perform_completion_once_result[-1])
+    set --global __git_bug_comp_results $__git_bug_perform_completion_once_result[1..-2]
 
     __git_bug_debug "Completions are: $__git_bug_comp_results"
     __git_bug_debug "Directive is: $directive"
@@ -171,7 +225,11 @@ end
 # Remove any pre-existing completions for the program since we will be handling all of them.
 complete -c git-bug -e
 
+# this will get called after the two calls below and clear the $__git_bug_perform_completion_once_result global
+complete -c git-bug -n '__git_bug_clear_perform_completion_once_result'
 # The call to __git_bug_prepare_completions will setup __git_bug_comp_results
 # which provides the program's completion choices.
-complete -c git-bug -n '__git_bug_prepare_completions' -f -a '$__git_bug_comp_results'
-
+# If this doesn't require order preservation, we don't use the -k flag
+complete -c git-bug -n 'not __git_bug_requires_order_preservation && __git_bug_prepare_completions' -f -a '$__git_bug_comp_results'
+# otherwise we use the -k flag
+complete -k -c git-bug -n '__git_bug_requires_order_preservation && __git_bug_prepare_completions' -f -a '$__git_bug_comp_results'
  
  
  
    
    @@ -40,6 +40,7 @@ filter __git-bug_escapeStringWithSpecialChars {
     $ShellCompDirectiveNoFileComp=4
     $ShellCompDirectiveFilterFileExt=8
     $ShellCompDirectiveFilterDirs=16
+    $ShellCompDirectiveKeepOrder=32
 
     # Prepare the command to request completions for the program.
     # Split the command at the first space to separate the program and arguments.
@@ -69,8 +70,17 @@ filter __git-bug_escapeStringWithSpecialChars {
         # If the last parameter is complete (there is a space following it)
         # We add an extra empty parameter so we can indicate this to the go method.
         __git-bug_debug "Adding extra empty parameter"
-        # We need to use `"`" to pass an empty argument a "" or '' does not work!!!
-        $RequestComp="$RequestComp" + ' `"`"'
+        # PowerShell 7.2+ changed the way how the arguments are passed to executables,
+        # so for pre-7.2 or when Legacy argument passing is enabled we need to use
+        # `"`" to pass an empty argument, a "" or '' does not work!!!
+        if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or
+            ($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or
+            (($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and
+              $PSNativeCommandArgumentPassing -eq 'Legacy')) {
+             $RequestComp="$RequestComp" + ' `"`"'
+        } else {
+             $RequestComp="$RequestComp" + ' ""'
+        }
     }
 
     __git-bug_debug "Calling $RequestComp"
@@ -100,7 +110,7 @@ filter __git-bug_escapeStringWithSpecialChars {
     }
 
     $Longest = 0
-    $Values = $Out | ForEach-Object {
+    [Array]$Values = $Out | ForEach-Object {
         #Split the output in name and description
         $Name, $Description = $_.Split("`t",2)
         __git-bug_debug "Name: $Name Description: $Description"
@@ -145,6 +155,11 @@ filter __git-bug_escapeStringWithSpecialChars {
         }
     }
 
+    # we sort the values in ascending order by name if keep order isn't passed
+    if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {
+        $Values = $Values | Sort-Object -Property Name
+    }
+
     if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
         __git-bug_debug "ShellCompDirectiveNoFileComp is called"
 
  
  
  
    
    @@ -1,4 +1,5 @@
 #compdef git-bug
+compdef _git-bug git-bug
 
 # zsh completion for git-bug                              -*- shell-script -*-
 
@@ -17,8 +18,9 @@ _git-bug()
     local shellCompDirectiveNoFileComp=4
     local shellCompDirectiveFilterFileExt=8
     local shellCompDirectiveFilterDirs=16
+    local shellCompDirectiveKeepOrder=32
 
-    local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace
+    local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
     local -a completions
 
     __git-bug_debug "\n========= starting completion logic =========="
@@ -136,6 +138,11 @@ _git-bug()
         noSpace="-S ''"
     fi
 
+    if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then
+        __git-bug_debug "Activating keep order."
+        keepOrder="-V"
+    fi
+
     if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then
         # File extension filtering
         local filteringCmd
@@ -171,7 +178,7 @@ _git-bug()
         return $result
     else
         __git-bug_debug "Calling _describe"
-        if eval _describe "completions" completions $flagPrefix $noSpace; then
+        if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then
             __git-bug_debug "_describe found some completions"
 
             # Return the success of having called _describe