diff --git a/CMakeLists.txt b/CMakeLists.txt index 4affe8795c..d25cd89342 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,9 +125,9 @@ set(NVIM_VERSION_PATCH 0) set(NVIM_VERSION_PRERELEASE "-dev") # for package maintainers # API level -set(NVIM_API_LEVEL 6) # Bump this after any API change. +set(NVIM_API_LEVEL 7) # Bump this after any API change. set(NVIM_API_LEVEL_COMPAT 0) # Adjust this after a _breaking_ API change. -set(NVIM_API_PRERELEASE false) +set(NVIM_API_PRERELEASE true) set(NVIM_VERSION_BUILD_TYPE "${CMAKE_BUILD_TYPE}") # NVIM_VERSION_CFLAGS set further below. diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index d6e420c427..93440f307c 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -1842,6 +1842,27 @@ nvim_buf_set_virtual_text({buffer}, {ns_id}, {line}, {chunks}, {opts}) Return: ~ The ns_id that was used +nvim_buf_get_virtual_text({buffer}, {lnum}) *nvim_buf_get_virtual_text()* + Get the virtual text (annotation) for a buffer line. + + The virtual text is returned as list of lists, whereas the + inner lists have either one or two elements. The first element + is the actual text, the optional second element is the + highlight group. + + The format is exactly the same as given to + nvim_buf_set_virtual_text(). + + If there is no virtual text associated with the given line, an + empty list is returned. + + Parameters: ~ + {buffer} Buffer handle, or 0 for current buffer + {line} Line to get the virtual text from (zero-indexed) + + Return: ~ + List of virtual text chunks + nvim__buf_stats({buffer}) *nvim__buf_stats()* TODO: Documentation diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index cb74c4227b..10250be044 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -1207,7 +1207,57 @@ free_exit: return 0; } -Dictionary nvim__buf_stats(Buffer buffer, Error *err) +/// Get the virtual text (annotation) for a buffer line. +/// +/// The virtual text is returned as list of lists, whereas the inner lists have +/// either one or two elements. The first element is the actual text, the +/// optional second element is the highlight group. +/// +/// The format is exactly the same as given to nvim_buf_set_virtual_text(). +/// +/// If there is no virtual text associated with the given line, an empty list +/// is returned. +/// +/// @param buffer Buffer handle, or 0 for current buffer +/// @param line Line to get the virtual text from (zero-indexed) +/// @param[out] err Error details, if any +/// @return List of virtual text chunks +Array nvim_buf_get_virtual_text(Buffer buffer, Integer lnum, Error *err) + FUNC_API_SINCE(7) +{ + Array chunks = ARRAY_DICT_INIT; + + buf_T *buf = find_buffer_by_handle(buffer, err); + if (!buf) { + return chunks; + } + + if (lnum < 0 || lnum >= MAXLNUM) { + api_set_error(err, kErrorTypeValidation, "Line number outside range"); + return chunks; + } + + BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, (linenr_T)(lnum + 1), + false); + if (!lineinfo) { + return chunks; + } + + for (size_t i = 0; i < lineinfo->virt_text.size; i++) { + Array chunk = ARRAY_DICT_INIT; + VirtTextChunk *vtc = &lineinfo->virt_text.items[i]; + ADD(chunk, STRING_OBJ(cstr_to_string(vtc->text))); + if (vtc->hl_id > 0) { + ADD(chunk, STRING_OBJ(cstr_to_string( + (const char *)syn_id2name(vtc->hl_id)))); + } + ADD(chunks, ARRAY_OBJ(chunk)); + } + + return chunks; +} + +Dictionary nvim__uf_stats(Buffer buffer, Error *err) { Dictionary rv = ARRAY_DICT_INIT; diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua index 5df909f79c..65c5f67726 100644 --- a/test/functional/ui/bufhl_spec.lua +++ b/test/functional/ui/bufhl_spec.lua @@ -386,6 +386,22 @@ describe('Buffer highlighting', function() ]]) end) + it('can be retrieved', function() + local get_virtual_text = curbufmeths.get_virtual_text + local line_count = curbufmeths.line_count + + local s1 = {{'Köttbullar', 'Comment'}, {'Kräuterbutter'}} + local s2 = {{'こんにちは', 'Comment'}} + + set_virtual_text(-1, 0, s1, {}) + eq(s1, get_virtual_text(0)) + + set_virtual_text(-1, line_count(), s2, {}) + eq(s2, get_virtual_text(line_count())) + + eq({}, get_virtual_text(line_count() + 9000)) + end) + it('is not highlighted by visual selection', function() feed("ggVG") screen:expect([[