~ubuntu-branches/debian/sid/neovim/sid

« back to all changes in this revision

Viewing changes to src/nvim/api/buffer.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2016-04-18 21:42:19 UTC
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: package-import@ubuntu.com-20160418214219-6lf1w0zadujghas7
Tags: upstream-0.1.3
ImportĀ upstreamĀ versionĀ 0.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include "nvim/mark.h"
20
20
#include "nvim/fileio.h"
21
21
#include "nvim/move.h"
 
22
#include "nvim/syntax.h"
22
23
#include "nvim/window.h"
23
24
#include "nvim/undo.h"
24
25
 
44
45
 
45
46
/// Gets a buffer line
46
47
///
 
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)"
 
53
///
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)
52
59
{
53
 
  String rv = {.size = 0};
54
 
  Array slice = buffer_get_line_slice(buffer, index, index, true, true, err);
 
60
  String rv = { .size = 0 };
 
61
 
 
62
  index = convert_index(index);
 
63
  Array slice = buffer_get_lines(buffer, index, index+1, true, err);
55
64
 
56
65
  if (!err->set && slice.size) {
57
66
    rv = slice.items[0].data.string;
64
73
 
65
74
/// Sets a buffer line
66
75
///
 
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])"
 
81
///
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)
72
87
{
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);
76
92
}
77
93
 
78
94
/// Deletes a buffer line
79
95
///
 
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)
84
105
{
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);
87
109
}
88
110
 
89
111
/// Retrieves a line range from the buffer
90
112
///
 
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,
103
129
                                 Error *err)
104
130
{
 
131
  start = convert_index(start) + !include_start;
 
132
  end = convert_index(end) + include_end;
 
133
  return buffer_get_lines(buffer, start , end, false, err);
 
134
}
 
135
 
 
136
 
 
137
/// Retrieves a line range from the buffer
 
138
///
 
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.
 
142
///
 
143
/// Out-of-bounds indices are clamped to the nearest valid value, unless
 
144
/// `strict_indexing` is set.
 
145
///
 
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,
 
153
                                 Integer start,
 
154
                                 Integer end,
 
155
                                 Boolean strict_indexing,
 
156
                                 Error *err)
 
157
{
105
158
  Array rv = ARRAY_DICT_INIT;
106
159
  buf_T *buf = find_buffer_by_handle(buffer, err);
107
160
 
108
 
  if (!buf || !inbounds(buf, start)) {
109
 
    return rv;
110
 
  }
111
 
 
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);
 
161
  if (!buf) {
 
162
    return rv;
 
163
  }
 
164
 
 
165
  bool oob = false;
 
166
  start = normalize_index(buf, start, &oob);
 
167
  end = normalize_index(buf, end, &oob);
 
168
 
 
169
  if (strict_indexing && oob) {
 
170
    api_set_error(err, Validation, _("Index out of bounds"));
 
171
    return rv;
 
172
  }
115
173
 
116
174
  if (start >= end) {
117
175
    // Return 0-length array
151
209
  return rv;
152
210
}
153
211
 
 
212
 
154
213
/// Replaces a line range on the buffer
155
214
///
 
215
/// @deprecated use buffer_set_lines(buffer, newstart, newend, false, lines)
 
216
///             where newstart = start + int(not include_start) + int(start < 0)
 
217
///                   newend = end + int(include_end) + int(end < 0)
 
218
///                   int(bool) = 1 if bool is true else 0
 
219
///
156
220
/// @param buffer The buffer handle
157
221
/// @param start The first line index
158
222
/// @param end The last line index
169
233
                      ArrayOf(String) replacement,
170
234
                      Error *err)
171
235
{
 
236
  start = convert_index(start) + !include_start;
 
237
  end = convert_index(end) + include_end;
 
238
  buffer_set_lines(buffer, start, end, false, replacement, err);
 
239
}
 
240
 
 
241
 
 
242
/// Replaces line range on the buffer
 
243
///
 
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.
 
247
///
 
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.
 
250
///
 
251
/// Out-of-bounds indices are clamped to the nearest valid value, unless
 
252
/// `strict_indexing` is set.
 
253
///
 
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,
 
261
                      Integer start,
 
262
                      Integer end,
 
263
                      Boolean strict_indexing,
 
264
                      ArrayOf(String) replacement,
 
265
                      Error *err)
 
