diff --git a/README.md b/README.md index e09b6a2e85..338c8df70e 100644 --- a/README.md +++ b/README.md @@ -148,14 +148,3 @@ See `LICENSE` for details. [Gentoo]: https://packages.gentoo.org/packages/app-editors/neovim - - -CC=clang make functionaltest CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=ON" TEST_FILE=test/functional/api TEST_TAG=extmarks - -CC=clang make functionaltest CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=ON" TEST_FILE=test/functional/ui/mouse_spec.lua TEST_TAG=blah -CC=clang make functionaltest CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=ON" - -CC=clang make functionaltest CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=OFF" TEST_FILE=test/functional/api/mark_extended_spec.lua TEST_TAG=broken - -# TODO debug in container with clion... -https://github.com/shuhaoliu/docker-clion-dev diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index d6b7938633..5d30c10486 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -439,34 +439,40 @@ Example: create a float with scratch buffer: > > ============================================================================== -Buffer extended marks *api-extended-marks* +Extended marks *api-extended-marks* -An extended mark represents a buffer annotation that remains logically -stationary even as the buffer changes. They could be used to represent cursors, +An extended mark (extmark) represents a buffer annotation that follows +movements as the buffer changes. They could be used to represent cursors, folds, misspelled words, and anything else that needs to track a logical location in the buffer over time. Example: -We will set an extmark at row 1, column three. +We will set an extmark at the first row and third column. As the API is zero- +indexed, use row and column counts 0 and 2: `let g:mark_ns = nvim_create_namespace('myplugin')` -`let g:mark_id = nvim_buf_set_mark(0, :g:mark_ns, 0, 1, 3)` +`let g:mark_id = nvim_buf_set_extmark(0, g:mark_ns, 0, 0, 2)` -Note: the mark id was randomly generated because we used an inital value of 0 +Passing in id=0 creates a new mark and returns the id. we can look-up a mark +by its id: -`echo nvim_buf_lookup_mark(0, g:mark_ns, g:mark_id)` -=> [1, 1, 3] -`echo nvim_buf_get_marks(0, g:mark_ns, [1, 1], [1, 3], -1, 0)` -=> [[1, 1, 3]] +`echo nvim_buf_get_extmark_by_id(0, g:mark_ns, g:mark_id)` +=> [0, 2] + +Or we can look-up all marks in a buffer for our namespace (or by a range): +`echo nvim_buf_get_extmarks(0, g:mark_ns, 0, -1, -1)` +=> [[1, 0, 2]] Deleting the text all around an extended mark does not remove it. If you want -to remove an extended mark, use the |nvim_buf_unset_mark()| function. +to remove an extended mark, use the |nvim_buf_del_extmark()| function. -The namepsace ensures you only ever work with the extended marks you mean to. - -Calling set and unset of marks will not automatically prop a new undo. +The namespace ensures your plugin doesn't have to deal with extmarks created +by another plugin. +Mark positions changed by an edit will be restored on undo/redo. Creating and +deleting marks doesn't count as a buffer change on itself, i e new undo +states will not be created only for marks. ============================================================================== Global Functions *api-global* @@ -1479,22 +1485,6 @@ nvim_select_popupmenu_item({item}, {insert}, {finish}, {opts}) nvim__inspect_cell({grid}, {row}, {col}) *nvim__inspect_cell()* TODO: Documentation - *nvim_init_mark_ns()* -nvim_init_mark_ns({namespace}) - Create a new namepsace for holding extended marks. The id - of the namespace is returned, this namespace id is required - for using the rest of the extended marks api. - - Parameters:~ - {namespace} String name to be assigned to the namespace - - - *nvim_mark_get_ns_ids()* -nvim_mark_get_ns_ids() - Returns a list of extended mark namespaces. - Pairs of ids and string names are returned. - An empty list will be returned if no namespaces are set. - ============================================================================== Buffer Functions *api-buffer* @@ -1793,6 +1783,86 @@ nvim_buf_get_mark({buffer}, {name}) *nvim_buf_get_mark()* Return: ~ (row, col) tuple + *nvim_buf_get_extmark_by_id()* +nvim_buf_get_extmark_by_id({buffer}, {ns_id}, {id}) + Returns position for a given extmark id + + Parameters: ~ + {buffer} The buffer handle + {namespace} a identifier returned previously with + nvim_create_namespace + {id} the extmark id + + Return: ~ + (row, col) tuple or empty list () if extmark id was absent + + *nvim_buf_get_extmarks()* +nvim_buf_get_extmarks({buffer}, {ns_id}, {start}, {end}, {opts}) + 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. + + Parameters: ~ + {buffer} The buffer handle + {ns_id} An id returned previously from + nvim_create_namespace + {lower} One of: extmark id, (row, col) or 0, -1 for + buffer ends + {upper} One of: extmark id, (row, col) or 0, -1 for + buffer ends + {opts} additional options. Supports the keys: + • amount: Maximum number of marks to return • + + Return: ~ + [[nsmark_id, row, col], ...] + + *nvim_buf_set_extmark()* +nvim_buf_set_extmark({buffer}, {ns_id}, {id}, {line}, {col}, {opts}) + 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. + + Parameters: ~ + {buffer} The buffer handle + {ns_id} a identifier returned previously with + nvim_create_namespace + {id} The extmark's id or 0 to create a new mark. + {row} The row to set the extmark to. + {col} The column to set the extmark to. + {opts} Optional parameters. Currently not used. + + Return: ~ + the id of the extmark. + +nvim_buf_del_extmark({buffer}, {ns_id}, {id}) *nvim_buf_del_extmark()* + Remove an extmark + + Parameters: ~ + {buffer} The buffer handle + {ns_id} a identifier returned previously with + nvim_create_namespace + {id} The extmarks's id + + Return: ~ + true on success, false if the extmark was not found. + *nvim_buf_add_highlight()* nvim_buf_add_highlight({buffer}, {ns_id}, {hl_group}, {line}, {col_start}, {col_end}) 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 #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,105 +790,35 @@ 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); + 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; - } - return col_amount; -} - /// Get the column position for EOL on a line /// @@ -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(); } } } diff --git a/test/functional/api/mark_extended_spec.lua b/test/functional/api/mark_extended_spec.lua index 6bf0e59133..a5d68c6b9f 100644 --- a/test/functional/api/mark_extended_spec.lua +++ b/test/functional/api/mark_extended_spec.lua @@ -1,7 +1,3 @@ --- TODO(timeyyy): go through todo's lol --- change representation of stored marks to have location start at 0 --- check with memsan, asan etc - local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') @@ -9,17 +5,14 @@ local request = helpers.request local eq = helpers.eq local ok = helpers.ok local curbufmeths = helpers.curbufmeths -local meth_pcall = helpers.meth_pcall +local pcall_err = helpers.pcall_err local insert = helpers.insert local feed = helpers.feed local clear = helpers.clear - -local ALL = -1 - -local rv = nil +local command = helpers.command local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end - rv = curbufmeths.get_extmark_by_id(ns, mark) + local rv = curbufmeths.get_extmark_by_id(ns, mark) eq({er, ec}, rv) feed("u") rv = curbufmeths.get_extmark_by_id(ns, mark) @@ -29,6 +22,20 @@ local function check_undo_redo(ns, mark, sr, sc, er, ec) --s = start, e = end eq({er, ec}, rv) end +local function set_extmark(ns_id, id, line, col, opts) + if opts == nil then + opts = {} + end + return curbufmeths.set_extmark(ns_id, id, line, col, opts) +end + +local function get_extmarks(ns_id, start, end_, opts) + if opts == nil then + opts = {} + end + return curbufmeths.get_extmarks(ns_id, start, end_, opts) +end + describe('Extmarks buffer api', function() local screen local marks, positions, ns_string2, ns_string, init_text, row, col @@ -55,24 +62,24 @@ describe('Extmarks buffer api', function() end) it('adds, updates and deletes marks #extmarks', function() - rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({positions[1][1], positions[1][2]}, rv) -- Test adding a second mark on same row works - rv = curbufmeths.set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + rv = set_extmark(ns, marks[2], positions[2][1], positions[2][2]) eq(marks[2], rv) -- Test an update, (same pos) - rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - eq(0, rv) + rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[2]) eq({positions[2][1], positions[2][2]}, rv) -- Test an update, (new pos) row = positions[1][1] col = positions[1][2] + 1 - rv = curbufmeths.set_extmark(ns, marks[1], row, col) - eq(0, rv) + rv = set_extmark(ns, marks[1], row, col) + eq(marks[1], rv) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({row, col}, rv) @@ -85,50 +92,50 @@ describe('Extmarks buffer api', function() end) it('can clear a specific namespace range #extmarks', function() - curbufmeths.set_extmark(ns, 1, 0, 1) - curbufmeths.set_extmark(ns2, 1, 0, 1) + set_extmark(ns, 1, 0, 1) + set_extmark(ns2, 1, 0, 1) -- force a new undo buffer feed('o') curbufmeths.clear_namespace(ns2, 0, -1) - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('u') - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({{1, 0, 1}}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('') - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) end) - it('can clear a namespace range using ALL #extmarks', function() - curbufmeths.set_extmark(ns, 1, 0, 1) - curbufmeths.set_extmark(ns2, 1, 0, 1) + it('can clear a namespace range using 0,-1 #extmarks', function() + set_extmark(ns, 1, 0, 1) + set_extmark(ns2, 1, 0, 1) -- force a new undo buffer feed('o') curbufmeths.clear_namespace(-1, 0, -1) - eq({}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('u') - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({{1, 0, 1}}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({{1, 0, 1}}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({{1, 0, 1}}, get_extmarks(ns2, {0, 0}, {-1, -1})) feed('') - eq({}, curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL)) - eq({}, curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL)) + eq({}, get_extmarks(ns, {0, 0}, {-1, -1})) + eq({}, get_extmarks(ns2, {0, 0}, {-1, -1})) end) it('querying for information and ranges #extmarks', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then - rv = curbufmeths.set_extmark(ns, m, positions[i][1], positions[i][2]) + local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) eq(m, rv) end end -- {0, 0} and {-1, -1} work as extreme values - eq({{1, 0, 0}}, curbufmeths.get_extmarks(ns, {0, 0}, {0, 0}, ALL)) - eq({}, curbufmeths.get_extmarks(ns, {-1, -1}, {-1, -1}, ALL)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + eq({{1, 0, 0}}, get_extmarks(ns, {0, 0}, {0, 0})) + eq({}, get_extmarks(ns, {-1, -1}, {-1, -1})) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}) for i, m in ipairs(marks) do if positions[i] ~= nil then eq({m, positions[i][1], positions[i][2]}, rv[i]) @@ -136,9 +143,9 @@ describe('Extmarks buffer api', function() end -- 0 and -1 works as short hand extreme values - eq({{1, 0, 0}}, curbufmeths.get_extmarks(ns, 0, 0, ALL)) - eq({}, curbufmeths.get_extmarks(ns, -1, -1, ALL)) - rv = curbufmeths.get_extmarks(ns, 0, -1, ALL) + eq({{1, 0, 0}}, get_extmarks(ns, 0, 0)) + eq({}, get_extmarks(ns, -1, -1)) + rv = get_extmarks(ns, 0, -1) for i, m in ipairs(marks) do if positions[i] ~= nil then eq({m, positions[i][1], positions[i][2]}, rv[i]) @@ -146,91 +153,91 @@ describe('Extmarks buffer api', function() end -- next with mark id - rv = curbufmeths.get_extmarks(ns, marks[1], {-1, -1}, 1) + rv = get_extmarks(ns, marks[1], {-1, -1}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) - rv = curbufmeths.get_extmarks(ns, marks[2], {-1, -1}, 1) + rv = get_extmarks(ns, marks[2], {-1, -1}, {amount=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[1], {-1, -1}, 1) + rv = get_extmarks(ns, positions[1], {-1, -1}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- next with positional index (no mark at position) - rv = curbufmeths.get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, 1) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {-1, -1}, {amount=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- next with Extremity index - rv = curbufmeths.get_extmarks(ns, {0,0}, {-1, -1}, 1) + rv = get_extmarks(ns, {0,0}, {-1, -1}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- nextrange with mark id - rv = curbufmeths.get_extmarks(ns, marks[1], marks[3], ALL) + rv = get_extmarks(ns, marks[1], marks[3]) eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) -- nextrange with amount - rv = curbufmeths.get_extmarks(ns, marks[1], marks[3], 2) + rv = get_extmarks(ns, marks[1], marks[3], {amount=2}) eq(2, table.getn(rv)) -- nextrange with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[1], positions[3], ALL) + rv = get_extmarks(ns, positions[1], positions[3]) eq({marks[1], positions[1][1], positions[1][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) - rv = curbufmeths.get_extmarks(ns, positions[2], positions[3], ALL) + rv = get_extmarks(ns, positions[2], positions[3]) eq(2, table.getn(rv)) -- nextrange with positional index (no mark at position) local lower = {positions[1][1], positions[2][2] -1} local upper = {positions[2][1], positions[3][2] - 1} - rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + rv = get_extmarks(ns, lower, upper) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) lower = {positions[3][1], positions[3][2] + 1} upper = {positions[3][1], positions[3][2] + 2} - rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + rv = get_extmarks(ns, lower, upper) eq({}, rv) -- nextrange with extremity index lower = {positions[2][1], positions[2][2]+1} upper = {-1, -1} - rv = curbufmeths.get_extmarks(ns, lower, upper, ALL) + rv = get_extmarks(ns, lower, upper) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with mark id - rv = curbufmeths.get_extmarks(ns, marks[3], {0, 0}, 1) + rv = get_extmarks(ns, marks[3], {0, 0}, {amount=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) - rv = curbufmeths.get_extmarks(ns, marks[2], {0, 0}, 1) + rv = get_extmarks(ns, marks[2], {0, 0}, {amount=1}) eq({{marks[2], positions[2][1], positions[2][2]}}, rv) -- prev with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[3], {0, 0}, 1) + rv = get_extmarks(ns, positions[3], {0, 0}, {amount=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prev with positional index (no mark at position) - rv = curbufmeths.get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, 1) + rv = get_extmarks(ns, {positions[1][1], positions[1][2] +1}, {0, 0}, {amount=1}) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) -- prev with Extremity index - rv = curbufmeths.get_extmarks(ns, {-1,-1}, {0,0}, 1) + rv = get_extmarks(ns, {-1,-1}, {0,0}, {amount=1}) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) -- prevrange with mark id - rv = curbufmeths.get_extmarks(ns, marks[3], marks[1], ALL) + rv = get_extmarks(ns, marks[3], marks[1]) eq({marks[3], positions[3][1], positions[3][2]}, rv[1]) eq({marks[2], positions[2][1], positions[2][2]}, rv[2]) eq({marks[1], positions[1][1], positions[1][2]}, rv[3]) -- prevrange with amount - rv = curbufmeths.get_extmarks(ns, marks[3], marks[1], 2) + rv = get_extmarks(ns, marks[3], marks[1], {amount=2}) eq(2, table.getn(rv)) -- prevrange with positional when mark exists at position - rv = curbufmeths.get_extmarks(ns, positions[3], positions[1], ALL) + rv = get_extmarks(ns, positions[3], positions[1]) eq({{marks[3], positions[3][1], positions[3][2]}, {marks[2], positions[2][1], positions[2][2]}, {marks[1], positions[1][1], positions[1][2]}}, rv) - rv = curbufmeths.get_extmarks(ns, positions[2], positions[1], ALL) + rv = get_extmarks(ns, positions[2], positions[1]) eq(2, table.getn(rv)) -- prevrange with positional index (no mark at position) lower = {positions[2][1], positions[2][2] + 1} upper = {positions[3][1], positions[3][2] + 1} - rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + rv = get_extmarks(ns, upper, lower) eq({{marks[3], positions[3][1], positions[3][2]}}, rv) lower = {positions[3][1], positions[3][2] + 1} upper = {positions[3][1], positions[3][2] + 2} - rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + rv = get_extmarks(ns, upper, lower) eq({}, rv) -- prevrange with extremity index lower = {0,0} upper = {positions[2][1], positions[2][2] - 1} - rv = curbufmeths.get_extmarks(ns, upper, lower, ALL) + rv = get_extmarks(ns, upper, lower) eq({{marks[1], positions[1][1], positions[1][2]}}, rv) end) @@ -238,50 +245,50 @@ describe('Extmarks buffer api', function() -- add some more marks for i, m in ipairs(marks) do if positions[i] ~= nil then - rv = curbufmeths.set_extmark(ns, m, positions[i][1], positions[i][2]) + local rv = set_extmark(ns, m, positions[i][1], positions[i][2]) eq(m, rv) end end - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 1) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 2) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 3) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) eq(3, table.getn(rv)) -- now in reverse - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 1) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 2) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=2}) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, 3) + rv = get_extmarks(ns, {0, 0}, {-1, -1}, {amount=3}) eq(3, table.getn(rv)) end) it('get_marks works when mark col > upper col #extmarks', function() feed('A12345') feed('A12345') - curbufmeths.set_extmark(ns, 10, 0, 2) -- this shouldn't be found - curbufmeths.set_extmark(ns, 11, 2, 1) -- this shouldn't be found - curbufmeths.set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound - curbufmeths.set_extmark(ns, marks[2], 1, 1) -- check col < lower bound - curbufmeths.set_extmark(ns, marks[3], 2, 0) -- check is inclusive + set_extmark(ns, 10, 0, 2) -- this shouldn't be found + set_extmark(ns, 11, 2, 1) -- this shouldn't be found + set_extmark(ns, marks[1], 0, 4) -- check col > our upper bound + set_extmark(ns, marks[2], 1, 1) -- check col < lower bound + set_extmark(ns, marks[3], 2, 0) -- check is inclusive eq({{marks[1], 0, 4}, {marks[2], 1, 1}, {marks[3], 2, 0}}, - curbufmeths.get_extmarks(ns, {0, 3}, {2, 0}, -1)) + get_extmarks(ns, {0, 3}, {2, 0})) end) it('get_marks works in reverse when mark col < lower col #extmarks', function() feed('A12345') feed('A12345') - curbufmeths.set_extmark(ns, 10, 0, 1) -- this shouldn't be found - curbufmeths.set_extmark(ns, 11, 2, 4) -- this shouldn't be found - curbufmeths.set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound - curbufmeths.set_extmark(ns, marks[2], 1, 4) -- check col > upper bound - curbufmeths.set_extmark(ns, marks[3], 0, 2) -- check is inclusive - rv = curbufmeths.get_extmarks(ns, {2, 3}, {0, 2}, -1) + set_extmark(ns, 10, 0, 1) -- this shouldn't be found + set_extmark(ns, 11, 2, 4) -- this shouldn't be found + set_extmark(ns, marks[1], 2, 1) -- check col < our lower bound + set_extmark(ns, marks[2], 1, 4) -- check col > upper bound + set_extmark(ns, marks[3], 0, 2) -- check is inclusive + local rv = get_extmarks(ns, {2, 3}, {0, 2}) eq({{marks[1], 2, 1}, {marks[2], 1, 4}, {marks[3], 0, 2}}, @@ -289,21 +296,21 @@ describe('Extmarks buffer api', function() end) it('get_marks amount 0 returns nothing #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = curbufmeths.get_extmarks(ns, {-1, -1}, {-1, -1}, 0) + set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = get_extmarks(ns, {-1, -1}, {-1, -1}, {amount=0}) eq({}, rv) end) it('marks move with line insertations #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[1], 0, 0) feed("yyP") check_undo_redo(ns, marks[1], 0, 0, 1, 0) end) it('marks move with multiline insertations #extmarks', function() feed("a2233") - curbufmeths.set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[1], 1, 1) feed('ggVGyP') check_undo_redo(ns, marks[1], 1, 1, 4, 1) end) @@ -311,7 +318,7 @@ describe('Extmarks buffer api', function() it('marks move with line join #extmarks', function() -- do_join in ops.c feed("a222") - curbufmeths.set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[1], 1, 0) feed('ggJ') check_undo_redo(ns, marks[1], 1, 0, 0, 6) end) @@ -337,21 +344,21 @@ describe('Extmarks buffer api', function() it('marks move with multiline join #extmarks', function() -- do_join in ops.c feed("a222333444") - curbufmeths.set_extmark(ns, marks[1], 3, 0) + set_extmark(ns, marks[1], 3, 0) feed('2GVGJ') check_undo_redo(ns, marks[1], 3, 0, 1, 8) end) it('marks move with line deletes #extmarks', function() feed("a222333444") - curbufmeths.set_extmark(ns, marks[1], 2, 1) + set_extmark(ns, marks[1], 2, 1) feed('ggjdd') check_undo_redo(ns, marks[1], 2, 1, 1, 1) end) it('marks move with multiline deletes #extmarks', function() feed("a222333444") - curbufmeths.set_extmark(ns, marks[1], 3, 0) + set_extmark(ns, marks[1], 3, 0) feed('gg2dd') check_undo_redo(ns, marks[1], 3, 0, 1, 0) -- regression test, undoing multiline delete when mark is on row 1 @@ -363,8 +370,8 @@ describe('Extmarks buffer api', function() -- open_line in misc1.c -- testing marks below are also moved feed("yyP") - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 1, 4) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 1, 4) feed('1G') check_undo_redo(ns, marks[1], 0, 4, 1, 4) check_undo_redo(ns, marks[2], 1, 4, 2, 4) @@ -373,10 +380,9 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[2], 2, 4, 3, 4) end) - -- NO idea why this doesn't work... works in program. - pending('marks move with char inserts #extmarks', function() + it('marks move with char inserts #extmarks', function() -- insertchar in edit.c (the ins_str branch) - curbufmeths.set_extmark(ns, marks[1], 1, 3) + set_extmark(ns, marks[1], 0, 3) feed('0') insert('abc') screen:expect([[ @@ -391,16 +397,15 @@ describe('Extmarks buffer api', function() ~ | | ]]) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq(1, rv[2]) - eq(6, rv[3]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + eq({0, 6}, rv) -- check_undo_redo(ns, marks[1], 0, 2, 0, 5) end) -- gravity right as definted in tk library it('marks have gravity right #extmarks', function() -- insertchar in edit.c (the ins_str branch) - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('03l') insert("X") check_undo_redo(ns, marks[1], 0, 2, 0, 2) @@ -414,7 +419,7 @@ describe('Extmarks buffer api', function() it('we can insert multibyte chars #extmarks', function() -- insertchar in edit.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) -- Insert a fullwidth (two col) tilde, NICE feed('0i~') check_undo_redo(ns, marks[1], 1, 2, 1, 3) @@ -423,7 +428,7 @@ describe('Extmarks buffer api', function() it('marks move with blockwise inserts #extmarks', function() -- op_insert in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) feed('0lkI9') check_undo_redo(ns, marks[1], 1, 2, 1, 3) end) @@ -432,18 +437,16 @@ describe('Extmarks buffer api', function() -- open_line in misc1.c -- testing marks below are also moved feed("yyP") - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 1, 4) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 1, 4) feed('1Gla') check_undo_redo(ns, marks[1], 0, 4, 1, 2) check_undo_redo(ns, marks[2], 1, 4, 2, 4) end) - -- TODO mark_col_adjust for normal marks fails in vim/neovim - -- because flags is 9 in: if (flags & OPENLINE_MARKFIX) { it('marks at last line move on insert new line #extmarks', function() -- open_line in misc1.c - curbufmeths.set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[1], 0, 4) feed('0i') check_undo_redo(ns, marks[1], 0, 4, 1, 4) end) @@ -451,22 +454,22 @@ describe('Extmarks buffer api', function() it('yet again marks move with line splits #extmarks', function() -- the first test above wasn't catching all errors.. feed("A67890") - curbufmeths.set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[1], 0, 4) feed("04li") check_undo_redo(ns, marks[1], 0, 4, 1, 0) end) it('and one last time line splits... #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) feed("02li") check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) end) it('multiple marks move with mark splits #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 3) feed("0li") check_undo_redo(ns, marks[1], 0, 1, 1, 0) check_undo_redo(ns, marks[2], 0, 3, 1, 2) @@ -474,14 +477,14 @@ describe('Extmarks buffer api', function() it('deleting on a mark works #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('02lx') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) it('marks move with char deletes #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('02dl') check_undo_redo(ns, marks[1], 0, 2, 0, 0) -- from the other side (nothing should happen) @@ -491,21 +494,20 @@ describe('Extmarks buffer api', function() it('marks move with char deletes over a range #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) feed('0l3dl') check_undo_redo(ns, marks[1], 0, 2, 0, 1) check_undo_redo(ns, marks[2], 0, 3, 0, 1) -- delete 1, nothing should happend to our marks feed('u') feed('$x') - -- TODO do we need to test marks[1] ??? check_undo_redo(ns, marks[2], 0, 3, 0, 3) end) it('deleting marks at end of line works #extmarks', function() -- mark_extended.c/extmark_col_adjust_delete - curbufmeths.set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[1], 0, 4) feed('$x') check_undo_redo(ns, marks[1], 0, 4, 0, 4) -- check the copy happened correctly on delete at eol @@ -518,7 +520,7 @@ describe('Extmarks buffer api', function() it('marks move with blockwise deletes #extmarks', function() -- op_delete in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 4) + set_extmark(ns, marks[1], 1, 4) feed('hhhkd') check_undo_redo(ns, marks[1], 1, 4, 1, 1) end) @@ -526,9 +528,9 @@ describe('Extmarks buffer api', function() it('marks move with blockwise deletes over a range #extmarks', function() -- op_delete in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 1, 2) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 1, 2) feed('0k3lx') check_undo_redo(ns, marks[1], 0, 1, 0, 0) check_undo_redo(ns, marks[2], 0, 3, 0, 0) @@ -536,14 +538,13 @@ describe('Extmarks buffer api', function() -- delete 1, nothing should happend to our marks feed('u') feed('$jx') - -- TODO do we need to test marks[1] ??? check_undo_redo(ns, marks[2], 0, 3, 0, 3) check_undo_redo(ns, marks[3], 1, 2, 1, 2) end) it('works with char deletes over multilines #extmarks', function() feed('a12345test-me') - curbufmeths.set_extmark(ns, marks[1], 2, 5) + set_extmark(ns, marks[1], 2, 5) feed('gg') feed('dv?-m?') check_undo_redo(ns, marks[1], 2, 5, 0, 0) @@ -551,7 +552,7 @@ describe('Extmarks buffer api', function() it('marks outside of deleted range move with visual char deletes #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[1], 0, 3) feed('0vx') check_undo_redo(ns, marks[1], 0, 3, 0, 2) @@ -570,7 +571,7 @@ describe('Extmarks buffer api', function() it('marks outside of deleted range move with char deletes #extmarks', function() -- op_delete in ops.c - curbufmeths.set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[1], 0, 3) feed('0x') check_undo_redo(ns, marks[1], 0, 3, 0, 2) @@ -591,7 +592,7 @@ describe('Extmarks buffer api', function() it('marks move with P(backward) paste #extmarks', function() -- do_put in ops.c feed('0iabc') - curbufmeths.set_extmark(ns, marks[1], 0, 7) + set_extmark(ns, marks[1], 0, 7) feed('0veyP') check_undo_redo(ns, marks[1], 0, 7, 0, 15) end) @@ -599,7 +600,7 @@ describe('Extmarks buffer api', function() it('marks move with p(forward) paste #extmarks', function() -- do_put in ops.c feed('0iabc') - curbufmeths.set_extmark(ns, marks[1], 0, 7) + set_extmark(ns, marks[1], 0, 7) feed('0veyp') check_undo_redo(ns, marks[1], 0, 7, 0, 14) end) @@ -607,7 +608,7 @@ describe('Extmarks buffer api', function() it('marks move with blockwise P(backward) paste #extmarks', function() -- do_put in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 4) + set_extmark(ns, marks[1], 1, 4) feed('hhkyP') check_undo_redo(ns, marks[1], 1, 4, 1, 7) end) @@ -615,20 +616,20 @@ describe('Extmarks buffer api', function() it('marks move with blockwise p(forward) paste #extmarks', function() -- do_put in ops.c feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 4) + set_extmark(ns, marks[1], 1, 4) feed('hhkyp') check_undo_redo(ns, marks[1], 1, 4, 1, 6) end) it('replace works #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0r2') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) it('blockwise replace works #extmarks', function() feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0llkr1') check_undo_redo(ns, marks[1], 0, 2, 0, 2) end) @@ -636,7 +637,7 @@ describe('Extmarks buffer api', function() it('shift line #extmarks', function() -- shift_line in ops.c feed(':set shiftwidth=4') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0>>') check_undo_redo(ns, marks[1], 0, 2, 0, 6) @@ -651,7 +652,7 @@ describe('Extmarks buffer api', function() -- shift_block in ops.c feed(':set shiftwidth=4') feed('a12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) feed('0k>') check_undo_redo(ns, marks[1], 1, 2, 1, 6) feed('j>') @@ -665,7 +666,7 @@ describe('Extmarks buffer api', function() -- ins_tab in edit.c feed(':set expandtab') feed(':set shiftwidth=2') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0i') check_undo_redo(ns, marks[1], 0, 2, 0, 6) end) @@ -676,7 +677,7 @@ describe('Extmarks buffer api', function() feed(':set shiftwidth=2') feed(':set softtabstop=2') feed(':set tabstop=8') - curbufmeths.set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[1], 0, 2) feed('0i') check_undo_redo(ns, marks[1], 0, 2, 0, 4) feed('0iX') @@ -684,7 +685,7 @@ describe('Extmarks buffer api', function() end) it('marks move when using :move #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[1], 0, 0) feed('A2:1move 2') check_undo_redo(ns, marks[1], 0, 0, 1, 0) -- test codepath when moving lines up @@ -695,7 +696,7 @@ describe('Extmarks buffer api', function() it('marks move when using :move part 2 #extmarks', function() -- make sure we didn't get lucky with the math... feed('A23456') - curbufmeths.set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[1], 1, 0) feed(':2,3move 5') check_undo_redo(ns, marks[1], 1, 0, 3, 0) -- test codepath when moving lines up @@ -706,23 +707,24 @@ describe('Extmarks buffer api', function() it('undo and redo of set and unset marks #extmarks', function() -- Force a new undo head feed('o') - curbufmeths.set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[1], 0, 1) feed('o') - curbufmeths.set_extmark(ns, marks[2], 0, -1) - curbufmeths.set_extmark(ns, marks[3], 0, -1) + set_extmark(ns, marks[2], 0, -1) + set_extmark(ns, marks[3], 0, -1) feed("u") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + local rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(1, table.getn(rv)) feed("") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(3, table.getn(rv)) -- Test updates feed('o') - curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) - rv = curbufmeths.get_extmarks(ns, marks[1], marks[1], 1) + set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + rv = get_extmarks(ns, marks[1], marks[1], {amount=1}) + eq(1, table.getn(rv)) feed("u") feed("") check_undo_redo(ns, marks[1], 0, 1, positions[1][1], positions[1][2]) @@ -731,80 +733,80 @@ describe('Extmarks buffer api', function() feed('o') curbufmeths.del_extmark(ns, marks[3]) feed("u") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(3, table.getn(rv)) feed("") - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) end) it('undo and redo of marks deleted during edits #extmarks', function() -- test extmark_adjust feed('A12345') - curbufmeths.set_extmark(ns, marks[1], 1, 2) + set_extmark(ns, marks[1], 1, 2) feed('dd') check_undo_redo(ns, marks[1], 1, 2, 1, 0) end) it('namespaces work properly #extmarks', function() - rv = curbufmeths.set_extmark(ns, marks[1], positions[1][1], positions[1][2]) + local rv = set_extmark(ns, marks[1], positions[1][1], positions[1][2]) eq(1, rv) - rv = curbufmeths.set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) + rv = set_extmark(ns2, marks[1], positions[1][1], positions[1][2]) eq(1, rv) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns2, {0, 0}, {-1, -1}) eq(1, table.getn(rv)) -- Set more marks for testing the ranges - rv = curbufmeths.set_extmark(ns, marks[2], positions[2][1], positions[2][2]) - rv = curbufmeths.set_extmark(ns, marks[3], positions[3][1], positions[3][2]) - rv = curbufmeths.set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) - rv = curbufmeths.set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) + set_extmark(ns, marks[2], positions[2][1], positions[2][2]) + set_extmark(ns, marks[3], positions[3][1], positions[3][2]) + set_extmark(ns2, marks[2], positions[2][1], positions[2][2]) + set_extmark(ns2, marks[3], positions[3][1], positions[3][2]) -- get_next (amount set) - rv = curbufmeths.get_extmarks(ns, {0, 0}, positions[2], 1) + rv = get_extmarks(ns, {0, 0}, positions[2], {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, {0, 0}, positions[2], 1) + rv = get_extmarks(ns2, {0, 0}, positions[2], {amount=1}) eq(1, table.getn(rv)) -- get_prev (amount set) - rv = curbufmeths.get_extmarks(ns, positions[1], {0, 0}, 1) + rv = get_extmarks(ns, positions[1], {0, 0}, {amount=1}) eq(1, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, positions[1], {0, 0}, 1) + rv = get_extmarks(ns2, positions[1], {0, 0}, {amount=1}) eq(1, table.getn(rv)) -- get_next (amount not set) - rv = curbufmeths.get_extmarks(ns, positions[1], positions[2], ALL) + rv = get_extmarks(ns, positions[1], positions[2]) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, positions[1], positions[2], ALL) + rv = get_extmarks(ns2, positions[1], positions[2]) eq(2, table.getn(rv)) -- get_prev (amount not set) - rv = curbufmeths.get_extmarks(ns, positions[2], positions[1], ALL) + rv = get_extmarks(ns, positions[2], positions[1]) eq(2, table.getn(rv)) - rv = curbufmeths.get_extmarks(ns2, positions[2], positions[1], ALL) + rv = get_extmarks(ns2, positions[2], positions[1]) eq(2, table.getn(rv)) curbufmeths.del_extmark(ns, marks[1]) - rv = curbufmeths.get_extmarks(ns, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) curbufmeths.del_extmark(ns2, marks[1]) - rv = curbufmeths.get_extmarks(ns2, {0, 0}, {-1, -1}, ALL) + rv = get_extmarks(ns2, {0, 0}, {-1, -1}) eq(2, table.getn(rv)) end) it('mark set can create unique identifiers #extmarks', function() -- create mark with id 1 - eq(1, curbufmeths.set_extmark(ns, 1, positions[1][1], positions[1][2])) + eq(1, set_extmark(ns, 1, positions[1][1], positions[1][2])) -- ask for unique id, it should be the next one, i e 2 - eq(2, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) - eq(3, curbufmeths.set_extmark(ns, 3, positions[2][1], positions[2][2])) - eq(4, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(2, set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(3, set_extmark(ns, 3, positions[2][1], positions[2][2])) + eq(4, set_extmark(ns, 0, positions[1][1], positions[1][2])) -- mixing manual and allocated id:s are not recommened, but it should -- do something reasonable - eq(6, curbufmeths.set_extmark(ns, 6, positions[2][1], positions[2][2])) - eq(7, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) - eq(8, curbufmeths.set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(6, set_extmark(ns, 6, positions[2][1], positions[2][2])) + eq(7, set_extmark(ns, 0, positions[1][1], positions[1][2])) + eq(8, set_extmark(ns, 0, positions[1][1], positions[1][2])) end) it('auto indenting with enter works #extmarks', function() @@ -814,11 +816,11 @@ describe('Extmarks buffer api', function() feed(':set shiftwidth=2') feed("0iint A {1M1b") -- Set the mark on the M, should move.. - curbufmeths.set_extmark(ns, marks[1], 0, 12) + set_extmark(ns, marks[1], 0, 12) -- Set the mark before the cursor, should stay there - curbufmeths.set_extmark(ns, marks[2], 0, 10) + set_extmark(ns, marks[2], 0, 10) feed("i") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({1, 3}, rv) rv = curbufmeths.get_extmark_by_id(ns, marks[2]) eq({0, 10}, rv) @@ -831,9 +833,9 @@ describe('Extmarks buffer api', function() feed(':set shiftwidth=2') -- will force an indent of 2 feed("0iint A {0i1M1") - curbufmeths.set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[1], 1, 1) feed("0i") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({1, 3}, rv) check_undo_redo(ns, marks[1], 1, 1, 1, 3) -- now check when cursor at eol @@ -847,9 +849,9 @@ describe('Extmarks buffer api', function() feed(':set autoindent') feed(':set shiftwidth=2') feed("0i") - curbufmeths.set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[1], 0, 3) feed("bi") - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, 1}, rv) check_undo_redo(ns, marks[1], 0, 3, 0, 1) -- check when cursor at eol @@ -863,8 +865,8 @@ describe('Extmarks buffer api', function() feed(':set autoindent') feed(':set shiftwidth=2') feed("0iint A {1M12M2") - curbufmeths.set_extmark(ns, marks[1], 1, 1) - curbufmeths.set_extmark(ns, marks[2], 2, 1) + set_extmark(ns, marks[1], 1, 1) + set_extmark(ns, marks[2], 2, 1) feed('=gg') check_undo_redo(ns, marks[1], 1, 1, 1, 3) check_undo_redo(ns, marks[2], 2, 1, 2, 5) @@ -872,8 +874,8 @@ describe('Extmarks buffer api', function() it('substitutes by deleting inside the replace matches #extmarks_sub', function() -- do_sub in ex_cmds.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) feed(':s/34/xx') check_undo_redo(ns, marks[1], 0, 2, 0, 4) check_undo_redo(ns, marks[2], 0, 3, 0, 4) @@ -881,8 +883,8 @@ describe('Extmarks buffer api', function() it('substitutes when insert text > deleted #extmarks_sub', function() -- do_sub in ex_cmds.c - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) feed(':s/34/xxx') check_undo_redo(ns, marks[1], 0, 2, 0, 5) check_undo_redo(ns, marks[2], 0, 3, 0, 5) @@ -890,8 +892,8 @@ describe('Extmarks buffer api', function() it('substitutes when marks around eol #extmarks_sub', function() -- do_sub in ex_cmds.c - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 0, 5) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 0, 5) feed(':s/5/xxx') check_undo_redo(ns, marks[1], 0, 4, 0, 7) check_undo_redo(ns, marks[2], 0, 5, 0, 7) @@ -901,9 +903,9 @@ describe('Extmarks buffer api', function() -- do_sub in ex_cmds.c feed('Ax34xx') feed('Axxx34') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 1, 1) - curbufmeths.set_extmark(ns, marks[3], 2, 4) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 1, 1) + set_extmark(ns, marks[3], 2, 4) feed(':1,3s/34/xxx') check_undo_redo(ns, marks[1], 0, 2, 0, 5) check_undo_redo(ns, marks[2], 1, 1, 1, 4) @@ -913,9 +915,9 @@ describe('Extmarks buffer api', function() it('substitutes multiple matches in a line #extmarks_sub', function() -- do_sub in ex_cmds.c feed('ddi3x3x3') - curbufmeths.set_extmark(ns, marks[1], 0, 0) - curbufmeths.set_extmark(ns, marks[2], 0, 2) - curbufmeths.set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) feed(':s/3/yy/g') check_undo_redo(ns, marks[1], 0, 0, 0, 2) check_undo_redo(ns, marks[2], 0, 2, 0, 5) @@ -924,11 +926,11 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with newline in pattern #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 1, 0) - curbufmeths.set_extmark(ns, marks[4], 1, 5) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:5\n:5 ]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 0, 6) @@ -939,12 +941,12 @@ describe('Extmarks buffer api', function() it('inserting #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 1, 0) - curbufmeths.set_extmark(ns, marks[4], 1, 5) - curbufmeths.set_extmark(ns, marks[5], 2, 0) - curbufmeths.set_extmark(ns, marks[6], 1, 2) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[6], 1, 2) feed([[:1,2s:5\n67:X]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 0, 5) @@ -956,11 +958,11 @@ describe('Extmarks buffer api', function() it('substitions with multiple newlines in pattern #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 4) - curbufmeths.set_extmark(ns, marks[2], 0, 5) - curbufmeths.set_extmark(ns, marks[3], 1, 0) - curbufmeths.set_extmark(ns, marks[4], 1, 5) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 4) + set_extmark(ns, marks[2], 0, 5) + set_extmark(ns, marks[3], 1, 0) + set_extmark(ns, marks[4], 1, 5) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:\n.*\n:X]]) check_undo_redo(ns, marks[1], 0, 4, 0, 4) check_undo_redo(ns, marks[2], 0, 5, 0, 6) @@ -971,11 +973,11 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with replace in substition #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 2) - curbufmeths.set_extmark(ns, marks[3], 0, 4) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:3:\r]]) check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) @@ -989,9 +991,9 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with replace in substition #extmarks_sub', function() feed('Ax3xx') - curbufmeths.set_extmark(ns, marks[1], 1, 0) - curbufmeths.set_extmark(ns, marks[2], 1, 1) - curbufmeths.set_extmark(ns, marks[3], 1, 2) + set_extmark(ns, marks[1], 1, 0) + set_extmark(ns, marks[2], 1, 1) + set_extmark(ns, marks[3], 1, 2) feed([[:2,2s:3:\r]]) check_undo_redo(ns, marks[1], 1, 0, 1, 0) check_undo_redo(ns, marks[2], 1, 1, 2, 0) @@ -1000,11 +1002,11 @@ describe('Extmarks buffer api', function() it('substitions over multiple lines with replace in substition #extmarks_sub', function() feed('Ax3xx') - curbufmeths.set_extmark(ns, marks[1], 0, 1) - curbufmeths.set_extmark(ns, marks[2], 0, 2) - curbufmeths.set_extmark(ns, marks[3], 0, 4) - curbufmeths.set_extmark(ns, marks[4], 1, 1) - curbufmeths.set_extmark(ns, marks[5], 2, 0) + set_extmark(ns, marks[1], 0, 1) + set_extmark(ns, marks[2], 0, 2) + set_extmark(ns, marks[3], 0, 4) + set_extmark(ns, marks[4], 1, 1) + set_extmark(ns, marks[5], 2, 0) feed([[:1,2s:3:\r]]) check_undo_redo(ns, marks[1], 0, 1, 0, 1) check_undo_redo(ns, marks[2], 0, 2, 1, 0) @@ -1018,12 +1020,12 @@ describe('Extmarks buffer api', function() it('substitions with newline in match and sub, delta is 0 #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) feed([[:1,1s:5\n:\r]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 1, 0) @@ -1035,12 +1037,12 @@ describe('Extmarks buffer api', function() it('substitions with newline in match and sub, delta > 0 #extmarks_sub', function() feed('A67890xx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) feed([[:1,1s:5\n:\r\r]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 2, 0) @@ -1052,13 +1054,13 @@ describe('Extmarks buffer api', function() it('substitions with newline in match and sub, delta < 0 #extmarks_sub', function() feed('A67890xxxx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 1) - curbufmeths.set_extmark(ns, marks[7], 3, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 1) + set_extmark(ns, marks[7], 3, 0) feed([[:1,2s:5\n.*\n:\r]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 1, 0) @@ -1071,12 +1073,12 @@ describe('Extmarks buffer api', function() it('substitions with backrefs, newline inserted into sub #extmarks_sub', function() feed('A67890xxxx') - curbufmeths.set_extmark(ns, marks[1], 0, 3) - curbufmeths.set_extmark(ns, marks[2], 0, 4) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 1, 0) - curbufmeths.set_extmark(ns, marks[5], 1, 5) - curbufmeths.set_extmark(ns, marks[6], 2, 0) + set_extmark(ns, marks[1], 0, 3) + set_extmark(ns, marks[2], 0, 4) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 1, 0) + set_extmark(ns, marks[5], 1, 5) + set_extmark(ns, marks[6], 2, 0) feed([[:1,1s:5\(\n\):\0\1]]) check_undo_redo(ns, marks[1], 0, 3, 0, 3) check_undo_redo(ns, marks[2], 0, 4, 2, 0) @@ -1087,8 +1089,8 @@ describe('Extmarks buffer api', function() end) it('substitions a ^ #extmarks_sub', function() - curbufmeths.set_extmark(ns, marks[1], 0, 0) - curbufmeths.set_extmark(ns, marks[2], 0, 1) + set_extmark(ns, marks[1], 0, 0) + set_extmark(ns, marks[2], 0, 1) feed([[:s:^:x]]) check_undo_redo(ns, marks[1], 0, 0, 0, 1) check_undo_redo(ns, marks[2], 0, 1, 0, 2) @@ -1097,11 +1099,11 @@ describe('Extmarks buffer api', function() it('using without increase in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc998xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 0, 6) - curbufmeths.set_extmark(ns, marks[5], 0, 7) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 6) @@ -1113,11 +1115,11 @@ describe('Extmarks buffer api', function() it('using when increase in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc999xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 0, 6) - curbufmeths.set_extmark(ns, marks[5], 0, 7) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1128,11 +1130,11 @@ describe('Extmarks buffer api', function() it('using when negative and without decrease in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-999xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1143,11 +1145,11 @@ describe('Extmarks buffer api', function() it('using when negative and decrease in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-1000xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 7) - curbufmeths.set_extmark(ns, marks[4], 0, 8) - curbufmeths.set_extmark(ns, marks[5], 0, 9) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 7) + set_extmark(ns, marks[4], 0, 8) + set_extmark(ns, marks[5], 0, 9) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1159,11 +1161,11 @@ describe('Extmarks buffer api', function() it('using without decrease in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc999xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 5) - curbufmeths.set_extmark(ns, marks[4], 0, 6) - curbufmeths.set_extmark(ns, marks[5], 0, 7) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 5) + set_extmark(ns, marks[4], 0, 6) + set_extmark(ns, marks[5], 0, 7) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 6) @@ -1175,11 +1177,11 @@ describe('Extmarks buffer api', function() it('using when decrease in order of magnitude #extmarks_inc_dec', function() -- do_addsub in ops.c feed('ddiabc1000xxxTc') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 6) @@ -1190,11 +1192,11 @@ describe('Extmarks buffer api', function() it('using when negative and without increase in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-998xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 7) @@ -1205,11 +1207,11 @@ describe('Extmarks buffer api', function() it('using when negative and increase in order of magnitude #extmarks_inc_dec', function() feed('ddiabc-999xxxT-') - curbufmeths.set_extmark(ns, marks[1], 0, 2) - curbufmeths.set_extmark(ns, marks[2], 0, 3) - curbufmeths.set_extmark(ns, marks[3], 0, 6) - curbufmeths.set_extmark(ns, marks[4], 0, 7) - curbufmeths.set_extmark(ns, marks[5], 0, 8) + set_extmark(ns, marks[1], 0, 2) + set_extmark(ns, marks[2], 0, 3) + set_extmark(ns, marks[3], 0, 6) + set_extmark(ns, marks[4], 0, 7) + set_extmark(ns, marks[5], 0, 8) feed('') check_undo_redo(ns, marks[1], 0, 2, 0, 2) check_undo_redo(ns, marks[2], 0, 3, 0, 8) @@ -1218,38 +1220,34 @@ describe('Extmarks buffer api', function() check_undo_redo(ns, marks[5], 0, 8, 0, 9) end) - -- TODO catch exceptions - pending('throws consistent error codes #todo', function() + it('throws consistent error codes', function() local ns_invalid = ns2 + 1 - rv = curbufmeths.set_extmark(ns_invalid, marks[1], positions[1][1], positions[1][2]) - rv = curbufmeths.del_extmark(ns_invalid, marks[1]) - rv = curbufmeths.get_extmarks(ns_invalid, positions[1], positions[2], ALL) - rv = curbufmeths.get_extmark_by_id(ns_invalid, marks[1]) - + eq("Invalid ns_id", pcall_err(set_extmark, ns_invalid, marks[1], positions[1][1], positions[1][2])) + eq("Invalid ns_id", pcall_err(curbufmeths.del_extmark, ns_invalid, marks[1])) + eq("Invalid ns_id", pcall_err(get_extmarks, ns_invalid, positions[1], positions[2])) + eq("Invalid ns_id", pcall_err(curbufmeths.get_extmark_by_id, ns_invalid, marks[1])) end) it('when col = line-length, set the mark on eol #extmarks', function() - curbufmeths.set_extmark(ns, marks[1], 0, -1) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) + set_extmark(ns, marks[1], 0, -1) + local rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, init_text:len()}, rv) -- Test another - curbufmeths.set_extmark(ns, marks[1], 0, -1) + set_extmark(ns, marks[1], 0, -1) rv = curbufmeths.get_extmark_by_id(ns, marks[1]) eq({0, init_text:len()}, rv) end) it('when col = line-length, set the mark on eol #extmarks', function() local invalid_col = init_text:len() + 1 - eq({false, "col value outside range"}, meth_pcall(curbufmeths.set_extmark, ns, marks[1], 0, invalid_col)) + eq("col value outside range", pcall_err(set_extmark, ns, marks[1], 0, invalid_col)) end) - -- TODO(bfredl): decide what to do with this - pending('when line > line, set the mark on end of buffer #extmarks', function() + it('when line > line_count, throw error #extmarks', function() local invalid_col = init_text:len() + 1 - local invalid_lnum = 3 -- line1 ends in an eol. so line 2 contains a valid position (eol)? - curbufmeths.set_extmark(ns, marks[1], invalid_lnum, invalid_col) - rv = curbufmeths.get_extmark_by_id(ns, marks[1]) - eq({2, 1}, rv) + local invalid_lnum = 3 + eq('line value outside range', pcall_err(set_extmark, ns, marks[1], invalid_lnum, invalid_col)) + eq({}, curbufmeths.get_extmark_by_id(ns, marks[1])) end) it('bug from check_col in extmark_set #extmarks_sub', function() @@ -1259,7 +1257,7 @@ describe('Extmarks buffer api', function() -- check_col and check_lnum only when they are required. feed('A67890xx') feed('A1234567890xx') - curbufmeths.set_extmark(ns, marks[1], 3, 4) + set_extmark(ns, marks[1], 3, 4) feed([[:1,5s:5\n:5 ]]) check_undo_redo(ns, marks[1], 3, 4, 2, 6) end) @@ -1284,7 +1282,7 @@ describe('Extmarks buffer api with many marks', function() local q = 0 for i = 0,29 do for j = 0,i do - local id = curbufmeths.set_extmark(ns,0, i,j) + local id = set_extmark(ns,0, i,j) eq(nil, ns_marks[ns][id]) ok(id > 0) ns_marks[ns][id] = {i,j} @@ -1298,7 +1296,7 @@ describe('Extmarks buffer api with many marks', function() end) local function get_marks(ns) - local mark_list = curbufmeths.get_extmarks(ns, 0, -1, -1) + local mark_list = get_extmarks(ns, 0, -1) local marks = {} for _, mark in ipairs(mark_list) do local id, row, col = unpack(mark) @@ -1362,4 +1360,10 @@ describe('Extmarks buffer api with many marks', function() eq(ns_marks[ns1], get_marks(ns1)) eq(ns_marks[ns2], get_marks(ns2)) end) + + it("can wipe buffer #extmarks", function() + command('bwipe!') + eq({}, get_marks(ns1)) + eq({}, get_marks(ns2)) + end) end) diff --git a/test/functional/legacy/046_multi_line_regexps_spec.lua b/test/functional/legacy/046_multi_line_regexps_spec.lua index 9d3ee57b46..30ec76ea3e 100644 --- a/test/functional/legacy/046_multi_line_regexps_spec.lua +++ b/test/functional/legacy/046_multi_line_regexps_spec.lua @@ -8,22 +8,22 @@ local expect = helpers.expect describe('multi-line regexp', function() setup(clear) - it('is working #fail', function() + it('is working', function() insert([[ -1 aa -bb -cc -2 dd -ee -3 ef -gh -4 ij -5 a8 -8b c9 -9d -6 e7 -77f -xxxxx]]) + 1 aa + bb + cc + 2 dd + ee + 3 ef + gh + 4 ij + 5 a8 + 8b c9 + 9d + 6 e7 + 77f + xxxxx]]) -- Test if replacing a line break works with a back reference feed([[:/^1/,/^2/s/\n\(.\)/ \1/]]) diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 0136e4e7e0..b841574643 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -131,7 +131,7 @@ describe(":substitute, inccommand=split interactivity", function() end) end) -describe(":substitute, 'inccommand' preserves #inc", function() +describe(":substitute, 'inccommand' preserves", function() before_each(clear) it('listed buffers (:ls)', function() @@ -293,7 +293,7 @@ describe(":substitute, 'inccommand' preserves #inc", function() end) -describe(":substitute, 'inccommand' preserves undo #inc", function() +describe(":substitute, 'inccommand' preserves undo", function() local cases = { "", "split", "nosplit" } local substrings = { @@ -1962,7 +1962,7 @@ describe(":substitute", function() clear() end) - it("inccommand=split, highlights multiline substitutions #inc2", function() + it("inccommand=split, highlights multiline substitutions", function() common_setup(screen, "split", multiline_text) feed("gg") @@ -2024,7 +2024,7 @@ describe(":substitute", function() ]]) end) - it("inccommand=nosplit, highlights multiline substitutions #inc2", function() + it("inccommand=nosplit, highlights multiline substitutions", function() common_setup(screen, "nosplit", multiline_text) feed("gg") @@ -2117,7 +2117,7 @@ describe(":substitute", function() ]]) end) - it("inccommand=split, with \\zs #inc", function() + it("inccommand=split, with \\zs", function() common_setup(screen, "split", multiline_text) feed("gg") @@ -2141,7 +2141,7 @@ describe(":substitute", function() ]]) end) - it("inccommand=nosplit, with \\zs #inc", function() + it("inccommand=nosplit, with \\zs", function() common_setup(screen, "nosplit", multiline_text) feed("gg") @@ -2212,7 +2212,7 @@ describe(":substitute", function() ]]) end) - it("inccommand=split, contraction of lines #inc2", function() + it("inccommand=split, contraction of lines", function() local text = [[ T T123 T T123 T2T TT T23423424 x @@ -2261,7 +2261,7 @@ describe(":substitute", function() ]]) end) - it("inccommand=nosplit, contraction of lines #inc2", function() + it("inccommand=nosplit, contraction of lines", function() local text = [[ T T123 T T123 T2T TT T23423424 x diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 2c50bcb97b..7840ba9167 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -817,6 +817,7 @@ describe('ui/mouse/input', function() feed_command('syntax match NonText "cats" conceal cchar=X') feed_command('syntax match NonText "x" conceal cchar=>') + -- First column is there to retain the tabs. insert([[ |Section *t1* | *t2* *t3* *t4*