deprecated.c (32402B)
1 // Island of misfit toys. 2 3 #include <stdbool.h> 4 #include <stdint.h> 5 #include <string.h> 6 7 #include "nvim/api/buffer.h" 8 #include "nvim/api/deprecated.h" 9 #include "nvim/api/extmark.h" 10 #include "nvim/api/keysets_defs.h" 11 #include "nvim/api/private/defs.h" 12 #include "nvim/api/private/dispatch.h" 13 #include "nvim/api/private/helpers.h" 14 #include "nvim/api/private/validate.h" 15 #include "nvim/api/vimscript.h" 16 #include "nvim/buffer_defs.h" 17 #include "nvim/decoration.h" 18 #include "nvim/decoration_defs.h" 19 #include "nvim/eval/vars.h" 20 #include "nvim/extmark.h" 21 #include "nvim/globals.h" 22 #include "nvim/highlight.h" 23 #include "nvim/highlight_group.h" 24 #include "nvim/lua/executor.h" 25 #include "nvim/marktree.h" 26 #include "nvim/memory.h" 27 #include "nvim/memory_defs.h" 28 #include "nvim/message.h" 29 #include "nvim/option.h" 30 #include "nvim/option_defs.h" 31 #include "nvim/pos_defs.h" 32 #include "nvim/strings.h" 33 #include "nvim/types_defs.h" 34 35 #include "api/deprecated.c.generated.h" 36 37 /// @deprecated Use nvim_exec2() instead. 38 /// @see nvim_exec2 39 String nvim_exec(uint64_t channel_id, String src, Boolean output, Error *err) 40 FUNC_API_SINCE(7) FUNC_API_DEPRECATED_SINCE(11) 41 FUNC_API_RET_ALLOC 42 { 43 Dict(exec_opts) opts = { .output = output }; 44 return exec_impl(channel_id, src, &opts, err); 45 } 46 47 /// @deprecated 48 /// @see nvim_exec2 49 String nvim_command_output(uint64_t channel_id, String command, Error *err) 50 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(7) 51 FUNC_API_RET_ALLOC 52 { 53 Dict(exec_opts) opts = { .output = true }; 54 return exec_impl(channel_id, command, &opts, err); 55 } 56 57 /// @deprecated Use nvim_exec_lua() instead. 58 /// @see nvim_exec_lua 59 Object nvim_execute_lua(String code, Array args, Arena *arena, Error *err) 60 FUNC_API_SINCE(3) 61 FUNC_API_DEPRECATED_SINCE(7) 62 FUNC_API_REMOTE_ONLY 63 { 64 return nlua_exec(code, NULL, args, kRetObject, arena, err); 65 } 66 67 /// Gets the buffer number 68 /// 69 /// @deprecated The buffer number now is equal to the object id 70 /// 71 /// @param buffer Buffer id, or 0 for current buffer 72 /// @param[out] err Error details, if any 73 /// @return Buffer number 74 Integer nvim_buf_get_number(Buffer buffer, Error *err) 75 FUNC_API_SINCE(1) 76 FUNC_API_DEPRECATED_SINCE(2) 77 { 78 buf_T *buf = find_buffer_by_handle(buffer, err); 79 80 if (!buf) { 81 return 0; 82 } 83 84 return buf->b_fnum; 85 } 86 87 static uint32_t src2ns(Integer *src_id) 88 { 89 if (*src_id == 0) { 90 *src_id = nvim_create_namespace((String)STRING_INIT); 91 } 92 if (*src_id < 0) { 93 return (((uint32_t)1) << 31) - 1; 94 } 95 return (uint32_t)(*src_id); 96 } 97 98 /// Clears highlights and virtual text from namespace and range of lines 99 /// 100 /// @deprecated use |nvim_buf_clear_namespace()|. 101 /// 102 /// @param buffer Buffer id, or 0 for current buffer 103 /// @param ns_id Namespace to clear, or -1 to clear all. 104 /// @param line_start Start of range of lines to clear 105 /// @param line_end End of range of lines to clear (exclusive) or -1 to clear 106 /// to end of file. 107 /// @param[out] err Error details, if any 108 void nvim_buf_clear_highlight(Buffer buffer, Integer ns_id, Integer line_start, Integer line_end, 109 Error *err) 110 FUNC_API_SINCE(1) 111 FUNC_API_DEPRECATED_SINCE(7) 112 { 113 nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end, err); 114 } 115 116 /// Adds a highlight to buffer. 117 /// 118 /// @deprecated use |nvim_buf_set_extmark()| or |vim.hl.range()| 119 /// 120 /// Namespaces are used for batch deletion/updating of a set of highlights. To 121 /// create a namespace, use |nvim_create_namespace()| which returns a namespace 122 /// id. Pass it in to this function as `ns_id` to add highlights to the 123 /// namespace. All highlights in the same namespace can then be cleared with 124 /// single call to |nvim_buf_clear_namespace()|. If the highlight never will be 125 /// deleted by an API call, pass `ns_id = -1`. 126 /// 127 /// As a shorthand, `ns_id = 0` can be used to create a new namespace for the 128 /// highlight, the allocated id is then returned. If `hl_group` is the empty 129 /// string no highlight is added, but a new `ns_id` is still returned. This is 130 /// supported for backwards compatibility, new code should use 131 /// |nvim_create_namespace()| to create a new empty namespace. 132 /// 133 /// @param buffer Buffer id, or 0 for current buffer 134 /// @param ns_id namespace to use or -1 for ungrouped highlight 135 /// @param hl_group Name of the highlight group to use 136 /// @param line Line to highlight (zero-indexed) 137 /// @param col_start Start of (byte-indexed) column range to highlight 138 /// @param col_end End of (byte-indexed) column range to highlight, 139 /// or -1 to highlight to end of line 140 /// @param[out] err Error details, if any 141 /// @return The ns_id that was used 142 Integer nvim_buf_add_highlight(Buffer buffer, Integer ns_id, String hl_group, Integer line, 143 Integer col_start, Integer col_end, Error *err) 144 FUNC_API_SINCE(1) 145 FUNC_API_DEPRECATED_SINCE(13) 146 { 147 buf_T *buf = find_buffer_by_handle(buffer, err); 148 if (!buf) { 149 return 0; 150 } 151 152 VALIDATE_RANGE((line >= 0 && line < MAXLNUM), "line number", { 153 return 0; 154 }); 155 VALIDATE_RANGE((col_start >= 0 && col_start <= MAXCOL), "column", { 156 return 0; 157 }); 158 159 if (col_end < 0 || col_end > MAXCOL) { 160 col_end = MAXCOL; 161 } 162 163 uint32_t ns = src2ns(&ns_id); 164 165 if (!(line < buf->b_ml.ml_line_count)) { 166 // safety check, we can't add marks outside the range 167 return ns_id; 168 } 169 170 int hl_id = 0; 171 if (hl_group.size > 0) { 172 hl_id = syn_check_group(hl_group.data, hl_group.size); 173 } else { 174 return ns_id; 175 } 176 177 int end_line = (int)line; 178 if (col_end == MAXCOL) { 179 col_end = 0; 180 end_line++; 181 } 182 183 DecorInline decor = DECOR_INLINE_INIT; 184 decor.data.hl.hl_id = hl_id; 185 186 extmark_set(buf, ns, NULL, (int)line, (colnr_T)col_start, end_line, (colnr_T)col_end, 187 decor, MT_FLAG_DECOR_HL, true, false, false, false, NULL); 188 return ns_id; 189 } 190 /// Set the virtual text (annotation) for a buffer line. 191 /// 192 /// @deprecated use nvim_buf_set_extmark to use full virtual text functionality. 193 /// 194 /// The text will be placed after the buffer text. Virtual text will never 195 /// cause reflow, rather virtual text will be truncated at the end of the screen 196 /// line. The virtual text will begin one cell (|lcs-eol| or space) after the 197 /// ordinary text. 198 /// 199 /// Namespaces are used to support batch deletion/updating of virtual text. 200 /// To create a namespace, use |nvim_create_namespace()|. Virtual text is 201 /// cleared using |nvim_buf_clear_namespace()|. The same `ns_id` can be used for 202 /// both virtual text and highlights added by |nvim_buf_add_highlight()|, both 203 /// can then be cleared with a single call to |nvim_buf_clear_namespace()|. If 204 /// the virtual text never will be cleared by an API call, pass `ns_id = -1`. 205 /// 206 /// As a shorthand, `ns_id = 0` can be used to create a new namespace for the 207 /// virtual text, the allocated id is then returned. 208 /// 209 /// @param buffer Buffer id, or 0 for current buffer 210 /// @param src_id Namespace to use or 0 to create a namespace, 211 /// or -1 for a ungrouped annotation 212 /// @param line Line to annotate with virtual text (zero-indexed) 213 /// @param chunks A list of [text, hl_group] arrays, each representing a 214 /// text chunk with specified highlight. `hl_group` element 215 /// can be omitted for no highlight. 216 /// @param opts Optional parameters. Currently not used. 217 /// @param[out] err Error details, if any 218 /// @return The ns_id that was used 219 Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, Array chunks, 220 Dict(empty) *opts, Error *err) 221 FUNC_API_SINCE(5) 222 FUNC_API_DEPRECATED_SINCE(8) 223 { 224 buf_T *buf = find_buffer_by_handle(buffer, err); 225 if (!buf) { 226 return 0; 227 } 228 229 if (line < 0 || line >= MAXLNUM) { 230 api_set_error(err, kErrorTypeValidation, "Line number outside range"); 231 return 0; 232 } 233 234 uint32_t ns_id = src2ns(&src_id); 235 int width; 236 237 VirtText virt_text = parse_virt_text(chunks, err, &width); 238 if (ERROR_SET(err)) { 239 return 0; 240 } 241 242 DecorVirtText *existing = decor_find_virttext(buf, (int)line, ns_id); 243 244 if (existing) { 245 clear_virttext(&existing->data.virt_text); 246 existing->data.virt_text = virt_text; 247 existing->width = width; 248 return src_id; 249 } 250 251 DecorVirtText *vt = xmalloc(sizeof *vt); 252 *vt = (DecorVirtText)DECOR_VIRT_TEXT_INIT; 253 vt->data.virt_text = virt_text; 254 vt->width = width; 255 vt->priority = 0; 256 257 DecorInline decor = { .ext = true, .data.ext.vt = vt, .data.ext.sh_idx = DECOR_ID_INVALID }; 258 259 extmark_set(buf, ns_id, NULL, (int)line, 0, -1, -1, decor, 0, true, 260 false, false, false, NULL); 261 return src_id; 262 } 263 264 /// Gets a highlight definition by id. |hlID()| 265 /// 266 /// @deprecated use |nvim_get_hl()| instead 267 /// 268 /// @param hl_id Highlight id as returned by |hlID()| 269 /// @param rgb Export RGB colors 270 /// @param[out] err Error details, if any 271 /// @return Highlight definition map 272 /// @see nvim_get_hl_by_name 273 Dict nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Arena *arena, Error *err) 274 FUNC_API_SINCE(3) 275 FUNC_API_DEPRECATED_SINCE(9) 276 { 277 Dict dic = ARRAY_DICT_INIT; 278 VALIDATE_INT((syn_get_final_id((int)hl_id) != 0), "highlight id", hl_id, { 279 return dic; 280 }); 281 int attrcode = syn_id2attr((int)hl_id); 282 return hl_get_attr_by_id(attrcode, rgb, arena, err); 283 } 284 285 /// Gets a highlight definition by name. 286 /// 287 /// @deprecated use |nvim_get_hl()| instead 288 /// 289 /// @param name Highlight group name 290 /// @param rgb Export RGB colors 291 /// @param[out] err Error details, if any 292 /// @return Highlight definition map 293 /// @see nvim_get_hl_by_id 294 Dict nvim_get_hl_by_name(String name, Boolean rgb, Arena *arena, Error *err) 295 FUNC_API_SINCE(3) 296 FUNC_API_DEPRECATED_SINCE(9) 297 { 298 Dict result = ARRAY_DICT_INIT; 299 int id = syn_name2id(name.data); 300 301 VALIDATE_S((id != 0), "highlight name", name.data, { 302 return result; 303 }); 304 return nvim_get_hl_by_id(id, rgb, arena, err); 305 } 306 307 /// Inserts a sequence of lines to a buffer at a certain index 308 /// 309 /// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines) 310 /// 311 /// @param buffer Buffer id 312 /// @param lnum Insert the lines after `lnum`. If negative, appends to 313 /// the end of the buffer. 314 /// @param lines Array of lines 315 /// @param[out] err Error details, if any 316 void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Arena *arena, Error *err) 317 FUNC_API_DEPRECATED_SINCE(1) 318 { 319 // "lnum" will be the index of the line after inserting, 320 // no matter if it is negative or not 321 nvim_buf_set_lines(0, buffer, lnum, lnum, true, lines, arena, err); 322 } 323 324 /// Gets a buffer line 325 /// 326 /// @deprecated use nvim_buf_get_lines instead. 327 /// for positive indices (including 0) use 328 /// "nvim_buf_get_lines(buffer, index, index+1, true)" 329 /// for negative indices use 330 /// "nvim_buf_get_lines(buffer, index-1, index, true)" 331 /// 332 /// @param buffer Buffer id 333 /// @param index Line index 334 /// @param[out] err Error details, if any 335 /// @return Line string 336 String buffer_get_line(Buffer buffer, Integer index, Arena *arena, Error *err) 337 FUNC_API_DEPRECATED_SINCE(1) 338 { 339 String rv = { .size = 0 }; 340 341 index = convert_index(index); 342 Array slice = nvim_buf_get_lines(0, buffer, index, index + 1, true, arena, NULL, err); 343 344 if (!ERROR_SET(err) && slice.size) { 345 rv = slice.items[0].data.string; 346 } 347 348 return rv; 349 } 350 351 /// Sets a buffer line 352 /// 353 /// @deprecated use nvim_buf_set_lines instead. 354 /// for positive indices use 355 /// "nvim_buf_set_lines(buffer, index, index+1, true, [line])" 356 /// for negative indices use 357 /// "nvim_buf_set_lines(buffer, index-1, index, true, [line])" 358 /// 359 /// @param buffer Buffer id 360 /// @param index Line index 361 /// @param line Contents of the new line 362 /// @param[out] err Error details, if any 363 void buffer_set_line(Buffer buffer, Integer index, String line, Arena *arena, Error *err) 364 FUNC_API_DEPRECATED_SINCE(1) 365 { 366 Object l = STRING_OBJ(line); 367 Array array = { .items = &l, .size = 1 }; 368 index = convert_index(index); 369 nvim_buf_set_lines(0, buffer, index, index + 1, true, array, arena, err); 370 } 371 372 /// Deletes a buffer line 373 /// 374 /// @deprecated use nvim_buf_set_lines instead. 375 /// for positive indices use 376 /// "nvim_buf_set_lines(buffer, index, index+1, true, [])" 377 /// for negative indices use 378 /// "nvim_buf_set_lines(buffer, index-1, index, true, [])" 379 /// @param buffer buffer id 380 /// @param index line index 381 /// @param[out] err Error details, if any 382 void buffer_del_line(Buffer buffer, Integer index, Arena *arena, Error *err) 383 FUNC_API_DEPRECATED_SINCE(1) 384 { 385 Array array = ARRAY_DICT_INIT; 386 index = convert_index(index); 387 nvim_buf_set_lines(0, buffer, index, index + 1, true, array, arena, err); 388 } 389 390 /// Retrieves a line range from the buffer 391 /// 392 /// @deprecated use nvim_buf_get_lines(buffer, newstart, newend, false) 393 /// where newstart = start + int(not include_start) - int(start < 0) 394 /// newend = end + int(include_end) - int(end < 0) 395 /// int(bool) = 1 if bool is true else 0 396 /// @param buffer Buffer id 397 /// @param start First line index 398 /// @param end Last line index 399 /// @param include_start True if the slice includes the `start` parameter 400 /// @param include_end True if the slice includes the `end` parameter 401 /// @param[out] err Error details, if any 402 /// @return Array of lines 403 ArrayOf(String) buffer_get_line_slice(Buffer buffer, 404 Integer start, 405 Integer end, 406 Boolean include_start, 407 Boolean include_end, 408 Arena *arena, 409 Error *err) 410 FUNC_API_DEPRECATED_SINCE(1) 411 { 412 start = convert_index(start) + !include_start; 413 end = convert_index(end) + include_end; 414 return nvim_buf_get_lines(0, buffer, start, end, false, arena, NULL, err); 415 } 416 417 /// Replaces a line range on the buffer 418 /// 419 /// @deprecated use nvim_buf_set_lines(buffer, newstart, newend, false, lines) 420 /// where newstart = start + int(not include_start) + int(start < 0) 421 /// newend = end + int(include_end) + int(end < 0) 422 /// int(bool) = 1 if bool is true else 0 423 /// 424 /// @param buffer Buffer id, or 0 for current buffer 425 /// @param start First line index 426 /// @param end Last line index 427 /// @param include_start True if the slice includes the `start` parameter 428 /// @param include_end True if the slice includes the `end` parameter 429 /// @param replacement Array of lines to use as replacement (0-length 430 // array will delete the line range) 431 /// @param[out] err Error details, if any 432 void buffer_set_line_slice(Buffer buffer, Integer start, Integer end, Boolean include_start, 433 Boolean include_end, ArrayOf(String) replacement, Arena *arena, 434 Error *err) 435 FUNC_API_DEPRECATED_SINCE(1) 436 { 437 start = convert_index(start) + !include_start; 438 end = convert_index(end) + include_end; 439 nvim_buf_set_lines(0, buffer, start, end, false, replacement, arena, err); 440 } 441 442 /// Sets a buffer-scoped (b:) variable 443 /// 444 /// @deprecated 445 /// 446 /// @param buffer Buffer id, or 0 for current buffer 447 /// @param name Variable name 448 /// @param value Variable value 449 /// @param[out] err Error details, if any 450 /// @return Old value or nil if there was no previous value. 451 /// 452 /// @warning It may return nil if there was no previous value 453 /// or if previous value was `v:null`. 454 Object buffer_set_var(Buffer buffer, String name, Object value, Arena *arena, Error *err) 455 FUNC_API_DEPRECATED_SINCE(1) 456 { 457 buf_T *buf = find_buffer_by_handle(buffer, err); 458 459 if (!buf) { 460 return NIL; 461 } 462 463 return dict_set_var(buf->b_vars, name, value, false, true, arena, err); 464 } 465 466 /// Removes a buffer-scoped (b:) variable 467 /// 468 /// @deprecated 469 /// 470 /// @param buffer Buffer id, or 0 for current buffer 471 /// @param name Variable name 472 /// @param[out] err Error details, if any 473 /// @return Old value 474 Object buffer_del_var(Buffer buffer, String name, Arena *arena, Error *err) 475 FUNC_API_DEPRECATED_SINCE(1) 476 { 477 buf_T *buf = find_buffer_by_handle(buffer, err); 478 479 if (!buf) { 480 return NIL; 481 } 482 483 return dict_set_var(buf->b_vars, name, NIL, true, true, arena, err); 484 } 485 486 /// Sets a window-scoped (w:) variable 487 /// 488 /// @deprecated 489 /// 490 /// @param window |window-ID|, or 0 for current window 491 /// @param name Variable name 492 /// @param value Variable value 493 /// @param[out] err Error details, if any 494 /// @return Old value or nil if there was no previous value. 495 /// 496 /// @warning It may return nil if there was no previous value 497 /// or if previous value was `v:null`. 498 Object window_set_var(Window window, String name, Object value, Arena *arena, Error *err) 499 FUNC_API_DEPRECATED_SINCE(1) 500 { 501 win_T *win = find_window_by_handle(window, err); 502 503 if (!win) { 504 return NIL; 505 } 506 507 return dict_set_var(win->w_vars, name, value, false, true, arena, err); 508 } 509 510 /// Removes a window-scoped (w:) variable 511 /// 512 /// @deprecated 513 /// 514 /// @param window |window-ID|, or 0 for current window 515 /// @param name variable name 516 /// @param[out] err Error details, if any 517 /// @return Old value 518 Object window_del_var(Window window, String name, Arena *arena, Error *err) 519 FUNC_API_DEPRECATED_SINCE(1) 520 { 521 win_T *win = find_window_by_handle(window, err); 522 523 if (!win) { 524 return NIL; 525 } 526 527 return dict_set_var(win->w_vars, name, NIL, true, true, arena, err); 528 } 529 530 /// Sets a tab-scoped (t:) variable 531 /// 532 /// @deprecated 533 /// 534 /// @param tabpage |tab-ID|, or 0 for current tabpage 535 /// @param name Variable name 536 /// @param value Variable value 537 /// @param[out] err Error details, if any 538 /// @return Old value or nil if there was no previous value. 539 /// 540 /// @warning It may return nil if there was no previous value 541 /// or if previous value was `v:null`. 542 Object tabpage_set_var(Tabpage tabpage, String name, Object value, Arena *arena, Error *err) 543 FUNC_API_DEPRECATED_SINCE(1) 544 { 545 tabpage_T *tab = find_tab_by_handle(tabpage, err); 546 547 if (!tab) { 548 return NIL; 549 } 550 551 return dict_set_var(tab->tp_vars, name, value, false, true, arena, err); 552 } 553 554 /// Removes a tab-scoped (t:) variable 555 /// 556 /// @deprecated 557 /// 558 /// @param tabpage |tab-ID|, or 0 for current tabpage 559 /// @param name Variable name 560 /// @param[out] err Error details, if any 561 /// @return Old value 562 Object tabpage_del_var(Tabpage tabpage, String name, Arena *arena, Error *err) 563 FUNC_API_DEPRECATED_SINCE(1) 564 { 565 tabpage_T *tab = find_tab_by_handle(tabpage, err); 566 567 if (!tab) { 568 return NIL; 569 } 570 571 return dict_set_var(tab->tp_vars, name, NIL, true, true, arena, err); 572 } 573 574 /// @deprecated 575 /// @see nvim_set_var 576 /// @warning May return nil if there was no previous value 577 /// OR if previous value was `v:null`. 578 /// @return Old value or nil if there was no previous value. 579 Object vim_set_var(String name, Object value, Arena *arena, Error *err) 580 FUNC_API_DEPRECATED_SINCE(1) 581 { 582 return dict_set_var(get_globvar_dict(), name, value, false, true, arena, err); 583 } 584 585 /// @deprecated 586 /// @see nvim_del_var 587 Object vim_del_var(String name, Arena *arena, Error *err) 588 FUNC_API_DEPRECATED_SINCE(1) 589 { 590 return dict_set_var(get_globvar_dict(), name, NIL, true, true, arena, err); 591 } 592 593 static int64_t convert_index(int64_t index) 594 { 595 return index < 0 ? index - 1 : index; 596 } 597 598 /// Gets the option information for one option 599 /// 600 /// @deprecated Use @ref nvim_get_option_info2 instead. 601 /// 602 /// @param name Option name 603 /// @param[out] err Error details, if any 604 /// @return Option Information 605 DictAs(get_option_info) nvim_get_option_info(String name, Arena *arena, Error *err) 606 FUNC_API_SINCE(7) 607 FUNC_API_DEPRECATED_SINCE(11) 608 { 609 return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, arena, err); 610 } 611 612 /// Sets the global value of an option. 613 /// 614 /// @deprecated 615 /// @param channel_id 616 /// @param name Option name 617 /// @param value New option value 618 /// @param[out] err Error details, if any 619 void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err) 620 FUNC_API_SINCE(1) 621 FUNC_API_DEPRECATED_SINCE(11) 622 { 623 set_option_to(channel_id, NULL, kOptScopeGlobal, name, value, err); 624 } 625 626 /// Gets the global value of an option. 627 /// 628 /// @deprecated 629 /// @param name Option name 630 /// @param[out] err Error details, if any 631 /// @return Option value (global) 632 Object nvim_get_option(String name, Error *err) 633 FUNC_API_SINCE(1) 634 FUNC_API_DEPRECATED_SINCE(11) 635 FUNC_API_RET_ALLOC 636 { 637 return get_option_from(NULL, kOptScopeGlobal, name, err); 638 } 639 640 /// Gets a buffer option value 641 /// 642 /// @deprecated 643 /// @param buffer Buffer id, or 0 for current buffer 644 /// @param name Option name 645 /// @param[out] err Error details, if any 646 /// @return Option value 647 Object nvim_buf_get_option(Buffer buffer, String name, Error *err) 648 FUNC_API_SINCE(1) 649 FUNC_API_DEPRECATED_SINCE(11) 650 FUNC_API_RET_ALLOC 651 { 652 buf_T *buf = find_buffer_by_handle(buffer, err); 653 654 if (!buf) { 655 return (Object)OBJECT_INIT; 656 } 657 658 return get_option_from(buf, kOptScopeBuf, name, err); 659 } 660 661 /// Sets a buffer option value. Passing `nil` as value deletes the option (only 662 /// works if there's a global fallback) 663 /// 664 /// @deprecated 665 /// @param channel_id 666 /// @param buffer Buffer id, or 0 for current buffer 667 /// @param name Option name 668 /// @param value Option value 669 /// @param[out] err Error details, if any 670 void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object value, Error *err) 671 FUNC_API_SINCE(1) 672 FUNC_API_DEPRECATED_SINCE(11) 673 { 674 buf_T *buf = find_buffer_by_handle(buffer, err); 675 676 if (!buf) { 677 return; 678 } 679 680 set_option_to(channel_id, buf, kOptScopeBuf, name, value, err); 681 } 682 683 /// Gets a window option value 684 /// 685 /// @deprecated 686 /// @param window |window-ID|, or 0 for current window 687 /// @param name Option name 688 /// @param[out] err Error details, if any 689 /// @return Option value 690 Object nvim_win_get_option(Window window, String name, Error *err) 691 FUNC_API_SINCE(1) 692 FUNC_API_DEPRECATED_SINCE(11) 693 FUNC_API_RET_ALLOC 694 { 695 win_T *win = find_window_by_handle(window, err); 696 697 if (!win) { 698 return (Object)OBJECT_INIT; 699 } 700 701 return get_option_from(win, kOptScopeWin, name, err); 702 } 703 704 /// Sets a window option value. Passing `nil` as value deletes the option (only 705 /// works if there's a global fallback) 706 /// 707 /// @deprecated 708 /// @param channel_id 709 /// @param window |window-ID|, or 0 for current window 710 /// @param name Option name 711 /// @param value Option value 712 /// @param[out] err Error details, if any 713 void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object value, Error *err) 714 FUNC_API_SINCE(1) 715 FUNC_API_DEPRECATED_SINCE(11) 716 { 717 win_T *win = find_window_by_handle(window, err); 718 719 if (!win) { 720 return; 721 } 722 723 set_option_to(channel_id, win, kOptScopeWin, name, value, err); 724 } 725 726 /// Gets the value of a global or local (buffer, window) option. 727 /// 728 /// @param[in] from Pointer to buffer or window for local option value. 729 /// @param scope Option scope. See OptScope in option.h. 730 /// @param name The option name. 731 /// @param[out] err Details of an error that may have occurred. 732 /// 733 /// @return the option value. Must be freed by caller. 734 static Object get_option_from(void *from, OptScope scope, String name, Error *err) 735 { 736 VALIDATE_S(name.size > 0, "option name", "<empty>", { 737 return (Object)OBJECT_INIT; 738 }); 739 740 OptIndex opt_idx = find_option(name.data); 741 VALIDATE_S(opt_idx != kOptInvalid, "option name", name.data, { 742 return (Object)OBJECT_INIT; 743 }); 744 745 OptVal value = NIL_OPTVAL; 746 747 if (option_has_scope(opt_idx, scope)) { 748 value = get_option_value_for(opt_idx, scope == kOptScopeGlobal ? OPT_GLOBAL : OPT_LOCAL, 749 scope, from, err); 750 if (ERROR_SET(err)) { 751 return (Object)OBJECT_INIT; 752 } 753 } 754 755 VALIDATE_S(value.type != kOptValTypeNil, "option name", name.data, { 756 return (Object)OBJECT_INIT; 757 }); 758 759 return optval_as_object(value); 760 } 761 762 /// Sets the value of a global or local (buffer, window) option. 763 /// 764 /// @param[in] to Pointer to buffer or window for local option value. 765 /// @param scope Option scope. See OptScope in option.h. 766 /// @param name The option name. 767 /// @param value New option value. 768 /// @param[out] err Details of an error that may have occurred. 769 static void set_option_to(uint64_t channel_id, void *to, OptScope scope, String name, Object value, 770 Error *err) 771 { 772 VALIDATE_S(name.size > 0, "option name", "<empty>", { 773 return; 774 }); 775 776 OptIndex opt_idx = find_option(name.data); 777 VALIDATE_S(opt_idx != kOptInvalid, "option name", name.data, { 778 return; 779 }); 780 781 bool error = false; 782 OptVal optval = object_as_optval(value, &error); 783 784 // Handle invalid option value type. 785 // Don't use `name` in the error message here, because `name` can be any String. 786 // No need to check if value type actually matches the types for the option, as set_option_value() 787 // already handles that. 788 VALIDATE_EXP(!error, "value", "valid option type", api_typename(value.type), { 789 return; 790 }); 791 792 // For global-win-local options -> setlocal 793 // For win-local options -> setglobal and setlocal (opt_flags == 0) 794 const int opt_flags 795 = (scope == kOptScopeWin && !option_has_scope(opt_idx, kOptScopeGlobal)) 796 ? 0 797 : ((scope == kOptScopeGlobal) ? OPT_GLOBAL : OPT_LOCAL); 798 799 WITH_SCRIPT_CONTEXT(channel_id, { 800 set_option_value_for(name.data, opt_idx, optval, opt_flags, scope, to, err); 801 }); 802 } 803 804 /// @deprecated Use nvim_exec_lua() instead. 805 /// 806 /// Calls many API methods atomically. 807 /// 808 /// This has two main usages: 809 /// 1. To perform several requests from an async context atomically, i.e. 810 /// without interleaving redraws, RPC requests from other clients, or user 811 /// interactions (however API methods may trigger autocommands or event 812 /// processing which have such side effects, e.g. |:sleep| may wake timers). 813 /// 2. To minimize RPC overhead (roundtrips) of a sequence of many requests. 814 /// 815 /// @param channel_id 816 /// @param calls an array of calls, where each call is described by an array 817 /// with two elements: the request name, and an array of arguments. 818 /// @param[out] err Validation error details (malformed `calls` parameter), 819 /// if any. Errors from batched calls are given in the return value. 820 /// 821 /// @return Array of two elements. The first is an array of return 822 /// values. The second is NIL if all calls succeeded. If a call resulted in 823 /// an error, it is a three-element array with the zero-based index of the call 824 /// which resulted in an error, the error type and the error message. If an 825 /// error occurred, the values from all preceding calls will still be returned. 826 Array nvim_call_atomic(uint64_t channel_id, Array calls, Arena *arena, Error *err) 827 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(12) FUNC_API_REMOTE_ONLY 828 { 829 Array rv = arena_array(arena, 2); 830 Array results = arena_array(arena, calls.size); 831 Error nested_error = ERROR_INIT; 832 833 size_t i; // also used for freeing the variables 834 for (i = 0; i < calls.size; i++) { 835 VALIDATE_T("'calls' item", kObjectTypeArray, calls.items[i].type, { 836 goto theend; 837 }); 838 Array call = calls.items[i].data.array; 839 VALIDATE_EXP((call.size == 2), "'calls' item", "2-item Array", NULL, { 840 goto theend; 841 }); 842 VALIDATE_T("name", kObjectTypeString, call.items[0].type, { 843 goto theend; 844 }); 845 String name = call.items[0].data.string; 846 VALIDATE_T("call args", kObjectTypeArray, call.items[1].type, { 847 goto theend; 848 }); 849 Array args = call.items[1].data.array; 850 851 MsgpackRpcRequestHandler handler = 852 msgpack_rpc_get_handler_for(name.data, 853 name.size, 854 &nested_error); 855 856 if (ERROR_SET(&nested_error)) { 857 break; 858 } 859 860 Object result = handler.fn(channel_id, args, arena, &nested_error); 861 if (ERROR_SET(&nested_error)) { 862 // error handled after loop 863 break; 864 } 865 // TODO(bfredl): wasteful copy. It could be avoided to encoding to msgpack 866 // directly here. But `result` might become invalid when next api function 867 // is called in the loop. 868 ADD_C(results, copy_object(result, arena)); 869 if (handler.ret_alloc) { 870 api_free_object(result); 871 } 872 } 873 874 ADD_C(rv, ARRAY_OBJ(results)); 875 if (ERROR_SET(&nested_error)) { 876 Array errval = arena_array(arena, 3); 877 ADD_C(errval, INTEGER_OBJ((Integer)i)); 878 ADD_C(errval, INTEGER_OBJ(nested_error.type)); 879 ADD_C(errval, STRING_OBJ(copy_string(cstr_as_string(nested_error.msg), arena))); 880 ADD_C(rv, ARRAY_OBJ(errval)); 881 } else { 882 ADD_C(rv, NIL); 883 } 884 885 theend: 886 api_clear_error(&nested_error); 887 return rv; 888 } 889 890 /// @deprecated 891 /// 892 /// @param channel_id Channel id (passed automatically by the dispatcher) 893 /// @param event Event type string 894 void nvim_subscribe(uint64_t channel_id, String event) 895 // XXX: c_grammar.lua is order-sensitive. 896 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) FUNC_API_REMOTE_ONLY 897 { 898 // Does nothing. `rpcnotify(0,…)` broadcasts to all channels, there are no "subscriptions". 899 } 900 901 /// @deprecated 902 /// 903 /// @param channel_id Channel id (passed automatically by the dispatcher) 904 /// @param event Event type string 905 void nvim_unsubscribe(uint64_t channel_id, String event) 906 // XXX: c_grammar.lua is order-sensitive. 907 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) FUNC_API_REMOTE_ONLY 908 { 909 // Does nothing. `rpcnotify(0,…)` broadcasts to all channels, there are no "subscriptions". 910 } 911 912 enum { LINE_BUFFER_MIN_SIZE = 4096, }; 913 914 /// Writes a message to vim output or error buffer. The string is split 915 /// and flushed after each newline. Incomplete lines are kept for writing 916 /// later. 917 /// 918 /// @param message Message to write 919 /// @param to_err true: message is an error (uses `emsg` instead of `msg`) 920 /// @param writeln Append a trailing newline 921 static void write_msg(String message, bool to_err, bool writeln) 922 { 923 static StringBuilder out_line_buf = KV_INITIAL_VALUE; 924 static StringBuilder err_line_buf = KV_INITIAL_VALUE; 925 StringBuilder *line_buf = to_err ? &err_line_buf : &out_line_buf; 926 927 #define PUSH_CHAR(c) \ 928 if (kv_max(*line_buf) == 0) { \ 929 kv_resize(*line_buf, LINE_BUFFER_MIN_SIZE); \ 930 } \ 931 if (c == NL) { \ 932 kv_push(*line_buf, NUL); \ 933 if (to_err) { \ 934 emsg(line_buf->items); \ 935 } else { \ 936 msg(line_buf->items, 0); \ 937 } \ 938 if (msg_silent == 0) { \ 939 msg_didout = true; \ 940 } \ 941 kv_drop(*line_buf, kv_size(*line_buf)); \ 942 kv_resize(*line_buf, LINE_BUFFER_MIN_SIZE); \ 943 } else if (c == NUL) { \ 944 kv_push(*line_buf, NL); \ 945 } else { \ 946 kv_push(*line_buf, c); \ 947 } 948 949 no_wait_return++; 950 for (uint32_t i = 0; i < message.size; i++) { 951 if (got_int) { 952 break; 953 } 954 PUSH_CHAR(message.data[i]); 955 } 956 if (writeln) { 957 PUSH_CHAR(NL); 958 } 959 no_wait_return--; 960 msg_end(); 961 } 962 963 /// @deprecated 964 /// 965 /// @param str Message 966 void nvim_out_write(String str) 967 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) 968 { 969 write_msg(str, false, false); 970 } 971 972 /// @deprecated 973 /// 974 /// @param str Message 975 void nvim_err_write(String str) 976 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) 977 { 978 write_msg(str, true, false); 979 } 980 981 /// @deprecated 982 /// 983 /// @param str Message 984 void nvim_err_writeln(String str) 985 FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) 986 { 987 write_msg(str, true, true); 988 } 989 990 /// @deprecated 991 /// 992 /// Use `nvim_echo` or `nvim_exec_lua("vim.notify(...)", ...)` instead. 993 /// 994 /// @param msg Message to display to the user 995 /// @param log_level The log level 996 /// @param opts Reserved for future use. 997 /// @param[out] err Error details, if any 998 Object nvim_notify(String msg, Integer log_level, Dict opts, Arena *arena, Error *err) 999 FUNC_API_SINCE(7) FUNC_API_DEPRECATED_SINCE(13) 1000 { 1001 MAXSIZE_TEMP_ARRAY(args, 3); 1002 ADD_C(args, STRING_OBJ(msg)); 1003 ADD_C(args, INTEGER_OBJ(log_level)); 1004 ADD_C(args, DICT_OBJ(opts)); 1005 1006 return NLUA_EXEC_STATIC("return vim.notify(...)", args, kRetObject, arena, err); 1007 }