diff options
Diffstat (limited to 'src/nvim/api')
| -rw-r--r-- | src/nvim/api/buffer.c | 14 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.c | 53 | ||||
| -rw-r--r-- | src/nvim/api/ui_events.in.h | 3 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 15 | ||||
| -rw-r--r-- | src/nvim/api/window.c | 4 |
5 files changed, 65 insertions, 24 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 915b99486d..11a4647d1c 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -27,6 +27,7 @@ #include "nvim/map_defs.h" #include "nvim/map.h" #include "nvim/mark.h" +#include "nvim/ops.h" #include "nvim/extmark.h" #include "nvim/decoration.h" #include "nvim/fileio.h" @@ -441,6 +442,8 @@ void nvim_buf_set_lines(uint64_t channel_id, goto end; } + bcount_t deleted_bytes = get_region_bytecount(curbuf, start, end, 0, 0); + // If the size of the range is reducing (ie, new_len < old_len) we // need to delete some old_len. We do this at the start, by // repeatedly deleting line "start". @@ -460,6 +463,7 @@ void nvim_buf_set_lines(uint64_t channel_id, // new old_len. This is a more efficient operation, as it requires // less memory allocation and freeing. size_t to_replace = old_len < new_len ? old_len : new_len; + bcount_t inserted_bytes = 0; for (size_t i = 0; i < to_replace; i++) { int64_t lnum = start + (int64_t)i; @@ -472,6 +476,8 @@ void nvim_buf_set_lines(uint64_t channel_id, api_set_error(err, kErrorTypeException, "Failed to replace line"); goto end; } + + inserted_bytes += (bcount_t)strlen(lines[i]) + 1; // Mark lines that haven't been passed to the buffer as they need // to be freed later lines[i] = NULL; @@ -491,6 +497,8 @@ void nvim_buf_set_lines(uint64_t channel_id, goto end; } + inserted_bytes += (bcount_t)strlen(lines[i]) + 1; + // Same as with replacing, but we also need to free lines xfree(lines[i]); lines[i] = NULL; @@ -505,7 +513,11 @@ void nvim_buf_set_lines(uint64_t channel_id, (linenr_T)(end - 1), MAXLNUM, (long)extra, - kExtmarkUndo); + kExtmarkNOOP); + + extmark_splice(curbuf, (int)start-1, 0, (int)(end-start), 0, + deleted_bytes, (int)new_len, 0, inserted_bytes, + kExtmarkUndo); changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true); fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra); diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 24ba6110c4..5abdc33709 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -177,42 +177,47 @@ Object dict_get_value(dict_T *dict, String key, Error *err) return vim_to_object(&di->di_tv); } -/// Set a value in a scope dict. Objects are recursively expanded into their -/// vimscript equivalents. -/// -/// @param dict The vimscript dict -/// @param key The key -/// @param value The new value -/// @param del Delete key in place of setting it. Argument `value` is ignored in -/// this case. -/// @param retval If true the old value will be converted and returned. -/// @param[out] err Details of an error that may have occurred -/// @return The old value if `retval` is true and the key was present, else NIL -Object dict_set_var(dict_T *dict, String key, Object value, bool del, - bool retval, Error *err) +dictitem_T *dict_check_writable(dict_T *dict, String key, bool del, Error *err) { - Object rv = OBJECT_INIT; dictitem_T *di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di != NULL) { if (di->di_flags & DI_FLAGS_RO) { api_set_error(err, kErrorTypeException, "Key is read-only: %s", key.data); - return rv; } else if (di->di_flags & DI_FLAGS_LOCK) { api_set_error(err, kErrorTypeException, "Key is locked: %s", key.data); - return rv; } else if (del && (di->di_flags & DI_FLAGS_FIX)) { api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data); - return rv; } } else if (dict->dv_lock) { api_set_error(err, kErrorTypeException, "Dictionary is locked"); - return rv; } else if (key.size == 0) { api_set_error(err, kErrorTypeValidation, "Key name is empty"); - return rv; } else if (key.size > INT_MAX) { api_set_error(err, kErrorTypeValidation, "Key name is too long"); + } + + return di; +} + +/// Set a value in a scope dict. Objects are recursively expanded into their +/// vimscript equivalents. +/// +/// @param dict The vimscript dict +/// @param key The key +/// @param value The new value +/// @param del Delete key in place of setting it. Argument `value` is ignored in +/// this case. +/// @param retval If true the old value will be converted and returned. +/// @param[out] err Details of an error that may have occurred +/// @return The old value if `retval` is true and the key was present, else NIL +Object dict_set_var(dict_T *dict, String key, Object value, bool del, + bool retval, Error *err) +{ + Object rv = OBJECT_INIT; + dictitem_T *di = dict_check_writable(dict, key, del, err); + + if (ERROR_SET(err)) { return rv; } @@ -1909,7 +1914,7 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, } else if (strequal(key, "height")) { has_height = true; if (val.type == kObjectTypeInteger && val.data.integer > 0) { - fconfig->height= (int)val.data.integer; + fconfig->height = (int)val.data.integer; } else { api_set_error(err, kErrorTypeValidation, "'height' key must be a positive Integer"); @@ -1983,6 +1988,14 @@ bool parse_float_config(Dictionary config, FloatConfig *fconfig, bool reconf, "'focusable' key must be Boolean"); return false; } + } else if (strequal(key, "zindex")) { + if (val.type == kObjectTypeInteger && val.data.integer > 0) { + fconfig->zindex = (int)val.data.integer; + } else { + api_set_error(err, kErrorTypeValidation, + "'zindex' key must be a positive Integer"); + return false; + } } else if (!strcmp(key, "border")) { parse_border_style(val, fconfig, err); if (ERROR_SET(err)) { diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index e934d5dc92..11e21a88ea 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -106,7 +106,8 @@ void win_pos(Integer grid, Window win, Integer startrow, Integer startcol, Integer width, Integer height) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void win_float_pos(Integer grid, Window win, String anchor, Integer anchor_grid, - Float anchor_row, Float anchor_col, Boolean focusable) + Float anchor_row, Float anchor_col, Boolean focusable, + Integer zindex) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void win_external_pos(Integer grid, Window win) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index c363c77afb..e9a0b0df2e 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -221,6 +221,12 @@ Dictionary nvim__get_hl_defs(Integer ns_id, Error *err) /// in addition the following keys are also recognized: /// `default`: don't override existing definition, /// like `hi default` +/// `ctermfg`: sets foreground of cterm color +/// `ctermbg`: sets background of cterm color +/// `cterm` : cterm attribute map. sets attributed for +/// cterm colors. similer to `hi cterm` +/// Note: by default cterm attributes are +/// same as attributes of gui color /// @param[out] err Error details, if any /// /// TODO: ns_id = 0, should modify :highlight namespace @@ -1411,6 +1417,15 @@ void nvim_chan_send(Integer chan, String data, Error *err) /// - `external`: GUI should display the window as an external /// top-level window. Currently accepts no other positioning /// configuration together with this. +/// - `zindex`: Stacking order. floats with higher `zindex` go on top on +/// floats with lower indices. Must be larger than zero. The +/// following screen elements have hard-coded z-indices: +/// - 100: insert completion popupmenu +/// - 200: message scrollback +/// - 250: cmdline completion popupmenu (when wildoptions+=pum) +/// The default value for floats are 50. In general, values below 100 are +/// recommended, unless there is a good reason to overshadow builtin +/// elements. /// - `style`: Configure the appearance of the window. Currently only takes /// one non-empty value: /// - "minimal" Nvim will display the window with many UI options diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c index f942d6b19f..158e149628 100644 --- a/src/nvim/api/window.c +++ b/src/nvim/api/window.c @@ -54,7 +54,7 @@ void nvim_win_set_buf(Window window, Buffer buffer, Error *err) return; } - if (switch_win(&save_curwin, &save_curtab, win, tab, false) == FAIL) { + if (switch_win_noblock(&save_curwin, &save_curtab, win, tab, false) == FAIL) { api_set_error(err, kErrorTypeException, "Failed to switch to window %d", @@ -74,7 +74,7 @@ void nvim_win_set_buf(Window window, Buffer buffer, Error *err) // So do it now. validate_cursor(); - restore_win(save_curwin, save_curtab, false); + restore_win_noblock(save_curwin, save_curtab, false); } /// Gets the (1,0)-indexed cursor position in the window. |api-indexing| |