diff --git a/src/yycc/carton/clap/manual.cpp b/src/yycc/carton/clap/manual.cpp index 1bd1fdf..be4f539 100644 --- a/src/yycc/carton/clap/manual.cpp +++ b/src/yycc/carton/clap/manual.cpp @@ -55,13 +55,44 @@ namespace yycc::carton::clap::manual { for (const auto ®_opt : options.all_options()) { const auto &opt = reg_opt.get_option(); - //for (const auto [index, item] : std::views::enumerate(header)) { - // - //} + auto desc_by_line = OP::lazy_split(opt.get_description(), u8"\n"); + for (const auto [index, item] : std::views::enumerate(desc_by_line)) { + if (index == 0) { + auto full_name = TERMCOLOR::colored(opt.to_showcase_name(), + TERMCOLOR::Color::LightYellow, + TERMCOLOR::Color::Default, + TERMCOLOR::Attribute::Default); + auto value_hint = TERMCOLOR::colored(opt.to_showcase_value(), + TERMCOLOR::Color::LightGreen, + TERMCOLOR::Color::Default, + TERMCOLOR::Attribute::Default); + this->opt_printer.add_row({full_name, value_hint, item}); + } else { + this->opt_printer.add_row({u8"", u8"", item}); + } + } } } - void Manual::fill_var_table() {} + void Manual::fill_var_table() { + const auto &variables = app.get_variables(); + for (const auto ®_var : variables.all_variables()) { + const auto &var = reg_var.get_variable(); + + auto desc_by_line = OP::lazy_split(var.get_description(), u8"\n"); + for (const auto [index, item] : std::views::enumerate(desc_by_line)) { + if (index == 0) { + auto name = TERMCOLOR::colored(var.get_name(), + TERMCOLOR::Color::LightYellow, + TERMCOLOR::Color::Default, + TERMCOLOR::Attribute::Default); + this->var_printer.add_row({name, item}); + } else { + this->var_printer.add_row({u8"", item}); + } + } + } + } void Manual::print_version(std::ostream &dst) const { const auto &summary = this->app.get_summary(); diff --git a/src/yycc/string/op.cpp b/src/yycc/string/op.cpp index 3f2b6dc..ec192cf 100644 --- a/src/yycc/string/op.cpp +++ b/src/yycc/string/op.cpp @@ -181,12 +181,12 @@ namespace yycc::string::op { std::u8string_view next_str; public: + CodePointIterator() : CodePointIterator(std::u8string_view()) {} CodePointIterator(const std::u8string_view& strl) : current_str(), next_str(strl) { ++(*this); } + YYCC_DEFAULT_COPY_MOVE(CodePointIterator) reference operator*() const { return this->current_str; } - pointer operator->() const { return &this->current_str; } - CodePointIterator& operator++() { // move next string to current string and analyse it current_str = next_str; @@ -214,17 +214,14 @@ namespace yycc::string::op { // return self return *this; } - CodePointIterator operator++(int) { CodePointIterator temp = *this; ++(*this); return temp; } - bool operator==(const CodePointIterator& other) const { return this->current_str == other.current_str && this->next_str == other.next_str; } - bool operator!=(const CodePointIterator& other) const { return !(*this == other); } private: @@ -263,9 +260,9 @@ namespace yycc::string::op { public: explicit CodePoint(std::u8string_view u8str) : u8str(u8str) {} + YYCC_DEFAULT_COPY_MOVE(CodePoint) CodePointIterator begin() const { return CodePointIterator(u8str); } - CodePointIterator end() const { // Pass empty string view indicate end. return CodePointIterator(std::u8string_view()); @@ -295,7 +292,7 @@ namespace yycc::string::op { // Do not accept root element always (no empty string). root->is_end = false; } - + /** * @brief Insert new words in trie tree. * @details @@ -352,18 +349,18 @@ namespace yycc::string::op { // YYC MARK: // There is a fatal bug for Trie Tree, but it doesn't matter with our usage scenario. - // + // // Assume there is two string "ab" and "abcd". If user give "abc", // we should match it with "ab" prefix, but this function will return there is no match. // However, this is impossible for UTF8 sequence. // There is no possibility that two UTF8 sequence, indicating two different Unicode code point respectively, // has the same prefix and different length. Because their first byte must be different, // the first byte indicate the length of sequence. - // - // This result also can be proven for suffix, + // + // This result also can be proven for suffix, // because first byte must not be equal to any other continuation bytes. // It is impossible that they have same "ab". - // + // // So it is safe for our usage scenario although this bug is presented. // check whether current is valid end. @@ -471,10 +468,8 @@ namespace yycc::string::op { return internal_trim(strl, words); } - #pragma endregion - #pragma region Split // Reference: @@ -482,6 +477,8 @@ namespace yycc::string::op { #pragma region Lazy Split Iterator + LazySplitIterator::LazySplitIterator() : LazySplitIterator(std::nullopt, std::u8string_view()) {} + LazySplitIterator::LazySplitIterator(std::optional strl, const std::u8string_view& delimiter) : m_current_str(std::nullopt), m_next_str(strl), m_delimiter(delimiter) { // We can archive result by assign string into next string, @@ -542,8 +539,8 @@ namespace yycc::string::op { } bool LazySplitIterator::operator==(const LazySplitIterator& other) const { - return (this->m_current_str == other.m_current_str) && (this->m_next_str == other.m_next_str) - && (this->m_delimiter == other.m_delimiter); + // YYC MARK: do not compare the delimiter + return (this->m_current_str == other.m_current_str) && (this->m_next_str == other.m_next_str); } bool LazySplitIterator::operator!=(const LazySplitIterator& other) const { diff --git a/src/yycc/string/op.hpp b/src/yycc/string/op.hpp index e2e5742..5ad1eef 100644 --- a/src/yycc/string/op.hpp +++ b/src/yycc/string/op.hpp @@ -1,5 +1,6 @@ #pragma once #include "../macro/printf_checker.hpp" +#include "../macro/class_copy_move.hpp" #include #include #include @@ -243,7 +244,9 @@ namespace yycc::string::op { std::u8string_view m_delimiter; ///< Delimiter public: + LazySplitIterator(); LazySplitIterator(std::optional strl, const std::u8string_view& delimiter); + YYCC_DEFAULT_COPY_MOVE(LazySplitIterator) reference operator*() const; pointer operator->() const; @@ -263,6 +266,8 @@ namespace yycc::string::op { public: LazySplit(const std::u8string_view& strl, const std::u8string_view& delimiter); + YYCC_DEFAULT_COPY_MOVE(LazySplit) + LazySplitIterator begin() const; LazySplitIterator end() const; };