diff options
author | Gregory Anders <8965202+gpanders@users.noreply.github.com> | 2022-02-22 13:19:21 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-22 20:19:21 +0000 |
commit | 11f7aeed7aa83d342d19897d9a69ba9f32ece7f7 (patch) | |
tree | 8dc8f25f2e3979203e1b109a5aecb0e820f04850 /src/nvim/api/private/helpers.c | |
parent | 30c9c8815b531e0130ebeb9358bc6d3947a6128a (diff) | |
download | rneovim-11f7aeed7aa83d342d19897d9a69ba9f32ece7f7.tar.gz rneovim-11f7aeed7aa83d342d19897d9a69ba9f32ece7f7.tar.bz2 rneovim-11f7aeed7aa83d342d19897d9a69ba9f32ece7f7.zip |
feat(api): implement nvim_buf_get_text (#15181)
nvim_buf_get_text is the mirror of nvim_buf_set_text. It differs from
nvim_buf_get_lines in that it allows retrieving only portions of lines.
While this can typically be done easily enough by API clients,
implementing this function provides symmetry between the get/set
text/lines APIs, and also provides a nice convenience that saves API
clients the work of having to slice the result of nvim_buf_get_lines
themselves.
Diffstat (limited to 'src/nvim/api/private/helpers.c')
-rw-r--r-- | src/nvim/api/private/helpers.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 2b107a3f27..971fa1cb0f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -411,7 +411,6 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object current_sctx = save_current_sctx; } - buf_T *find_buffer_by_handle(Buffer buffer, Error *err) { if (buffer == 0) { @@ -758,6 +757,52 @@ bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl, Arr return true; } +/// Returns a substring of a buffer line +/// +/// @param buf Buffer handle +/// @param lnum Line number (1-based) +/// @param start_col Starting byte offset into line (0-based) +/// @param end_col Ending byte offset into line (0-based, exclusive) +/// @param replace_nl Replace newlines ('\n') with null ('\0') +/// @param err Error object +/// @return The text between start_col and end_col on line lnum of buffer buf +String buf_get_text(buf_T *buf, int64_t lnum, int64_t start_col, int64_t end_col, bool replace_nl, + Error *err) +{ + String rv = STRING_INIT; + + if (lnum >= MAXLNUM) { + api_set_error(err, kErrorTypeValidation, "Line index is too high"); + return rv; + } + + const char *bufstr = (char *)ml_get_buf(buf, (linenr_T)lnum, false); + size_t line_length = strlen(bufstr); + + start_col = start_col < 0 ? (int64_t)line_length + start_col + 1 : start_col; + end_col = end_col < 0 ? (int64_t)line_length + end_col + 1 : end_col; + + if (start_col >= MAXCOL || end_col >= MAXCOL) { + api_set_error(err, kErrorTypeValidation, "Column index is too high"); + return rv; + } + + if (start_col > end_col) { + api_set_error(err, kErrorTypeValidation, "start_col must be less than end_col"); + return rv; + } + + if ((size_t)start_col >= line_length) { + return rv; + } + + rv = cstrn_to_string(&bufstr[start_col], (size_t)(end_col - start_col)); + if (replace_nl) { + strchrsub(rv.data, '\n', '\0'); + } + + return rv; +} void api_free_string(String value) { |