diff --git a/NodeApp/src/commander/CommanderApp.ts b/NodeApp/src/commander/CommanderApp.ts
index 046129f378c22cea128e5ad21a5bb1e1256f4a08..e4d16320e81c2c3555d988008372c6567f72f9f2 100644
--- a/NodeApp/src/commander/CommanderApp.ts
+++ b/NodeApp/src/commander/CommanderApp.ts
@@ -9,7 +9,7 @@ import { stateConfigFile } from '../config/ConfigFiles';
 import semver              from 'semver/preload';
 import { version }         from '../config/Version';
 import Config              from '../config/Config';
-import {getBashCompletion} from '../helpers/AutoCompletionHelper';
+import {getBashCompletion, getFishCompletion} from '../helpers/AutoCompletionHelper';
 
 
 class CommanderApp {
@@ -45,6 +45,7 @@ class CommanderApp {
         this.registerCommands();
 
         getBashCompletion(this.program, "bash_completion.sh")
+        getFishCompletion(this.program, "dojo.fish")
 
         this.program.parse();
     }
diff --git a/NodeApp/src/helpers/AutoCompletionHelper.ts b/NodeApp/src/helpers/AutoCompletionHelper.ts
index a6a079cde6761ac004f6d525cbbe955a014e63f3..bb46c1e6eecbdad4538303f5e5bf01c01a60fed1 100644
--- a/NodeApp/src/helpers/AutoCompletionHelper.ts
+++ b/NodeApp/src/helpers/AutoCompletionHelper.ts
@@ -97,6 +97,10 @@ function isLeaf(tree: CmdNode): boolean {
     return tree.children === undefined || tree.children.length == 0
 }
 
+function isRoot(tree: CmdNode): boolean {
+    return tree.parent === undefined
+}
+
 function search(tree: CmdNode, cmdName: string): Array<CmdNode> {
     if (isLeaf(tree)) {
         if (tree.name != cmdName) {
@@ -173,6 +177,52 @@ function addLine(identLevel: number, pattern: string): string {
     return `${'    '.repeat(identLevel)}${pattern}\n`
 }
 
+const fishFunctions = `### Fish completions for dojo ###
+function __fish_dojo_needs_command
+    set cmd (commandline -opc)
+    if [ (count $cmd) -eq 1 -a $cmd[1] = dojo ]
+        return 0
+    end
+    return 1
+end
+
+function __fish_dojo_using_command
+    set cmd (commandline -opc)
+    set num_cmd (count $cmd)
+    if [ $num_cmd -eq 2 ]
+        if [ $argv[(math $num_cmd - 1)] = $cmd[$num_cmd] ]
+            return 0
+        end
+    end
+    return 1
+end
+
+function __fish_dojo_using_two_commands
+    set cmd (commandline -opc)
+    set num_cmd (count $cmd)
+    if [ $num_cmd -gt 3 ]
+        if [ $argv[(math $num_cmd - 2)] = $cmd[(math $num_cmd - 1)] -a $argv[(math $num_cmd - 1)] = $cmd[$num_cmd] ]
+            return 0
+        end
+    end
+    return 1
+end
+`
+
+export function getFishCompletion(root: Command, filename: string) {
+    const tree = buildCmdNode(root)
+    const commands = Array.from(new Set(flatten(tree).filter(cmd => !isLeaf(cmd)).map(cmd => cmd.name))).map(name => search(tree, name))
+    let data = fishFunctions
+    for (const node of commands) {
+        const cmd = node[0]
+        data += addLine(0, `complete -f -c dojo -n __fish_dojo_needs_command ${cmd.name} -a "${cmd.children.map(c => c.name).join(" ")} --help -h"`)
+    }
+
+
+    writeFileSync(filename, data);
+}
+
+
 export function getBashCompletion(root: Command, filename: string) {
     const tree = buildCmdNode(root)