aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c87
-rw-r--r--src/nvim/api/private/helpers.c14
-rw-r--r--src/nvim/buffer_defs.h2
-rw-r--r--src/nvim/ex_cmds.c2
-rw-r--r--src/nvim/map.c1
-rw-r--r--src/nvim/map.h1
-rw-r--r--src/nvim/mark_extended.c464
-rw-r--r--src/nvim/mark_extended.h65
-rw-r--r--src/nvim/mark_extended_defs.h4
-rw-r--r--src/nvim/ops.c77
-rw-r--r--src/nvim/undo.c7
11 files changed, 294 insertions, 430 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index a77c33e891..24fa963fbc 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1003,16 +1003,16 @@ ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
return rv;
}
-/// Returns position info for a given extmark id
+/// Returns position 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,
+ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id,
Integer id, Error *err)
- FUNC_API_SINCE(6)
+ FUNC_API_SINCE(7)
{
Array rv = ARRAY_DICT_INIT;
@@ -1022,13 +1022,13 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer namespace,
return rv;
}
- if (!ns_initialized((uint64_t)namespace)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ if (!ns_initialized((uint64_t)ns_id)) {
+ api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
return rv;
}
ExtendedMark *extmark = extmark_from_id(buf,
- (uint64_t)namespace,
+ (uint64_t)ns_id,
(uint64_t)id);
if (!extmark) {
return rv;
@@ -1052,16 +1052,17 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer namespace,
/// first marks prior to a given position.
///
/// @param buffer The buffer handle
-/// @param namespace An id returned previously from nvim_create_namespace
+/// @param ns_id 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
+/// @param opts additional options. Supports the keys:
+/// - amount: Maximum number of marks to return
+/// @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,
+ Object start, Object end, Dictionary opts,
Error *err)
- FUNC_API_SINCE(6)
+ FUNC_API_SINCE(7)
{
Array rv = ARRAY_DICT_INIT;
@@ -1071,9 +1072,26 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
return rv;
}
+ Integer amount = -1;
+
+ for (size_t i = 0; i < opts.size; i++) {
+ String k = opts.items[i].key;
+ Object *v = &opts.items[i].value;
+ if (strequal("amount", k.data)) {
+ if (v->type != kObjectTypeInteger) {
+ api_set_error(err, kErrorTypeValidation, "amount is not an integer");
+ return rv;
+ }
+ amount = v->data.integer;
+ v->data.integer = LUA_NOREF;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ return rv;
+ }
+ }
if (amount == 0) {
return rv;
@@ -1122,20 +1140,30 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
return rv;
}
-/// Create or update a namespaced mark at a position
+/// Create or update an extmark at a position
///
/// If an invalid namespace is given, an error will be raised.
///
+/// To create a new extmark, pass in id=0. The new extmark id will be
+/// returned. To move an existing mark, pass in its id.
+///
+/// It is also allowed to create a new mark by passing in a previously unused
+/// id, but the caller must then keep track of existing and unused ids itself.
+/// This is mainly useful over RPC, to avoid needing to wait for the return
+/// value.
+///
/// @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 id The extmark's id or 0 to create a new mark.
/// @param row The row to set the extmark to.
/// @param col The column to set the extmark to.
+/// @param opts Optional parameters. Currently not used.
/// @param[out] err Details of an error that may have occurred
-/// @return the nsmark_id for a new mark, or 0 for an update
+/// @return the id of the extmark.
Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
- Integer line, Integer col, Error *err)
- FUNC_API_SINCE(6)
+ Integer line, Integer col,
+ Dictionary opts, Error *err)
+ FUNC_API_SINCE(7)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
@@ -1143,7 +1171,12 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
+ return 0;
+ }
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
return 0;
}
@@ -1172,16 +1205,10 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
return 0;
}
- bool new = extmark_set(buf, (uint64_t)ns_id, id_num,
- (linenr_T)line+1,
- (colnr_T)col+1,
- kExtmarkUndo);
+ 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;
- }
+ return (Integer)id_num;
}
/// Remove an extmark
@@ -1190,12 +1217,12 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer id,
/// @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
+/// @return true on success, false if the extmark was not found.
Boolean nvim_buf_del_extmark(Buffer buffer,
Integer ns_id,
Integer id,
Error *err)
- FUNC_API_SINCE(6)
+ FUNC_API_SINCE(7)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -1203,7 +1230,7 @@ Boolean nvim_buf_del_extmark(Buffer buffer,
return false;
}
if (!ns_initialized((uint64_t)ns_id)) {
- api_set_error(err, kErrorTypeValidation, _("Invalid mark namespace"));
+ api_set_error(err, kErrorTypeValidation, _("Invalid ns_id"));
return false;
}
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 5e9a572a78..6b69350429 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1575,12 +1575,14 @@ bool ns_initialized(uint64_t ns)
return ns < (uint64_t)next_namespace_id;
}
-// Extmarks may be queried from position or name or even special names
-// in the future such as "cursor". This macro sets the line and col
-// to make the extmark functions recognize what's required
-//
-// *lnum: linenr_T, lnum to be set
-// *col: colnr_T, col to be set
+/// Get line and column from extmark object
+///
+/// Extmarks may be queried from position or name or even special names
+/// in the future such as "cursor". This function sets the line and col
+/// to make the extmark functions recognize what's required
+///
+/// @param[out] lnum lnum to be set
+/// @param[out] colnr col to be set
bool set_extmark_index_from_obj(buf_T *buf, Integer namespace,
Object obj, linenr_T *lnum, colnr_T *colnr,
Error *err)
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 2d65d0e160..29eb32d40a 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -809,7 +809,7 @@ struct file_buffer {
kvec_t(BufhlLine *) b_bufhl_move_space; // temporary space for highlights
PMap(uint64_t) *b_extmark_ns; // extmark namespaces
- kbtree_t(extlines) b_extlines; // extmarks
+ kbtree_t(extmarklines) b_extlines; // extmarks
kvec_t(ExtMarkLine *) b_extmark_move_space; // temp space for extmarks
// array of channel_id:s which have asked to receive updates for this
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index fb97c46117..c5f7815fc5 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -106,8 +106,6 @@ typedef struct {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds.c.generated.h"
-#include "mark_extended.h"
-
#endif
/// ":ascii" and "ga" implementation
diff --git a/src/nvim/map.c b/src/nvim/map.c
index a4cf5304e0..cdade5ee71 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -184,7 +184,6 @@ MAP_IMPL(String, MsgpackRpcRequestHandler, MSGPACK_HANDLER_INITIALIZER)
#define KVEC_INITIALIZER { .size = 0, .capacity = 0, .items = NULL }
MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER)
MAP_IMPL(String, handle_T, 0)
-MAP_IMPL(uint64_t, cstr_t, DEFAULT_INITIALIZER)
/// Deletes a key:value pair from a string:pointer map, and frees the
diff --git a/src/nvim/map.h b/src/nvim/map.h
index 073be6822a..75ab64cca4 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -42,7 +42,6 @@ MAP_DECLS(handle_T, ptr_t)
MAP_DECLS(String, MsgpackRpcRequestHandler)
MAP_DECLS(HlEntry, int)
MAP_DECLS(String, handle_T)
-MAP_DECLS(uint64_t, cstr_t)
#define map_new(T, U) map_##T##_##U##_new
#define map_free(T, U) map_##T##_##U##_free
diff --git a/src/nvim/mark_extended.c b/src/nvim/mark_extended.c
index cb5f45d88c..88348a8045 100644
--- a/src/nvim/mark_extended.c
+++ b/src/nvim/mark_extended.c
@@ -1,8 +1,8 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-// Implements extended marks for plugins
-// Each Mark exists in a btree of lines containing btrees of columns.
+// Implements extended marks for plugins. Each mark exists in a btree of
+// lines containing btrees of columns.
//
// The btree provides efficent range lookups.
// A map of pointers to the marks is used for fast lookup by mark id.
@@ -17,17 +17,17 @@
// copy extmarks is for the area being effected by a delete.
//
// Marks live in namespaces that allow plugins/users to segregate marks
-// from other users, namespaces have to be initialized before usage
+// from other users.
//
// For possible ideas for efficency improvements see:
// http://blog.atom.io/2015/06/16/optimizing-an-important-atom-primitive.html
+// TODO(bfredl): These ideas could be used for an enhanced btree, which
+// wouldn't need separate line and column layers.
// Other implementations exist in gtk and tk toolkits.
//
-// Deleting marks only happens explicitly extmark_del, deleteing over a
-// range of marks will only move the marks.
-//
-// deleting on a mark will leave it in that same position unless it is on
-// the eol of the line.
+// Deleting marks only happens when explicitly calling extmark_del, deleteing
+// over a range of marks will only move the marks. Deleting on a mark will
+// leave it in same position unless it is on the EOL of a line.
#include <assert.h>
#include "nvim/vim.h"
@@ -50,23 +50,19 @@
///
/// must not be used during iteration!
/// @returns whether a new mark was created
-int extmark_set(buf_T *buf,
- uint64_t ns,
- uint64_t id,
- linenr_T lnum,
- colnr_T col,
- ExtmarkOp op)
+int extmark_set(buf_T *buf, uint64_t ns, uint64_t id,
+ linenr_T lnum, colnr_T col, ExtmarkOp op)
{
ExtendedMark *extmark = extmark_from_id(buf, ns, id);
if (!extmark) {
extmark_create(buf, ns, id, lnum, col, op);
return true;
} else {
- ExtMarkLine *extline = extmark->line;
+ ExtMarkLine *extmarkline = extmark->line;
extmark_update(extmark, buf, ns, id, lnum, col, op, NULL);
- if (kb_size(&extline->items) == 0) {
- kb_del(extlines, &buf->b_extlines, extline);
- extline_free(extline);
+ if (kb_size(&extmarkline->items) == 0) {
+ kb_del(extmarklines, &buf->b_extlines, extmarkline);
+ extmarkline_free(extmarkline);
}
return false;
}
@@ -74,10 +70,7 @@ int extmark_set(buf_T *buf,
// Remove an extmark
// Returns 0 on missing id
-int extmark_del(buf_T *buf,
- uint64_t ns,
- uint64_t id,
- ExtmarkOp op)
+int extmark_del(buf_T *buf, uint64_t ns, uint64_t id, ExtmarkOp op)
{
ExtendedMark *extmark = extmark_from_id(buf, ns, id);
if (!extmark) {
@@ -88,11 +81,8 @@ int extmark_del(buf_T *buf,
// Free extmarks in a ns between lines
// if ns = 0, it means clear all namespaces
-void extmark_clear(buf_T *buf,
- uint64_t ns,
- linenr_T l_lnum,
- linenr_T u_lnum,
- ExtmarkOp undo)
+void extmark_clear(buf_T *buf, uint64_t ns,
+ linenr_T l_lnum, linenr_T u_lnum, ExtmarkOp undo)
{
if (!buf->b_extmark_ns) {
return;
@@ -115,7 +105,7 @@ void extmark_clear(buf_T *buf,
}
FOR_ALL_EXTMARKLINES(buf, l_lnum, u_lnum, {
- FOR_ALL_EXTMARKS_IN_LINE(extline->items, 0, MAXCOL, {
+ FOR_ALL_EXTMARKS_IN_LINE(extmarkline->items, 0, MAXCOL, {
if (extmark->ns_id == ns || all_ns) {
marks_cleared = true;
if (all_ns) {
@@ -124,12 +114,12 @@ void extmark_clear(buf_T *buf,
ns_obj = pmap_get(uint64_t)(buf->b_extmark_ns, ns);
}
pmap_del(uint64_t)(ns_obj->map, extmark->mark_id);
- kb_del_itr(markitems, &extline->items, &mitr);
+ kb_del_itr(markitems, &extmarkline->items, &mitr);
}
});
- if (kb_size(&extline->items) == 0) {
- kb_del_itr(extlines, &buf->b_extlines, &itr);
- extline_free(extline);
+ if (kb_size(&extmarkline->items) == 0) {
+ kb_del_itr(extmarklines, &buf->b_extlines, &itr);
+ extmarkline_free(extmarkline);
}
});
@@ -145,14 +135,10 @@ void extmark_clear(buf_T *buf,
// will be searched to the start, or end
// dir can be set to control the order of the array
// amount = amount of marks to find or -1 for all
-ExtmarkArray extmark_get(buf_T *buf,
- uint64_t ns,
- linenr_T l_lnum,
- colnr_T l_col,
- linenr_T u_lnum,
- colnr_T u_col,
- int64_t amount,
- bool reverse)
+ExtmarkArray extmark_get(buf_T *buf, uint64_t ns,
+ linenr_T l_lnum, colnr_T l_col,
+ linenr_T u_lnum, colnr_T u_col,
+ int64_t amount, bool reverse)
{
ExtmarkArray array = KV_INITIAL_VALUE;
// Find all the marks
@@ -178,12 +164,8 @@ ExtmarkArray extmark_get(buf_T *buf,
return array;
}
-static void extmark_create(buf_T *buf,
- uint64_t ns,
- uint64_t id,
- linenr_T lnum,
- colnr_T col,
- ExtmarkOp op)
+static void extmark_create(buf_T *buf, uint64_t ns, uint64_t id,
+ linenr_T lnum, colnr_T col, ExtmarkOp op)
{
if (!buf->b_extmark_ns) {
buf->b_extmark_ns = pmap_new(uint64_t)();
@@ -198,13 +180,13 @@ static void extmark_create(buf_T *buf,
}
// Create or get a line
- ExtMarkLine *extline = extline_ref(buf, lnum, true);
+ ExtMarkLine *extmarkline = extmarkline_ref(buf, lnum, true);
// Create and put mark on the line
- extmark_put(col, id, extline, ns);
+ extmark_put(col, id, extmarkline, ns);
// Marks do not have stable address so we have to look them up
// by using the line instead of the mark
- pmap_put(uint64_t)(ns_obj->map, id, extline);
+ pmap_put(uint64_t)(ns_obj->map, id, extmarkline);
if (op != kExtmarkNoUndo) {
u_extmark_set(buf, ns, id, lnum, col, kExtmarkSet);
}
@@ -215,14 +197,10 @@ static void extmark_create(buf_T *buf,
// update the position of an extmark
// to update while iterating pass the markitems itr
-static void extmark_update(ExtendedMark *extmark,
- buf_T *buf,
- uint64_t ns,
- uint64_t id,
- linenr_T lnum,
- colnr_T col,
- ExtmarkOp op,
- kbitr_t(markitems) *mitr)
+static void extmark_update(ExtendedMark *extmark, buf_T *buf,
+ uint64_t ns, uint64_t id,
+ linenr_T lnum, colnr_T col,
+ ExtmarkOp op, kbitr_t(markitems) *mitr)
{
assert(op != kExtmarkNOOP);
if (op != kExtmarkNoUndo) {
@@ -232,7 +210,7 @@ static void extmark_update(ExtendedMark *extmark,
ExtMarkLine *old_line = extmark->line;
// Move the mark to a new line and update column
if (old_line->lnum != lnum) {
- ExtMarkLine *ref_line = extline_ref(buf, lnum, true);
+ ExtMarkLine *ref_line = extmarkline_ref(buf, lnum, true);
extmark_put(col, id, ref_line, ns);
// Update the hashmap
ExtmarkNs *ns_obj = pmap_get(uint64_t)(buf->b_extmark_ns, ns);
@@ -272,12 +250,12 @@ static int extmark_delete(ExtendedMark *extmark,
pmap_del(uint64_t)(ns_obj->map, id);
// Remove the mark mark from the line
- ExtMarkLine *extline = extmark->line;
- kb_del(markitems, &extline->items, *extmark);
+ ExtMarkLine *extmarkline = extmark->line;
+ kb_del(markitems, &extmarkline->items, *extmark);
// Remove the line if there are no more marks in the line
- if (kb_size(&extline->items) == 0) {
- kb_del(extlines, &buf->b_extlines, extline);
- extline_free(extline);
+ if (kb_size(&extmarkline->items) == 0) {
+ kb_del(extmarklines, &buf->b_extlines, extmarkline);
+ extmarkline_free(extmarkline);
}
return true;
}
@@ -292,12 +270,12 @@ ExtendedMark *extmark_from_id(buf_T *buf, uint64_t ns, uint64_t id)
if (!ns_obj || !kh_size(ns_obj->map->table)) {
return NULL;
}
- ExtMarkLine *extline = pmap_get(uint64_t)(ns_obj->map, id);
- if (!extline) {
+ ExtMarkLine *extmarkline = pmap_get(uint64_t)(ns_obj->map, id);
+ if (!extmarkline) {
return NULL;
}
- FOR_ALL_EXTMARKS_IN_LINE(extline->items, 0, MAXCOL, {
+ FOR_ALL_EXTMARKS_IN_LINE(extmarkline->items, 0, MAXCOL, {
if (extmark->ns_id == ns
&& extmark->mark_id == id) {
return extmark;
@@ -354,8 +332,8 @@ void extmark_free_all(buf_T *buf)
ExtmarkNs *ns_obj;
FOR_ALL_EXTMARKLINES(buf, 1, MAXLNUM, {
- kb_del_itr(extlines, &buf->b_extlines, &itr);
- extline_free(extline);
+ kb_del_itr(extmarklines, &buf->b_extlines, &itr);
+ extmarkline_free(extmarkline);
})
map_foreach(buf->b_extmark_ns, ns, ns_obj, {
@@ -365,9 +343,10 @@ void extmark_free_all(buf_T *buf)
});
pmap_free(uint64_t)(buf->b_extmark_ns);
+ buf->b_extmark_ns = NULL;
// k?_init called to set pointers to NULL
- kb_destroy(extlines, (&buf->b_extlines));
+ kb_destroy(extmarklines, (&buf->b_extlines));
kb_init(&buf->b_extlines);
kv_destroy(buf->b_extmark_move_space);
@@ -376,14 +355,10 @@ void extmark_free_all(buf_T *buf)
// Save info for undo/redo of set marks
-static void u_extmark_set(buf_T *buf,
- uint64_t ns,
- uint64_t id,
- linenr_T lnum,
- colnr_T col,
- UndoObjectType undo_type)
+static void u_extmark_set(buf_T *buf, uint64_t ns, uint64_t id,
+ linenr_T lnum, colnr_T col, UndoObjectType undo_type)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -401,15 +376,11 @@ static void u_extmark_set(buf_T *buf,
}
// Save info for undo/redo of deleted marks
-static void u_extmark_update(buf_T *buf,
- uint64_t ns,
- uint64_t id,
- linenr_T old_lnum,
- colnr_T old_col,
- linenr_T lnum,
- colnr_T col)
+static void u_extmark_update(buf_T *buf, uint64_t ns, uint64_t id,
+ linenr_T old_lnum, colnr_T old_col,
+ linenr_T lnum, colnr_T col)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -431,13 +402,10 @@ static void u_extmark_update(buf_T *buf,
// - Instead of 1 undo object for each char inserted,
// we create 1 undo objet for all text inserted before the user hits esc
// Return True if we compacted else False
-static bool u_compact_col_adjust(buf_T *buf,
- linenr_T lnum,
- colnr_T mincol,
- long lnum_amount,
- long col_amount)
+static bool u_compact_col_adjust(buf_T *buf, linenr_T lnum, colnr_T mincol,
+ long lnum_amount, long col_amount)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return false;
}
@@ -472,13 +440,10 @@ static bool u_compact_col_adjust(buf_T *buf,
}
// Save col_adjust info so we can undo/redo
-void u_extmark_col_adjust(buf_T *buf,
- linenr_T lnum,
- colnr_T mincol,
- long lnum_amount,
- long col_amount)
+void u_extmark_col_adjust(buf_T *buf, linenr_T lnum, colnr_T mincol,
+ long lnum_amount, long col_amount)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -498,13 +463,10 @@ void u_extmark_col_adjust(buf_T *buf,
}
// Save col_adjust_delete info so we can undo/redo
-void u_extmark_col_adjust_delete(buf_T *buf,
- linenr_T lnum,
- colnr_T mincol,
- colnr_T endcol,
- int eol)
+void u_extmark_col_adjust_delete(buf_T *buf, linenr_T lnum,
+ colnr_T mincol, colnr_T endcol, int eol)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -522,13 +484,10 @@ void u_extmark_col_adjust_delete(buf_T *buf,
}
// Save adjust info so we can undo/redo
-static void u_extmark_adjust(buf_T * buf,
- linenr_T line1,
- linenr_T line2,
- long amount,
- long amount_after)
+static void u_extmark_adjust(buf_T * buf, linenr_T line1, linenr_T line2,
+ long amount, long amount_after)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -546,15 +505,11 @@ static void u_extmark_adjust(buf_T * buf,
}
// save info to undo/redo a :move
-void u_extmark_move(buf_T *buf,
- linenr_T line1,
- linenr_T line2,
- linenr_T last_line,
- linenr_T dest,
- linenr_T num_lines,
+void u_extmark_move(buf_T *buf, linenr_T line1, linenr_T line2,
+ linenr_T last_line, linenr_T dest, linenr_T num_lines,
linenr_T extra)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -577,14 +532,11 @@ void u_extmark_move(buf_T *buf,
// the operation. This will do nothing on redo, enforces correct position when
// undo.
// if ns = 0, it means copy all namespaces
-void u_extmark_copy(buf_T *buf,
- uint64_t ns,
- linenr_T l_lnum,
- colnr_T l_col,
- linenr_T u_lnum,
- colnr_T u_col)
+void u_extmark_copy(buf_T *buf, uint64_t ns,
+ linenr_T l_lnum, colnr_T l_col,
+ linenr_T u_lnum, colnr_T u_col)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -608,14 +560,11 @@ void u_extmark_copy(buf_T *buf,
}
void u_extmark_copy_place(buf_T *buf,
- linenr_T l_lnum,
- colnr_T l_col,
- linenr_T u_lnum,
- colnr_T u_col,
- linenr_T p_lnum,
- colnr_T p_col)
+ linenr_T l_lnum, colnr_T l_col,
+ linenr_T u_lnum, colnr_T u_col,
+ linenr_T p_lnum, colnr_T p_col)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -635,12 +584,10 @@ void u_extmark_copy_place(buf_T *buf,
}
// Save info for undo/redo of extmark_clear
-static void u_extmark_clear(buf_T *buf,
- uint64_t ns,
- linenr_T l_lnum,
- linenr_T u_lnum)
+static void u_extmark_clear(buf_T *buf, uint64_t ns,
+ linenr_T l_lnum, linenr_T u_lnum)
{
- u_header_T *uhp = force_get_undo_header(buf);
+ u_header_T *uhp = u_force_get_undo_header(buf);
if (!uhp) {
return;
}
@@ -843,103 +790,33 @@ static void apply_undo_move(ExtmarkUndoObject undo_info, bool undo)
if (undo) {
if (dest >= line2) {
- extmark_adjust(curbuf,
- dest - num_lines + 1,
- dest,
- last_line - dest + num_lines - 1,
- 0L,
- kExtmarkNoUndo,
+ extmark_adjust(curbuf, dest - num_lines + 1, dest,
+ last_line - dest + num_lines - 1, 0L, kExtmarkNoUndo,
true);
- extmark_adjust(curbuf,
- dest - line2,
- dest - line1,
- dest - line2,
- 0L,
- kExtmarkNoUndo,
- false);
+ extmark_adjust(curbuf, dest - line2, dest - line1,
+ dest - line2, 0L, kExtmarkNoUndo, false);
} else {
- extmark_adjust(curbuf,
- line1-num_lines,
- line2-num_lines,
- last_line - (line1-num_lines),
- 0L,
- kExtmarkNoUndo,
- true);
- extmark_adjust(curbuf,
- (line1-num_lines) + 1,
- (line2-num_lines) + 1,
- -num_lines,
- 0L,
- kExtmarkNoUndo,
- false);
+ extmark_adjust(curbuf, line1-num_lines, line2-num_lines,
+ last_line - (line1-num_lines), 0L, kExtmarkNoUndo, true);
+ extmark_adjust(curbuf, (line1-num_lines) + 1, (line2-num_lines) + 1,
+ -num_lines, 0L, kExtmarkNoUndo, false);
}
- extmark_adjust(curbuf,
- last_line,
- last_line + num_lines - 1,
- line1 - last_line,
- 0L,
- kExtmarkNoUndo,
- true);
+ extmark_adjust(curbuf, last_line, last_line + num_lines - 1,
+ line1 - last_line, 0L, kExtmarkNoUndo, true);
// redo
} else {
- extmark_adjust(curbuf,
- line1,
- line2,
- last_line - line2,
- 0L,
- kExtmarkNoUndo,
- true);
+ extmark_adjust(curbuf, line1, line2,
+ last_line - line2, 0L, kExtmarkNoUndo, true);
if (dest >= line2) {
- extmark_adjust(curbuf,
- line2 + 1,
- dest,
- -num_lines,
- 0L,
- kExtmarkNoUndo,
- false);
+ extmark_adjust(curbuf, line2 + 1, dest,
+ -num_lines, 0L, kExtmarkNoUndo, false);
} else {
- extmark_adjust(curbuf,
- dest + 1,
- line1 - 1,
- num_lines,
- 0L,
- kExtmarkNoUndo,
- false);
+ extmark_adjust(curbuf, dest + 1, line1 - 1,
+ num_lines, 0L, kExtmarkNoUndo, false);
}
- extmark_adjust(curbuf,
- last_line - num_lines + 1,
- last_line,
- -(last_line - dest - extra),
- 0L,
- kExtmarkNoUndo,
- true);
- }
-}
-
-// for anything other than deletes
-// Return, desired col amount where the adjustment should take place
-// (not taking) eol into account
-static long update_constantly(colnr_T _, colnr_T __, long col_amount)
-{
- return col_amount;
-}
-
-// for deletes,
-// Return, desired col amount where the adjustment should take place
-// (not taking) eol into account
-static long update_variably(colnr_T mincol, colnr_T current, long endcol)
-{
- colnr_T start_effected_range = mincol - 1;
- long col_amount;
- // When mark inside range
- if (current < endcol) {
- col_amount = -(current - start_effected_range);
- // Mark outside of range
- } else {
- // -1 because a delete of width 0 should still move marks
- col_amount = -(endcol - mincol) - 1;
+ extmark_adjust(curbuf, last_line - num_lines + 1, last_line,
+ -(last_line - dest - extra), 0L, kExtmarkNoUndo, true);
}
- return col_amount;
}
@@ -960,23 +837,37 @@ colnr_T extmark_eol_col(buf_T *buf, linenr_T lnum)
// returns true if something was moved otherwise false
static bool extmark_col_adjust_impl(buf_T *buf, linenr_T lnum,
colnr_T mincol, long lnum_amount,
- long (*calc_amount)(colnr_T, colnr_T, long),
- long func_arg)
+ bool for_delete,
+ long update_col)
{
bool marks_exist = false;
- colnr_T *cp;
- long col_amount;
- ExtMarkLine *extline = extline_ref(buf, lnum, false);
- if (!extline) {
+ ExtMarkLine *extmarkline = extmarkline_ref(buf, lnum, false);
+ if (!extmarkline) {
return false;
}
- FOR_ALL_EXTMARKS_IN_LINE(extline->items, mincol, MAXCOL, {
+ FOR_ALL_EXTMARKS_IN_LINE(extmarkline->items, mincol, MAXCOL, {
marks_exist = true;
- cp = &(extmark->col);
- col_amount = (*calc_amount)(mincol, *cp, func_arg);
+ // Calculate desired col amount where the adjustment should take place
+ // (not taking) eol into account
+ long col_amount;
+ if (for_delete) {
+ if (extmark->col < update_col) {
+ // When mark inside range
+ colnr_T start_effected_range = mincol - 1;
+ col_amount = -(extmark->col - start_effected_range);
+ } else {
+ // Mark outside of range
+ // -1 because a delete of width 0 should still move marks
+ col_amount = -(update_col - mincol) - 1;
+ }
+ } else {
+ // for anything other than deletes
+ col_amount = update_col;
+ }
+
// No update required for this guy
if (col_amount == 0 && lnum_amount == 0) {
continue;
@@ -984,23 +875,22 @@ static bool extmark_col_adjust_impl(buf_T *buf, linenr_T lnum,
// Set mark to start of line
if (col_amount < 0
- && *cp <= (colnr_T)-col_amount) { // TODO(timeyyy): does mark.c
- // need this line?
+ && extmark->col <= (colnr_T)-col_amount) {
extmark_update(extmark, buf, extmark->ns_id, extmark->mark_id,
- extline->lnum + lnum_amount,
+ extmarkline->lnum + lnum_amount,
1, kExtmarkNoUndo, &mitr);
// Update the mark
} else {
// Note: The undo is handled by u_extmark_col_adjust, NoUndo here
extmark_update(extmark, buf, extmark->ns_id, extmark->mark_id,
- extline->lnum + lnum_amount,
- *cp + (colnr_T)col_amount, kExtmarkNoUndo, &mitr);
+ extmarkline->lnum + lnum_amount,
+ extmark->col + (colnr_T)col_amount, kExtmarkNoUndo, &mitr);
}
})
- if (kb_size(&extline->items) == 0) {
- kb_del(extlines, &buf->b_extlines, extline);
- extline_free(extline);
+ if (kb_size(&extmarkline->items) == 0) {
+ kb_del(extmarklines, &buf->b_extlines, extmarkline);
+ extmarkline_free(extmarkline);
}
return marks_exist;
@@ -1019,7 +909,7 @@ void extmark_col_adjust(buf_T *buf, linenr_T lnum,
assert(col_amount > INT_MIN && col_amount <= INT_MAX);
bool marks_moved = extmark_col_adjust_impl(buf, lnum, mincol, lnum_amount,
- &update_constantly, col_amount);
+ false, col_amount);
if (undo == kExtmarkUndo && marks_moved) {
u_extmark_col_adjust(buf, lnum, mincol, lnum_amount, col_amount);
@@ -1038,17 +928,6 @@ void extmark_col_adjust_delete(buf_T *buf, linenr_T lnum,
ExtmarkOp undo, int _eol)
{
colnr_T start_effected_range = mincol;
- // TODO(timeyyy): understand why this has to be uncommented out for the
- // tests to pass.. shouldn't this be required?
- // why is this even being called if it's not neeed?
-
- // Some tests in the vim suite were hitting the assertion that was here.
- // functional/ui/mouse_spec/
- // We don't know what to do in this case so just bail!
-
- // if (start_effected_range <= endcol) {
- // return;
- // }
bool marks_moved;
if (undo == kExtmarkUndo) {
@@ -1058,7 +937,7 @@ void extmark_col_adjust_delete(buf_T *buf, linenr_T lnum,
}
marks_moved = extmark_col_adjust_impl(buf, lnum, mincol, 0,
- &update_variably, (long)endcol);
+ true, (long)endcol);
// Deletes at the end of the line have different behaviour than the normal
// case when deleted.
@@ -1071,7 +950,7 @@ void extmark_col_adjust_delete(buf_T *buf, linenr_T lnum,
}
FOR_ALL_EXTMARKS(buf, 1, lnum, eol, lnum, -1, {
extmark_update(extmark, buf, extmark->ns_id, extmark->mark_id,
- extline->lnum, (colnr_T)eol, kExtmarkNoUndo, &mitr);
+ extmarkline->lnum, (colnr_T)eol, kExtmarkNoUndo, &mitr);
})
// Record the undo for the actual move
@@ -1092,12 +971,12 @@ void extmark_adjust(buf_T *buf,
ExtMarkLine *_extline;
// btree needs to be kept ordered to work, so far only :move requires this
- // 2nd call with end_temp = unpack the lines from the temp position
+ // 2nd call with end_temp = true unpack the lines from the temp position
if (end_temp && amount < 0) {
for (size_t i = 0; i < kv_size(buf->b_extmark_move_space); i++) {
_extline = kv_A(buf->b_extmark_move_space, i);
_extline->lnum += amount;
- kb_put(extlines, &buf->b_extlines, _extline);
+ kb_put(extmarklines, &buf->b_extlines, _extline);
}
kv_size(buf->b_extmark_move_space) = 0;
return;
@@ -1108,11 +987,12 @@ void extmark_adjust(buf_T *buf,
linenr_T adj_start = line1;
if (amount == MAXLNUM) {
- // Careful! marks from deleted region can end up on en extisting extline
+ // Careful! marks from deleted region can end up on en extisting extmarkline
// that is goinig to be adjusted to the target position.
linenr_T join_num = line1 - amount_after;
- ExtMarkLine *joinline = join_num > line2 \
- ? extline_ref(buf, join_num, false) : NULL;
+ ExtMarkLine *joinline = (join_num > line2
+ ? extmarkline_ref(buf, join_num, false) : NULL);
+
// extmark_adjust is already redoable, the copy should only be for undo
marks_exist = extmark_copy_and_place(curbuf,
line1, 1,
@@ -1123,12 +1003,12 @@ void extmark_adjust(buf_T *buf,
}
FOR_ALL_EXTMARKLINES(buf, adj_start, MAXLNUM, {
marks_exist = true;
- lp = &(extline->lnum);
+ lp = &(extmarkline->lnum);
if (*lp <= line2) {
// 1st call with end_temp = true, store the lines in a temp position
if (end_temp && amount > 0) {
- kb_del_itr_extlines(&buf->b_extlines, &itr);
- kv_push(buf->b_extmark_move_space, extline);
+ kb_del_itr_extmarklines(&buf->b_extlines, &itr);
+ kv_push(buf->b_extmark_move_space, extmarkline);
}
*lp += amount;
@@ -1147,14 +1027,10 @@ void extmark_adjust(buf_T *buf,
/// if part of a larger iteration we can't delete, then the caller
/// must check for empty lines.
bool extmark_copy_and_place(buf_T *buf,
- linenr_T l_lnum,
- colnr_T l_col,
- linenr_T u_lnum,
- colnr_T u_col,
- linenr_T p_lnum,
- colnr_T p_col,
- ExtmarkOp undo,
- bool delete,
+ linenr_T l_lnum, colnr_T l_col,
+ linenr_T u_lnum, colnr_T u_col,
+ linenr_T p_lnum, colnr_T p_col,
+ ExtmarkOp undo, bool delete,
ExtMarkLine *destline)
{
@@ -1166,17 +1042,17 @@ bool extmark_copy_and_place(buf_T *buf,
// Move extmarks to their final position
// Careful: if we move items within the same line, we might change order of
- // marks within the same extline. Too keep it simple, first delete all items
- // from the extline and put them back in the right order.
+ // marks within the same extmarkline. Too keep it simple, first delete all
+ // items from the extmarkline and put them back in the right order.
FOR_ALL_EXTMARKLINES(buf, l_lnum, u_lnum, {
kvec_t(ExtendedMark) temp_space = KV_INITIAL_VALUE;
- bool same_line = extline == destline;
- FOR_ALL_EXTMARKS_IN_LINE(extline->items,
- (extline->lnum > l_lnum) ? 0 : l_col,
- (extline->lnum < u_lnum) ? MAXCOL : u_col, {
+ bool same_line = extmarkline == destline;
+ FOR_ALL_EXTMARKS_IN_LINE(extmarkline->items,
+ (extmarkline->lnum > l_lnum) ? 0 : l_col,
+ (extmarkline->lnum < u_lnum) ? MAXCOL : u_col, {
if (!destline) {
- destline = extline_ref(buf, p_lnum, true);
- same_line = extline == destline;
+ destline = extmarkline_ref(buf, p_lnum, true);
+ same_line = extmarkline == destline;
}
marks_moved = true;
if (!same_line) {
@@ -1188,17 +1064,17 @@ bool extmark_copy_and_place(buf_T *buf,
kv_push(temp_space, *extmark);
}
// Delete old mark
- kb_del_itr(markitems, &extline->items, &mitr);
+ kb_del_itr(markitems, &extmarkline->items, &mitr);
})
if (same_line) {
for (size_t i = 0; i < kv_size(temp_space); i++) {
ExtendedMark mark = kv_A(temp_space, i);
- extmark_put(p_col, mark.mark_id, extline, mark.ns_id);
+ extmark_put(p_col, mark.mark_id, extmarkline, mark.ns_id);
}
kv_destroy(temp_space);
- } else if (delete && kb_size(&extline->items) == 0) {
- kb_del_itr(extlines, &buf->b_extlines, &itr);
- extline_free(extline);
+ } else if (delete && kb_size(&extmarkline->items) == 0) {
+ kb_del_itr(extmarklines, &buf->b_extlines, &itr);
+ extmarkline_free(extmarkline);
}
})
@@ -1211,13 +1087,13 @@ bool extmark_copy_and_place(buf_T *buf,
}
// Get reference to line in kbtree_t, allocating it if neccessary.
-ExtMarkLine *extline_ref(buf_T *buf, linenr_T lnum, bool put)
+ExtMarkLine *extmarkline_ref(buf_T *buf, linenr_T lnum, bool put)
{
- kbtree_t(extlines) *b = &buf->b_extlines;
+ kbtree_t(extmarklines) *b = &buf->b_extlines;
ExtMarkLine t, **pp;
t.lnum = lnum;
- pp = kb_get(extlines, b, &t);
+ pp = kb_get(extmarklines, b, &t);
if (!pp) {
if (!put) {
return NULL;
@@ -1225,34 +1101,32 @@ ExtMarkLine *extline_ref(buf_T *buf, linenr_T lnum, bool put)
ExtMarkLine *p = xcalloc(sizeof(ExtMarkLine), 1);
p->lnum = lnum;
// p->items zero initialized
- kb_put(extlines, b, p);
+ kb_put(extmarklines, b, p);
return p;
}
// Return existing
return *pp;
}
-void extline_free(ExtMarkLine *extline)
+void extmarkline_free(ExtMarkLine *extmarkline)
{
- kb_destroy(markitems, (&extline->items));
- xfree(extline);
+ kb_destroy(markitems, (&extmarkline->items));
+ xfree(extmarkline);
}
/// Put an extmark into a line,
///
/// caller must ensure combination of id and ns_id isn't in use.
-void extmark_put(colnr_T col,
- uint64_t id,
- ExtMarkLine *extline,
- uint64_t ns)
+void extmark_put(colnr_T col, uint64_t id,
+ ExtMarkLine *extmarkline, uint64_t ns)
{
ExtendedMark t;
t.col = col;
t.mark_id = id;
- t.line = extline;
+ t.line = extmarkline;
t.ns_id = ns;
- kbtree_t(markitems) *b = &(extline->items);
+ kbtree_t(markitems) *b = &(extmarkline->items);
// kb_put requries the key to not be there
assert(!kb_getp(markitems, b, &t));
diff --git a/src/nvim/mark_extended.h b/src/nvim/mark_extended.h
index 7f407a683c..b8b766b243 100644
--- a/src/nvim/mark_extended.h
+++ b/src/nvim/mark_extended.h
@@ -14,16 +14,17 @@
// see FOR_ALL_? for documentation
#define FOR_ALL_EXTMARKLINES(buf, l_lnum, u_lnum, code)\
- kbitr_t(extlines) itr;\
+ kbitr_t(extmarklines) itr;\
ExtMarkLine t;\
t.lnum = l_lnum;\
- if (!kb_itr_get(extlines, &buf->b_extlines, &t, &itr)) { \
- kb_itr_next(extlines, &buf->b_extlines, &itr);\
+ if (!kb_itr_get(extmarklines, &buf->b_extlines, &t, &itr)) { \
+ kb_itr_next(extmarklines, &buf->b_extlines, &itr);\
}\
- ExtMarkLine *extline;\
- for (; kb_itr_valid(&itr); kb_itr_next(extlines, &buf->b_extlines, &itr)) { \
- extline = kb_itr_key(&itr);\
- if (extline->lnum > u_lnum) { \
+ ExtMarkLine *extmarkline;\
+ for (; kb_itr_valid(&itr); kb_itr_next(extmarklines, \
+ &buf->b_extlines, &itr)) { \
+ extmarkline = kb_itr_key(&itr);\
+ if (extmarkline->lnum > u_lnum) { \
break;\
}\
code;\
@@ -31,16 +32,17 @@
// see FOR_ALL_? for documentation
#define FOR_ALL_EXTMARKLINES_PREV(buf, l_lnum, u_lnum, code)\
- kbitr_t(extlines) itr;\
+ kbitr_t(extmarklines) itr;\
ExtMarkLine t;\
t.lnum = u_lnum;\
- if (!kb_itr_get(extlines, &buf->b_extlines, &t, &itr)) { \
- kb_itr_prev(extlines, &buf->b_extlines, &itr);\
+ if (!kb_itr_get(extmarklines, &buf->b_extlines, &t, &itr)) { \
+ kb_itr_prev(extmarklines, &buf->b_extlines, &itr);\
}\
- ExtMarkLine *extline;\
- for (; kb_itr_valid(&itr); kb_itr_prev(extlines, &buf->b_extlines, &itr)) { \
- extline = kb_itr_key(&itr);\
- if (extline->lnum < l_lnum) { \
+ ExtMarkLine *extmarkline;\
+ for (; kb_itr_valid(&itr); kb_itr_prev(extmarklines, \
+ &buf->b_extlines, &itr)) { \
+ extmarkline = kb_itr_key(&itr);\
+ if (extmarkline->lnum < l_lnum) { \
break;\
}\
code;\
@@ -54,14 +56,14 @@
mt.mark_id = 0;\
mt.line = NULL;\
FOR_ALL_EXTMARKLINES(buf, l_lnum, u_lnum, { \
- mt.col = (extline->lnum != l_lnum) ? MINCOL : l_col;\
- if (!kb_itr_get(markitems, &extline->items, mt, &mitr)) { \
- kb_itr_next(markitems, &extline->items, &mitr);\
+ mt.col = (extmarkline->lnum != l_lnum) ? MINCOL : l_col;\
+ if (!kb_itr_get(markitems, &extmarkline->items, mt, &mitr)) { \
+ kb_itr_next(markitems, &extmarkline->items, &mitr);\
} \
ExtendedMark *extmark;\
for (; \
kb_itr_valid(&mitr); \
- kb_itr_next(markitems, &extline->items, &mitr)) { \
+ kb_itr_next(markitems, &extmarkline->items, &mitr)) { \
extmark = &kb_itr_key(&mitr);\
if (extmark->line->lnum == u_lnum \
&& extmark->col > u_col) { \
@@ -79,14 +81,14 @@
mt.mark_id = sizeof(uint64_t);\
mt.ns_id = ns;\
FOR_ALL_EXTMARKLINES_PREV(buf, l_lnum, u_lnum, { \
- mt.col = (extline->lnum != u_lnum) ? MAXCOL : u_col;\
- if (!kb_itr_get(markitems, &extline->items, mt, &mitr)) { \
- kb_itr_prev(markitems, &extline->items, &mitr);\
+ mt.col = (extmarkline->lnum != u_lnum) ? MAXCOL : u_col;\
+ if (!kb_itr_get(markitems, &extmarkline->items, mt, &mitr)) { \
+ kb_itr_prev(markitems, &extmarkline->items, &mitr);\
} \
ExtendedMark *extmark;\
for (; \
kb_itr_valid(&mitr); \
- kb_itr_prev(markitems, &extline->items, &mitr)) { \
+ kb_itr_prev(markitems, &extmarkline->items, &mitr)) { \
extmark = &kb_itr_key(&mitr);\
if (extmark->line->lnum == l_lnum \
&& extmark->col < l_col) { \
@@ -104,14 +106,14 @@
mt.mark_id = 0;\
mt.line = NULL;\
mt.col = l_col;\
- colnr_T extline_u_col = u_col;\
+ colnr_T extmarkline_u_col = u_col;\
if (!kb_itr_get(markitems, &items, mt, &mitr)) { \
kb_itr_next(markitems, &items, &mitr);\
} \
ExtendedMark *extmark;\
for (; kb_itr_valid(&mitr); kb_itr_next(markitems, &items, &mitr)) { \
extmark = &kb_itr_key(&mitr);\
- if (extmark->col > extline_u_col) { \
+ if (extmark->col > extmarkline_u_col) { \
break;\
}\
code;\
@@ -125,7 +127,6 @@ typedef struct ExtmarkNs { // For namespacing extmarks
typedef kvec_t(ExtendedMark *) ExtmarkArray;
-typedef kvec_t(ExtMarkLine *) ExtlineArray;
// Undo/redo extmarks
@@ -138,6 +139,7 @@ typedef enum {
} ExtmarkOp;
+// adjust line numbers only, corresponding to mark_adjust call
typedef struct {
linenr_T line1;
linenr_T line2;
@@ -145,6 +147,7 @@ typedef struct {
long amount_after;
} Adjust;
+// adjust columns after split/join line, like mark_col_adjust
typedef struct {
linenr_T lnum;
colnr_T mincol;
@@ -152,6 +155,7 @@ typedef struct {
long lnum_amount;
} ColAdjust;
+// delete the columns between mincol and endcol
typedef struct {
linenr_T lnum;
colnr_T mincol;
@@ -159,6 +163,7 @@ typedef struct {
int eol;
} ColAdjustDelete;
+// adjust linenumbers after :move operation
typedef struct {
linenr_T line1;
linenr_T line2;
@@ -168,6 +173,9 @@ typedef struct {
linenr_T extra;
} AdjustMove;
+// TODO(bfredl): reconsider if we really should track mark creation/updating
+// itself, these are not really "edit" operation.
+// extmark was created
typedef struct {
uint64_t ns_id;
uint64_t mark_id;
@@ -175,6 +183,7 @@ typedef struct {
colnr_T col;
} ExtmarkSet;
+// extmark was updated
typedef struct {
uint64_t ns_id;
uint64_t mark_id;
@@ -184,6 +193,7 @@ typedef struct {
colnr_T col;
} ExtmarkUpdate;
+// copied mark before deletion (as operation is destructive)
typedef struct {
uint64_t ns_id;
uint64_t mark_id;
@@ -191,6 +201,8 @@ typedef struct {
colnr_T col;
} ExtmarkCopy;
+// also used as part of :move operation? probably can be simplified to one
+// event.
typedef struct {
linenr_T l_lnum;
colnr_T l_col;
@@ -200,6 +212,8 @@ typedef struct {
colnr_T p_col;
} ExtmarkCopyPlace;
+// extmark was cleared.
+// TODO(bfredl): same reconsideration as for ExtmarkSet/ExtmarkUpdate
typedef struct {
uint64_t ns_id;
linenr_T l_lnum;
@@ -220,6 +234,7 @@ typedef enum {
kExtmarkClear,
} UndoObjectType;
+// TODO(bfredl): reduce the number of undo action types
struct undo_object {
UndoObjectType type;
union {
diff --git a/src/nvim/mark_extended_defs.h b/src/nvim/mark_extended_defs.h
index 4da35a05c8..b9475d46f5 100644
--- a/src/nvim/mark_extended_defs.h
+++ b/src/nvim/mark_extended_defs.h
@@ -43,8 +43,8 @@ typedef struct ExtMarkLine
kbtree_t(markitems) items;
} ExtMarkLine;
-#define extline_cmp(a, b) (kb_generic_cmp((a)->lnum, (b)->lnum))
-KBTREE_INIT(extlines, ExtMarkLine *, extline_cmp, 10)
+#define EXTMARKLINE_CMP(a, b) (kb_generic_cmp((a)->lnum, (b)->lnum))
+KBTREE_INIT(extmarklines, ExtMarkLine *, EXTMARKLINE_CMP, 10)
typedef struct undo_object ExtmarkUndoObject;
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 1631204840..95674f8b40 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -127,30 +127,6 @@ static char opchars[][3] =
{ Ctrl_X, NUL, false }, // OP_NR_SUB
};
-char *nvim_lltoa(int64_t val, int base)
-{
- static char buf[64] = { 0 };
-
- int i = 62;
- int sign = (val < 0);
- if (sign) {
- val = -val;
- }
-
- if (val == 0) {
- return "0";
- }
-
- for (; val && i ; i--, val /= base) {
- buf[i] = "0123456789abcdef"[val % base];
- }
-
- if (sign) {
- buf[i--] = '-';
- }
- return &buf[i+1];
-}
-
/*
* Translate a command name into an operator type.
* Must only be called with a valid operator name!
@@ -332,13 +308,8 @@ void shift_line(
} else {
(void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0);
- colnr_T col_amount;
colnr_T mincol = (curwin->w_cursor.col + 1) -p_sw;
- if (left) {
- col_amount = -p_sw;
- } else {
- col_amount = p_sw;
- }
+ colnr_T col_amount = left ? -p_sw : p_sw;
extmark_col_adjust(curbuf,
curwin->w_cursor.lnum,
mincol,
@@ -519,10 +490,7 @@ static void shift_block(oparg_T *oap, int amount)
curwin->w_cursor.col = oldcol;
p_ri = old_p_ri;
- colnr_T col_amount = p_sw;
- if (left) {
- col_amount = -col_amount;
- }
+ colnr_T col_amount = left ? -p_sw : p_sw;
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
curwin->w_cursor.col, 0, col_amount, kExtmarkUndo);
}
@@ -1669,7 +1637,7 @@ int op_delete(oparg_T *oap)
curpos = curwin->w_cursor; // remember curwin->w_cursor
curwin->w_cursor.lnum++;
- del_lines(oap->line_count - 2, true);
+ del_lines(oap->line_count - 2, false);
// delete from start of line until op_end
n = (oap->end.col + 1 - !oap->inclusive);
@@ -1715,12 +1683,7 @@ setmarks:
lnum = curwin->w_cursor.lnum;
if (oap->is_VIsual == false) {
- // for some reason we required this :/
- endcol = endcol - 1;
- // for some reason we required this :/
- if (endcol < mincol) {
- endcol = mincol;
- }
+ endcol = MAX(endcol - 1, mincol);
}
extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0);
}
@@ -2787,8 +2750,6 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
}
-
-// Function length couldn't be over 500 lines..
static void extmarks_do_put(int dir,
size_t totlen,
MotionType y_type,
@@ -2796,12 +2757,7 @@ static void extmarks_do_put(int dir,
colnr_T col)
{
// adjust extmarks
- colnr_T col_amount;
- if (dir == FORWARD) {
- col_amount = (colnr_T)(totlen-1);
- } else {
- col_amount = (colnr_T)totlen;
- }
+ colnr_T col_amount = (colnr_T)(dir == FORWARD ? totlen-1 : totlen);
// Move extmark with char put
if (y_type == kMTCharWise) {
extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo);
@@ -3869,11 +3825,6 @@ int do_join(size_t count,
* should not really be a problem.
*/
- linenr_T lnum;
- colnr_T mincol;
- long lnum_amount;
- long col_amount;
-
for (t = (linenr_T)count - 1;; t--) {
cend -= currsize;
memmove(cend, curr, (size_t)currsize);
@@ -3885,10 +3836,10 @@ int do_join(size_t count,
// If deleting more spaces than adding, the cursor moves no more than
// what is added if it is inside these spaces.
const int spaces_removed = (int)((curr - curr_start) - spaces[t]);
- lnum = curwin->w_cursor.lnum + t;
- mincol = (colnr_T)0;
- lnum_amount = (linenr_T)-t;
- col_amount = (long)(cend - newp - spaces_removed);
+ linenr_T lnum = curwin->w_cursor.lnum + t;
+ colnr_T mincol = (colnr_T)0;
+ long lnum_amount = (linenr_T)-t;
+ long col_amount = (long)(cend - newp - spaces_removed);
mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed,
kExtmarkUndo);
@@ -4675,7 +4626,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
{
int col;
- char_u *buf1;
+ char_u *buf1 = NULL;
char_u buf2[NUMBUFLEN];
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC
@@ -4984,7 +4935,6 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
*ptr = NUL;
STRCAT(buf1, buf2);
ins_str(buf1); // insert the new number
- xfree(buf1);
endpos = curwin->w_cursor;
if (curwin->w_cursor.col) {
curwin->w_cursor.col--;
@@ -4998,15 +4948,15 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
curbuf->b_op_end.col--;
}
- if (did_change) {
+ // if buf1 wasn't allocated, only a singe ASCII char was changed in-place.
+ if (did_change && buf1 != NULL) {
extmark_col_adjust_delete(curbuf,
pos->lnum,
startpos.col + 2,
endpos.col + 1 + length,
kExtmarkUndo,
0);
- long col_amount = (long)strlen(nvim_lltoa((int64_t)n, 10));
- col_amount = negative ? col_amount + 1 : col_amount;
+ long col_amount = (long)STRLEN(buf1);
extmark_col_adjust(curbuf,
pos->lnum,
startpos.col + 1,
@@ -5016,6 +4966,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
theend:
+ xfree(buf1);
if (visual) {
curwin->w_cursor = save_cursor;
} else if (did_change) {
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 91a142214b..b00d2d505f 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2849,7 +2849,6 @@ u_freeentries(
u_freeentry(uep, uep->ue_size);
}
- // TODO(timeyyy): is this the correct place? ...
kv_destroy(uhp->uh_extmark);
#ifdef U_DEBUG
@@ -3049,7 +3048,7 @@ list_T *u_eval_tree(const u_header_T *const first_uhp)
// Given the buffer, Return the undo header. If none is set, set one first.
// NULL will be returned if e.g undolevels = -1 (undo disabled)
-u_header_T *force_get_undo_header(buf_T *buf)
+u_header_T *u_force_get_undo_header(buf_T *buf)
{
u_header_T *uhp = NULL;
if (buf->b_u_curhead != NULL) {
@@ -3064,8 +3063,8 @@ u_header_T *force_get_undo_header(buf_T *buf)
uhp = buf->b_u_curhead;
if (!uhp) {
uhp = buf->b_u_newhead;
- if (get_undolevel() > 0) {
- assert(uhp);
+ if (get_undolevel() > 0 && !uhp) {
+ abort();
}
}
}