From f9d249072e21cfad92e27a1613b5d339726ea10d Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Tue, 13 Feb 2024 10:44:03 +0100
Subject: [PATCH] fish completion done

---
 NodeApp/src/helpers/AutoCompletionHelper.ts | 60 +++++++++++++++++----
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/NodeApp/src/helpers/AutoCompletionHelper.ts b/NodeApp/src/helpers/AutoCompletionHelper.ts
index 0e3fbdb..dc45210 100644
--- a/NodeApp/src/helpers/AutoCompletionHelper.ts
+++ b/NodeApp/src/helpers/AutoCompletionHelper.ts
@@ -23,6 +23,17 @@ function isLeaf(cmd: Command): boolean {
     return cmd.commands.length == 0
 }
 
+function flatten(cmd: Command): Array<Command> {
+    if (isLeaf(cmd)) {
+        return [cmd]
+    } else {
+        return cmd.commands
+            .map(child => flatten(child))
+            .reduce((acc, cmd) => acc.concat(cmd), [cmd])
+    }
+}
+
+// Computes the maximum number of commands until a leaf is reached
 function computeDepth(cmd: Command | undefined): number {
     if (cmd === undefined) {
         return 0
@@ -31,6 +42,17 @@ function computeDepth(cmd: Command | undefined): number {
     }
 }
 
+// Computes the maximum number of commands until the root is reached
+function computeHeigth(cmd: Command | null): number {
+    let height = 0
+    let tmp = cmd
+    while (tmp !== null) {
+        tmp = tmp.parent
+        height += 1
+    }
+    return height
+}
+
 function getOptions(cmd: Command): string {
     // we remove <args>, [command], and , from option lines
     return cmd.options.filter(opt => !opt.hidden).map(opt =>
@@ -93,22 +115,40 @@ export function writeBashCompletion(root: Command, filename: string) {
 
 const prefix = 'complete -f -c dojo -n \'__fish_dojo_using_commands'
 
-function generateFishSubCommands(cmd: Command, crtDepth: number): string {
+function generateCommandChain(cmd: Command | null): string {
     let data = ''
-    for (const arg of cmd.commands) {
-        data += `${prefix} ${crtDepth} ${cmd.name()}' -a ${arg.name()} -d "${arg.description()}"\n`
+    while (cmd !== null) {
+        data = cmd.name().concat(` ${data}`)
+        cmd = cmd.parent
     }
-    return data
+    return data.trimEnd()
 }
 
 export function writeFishCompletion(root: Command, filename: string) {
-    const depth = computeDepth(root)
+    const commands = flatten(root)
 
-    let data =
-        fishFunction
-    for (let i = 1; i <= depth; i++) {
-        data += generateFishSubCommands(root, i)
-    }
+    let data = fishFunction
+    // add commands and subcommands
+    commands.forEach(cmd => {
+        if (isLeaf(cmd)) {
+            cmd.options.forEach(opt => {
+                if (!opt.hidden) {
+                    data += `${prefix} ${computeHeigth(cmd)} ${generateCommandChain(cmd)}' -a "--${opt.name()}" -d "${opt.description}"\n`
+
+                }
+            })
+        }
+        cmd.commands.forEach(subCmd => {
+            data += `${prefix} ${computeHeigth(cmd)} ${generateCommandChain(cmd)}' -a ${subCmd.name()} -d "${subCmd.description()}"\n`
+            if (cmd.options.length > 0) {
+                cmd.options.forEach(opt => {
+                    if (!opt.hidden) {
+                        data += `${prefix} ${computeHeigth(cmd)} ${generateCommandChain(cmd)}' -a "--${opt.name()}" -d "${opt.description}"\n`
+                    }
+                })
+            }
+        })
+    })
 
     writeFileSync(filename, data);
 }
-- 
GitLab