#include <assert.h>
#include <lauxlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "klib/kvec.h"
#include "nvim/api/extmark.h"
#include "nvim/api/keysets_defs.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/validate.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/decoration.h"
#include "nvim/decoration_defs.h"
#include "nvim/decoration_provider.h"
#include "nvim/drawscreen.h"
#include "nvim/extmark.h"
#include "nvim/globals.h"
#include "nvim/grid.h"
#include "nvim/highlight_group.h"
#include "nvim/map_defs.h"
#include "nvim/marktree.h"
#include "nvim/marktree_defs.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/memory_defs.h"
#include "nvim/move.h"
#include "nvim/pos_defs.h"
#include "nvim/sign.h"
#include "api/extmark.c.generated.h"
void api_extmark_free_all_mem(void)
{
String name;
map_foreach_key(&namespace_ids, name, {
xfree(name.data);
})
map_destroy(String, &namespace_ids);
set_destroy(uint32_t, &namespace_localscope);
}
/// Creates a new namespace or gets an existing one. [namespace]()
///
/// Namespaces are used for buffer highlights and virtual text, see
/// |nvim_buf_set_extmark()|.
///
/// Namespaces can be named or anonymous. If `name` matches an existing
/// namespace, the associated id is returned. If `name` is an empty string
/// a new, anonymous namespace is created.
///
/// @param name Namespace name or empty string
/// @return Namespace id
Integer nvim_create_namespace(String name)
FUNC_API_SINCE(5)
{
handle_T id = map_get(String, int)(&namespace_ids, name);
if (id > 0) {
return (Integer)id;
}
id = next_namespace_id++;
if (name.size > 0) {
String name_alloc = copy_string(name, NULL);
map_put(String, int)(&namespace_ids, name_alloc, id);
}
return (Integer)id;
}
/// Gets existing, non-anonymous |namespace|s.
///
/// @return dict that maps from names to namespace ids.
DictOf(Integer) nvim_get_namespaces(Arena *arena)
FUNC_API_SINCE(5)
{
Dict retval = arena_dict(arena, map_size(&namespace_ids));
String name;
handle_T id;
map_foreach(&namespace_ids, name, id, {
PUT_C(retval, name.data, INTEGER_OBJ(id));
})
return retval;
}
const char *describe_ns(NS ns_id, const char *unknown)
{
String name;
handle_T id;
map_foreach(&namespace_ids, name, id, {
if ((NS)id == ns_id && name.size) {
return name.data;
}
})
return unknown;
}
// Is the Namespace in use?
bool ns_initialized(uint32_t ns)
{
if (ns < 1) {
return false;
}
return ns < (uint32_t)next_namespace_id;
}
Array virt_text_to_array(VirtText vt, bool hl_name, Arena *arena)
{
Array chunks = arena_array(arena, kv_size(vt));
for (size_t i = 0; i < kv_size(vt); i++) {
size_t j = i;
for (; j < kv_size(vt); j++) {
if (kv_A(vt, j).text != NULL) {
break;
}
}
Array hl_array = arena_array(arena, i < j ? j - i + 1 : 0);
for (; i < j; i++) {
int hl_id = kv_A(vt, i).hl_id;
if (hl_id >= 0) {
ADD_C(hl_array, hl_group_name(hl_id, hl_name));
}
}
char *text = kv_A(vt, i).text;
int hl_id = kv_A(vt, i).hl_id;
Array chunk = arena_array(arena, 2);
ADD_C(chunk, CSTR_AS_OBJ(text));
if (hl_array.size > 0) {
if (hl_id >= 0) {
ADD_C(hl_array, hl_group_name(hl_id, hl_name));
|