diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index fb04829..a47ddb7 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.10) project(dropshell VERSION 1.0.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 23) +set(CMAKE_C_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Set default build type to Release if not specified diff --git a/source/src/commands/create-service.cpp b/source/src/commands/create-service.cpp index d1b8fae..f112e2d 100644 --- a/source/src/commands/create-service.cpp +++ b/source/src/commands/create-service.cpp @@ -94,7 +94,7 @@ namespace dropshell std::string line; while (std::getline(readme_file, line)) { - info << substitute_provided_key_value_pairs(line, all_env_vars) << std::endl; + rawout << substitute_provided_key_value_pairs(line, all_env_vars) << std::endl; } return true; } diff --git a/source/src/commands/help.cpp b/source/src/commands/help.cpp index 935bf00..9d4244b 100644 --- a/source/src/commands/help.cpp +++ b/source/src/commands/help.cpp @@ -55,6 +55,11 @@ void help_autocomplete(const CommandContext& ctx) { } void show_command(const std::string& cmd) { + // get console width + int width = get_console_width() - 6; // 5 for [INF] + 1 for space + int firstcol = 34; + int secondcol = width - firstcol - 3; + const auto& cmd_info = CommandRegistry::instance().find_command(cmd); if (!cmd_info) { @@ -62,9 +67,22 @@ void show_command(const std::string& cmd) { return; } - info << " "; - info << left_align(cmd_info->help_usage, 32); - info << cmd_info->help_description << std::endl; + if (cmd_info->help_usage.length() < width-secondcol) + { + std::string remaining_description = cmd_info->help_description; + + info << " " << left_align(cmd_info->help_usage, firstcol) << get_line_wrap(remaining_description, secondcol); + while (!remaining_description.empty()) + info << " " << left_align(" ",firstcol) << get_line_wrap(remaining_description, secondcol-1); + } + else + { + info << " " << cmd_info->help_usage << std::endl; + std::string remaining_description = cmd_info->help_description; + info << " " << left_align(" ",firstcol) << get_line_wrap(remaining_description, secondcol); + while (!remaining_description.empty()) + info << " " << left_align(" ",firstcol) << get_line_wrap(remaining_description, secondcol-1); + } } extern const std::string VERSION; @@ -106,7 +124,7 @@ int help_handler(const CommandContext& ctx) { if (ctx.args.size() > 0) return show_command_help(ctx.args[0]); - info << std::endl; + std::cout << std::endl; maketitle("DropShell version " + VERSION); info << std::endl; info << "A tool for managing remote servers, by " << AUTHOR << std::endl; @@ -120,16 +138,17 @@ int help_handler(const CommandContext& ctx) { { // show more! show_command("list"); - std::cout << std::endl; + info << std::endl; show_command("install"); show_command("uninstall"); show_command("nuke"); - std::cout << std::endl; + info << std::endl; show_command("start"); show_command("stop"); - std::cout << std::endl; + info << std::endl; show_command("ssh"); - std::cout << std::endl; + info << std::endl; + show_command("create-service"); } return 0; } diff --git a/source/src/utils/output.cpp b/source/src/utils/output.cpp index ab91a46..35eb7e2 100644 --- a/source/src/utils/output.cpp +++ b/source/src/utils/output.cpp @@ -42,7 +42,7 @@ namespace dropshell std::lock_guard lock(output_mutex); if (c == EOF) return !EOF; - if (at_line_start_ && c != '\n') + if (at_line_start_) // && c != '\n') { dest_ << GREY << tag_ << RESET << ' ' << colour_; at_line_start_ = false; diff --git a/source/src/utils/utils.cpp b/source/src/utils/utils.cpp index 4e7f26d..574c09a 100644 --- a/source/src/utils/utils.cpp +++ b/source/src/utils/utils.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include namespace dropshell { @@ -388,4 +390,46 @@ std::string substitute_provided_key_value_pairs(std::string str, const std::map< return result; } +int get_console_width() +{ + struct winsize w; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == 0) { + return w.ws_col; + } + // Fallback to a reasonable default if we can't get the width + return 80; +} + +std::string remove_return(std::string str) +{ + str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); + return str; +} + +std::string get_line_wrap(std::string &src, int maxchars) +{ + if (src.empty()) + return ""; + + if (src.length() <= maxchars) + { + std::string out = src; + src.erase(); + return remove_return(out) + '\n'; + } + + // find last whitespace up to but not more than maxchars + size_t grab_to=maxchars; + size_t lastreturn = src.rfind('\n', maxchars); + size_t lastspace = src.rfind(' ', maxchars); + if (lastreturn != std::string::npos) + grab_to = lastreturn; + else if (lastspace != std::string::npos) + grab_to = lastspace; + + std::string out = src.substr(0, grab_to); + src = src.substr(grab_to + 1); + return remove_return(out) + '\n'; +} + } // namespace dropshell \ No newline at end of file diff --git a/source/src/utils/utils.hpp b/source/src/utils/utils.hpp index a1425b9..c652862 100644 --- a/source/src/utils/utils.hpp +++ b/source/src/utils/utils.hpp @@ -55,4 +55,8 @@ std::string center_align(const std::string & str, int width); std::string replace_with_environment_variables_like_bash(std::string str); std::string substitute_provided_key_value_pairs(std::string str, const std::map & env_vars); +int get_console_width(); + +std::string get_line_wrap(std::string & src, int maxchars); + } // namespace dropshell \ No newline at end of file