diff --git a/clients/vscode-hlasmplugin/CHANGELOG.md b/clients/vscode-hlasmplugin/CHANGELOG.md index 4ce567fff..2fe6aa54a 100644 --- a/clients/vscode-hlasmplugin/CHANGELOG.md +++ b/clients/vscode-hlasmplugin/CHANGELOG.md @@ -6,6 +6,9 @@ - Provide more details about machine instructions in hover texts - Faded preprocessor statements +#### Fixed +- Large macro documentation is not highlighted correctly in hover texts + ## [1.6.0](https://github.com/eclipse/che-che4z-lsp-for-hlasm/compare/1.5.0...1.6.0) (2023-01-18) #### Added diff --git a/language_server/src/lsp/feature_language_features.cpp b/language_server/src/lsp/feature_language_features.cpp index 9624c22b6..7e56c12ca 100644 --- a/language_server/src/lsp/feature_language_features.cpp +++ b/language_server/src/lsp/feature_language_features.cpp @@ -199,7 +199,7 @@ void feature_language_features::hover(const nlohmann::json& id, const nlohmann:: response_->respond(id, "", nlohmann::json { - { "contents", hover_list.empty() ? nlohmann::json() : get_markup_content(hover_list) }, + { "contents", hover_list.empty() ? "" : get_markup_content(hover_list) }, }); } diff --git a/parser_library/src/lsp/item_convertors.cpp b/parser_library/src/lsp/item_convertors.cpp index 0a123d96f..0ca8ad8f9 100644 --- a/parser_library/src/lsp/item_convertors.cpp +++ b/parser_library/src/lsp/item_convertors.cpp @@ -14,6 +14,7 @@ #include "item_convertors.h" +#include #include #include "completion_item.h" @@ -26,11 +27,12 @@ #include "text_data_view.h" #include "utils/concat.h" #include "utils/string_operations.h" +#include "utils/unicode_text.h" namespace hlasm_plugin::parser_library::lsp { namespace { -template +template std::string& append_hex_and_dec(std::string& t, T value) { using UT = std::make_unsigned_t; @@ -185,25 +187,57 @@ std::string get_macro_documentation(const text_data_view& text, size_t definitio --doc_before_begin_line; ++doc_before_begin_line; - std::string_view doc_before = text.get_range_content({ { doc_before_begin_line, 0 }, { MACRO_line, 0 } }); - // Find the end line of macro definition size_t macro_def_end_line = definition_line; while (macro_def_end_line < text.get_number_of_lines() && is_continued_line(text.get_line(macro_def_end_line))) ++macro_def_end_line; ++macro_def_end_line; - std::string_view macro_def = text.get_range_content({ { definition_line, 0 }, { macro_def_end_line, 0 } }); - // Find the end line of documentation that comes after the macro definition size_t doc_after_end_line = macro_def_end_line; while (doc_after_end_line < text.get_number_of_lines() && is_comment(text.get_line(doc_after_end_line))) ++doc_after_end_line; - std::string_view doc_after = text.get_range_content({ { macro_def_end_line, 0 }, { doc_after_end_line, 0 } }); + constexpr static std::string_view prolog("```hlasm"); + constexpr static std::string_view epilog("\n```\n"); + + constexpr static auto add_line = [](std::string& str, std::string_view line) { + auto append = utils::utf8_substr(line, 0, 72).str; + str.push_back('\n'); + size_t trim_pos = append.find_last_not_of(" \n\r") + 1; + str.append(append.substr(0, trim_pos - (trim_pos == 0))); + }; + + // There is a limit editor.maxTokenizationLineLength which seems to be applied a bit strangely... + // Breaking the content into two blocks ensures that at least the first one is likely highlighted correctly + + std::string result; + /* 2x(prolog + epilog) + line count * (72 columns, newline, reserve 1 byte per line for weird chars) */ + result.reserve(2 * (prolog.size() + epilog.size()) + (72 + 1 + 1) * (doc_after_end_line - doc_before_begin_line)); + + result.append(prolog); + for (auto i = definition_line; i < macro_def_end_line; ++i) + add_line(result, text.get_line(i)); + result.append(epilog); + + if (MACRO_line - doc_before_begin_line + doc_after_end_line - macro_def_end_line > 0) + { + size_t doc_lines = 0; + constexpr size_t doc_limit = 1024; + + result.append(prolog); + for (auto i = doc_before_begin_line; i < MACRO_line && doc_lines < doc_limit; ++i, ++doc_lines) + add_line(result, text.get_line(i)); + for (auto i = macro_def_end_line; i < doc_after_end_line && doc_lines < doc_limit; ++i, ++doc_lines) + add_line(result, text.get_line(i)); + result.append(epilog); + + if (doc_lines >= doc_limit) + result.append("Documentation truncated..."); + } - return utils::concat("```\n", macro_def, doc_before, doc_after, "\n```\n"); + return result; } completion_item_s generate_completion_item(const context::sequence_symbol& sym) diff --git a/parser_library/test/lsp/item_convertors_test.cpp b/parser_library/test/lsp/item_convertors_test.cpp index 739abc6f1..5da3bc8b6 100644 --- a/parser_library/test/lsp/item_convertors_test.cpp +++ b/parser_library/test/lsp/item_convertors_test.cpp @@ -97,14 +97,15 @@ const std::string macro_def_input = )"; -const std::string macro_def_expected = R"(``` +const std::string macro_def_expected = R"(```hlasm MAC &FIRST_PARAM, first param remark X &SECOND_PARAM=1 second param remark +``` +```hlasm * Before macro line 1 * Before macro line 2 * After macro line 1 .* After macro line 2 - ``` )"; } // namespace diff --git a/parser_library/test/lsp/lsp_context_macro_documentation_test.cpp b/parser_library/test/lsp/lsp_context_macro_documentation_test.cpp index 12720b927..6275c9e91 100644 --- a/parser_library/test/lsp/lsp_context_macro_documentation_test.cpp +++ b/parser_library/test/lsp/lsp_context_macro_documentation_test.cpp @@ -40,14 +40,15 @@ struct lsp_context_macro_documentation : public analyzer_fixture )"; - const static inline std::string macro_documentation = R"(``` + const static inline std::string macro_documentation = R"(```hlasm MAC &FIRST_PARAM, first param remark X &SECOND_PARAM=1 second param remark +``` +```hlasm * Before macro line 1 * Before macro line 2 * After macro line 1 .* After macro line 2 - ``` )"; diff --git a/parser_library/test/lsp/lsp_context_macro_in_opencode_test.cpp b/parser_library/test/lsp/lsp_context_macro_in_opencode_test.cpp index 96dc204d3..7e191135e 100644 --- a/parser_library/test/lsp/lsp_context_macro_in_opencode_test.cpp +++ b/parser_library/test/lsp/lsp_context_macro_in_opencode_test.cpp @@ -66,9 +66,8 @@ TEST_F(lsp_context_macro_in_opencode, hover_macro) { auto res = a.context().lsp_ctx->hover(opencode_loc, { 7, 8 }); - EXPECT_EQ(res, R"(``` + EXPECT_EQ(res, R"(```hlasm &LABEL MAC &POS_PAR,&KEY_PAR=1 - ``` )"); }