Skip to content

Commit

Permalink
fix: Large macro documentation is not highlighted correctly in hover …
Browse files Browse the repository at this point in the history
…texts
  • Loading branch information
slavek-kucera authored Feb 6, 2023
1 parent 3a9490d commit 3179b14
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 14 deletions.
3 changes: 3 additions & 0 deletions clients/vscode-hlasmplugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion language_server/src/lsp/feature_language_features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
});
}

Expand Down
48 changes: 41 additions & 7 deletions parser_library/src/lsp/item_convertors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "item_convertors.h"

#include <concepts>
#include <limits>

#include "completion_item.h"
Expand All @@ -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</*std::integral*/ typename T>
template<std::integral T>
std::string& append_hex_and_dec(std::string& t, T value)
{
using UT = std::make_unsigned_t<T>;
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions parser_library/test/lsp/item_convertors_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
)";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
)");
}
Expand Down

0 comments on commit 3179b14

Please sign in to comment.