aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/buffer.c
diff options
context:
space:
mode:
authortimeyyy <timeyyy_da_man@hotmail.com>2017-01-18 13:20:07 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2019-11-11 19:43:15 +0100
commita9065a50518ef59351f9d0d32041a991a751653f (patch)
tree4448b4895b8977fcb09b8d87060cfa20fb8058b9 /src/nvim/api/buffer.c
parente757f4d5363125e242f1e680d1f5bb53e8014b06 (diff)
downloadrneovim-a9065a50518ef59351f9d0d32041a991a751653f.tar.gz
rneovim-a9065a50518ef59351f9d0d32041a991a751653f.tar.bz2
rneovim-a9065a50518ef59351f9d0d32041a991a751653f.zip
nsmarks: initial commit
Diffstat (limited to 'src/nvim/api/buffer.c')
-rw-r--r--src/nvim/api/buffer.c217
1 files changed, 216 insertions, 1 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 10250be044..a77c33e891 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -23,7 +23,10 @@
#include "nvim/memory.h"
#include "nvim/misc1.h"
#include "nvim/ex_cmds.h"
+#include "nvim/map_defs.h"
+#include "nvim/map.h"
#include "nvim/mark.h"
+#include "nvim/mark_extended.h"
#include "nvim/fileio.h"
#include "nvim/move.h"
#include "nvim/syntax.h"
@@ -544,7 +547,8 @@ void nvim_buf_set_lines(uint64_t channel_id,
(linenr_T)(end - 1),
MAXLNUM,
(long)extra,
- false);
+ false,
+ kExtmarkUndo);
changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true);
fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra);
@@ -999,6 +1003,213 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
return rv;
}
+/// Returns position info for a given extmark id
+///
+/// @param buffer The buffer handle
+/// @param namespace a identifier returned previously with nvim_create_namespace
+/// @param id the extmark id
+/// @param[out] err Details of an error that may have occurred
+/// @return (row, col) tuple or empty list () if extmark id was absent
+ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer namespace,
+ Integer id, Error *err)
+ FUNC_API_SINCE(6)
+{
+ Array rv = ARRAY_DICT_INIT;
+
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return rv;
+ }
+
+ if (!ns_initialized((uint64_t)namespace)) {
+ api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ return rv;
+ }
+
+ ExtendedMark *extmark = extmark_from_id(buf,
+ (uint64_t)namespace,
+ (uint64_t)id);
+ if (!extmark) {
+ return rv;
+ }
+ ADD(rv, INTEGER_OBJ((Integer)extmark->line->lnum-1));
+ ADD(rv, INTEGER_OBJ((Integer)extmark->col-1));
+ return rv;
+}
+
+/// List extmarks in a range (inclusive)
+///
+/// range ends can be specified as (row, col) tuples, as well as extmark
+/// ids in the same namespace. In addition, 0 and -1 works as shorthands
+/// for (0,0) and (-1,-1) respectively, so that all marks in the buffer can be
+/// quieried as:
+///
+/// all_marks = nvim_buf_get_extmarks(0, my_ns, 0, -1, -1)
+///
+/// If end is a lower position than start, then the range will be traversed
+/// backwards. This is mostly used with limited amount, to be able to get the
+/// first marks prior to a given position.
+///
+/// @param buffer The buffer handle
+/// @param namespace An id returned previously from nvim_create_namespace
+/// @param lower One of: extmark id, (row, col) or 0, -1 for buffer ends
+/// @param upper One of: extmark id, (row, col) or 0, -1 for buffer ends
+/// @param amount Maximum number of marks to return or -1 for all marks found
+/// /// @param[out] err Details of an error that may have occurred
+/// @return [[nsmark_id, row, col], ...]
+Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
+ Object start, Object end, Integer amount,
+ Error *err)
+ FUNC_API_SINCE(6)
+{
+ Array rv = ARRAY_DICT_INIT;
+
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return rv;
+ }
+
+ if (!ns_initialized((uint64_t)ns_id)) {
+ api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ return rv;
+ }
+
+ if (amount == 0) {
+ return rv;
+ }
+
+
+ bool reverse = false;
+
+ linenr_T l_lnum;
+ colnr_T l_col;
+ if (!set_extmark_index_from_obj(buf, ns_id, start, &l_lnum, &l_col, err)) {
+ return rv;
+ }
+
+ linenr_T u_lnum;
+ colnr_T u_col;
+ if (!set_extmark_index_from_obj(buf, ns_id, end, &u_lnum, &u_col, err)) {
+ return rv;
+ }
+
+ if (l_lnum > u_lnum || (l_lnum == u_lnum && l_col > u_col)) {
+ reverse = true;
+ linenr_T tmp_lnum = l_lnum;
+ l_lnum = u_lnum;
+ u_lnum = tmp_lnum;
+ colnr_T tmp_col = l_col;
+ l_col = u_col;
+ u_col = tmp_col;
+ }
+
+
+ ExtmarkArray marks = extmark_get(buf, (uint64_t)ns_id, l_lnum, l_col,
+ u_lnum, u_col, (int64_t)amount,
+ reverse);
+
+ for (size_t i = 0; i < kv_size(marks); i++) {
+ Array mark = ARRAY_DICT_INIT;
+ ExtendedMark *extmark = kv_A(marks, i);
+ ADD(mark, INTEGER_OBJ((Integer)extmark->mark_id));
+ ADD(mark, INTEGER_OBJ(extmark->line->lnum-1));
+ ADD(mark, INTEGER_OBJ(extmark->col-1));
+ ADD(rv, ARRAY_OBJ(mark));
+ }
+
+ kv_destroy(marks);
+ return rv;
+}
+
+/// Create or update a namespaced mark at a position
+///
+/// If an invalid namespace is given, an error will be raised.
+///
+/// @param buffer The buffer handle
+/// @param ns_id a identifier returned previously with nvim_create_namespace
+/// @param id The extmark's id or 0 for next free id
+/// @param row The row to set the extmark to.
+/// @param col The column to set the extmark to.
+/// @param[out] err Details of an error that may have occurred
+/// @return the nsmark_id for a new mark, or 0 for an update
+Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
+ Integer line, Integer col, Error *err)
+ FUNC_API_SINCE(6)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return 0;
+ }
+
+ if (!ns_initialized((uint64_t)ns_id)) {
+ api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ return 0;
+ }
+
+ size_t len = 0;
+ if (line < 0 || line > buf->b_ml.ml_line_count) {
+ api_set_error(err, kErrorTypeValidation, "line value outside range");
+ return 0;
+ } else if (line < buf->b_ml.ml_line_count) {
+ len = STRLEN(ml_get_buf(curbuf, (linenr_T)line+1, false));
+ }
+
+ if (col == -1) {
+ col = (Integer)len;
+ } else if (col < -1 || col > (Integer)len) {
+ api_set_error(err, kErrorTypeValidation, "col value outside range");
+ return 0;
+ }
+
+ uint64_t id_num;
+ if (id == 0) {
+ id_num = extmark_free_id_get(buf, (uint64_t)ns_id);
+ } else if (id > 0) {
+ id_num = (uint64_t)id;
+ } else {
+ api_set_error(err, kErrorTypeValidation, _("Invalid mark id"));
+ return 0;
+ }
+
+ bool new = extmark_set(buf, (uint64_t)ns_id, id_num,
+ (linenr_T)line+1,
+ (colnr_T)col+1,
+ kExtmarkUndo);
+
+ if (new) {
+ return (Integer)id_num;
+ } else {
+ return 0;
+ }
+}
+
+/// Remove an extmark
+///
+/// @param buffer The buffer handle
+/// @param ns_id a identifier returned previously with nvim_create_namespace
+/// @param id The extmarks's id
+/// @param[out] err Details of an error that may have occurred
+/// @return true on success, false if no extmarks found
+Boolean nvim_buf_del_extmark(Buffer buffer,
+ Integer ns_id,
+ Integer id,
+ Error *err)
+ FUNC_API_SINCE(6)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return false;
+ }
+ if (!ns_initialized((uint64_t)ns_id)) {
+ api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ return false;
+ }
+
+ return extmark_del(buf, (uint64_t)ns_id, (uint64_t)id, kExtmarkUndo);
+}
+
/// Adds a highlight to buffer.
///
/// Useful for plugins that dynamically generate highlights to a buffer
@@ -1097,6 +1308,10 @@ void nvim_buf_clear_namespace(Buffer buffer,
}
bufhl_clear_line_range(buf, (int)ns_id, (int)line_start+1, (int)line_end);
+ extmark_clear(buf, ns_id == -1 ? 0 : (uint64_t)ns_id,
+ (linenr_T)line_start+1,
+ (linenr_T)line_end,
+ kExtmarkUndo);
}
/// Clears highlights and virtual text from namespace and range of lines