From 0bb098b3f19bd791b619bcb69a5cbe4ebdfd5372 Mon Sep 17 00:00:00 2001
From: Your Name <j@842.be>
Date: Mon, 21 Apr 2025 13:00:01 +1200
Subject: [PATCH] .

---
 src/autocomplete.cpp          | 61 +++++++++++++++++++++++++++++++++++
 src/dropshell-completion.bash | 23 ++++++-------
 src/dropshell.hpp             |  2 ++
 src/main.cpp                  | 16 +++++++++
 src/server_env.hpp            |  5 +++
 5 files changed, 94 insertions(+), 13 deletions(-)
 create mode 100644 src/autocomplete.cpp

diff --git a/src/autocomplete.cpp b/src/autocomplete.cpp
new file mode 100644
index 0000000..3008a7c
--- /dev/null
+++ b/src/autocomplete.cpp
@@ -0,0 +1,61 @@
+#include "dropshell.hpp"
+#include "init_user_directory.hpp"
+#include "config.hpp"
+#include <boost/filesystem.hpp>
+#include <iostream>
+
+namespace fs = boost::filesystem;
+
+namespace dropshell {
+
+std::vector<std::string> autocomplete_list_servers() {
+    std::vector<std::string> servers;
+    std::string user_dir;
+    
+    if (!get_user_directory(user_dir)) {
+        std::cerr << "Error: User directory not set" << std::endl;
+        return servers;
+    }
+    
+    fs::path servers_dir = fs::path(user_dir) / "servers";
+    if (!fs::exists(servers_dir)) {
+        std::cerr << "Error: Servers directory not found" << std::endl;
+        return servers;
+    }
+    
+    // List all server directories
+    for (const auto& entry : fs::directory_iterator(servers_dir)) {
+        if (fs::is_directory(entry)) {
+            servers.push_back(entry.path().filename().string());
+        }
+    }
+    
+    return servers;
+}
+
+std::vector<std::string> autocomplete_list_services(const std::string& server_name) {
+    std::vector<std::string> services;
+    std::string user_dir;
+    
+    if (!get_user_directory(user_dir)) {
+        std::cerr << "Error: User directory not set" << std::endl;
+        return services;
+    }
+    
+    fs::path server_dir = fs::path(user_dir) / "servers" / server_name;
+    if (!fs::exists(server_dir)) {
+        std::cerr << "Error: Server directory not found" << std::endl;
+        return services;
+    }
+    
+    // Look for .env files in the server directory
+    for (const auto& entry : fs::directory_iterator(server_dir)) {
+        if (entry.path().extension() == ".env" && entry.path().filename().string() != "_server.env") {
+            services.push_back(entry.path().stem().string());
+        }
+    }
+    
+    return services;
+}
+
+} // namespace dropshell 
\ No newline at end of file
diff --git a/src/dropshell-completion.bash b/src/dropshell-completion.bash
index 73f0049..7d872ee 100755
--- a/src/dropshell-completion.bash
+++ b/src/dropshell-completion.bash
@@ -7,7 +7,7 @@ _dropshell_completions() {
     prev="${COMP_WORDS[COMP_CWORD-1]}"
     
     # List of main commands
-    opts="help version status servers templates"
+    opts="help version status servers templates autocomplete_list_servers autocomplete_list_services"
 
     # If we're completing the first argument, show all commands
     if [[ ${COMP_CWORD} -eq 1 ]] ; then
@@ -22,24 +22,21 @@ _dropshell_completions() {
             COMPREPLY=()
             ;;
         servers)
-            # List servers from _server.env files
-            local servers_dir="/opt/dropshell/user/servers"
-            local servers=()
-            
-            # Read all _server.env files
-            for server_file in "$servers_dir"/*/_server.env; do
-                if [ -f "$server_file" ]; then
-                    local server_name=$(basename "$(dirname "$server_file")")
-                    servers+=("$server_name")
-                fi
-            done
-            COMPREPLY=( $(compgen -W "${servers[@]}" -- ${cur}) )
+            # Use the new autocomplete_list_servers command
+            local servers=($(dropshell autocomplete_list_servers))
+            COMPREPLY=( $(compgen -W "${servers[*]}" -- ${cur}) )
             return 0
             ;;
         templates)
             # No additional completions for templates
             COMPREPLY=()
             ;;
+        autocomplete_list_services)
+            # Use the new autocomplete_list_servers command for server names
+            local servers=($(dropshell autocomplete_list_servers))
+            COMPREPLY=( $(compgen -W "${servers[*]}" -- ${cur}) )
+            return 0
+            ;;
         *)
             ;;
     esac
diff --git a/src/dropshell.hpp b/src/dropshell.hpp
index 13215cf..f49463d 100644
--- a/src/dropshell.hpp
+++ b/src/dropshell.hpp
@@ -31,5 +31,7 @@ void show_server_details(const std::string& server_name);
 
 // Utility functions
 std::vector<ServerInfo> get_configured_servers();
+std::vector<std::string> autocomplete_list_servers();
+std::vector<std::string> autocomplete_list_services(const std::string& server_name);
 
 } // namespace dropshell 
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index 643a4bb..4667a3a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -77,6 +77,22 @@ int main(int argc, char* argv[]) {
                     std::cerr << "Error: " << e.what() << std::endl;
                     return 1;
                 }
+            } else if (cmd == "autocomplete_list_servers") {
+                auto servers = dropshell::autocomplete_list_servers();
+                for (const auto& server : servers) {
+                    std::cout << server << std::endl;
+                }
+                return 0;
+            } else if (cmd == "autocomplete_list_services") {
+                if (argc < 3) {
+                    std::cerr << "Error: autocomplete_list_services requires a server name" << std::endl;
+                    return 1;
+                }
+                auto services = dropshell::autocomplete_list_services(argv[2]);
+                for (const auto& service : services) {
+                    std::cout << service << std::endl;
+                }
+                return 0;
             } else {
                 std::cerr << "Error: Unknown command '" << cmd << "'" << std::endl;
                 dropshell::print_help(desc);
diff --git a/src/server_env.hpp b/src/server_env.hpp
index 46e1448..6cc8086 100644
--- a/src/server_env.hpp
+++ b/src/server_env.hpp
@@ -3,6 +3,9 @@
 // read the _server.env file and provide a class to access the variables
 //
 
+#ifndef __SERVER_ENV_HPP
+#define __SERVER_ENV_HPP
+
 #include <string>
 #include <map>
 
@@ -35,3 +38,5 @@ class server_env {
 
 } // namespace dropshell
 
+
+#endif // __SERVER_ENV_HPP  
\ No newline at end of file