45
46
/// Gets a buffer line
48
/// @deprecated use buffer_get_lines instead.
49
/// for positive indices (including 0) use
50
/// "buffer_get_lines(buffer, index, index+1, true)"
51
/// for negative indices use
52
/// "buffer_get_lines(buffer, index-1, index, true)"
47
54
/// @param buffer The buffer handle
48
55
/// @param index The line index
49
56
/// @param[out] err Details of an error that may have occurred
50
57
/// @return The line string
51
58
String buffer_get_line(Buffer buffer, Integer index, Error *err)
53
String rv = {.size = 0};
54
Array slice = buffer_get_line_slice(buffer, index, index, true, true, err);
60
String rv = { .size = 0 };
62
index = convert_index(index);
63
Array slice = buffer_get_lines(buffer, index, index+1, true, err);
56
65
if (!err->set && slice.size) {
57
66
rv = slice.items[0].data.string;
65
74
/// Sets a buffer line
76
/// @deprecated use buffer_set_lines instead.
77
/// for positive indices use
78
/// "buffer_set_lines(buffer, index, index+1, true, [line])"
79
/// for negative indices use
80
/// "buffer_set_lines(buffer, index-1, index, true, [line])"
67
82
/// @param buffer The buffer handle
68
83
/// @param index The line index
69
84
/// @param line The new line.
71
86
void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
73
88
Object l = STRING_OBJ(line);
74
Array array = {.items = &l, .size = 1};
75
buffer_set_line_slice(buffer, index, index, true, true, array, err);
89
Array array = { .items = &l, .size = 1 };
90
index = convert_index(index);
91
buffer_set_lines(buffer, index, index+1, true, array, err);
78
94
/// Deletes a buffer line
96
/// @deprecated use buffer_set_lines instead.
97
/// for positive indices use
98
/// "buffer_set_lines(buffer, index, index+1, true, [])"
99
/// for negative indices use
100
/// "buffer_set_lines(buffer, index-1, index, true, [])"
80
101
/// @param buffer The buffer handle
81
102
/// @param index The line index
82
103
/// @param[out] err Details of an error that may have occurred
83
104
void buffer_del_line(Buffer buffer, Integer index, Error *err)
85
106
Array array = ARRAY_DICT_INIT;
86
buffer_set_line_slice(buffer, index, index, true, true, array, err);
107
index = convert_index(index);
108
buffer_set_lines(buffer, index, index+1, true, array, err);
89
111
/// Retrieves a line range from the buffer
113
/// @deprecated use buffer_get_lines(buffer, newstart, newend, false)
114
/// where newstart = start + int(not include_start) - int(start < 0)
115
/// newend = end + int(include_end) - int(end < 0)
116
/// int(bool) = 1 if bool is true else 0
91
117
/// @param buffer The buffer handle
92
118
/// @param start The first line index
93
119
/// @param end The last line index
102
128
Boolean include_end,
131
start = convert_index(start) + !include_start;
132
end = convert_index(end) + include_end;
133
return buffer_get_lines(buffer, start , end, false, err);
137
/// Retrieves a line range from the buffer
139
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
140
/// as length+1+index, i e -1 refers to the index past the end. So to get the
141
/// last element set start=-2 and end=-1.
143
/// Out-of-bounds indices are clamped to the nearest valid value, unless
144
/// `strict_indexing` is set.
146
/// @param buffer The buffer handle
147
/// @param start The first line index
148
/// @param end The last line index (exclusive)
149
/// @param strict_indexing whether out-of-bounds should be an error.
150
/// @param[out] err Details of an error that may have occurred
151
/// @return An array of lines
152
ArrayOf(String) buffer_get_lines(Buffer buffer,
155
Boolean strict_indexing,
105
158
Array rv = ARRAY_DICT_INIT;
106
159
buf_T *buf = find_buffer_by_handle(buffer, err);
108
if (!buf || !inbounds(buf, start)) {
112
start = normalize_index(buf, start) + (include_start ? 0 : 1);
113
include_end = include_end || (end >= buf->b_ml.ml_line_count);
114
end = normalize_index(buf, end) + (include_end ? 1 : 0);
166
start = normalize_index(buf, start, &oob);
167
end = normalize_index(buf, end, &oob);
169
if (strict_indexing && oob) {
170
api_set_error(err, Validation, _("Index out of bounds"));
116
174
if (start >= end) {
117
175
// Return 0-length array
169
233
ArrayOf(String) replacement,
236
start = convert_index(start) + !include_start;
237
end = convert_index(end) + include_end;
238
buffer_set_lines(buffer, start, end, false, replacement, err);
242
/// Replaces line range on the buffer
244
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
245
/// as length+1+index, i e -1 refers to the index past the end. So to change
246
/// or delete the last element set start=-2 and end=-1.
248
/// To insert lines at a given index, set both start and end to the same index.
249
/// To delete a range of lines, set replacement to an empty array.
251
/// Out-of-bounds indices are clamped to the nearest valid value, unless
252
/// `strict_indexing` is set.
254
/// @param buffer The buffer handle
255
/// @param start The first line index
256
/// @param end The last line index (exclusive)
257
/// @param strict_indexing whether out-of-bounds should be an error.
258
/// @param replacement An array of lines to use as replacement
259
/// @param[out] err Details of an error that may have occurred
260
void buffer_set_lines(Buffer buffer,
263
Boolean strict_indexing,
264
ArrayOf(String) replacement,
172
267
buf_T *buf = find_buffer_by_handle(buffer, err);
178
if (!inbounds(buf, start)) {
274
start = normalize_index(buf, start, &oob);
275
end = normalize_index(buf, end, &oob);
277
if (strict_indexing && oob) {
179
278
api_set_error(err, Validation, _("Index out of bounds"));
183
start = normalize_index(buf, start) + (include_start ? 0 : 1);
184
include_end = include_end || (end >= buf->b_ml.ml_line_count);
185
end = normalize_index(buf, end) + (include_end ? 1 : 0);
187
283
if (start > end) {
188
284
api_set_error(err,
466
564
ArrayOf(String) lines,
469
bool end_start = lnum < 0;
470
buffer_set_line_slice(buffer, lnum, lnum, !end_start, end_start, lines, err);
567
// "lnum" will be the index of the line after inserting,
568
// no matter if it is negative or not
569
buffer_set_lines(buffer, lnum, lnum, true, lines, err);
473
572
/// Return a tuple (row,col) representing the position of the named mark
616
/// Adds a highlight to buffer.
618
/// This can be used for plugins which dynamically generate highlights to a
619
/// buffer (like a semantic highlighter or linter). The function adds a single
620
/// highlight to a buffer. Unlike matchaddpos() highlights follow changes to
621
/// line numbering (as lines are inserted/removed above the highlighted line),
622
/// like signs and marks do.
624
/// "src_id" is useful for batch deletion/updating of a set of highlights. When
625
/// called with src_id = 0, an unique source id is generated and returned.
626
/// Succesive calls can pass in it as "src_id" to add new highlights to the same
627
/// source group. All highlights in the same group can then be cleared with
628
/// buffer_clear_highlight. If the highlight never will be manually deleted
629
/// pass in -1 for "src_id".
631
/// If "hl_group" is the empty string no highlight is added, but a new src_id
632
/// is still returned. This is useful for an external plugin to synchrounously
633
/// request an unique src_id at initialization, and later asynchronously add and
634
/// clear highlights in response to buffer changes.
636
/// @param buffer The buffer handle
637
/// @param src_id Source group to use or 0 to use a new group,
638
/// or -1 for ungrouped highlight
639
/// @param hl_group Name of the highlight group to use
640
/// @param line The line to highlight
641
/// @param col_start Start of range of columns to highlight
642
/// @param col_end End of range of columns to highlight,
643
/// or -1 to highlight to end of line
644
/// @param[out] err Details of an error that may have occurred
645
/// @return The src_id that was used
646
Integer buffer_add_highlight(Buffer buffer,
654
buf_T *buf = find_buffer_by_handle(buffer, err);
659
if (line < 0 || line >= MAXLNUM) {
660
api_set_error(err, Validation, _("Line number outside range"));
663
if (col_start < 0 || col_start > MAXCOL) {
664
api_set_error(err, Validation, _("Column value outside range"));
667
if (col_end < 0 || col_end > MAXCOL) {
671
int hlg_id = syn_name2id((char_u*)hl_group.data);
672
src_id = bufhl_add_hl(buf, (int)src_id, hlg_id, (linenr_T)line+1,
673
(colnr_T)col_start+1, (colnr_T)col_end);
677
/// Clears highlights from a given source group and a range of lines
679
/// To clear a source group in the entire buffer, pass in 1 and -1 to
680
/// line_start and line_end respectively.
682
/// @param buffer The buffer handle
683
/// @param src_id Highlight source group to clear, or -1 to clear all groups.
684
/// @param line_start Start of range of lines to clear
685
/// @param line_end End of range of lines to clear (exclusive)
686
/// or -1 to clear to end of file.
687
/// @param[out] err Details of an error that may have occurred
688
void buffer_clear_highlight(Buffer buffer,
694
buf_T *buf = find_buffer_by_handle(buffer, err);
699
if (line_start < 0 || line_start >= MAXLNUM) {
700
api_set_error(err, Validation, _("Line number outside range"));
703
if (line_end < 0 || line_end > MAXLNUM) {
707
bufhl_clear_line_range(buf, (int)src_id, (int)line_start+1, (int)line_end);
518
710
// Check if deleting lines made the cursor position invalid.
519
711
// Changed the lines from "lo" to "hi" and added "extra" lines (negative if
540
732
// Normalizes 0-based indexes to buffer line numbers
541
static int64_t normalize_index(buf_T *buf, int64_t index)
733
static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
735
int64_t line_count = buf->b_ml.ml_line_count;
544
index = index < 0 ? buf->b_ml.ml_line_count + index : index;
737
index = index < 0 ? line_count + index +1 : index;
740
if (index > line_count) {
743
} else if (index < 0) {
545
747
// Convert the index to a vim line number
547
// Fix if > line_count
548
index = index > buf->b_ml.ml_line_count ? buf->b_ml.ml_line_count : index;
552
// Returns true if the 0-indexed `index` is within the 1-indexed buffer bounds.
553
static bool inbounds(buf_T *buf, int64_t index)
752
static int64_t convert_index(int64_t index)
555
linenr_T nlines = buf->b_ml.ml_line_count;
556
return index >= -nlines && index < nlines;
754
return index < 0 ? index - 1 : index;