diff --git a/src/servers.cpp b/src/servers.cpp index 802b82c..696465e 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -2,6 +2,7 @@ #include "dropshell.hpp" #include "server_env.hpp" #include "server_service.hpp" +#include "tableprint.hpp" #include #include #include @@ -52,34 +53,13 @@ std::vector get_configured_servers() { void list_servers() { auto servers = get_configured_servers(); - - if (servers.empty()) { - std::cout << "No servers configured." << std::endl; - return; - } - // Find maximum lengths for formatting - size_t max_name_len = 4; // "Name" is 4 chars - size_t max_addr_len = 7; // "Address" is 7 chars - + tableprint tp; + tp.add_row({"Name", "Address"}); for (const auto& server : servers) { - max_name_len = std::max(max_name_len, server.name.length()); - max_addr_len = std::max(max_addr_len, server.ssh_host.length()); - } - - // Print header - std::cout << std::left << std::setw(max_name_len) << "Name" << " | " - << std::setw(max_addr_len) << "Address" << std::endl; - - // Print separator - std::cout << std::string(max_name_len, '-') << "-+-" - << std::string(max_addr_len, '-') << std::endl; - - // Print server rows - for (const auto& server : servers) { - std::cout << std::left << std::setw(max_name_len) << server.name << " | " - << std::setw(max_addr_len) << server.ssh_host << std::endl; + tp.add_row({server.name, server.ssh_host}); } + tp.print(); } void show_server_details(const std::string& server_name) { diff --git a/src/tableprint.cpp b/src/tableprint.cpp new file mode 100644 index 0000000..23a5499 --- /dev/null +++ b/src/tableprint.cpp @@ -0,0 +1,53 @@ +#include "tableprint.hpp" +#include +#include + +tableprint::tableprint() {} + +tableprint::~tableprint() {} + +void tableprint::add_row(const std::vector& row) { + rows.push_back(row); +} + +void tableprint::print() { + if (rows.empty()) return; + + // Calculate column widths + std::vector col_widths(rows[0].size(), 0); + for (const auto& row : rows) { + for (size_t i = 0; i < row.size(); ++i) { + col_widths[i] = std::max(col_widths[i], row[i].length()); + } + } + + // Print header + std::cout << "\033[1;36m"; // Cyan color for header + for (size_t i = 0; i < rows[0].size(); ++i) { + std::cout << std::setw(col_widths[i] + 2) << std::left << rows[0][i]; + } + std::cout << "\033[0m" << std::endl; // Reset color + + // Print separator + for (size_t i = 0; i < rows[0].size(); ++i) { + std::cout << std::string(col_widths[i] + 2, '-'); + } + std::cout << std::endl; + + // Print rows + for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) { + const auto& row = rows[row_idx]; + for (size_t i = 0; i < row.size(); ++i) { + std::string cell = row[i]; + // Replace :tick: and :cross: with colored symbols + if (cell == ":tick:") { + std::cout << "\033[1;32m" << std::setw(col_widths[i] + 2) << std::left << "✓" << "\033[0m"; + } else if (cell == ":cross:") { + std::cout << "\033[1;31m" << std::setw(col_widths[i] + 2) << std::left << "✗" << "\033[0m"; + } else { + std::cout << std::setw(col_widths[i] + 2) << std::left << cell; + } + } + std::cout << std::endl; + } +} \ No newline at end of file diff --git a/src/tableprint.hpp b/src/tableprint.hpp new file mode 100644 index 0000000..25feefb --- /dev/null +++ b/src/tableprint.hpp @@ -0,0 +1,22 @@ +# ifndef TABLEPRINT_HPP +# define TABLEPRINT_HPP + +#include +#include +#include + +// tableprint is a class that prints a table of strings. +// formatted to look nice with colored headings and rows. +// converts :tick: to a green tick and :cross: to a red cross. +// assumes the first row is the header. +class tableprint { + public: + tableprint(); + ~tableprint(); + void add_row(const std::vector& row); + void print(); + private: + std::vector> rows; +}; + +# endif