266
{
172
267
  buf_T *buf = find_buffer_by_handle(buffer, err);
173
268
 
174
269
  if (!buf) {
175
270
    return;
176
271
  }
177
272
 
178
 
  if (!inbounds(buf, start)) {
 
273
  bool oob = false;
 
274
  start = normalize_index(buf, start, &oob);
 
275
  end = normalize_index(buf, end, &oob);
 
276
 
 
277
  if (strict_indexing && oob) {
179
278
    api_set_error(err, Validation, _("Index out of bounds"));
180
279
    return;
181
280
  }
182
281
 
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);
186
282
 
187
283
  if (start > end) {
188
284
    api_set_error(err,
456
552
 
457
553
/// Inserts a sequence of lines to a buffer at a certain index
458
554
///
 
555
/// @deprecated use buffer_set_lines(buffer, lnum, lnum, true, lines)
 
556
///
459
557
/// @param buffer The buffer handle
460
558
/// @param lnum Insert the lines after `lnum`. If negative, it will append
461
559
///        to the end of the buffer.
466
564
                   ArrayOf(String) lines,
467
565
                   Error *err)
468
566
{
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);
471
570
}
472
571
 
473
572
/// Return a tuple (row,col) representing the position of the named mark
514
613
  return rv;
515
614
}
516
615
 
 
616
/// Adds a highlight to buffer.
 
617
///
 
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.
 
623
///
 
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".
 
630
///
 
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.
 
635
///
 
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,
 
647
                             Integer src_id,
 
648
                             String hl_group,
 
649
                             Integer line,
 
650
                             Integer col_start,
 
651
                             Integer col_end,
 
652
                             Error *err)
 
653
{
 
654
  buf_T *buf = find_buffer_by_handle(buffer, err);
 
655
  if (!buf) {
 
656
    return 0;
 
657
  }
 
658
 
 
659
  if (line < 0 || line >= MAXLNUM) {
 
660
    api_set_error(err, Validation, _("Line number outside range"));
 
661
    return 0;
 
662
  }
 
663
  if (col_start < 0 || col_start > MAXCOL) {
 
664
    api_set_error(err, Validation, _("Column value outside range"));
 
665
    return 0;
 
666
  }
 
667
  if (col_end < 0 || col_end > MAXCOL) {
 
668
    col_end = MAXCOL;
 
669
  }
 
670
 
 
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);
 
674
  return src_id;
 
675
}
 
676
 
 
677
/// Clears highlights from a given source group and a range of lines
 
678
///
 
679
/// To clear a source group in the entire buffer, pass in 1 and -1 to
 
680
/// line_start and line_end respectively.
 
681
///
 
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,
 
689
                            Integer src_id,
 
690
                            Integer line_start,
 
691
                            Integer line_end,
 
692
                            Error *err)
 
693
{
 
694
  buf_T *buf = find_buffer_by_handle(buffer, err);
 
695
  if (!buf) {
 
696
    return;
 
697
  }
 
698
 
 
699
  if (line_start < 0 || line_start >= MAXLNUM) {
 
700
    api_set_error(err, Validation, _("Line number outside range"));
 
701
    return;
 
702
  }
 
703
  if (line_end < 0 || line_end > MAXLNUM) {
 
704
    line_end = MAXLNUM;
 
705
  }
 
706
 
 
707
  bufhl_clear_line_range(buf, (int)src_id, (int)line_start+1, (int)line_end);
 
708
}
517
709
 
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
538
730
}
539
731
 
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)
542
734
{
 
735
  int64_t line_count = buf->b_ml.ml_line_count;
543
736
  // Fix if < 0
544
 
  index = index < 0 ?  buf->b_ml.ml_line_count + index : index;
 
737
  index = index < 0 ? line_count + index +1 : index;
 
738
 
 
739
  // Check for oob
 
740
  if (index > line_count) {
 
741
    *oob = true;
 
742
    index = line_count;
 
743
  } else if (index < 0) {
 
744
    *oob = true;
 
745
    index = 0;
 
746
  }
545
747
  // Convert the index to a vim line number
546
748
  index++;
547
 
  // Fix if > line_count
548
 
  index = index > buf->b_ml.ml_line_count ? buf->b_ml.ml_line_count : index;
549
749
  return index;
550
750
}
551
751
 
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)
554
753
{
555
 
  linenr_T nlines = buf->b_ml.ml_line_count;
556
 
  return index >= -nlines && index < nlines;
 
754
  return index < 0 ? index - 1 : index;
557
755
}