Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extmarks api: allow for gravity #13679

Merged
merged 4 commits into from Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 20 additions & 3 deletions src/nvim/api/buffer.c
Expand Up @@ -1400,6 +1400,9 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id,
/// callbacks. The mark will only be used for the current
/// redraw cycle, and not be permantently stored in the
/// buffer.
/// - gravity : the direction the extmark will be shifted in
/// when new text is inserted. Must be either 'left' or
/// 'right'.
chentoast marked this conversation as resolved.
Show resolved Hide resolved
/// @param[out] err Error details, if any
/// @return Id of the created/updated extmark
Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
Expand Down Expand Up @@ -1440,6 +1443,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
DecorPriority priority = DECOR_PRIORITY_BASE;
colnr_T col2 = 0;
VirtText virt_text = KV_INITIAL_VALUE;
bool right_gravity = true;
for (size_t i = 0; i < opts.size; i++) {
String k = opts.items[i].key;
Object *v = &opts.items[i].value;
Expand Down Expand Up @@ -1522,6 +1526,19 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
goto error;
}
priority = (DecorPriority)v->data.integer;
} else if (strequal("gravity", k.data)) {
if (v->type != kObjectTypeString) {
chentoast marked this conversation as resolved.
Show resolved Hide resolved
api_set_error(err, kErrorTypeValidation,
"gravity must be a string");
goto error;
}
if (strequal("left", v->data.string.data)) {
right_gravity = false;
} else if (!strequal("right", v->data.string.data)) {
api_set_error(err, kErrorTypeValidation,
"invalid option for gravity: must be 'left' or 'right'");
goto error;
}
} else {
api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
goto error;
Expand Down Expand Up @@ -1572,7 +1589,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
}

id = extmark_set(buf, (uint64_t)ns_id, id, (int)line, (colnr_T)col,
line2, col2, decor, kExtmarkNoUndo);
line2, col2, decor, right_gravity, kExtmarkNoUndo);
}

return (Integer)id;
Expand Down Expand Up @@ -1687,7 +1704,7 @@ Integer nvim_buf_add_highlight(Buffer buffer,
extmark_set(buf, ns_id, 0,
(int)line, (colnr_T)col_start,
end_line, (colnr_T)col_end,
decor_hl(hl_id), kExtmarkNoUndo);
decor_hl(hl_id), true, kExtmarkNoUndo);
return src_id;
}

Expand Down Expand Up @@ -1796,7 +1813,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer,
Decoration *decor = xcalloc(1, sizeof(*decor));
decor->virt_text = virt_text;

extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, kExtmarkNoUndo);
extmark_set(buf, ns_id, 0, (int)line, 0, -1, -1, decor, true, kExtmarkNoUndo);
return src_id;
}

Expand Down
2 changes: 1 addition & 1 deletion src/nvim/decoration.c
Expand Up @@ -69,7 +69,7 @@ void bufhl_add_hl_pos_offset(buf_T *buf,
}
(void)extmark_set(buf, (uint64_t)src_id, 0,
(int)lnum-1, hl_start, (int)lnum-1+end_off, hl_end,
decor, kExtmarkNoUndo);
decor, true, kExtmarkNoUndo);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/nvim/extmark.c
Expand Up @@ -71,7 +71,7 @@ static ExtmarkNs *buf_ns_ref(buf_T *buf, uint64_t ns_id, bool put) {
/// @returns the mark id
uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,
int row, colnr_T col, int end_row, colnr_T end_col,
Decoration *decor, ExtmarkOp op)
Decoration *decor, bool right_gravity, ExtmarkOp op)
{
ExtmarkNs *ns = buf_ns_ref(buf, ns_id, true);
assert(ns != NULL);
Expand Down Expand Up @@ -109,10 +109,10 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id,

if (end_row > -1) {
mark = marktree_put_pair(buf->b_marktree,
row, col, true,
row, col, right_gravity,
end_row, end_col, false);
} else {
mark = marktree_put(buf->b_marktree, row, col, true);
mark = marktree_put(buf->b_marktree, row, col, right_gravity);
}

revised:
Expand Down
34 changes: 34 additions & 0 deletions test/functional/api/extmark_spec.lua
Expand Up @@ -1389,6 +1389,40 @@ describe('API/extmarks', function()
undo]],false)
eq(2, meths.eval('1+1')) -- did not crash
end)

it('works with left and right gravity', function()
-- right gravity should move with inserted text, while
-- left gravity should stay in place.
curbufmeths.set_extmark(ns, 0, 5, {gravity = 'left'})
curbufmeths.set_extmark(ns, 0, 5, {gravity = 'right'})
feed([[Aasdfasdf]])

eq({ {1, 0, 5}, {2, 0, 13} },
curbufmeths.get_extmarks(ns, 0, -1, {}))

-- but both move when text is inserted before
feed([[<esc>Iasdf<esc>]])
-- eq({}, curbufmeths.get_lines(0, -1, true))
eq({ {1, 0, 9}, {2, 0, 17} },
curbufmeths.get_extmarks(ns, 0, -1, {}))

-- clear text
curbufmeths.set_text(0, 0, 0, 17, {})

-- handles set_text correctly as well
eq({ {1, 0, 0}, {2, 0, 0} },
meths.buf_get_extmarks(0, ns, 0, -1, {}))
curbufmeths.set_text(0, 0, 0, 0, {'asdfasdf'})
eq({ {1, 0, 0}, {2, 0, 8} },
curbufmeths.get_extmarks(ns, 0, -1, {}))

feed('u')
-- handles pasting
meths.exec([[let @a='asdfasdf']], false)
feed([["ap]])
eq({ {1, 0, 0}, {2, 0, 8} },
meths.buf_get_extmarks(0, ns, 0, -1, {}))
end)
end)

describe('Extmarks buffer api with many marks', function()
Expand Down