mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	Merge pull request #27534 from bfredl/userarena
refactor(api): next PR to make use of the arena
This commit is contained in:
		| @@ -1166,10 +1166,10 @@ err: | |||||||
| /// @param[out]  err   Error details, if any. | /// @param[out]  err   Error details, if any. | ||||||
| /// | /// | ||||||
| /// @returns Map of maps describing commands. | /// @returns Map of maps describing commands. | ||||||
| Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err) | Dictionary nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(4) |   FUNC_API_SINCE(4) | ||||||
| { | { | ||||||
|   return nvim_buf_get_commands(-1, opts, err); |   return nvim_buf_get_commands(-1, opts, arena, err); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Gets a map of buffer-local |user-commands|. | /// Gets a map of buffer-local |user-commands|. | ||||||
| @@ -1179,7 +1179,7 @@ Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err) | |||||||
| /// @param[out]  err   Error details, if any. | /// @param[out]  err   Error details, if any. | ||||||
| /// | /// | ||||||
| /// @returns Map of maps describing commands. | /// @returns Map of maps describing commands. | ||||||
| Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error *err) | Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(4) |   FUNC_API_SINCE(4) | ||||||
| { | { | ||||||
|   bool global = (buffer == -1); |   bool global = (buffer == -1); | ||||||
| @@ -1192,12 +1192,12 @@ Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error | |||||||
|       api_set_error(err, kErrorTypeValidation, "builtin=true not implemented"); |       api_set_error(err, kErrorTypeValidation, "builtin=true not implemented"); | ||||||
|       return (Dictionary)ARRAY_DICT_INIT; |       return (Dictionary)ARRAY_DICT_INIT; | ||||||
|     } |     } | ||||||
|     return commands_array(NULL); |     return commands_array(NULL, arena); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   buf_T *buf = find_buffer_by_handle(buffer, err); |   buf_T *buf = find_buffer_by_handle(buffer, err); | ||||||
|   if (opts->builtin || !buf) { |   if (opts->builtin || !buf) { | ||||||
|     return (Dictionary)ARRAY_DICT_INIT; |     return (Dictionary)ARRAY_DICT_INIT; | ||||||
|   } |   } | ||||||
|   return commands_array(buf); |   return commands_array(buf, arena); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -456,9 +456,10 @@ String ga_take_string(garray_T *ga) | |||||||
| /// @param input  Binary string | /// @param input  Binary string | ||||||
| /// @param crlf  Also break lines at CR and CRLF. | /// @param crlf  Also break lines at CR and CRLF. | ||||||
| /// @return [allocated] String array | /// @return [allocated] String array | ||||||
| Array string_to_array(const String input, bool crlf) | Array string_to_array(const String input, bool crlf, Arena *arena) | ||||||
| { | { | ||||||
|   Array ret = ARRAY_DICT_INIT; |   ArrayBuilder ret = ARRAY_DICT_INIT; | ||||||
|  |   kvi_init(ret); | ||||||
|   for (size_t i = 0; i < input.size; i++) { |   for (size_t i = 0; i < input.size; i++) { | ||||||
|     const char *start = input.data + i; |     const char *start = input.data + i; | ||||||
|     const char *end = start; |     const char *end = start; | ||||||
| @@ -473,20 +474,17 @@ Array string_to_array(const String input, bool crlf) | |||||||
|     if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) { |     if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) { | ||||||
|       i += 1;  // Advance past CRLF. |       i += 1;  // Advance past CRLF. | ||||||
|     } |     } | ||||||
|     String s = { |     String s = CBUF_TO_ARENA_STR(arena, start, line_len); | ||||||
|       .size = line_len, |  | ||||||
|       .data = xmemdupz(start, line_len), |  | ||||||
|     }; |  | ||||||
|     memchrsub(s.data, NUL, NL, line_len); |     memchrsub(s.data, NUL, NL, line_len); | ||||||
|     ADD(ret, STRING_OBJ(s)); |     kvi_push(ret, STRING_OBJ(s)); | ||||||
|     // If line ends at end-of-buffer, add empty final item. |     // If line ends at end-of-buffer, add empty final item. | ||||||
|     // This is "readfile()-style", see also ":help channel-lines". |     // This is "readfile()-style", see also ":help channel-lines". | ||||||
|     if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) { |     if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) { | ||||||
|       ADD(ret, STRING_OBJ(STRING_INIT)); |       kvi_push(ret, STRING_OBJ(STRING_INIT)); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return ret; |   return arena_take_arraybuilder(arena, &ret); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Normalizes 0-based indexes to buffer line numbers. | /// Normalizes 0-based indexes to buffer line numbers. | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ | |||||||
| /// @param tabpage  Tabpage handle, or 0 for current tabpage | /// @param tabpage  Tabpage handle, or 0 for current tabpage | ||||||
| /// @param[out] err Error details, if any | /// @param[out] err Error details, if any | ||||||
| /// @return List of windows in `tabpage` | /// @return List of windows in `tabpage` | ||||||
| ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) | ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(1) |   FUNC_API_SINCE(1) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   Array rv = ARRAY_DICT_INIT; | ||||||
| @@ -29,15 +29,15 @@ ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) | |||||||
|     return rv; |     return rv; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   size_t n = 0; | ||||||
|   FOR_ALL_WINDOWS_IN_TAB(wp, tab) { |   FOR_ALL_WINDOWS_IN_TAB(wp, tab) { | ||||||
|     rv.size++; |     n++; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   rv.items = xmalloc(sizeof(Object) * rv.size); |   rv = arena_array(arena, n); | ||||||
|   size_t i = 0; |  | ||||||
|  |  | ||||||
|   FOR_ALL_WINDOWS_IN_TAB(wp, tab) { |   FOR_ALL_WINDOWS_IN_TAB(wp, tab) { | ||||||
|     rv.items[i++] = WINDOW_OBJ(wp->handle); |     ADD_C(rv, WINDOW_OBJ(wp->handle)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return rv; |   return rv; | ||||||
|   | |||||||
| @@ -543,17 +543,22 @@ Integer nvim_strwidth(String text, Error *err) | |||||||
| /// Gets the paths contained in |runtime-search-path|. | /// Gets the paths contained in |runtime-search-path|. | ||||||
| /// | /// | ||||||
| /// @return List of paths | /// @return List of paths | ||||||
| ArrayOf(String) nvim_list_runtime_paths(Error *err) | ArrayOf(String) nvim_list_runtime_paths(Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(1) |   FUNC_API_SINCE(1) | ||||||
| { | { | ||||||
|   return nvim_get_runtime_file(NULL_STRING, true, err); |   return nvim_get_runtime_file(NULL_STRING, true, arena, err); | ||||||
| } | } | ||||||
|  |  | ||||||
| Array nvim__runtime_inspect(void) | Array nvim__runtime_inspect(Arena *arena) | ||||||
| { | { | ||||||
|   return runtime_inspect(); |   return runtime_inspect(arena); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | typedef struct { | ||||||
|  |   ArrayBuilder rv; | ||||||
|  |   Arena *arena; | ||||||
|  | } RuntimeCookie; | ||||||
|  |  | ||||||
| /// Find files in runtime directories | /// Find files in runtime directories | ||||||
| /// | /// | ||||||
| /// "name" can contain wildcards. For example | /// "name" can contain wildcards. For example | ||||||
| @@ -566,25 +571,27 @@ Array nvim__runtime_inspect(void) | |||||||
| /// @param name pattern of files to search for | /// @param name pattern of files to search for | ||||||
| /// @param all whether to return all matches or only the first | /// @param all whether to return all matches or only the first | ||||||
| /// @return list of absolute paths to the found files | /// @return list of absolute paths to the found files | ||||||
| ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err) | ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(7) |   FUNC_API_SINCE(7) | ||||||
|   FUNC_API_FAST |   FUNC_API_FAST | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   RuntimeCookie cookie = { .rv = ARRAY_DICT_INIT, .arena = arena, }; | ||||||
|  |   kvi_init(cookie.rv); | ||||||
|  |  | ||||||
|   int flags = DIP_DIRFILE | (all ? DIP_ALL : 0); |   int flags = DIP_DIRFILE | (all ? DIP_ALL : 0); | ||||||
|  |  | ||||||
|   TRY_WRAP(err, { |   TRY_WRAP(err, { | ||||||
|     do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &rv); |     do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie); | ||||||
|   }); |   }); | ||||||
|   return rv; |   return arena_take_arraybuilder(arena, &cookie.rv); | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *cookie) | static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *c) | ||||||
| { | { | ||||||
|   Array *rv = (Array *)cookie; |   RuntimeCookie *cookie = (RuntimeCookie *)c; | ||||||
|   for (int i = 0; i < num_fnames; i++) { |   for (int i = 0; i < num_fnames; i++) { | ||||||
|     ADD(*rv, CSTR_TO_OBJ(fnames[i])); |     // TODO(bfredl): consider memory management of gen_expand_wildcards() itself | ||||||
|  |     kvi_push(cookie->rv, CSTR_TO_ARENA_OBJ(cookie->arena, fnames[i])); | ||||||
|     if (!all) { |     if (!all) { | ||||||
|       return true; |       return true; | ||||||
|     } |     } | ||||||
| @@ -825,20 +832,19 @@ void nvim_err_writeln(String str) | |||||||
| /// Use |nvim_buf_is_loaded()| to check if a buffer is loaded. | /// Use |nvim_buf_is_loaded()| to check if a buffer is loaded. | ||||||
| /// | /// | ||||||
| /// @return List of buffer handles | /// @return List of buffer handles | ||||||
| ArrayOf(Buffer) nvim_list_bufs(void) | ArrayOf(Buffer) nvim_list_bufs(Arena *arena) | ||||||
|   FUNC_API_SINCE(1) |   FUNC_API_SINCE(1) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   size_t n = 0; | ||||||
|  |  | ||||||
|   FOR_ALL_BUFFERS(b) { |   FOR_ALL_BUFFERS(b) { | ||||||
|     rv.size++; |     n++; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   rv.items = xmalloc(sizeof(Object) * rv.size); |   Array rv = arena_array(arena, n); | ||||||
|   size_t i = 0; |  | ||||||
|  |  | ||||||
|   FOR_ALL_BUFFERS(b) { |   FOR_ALL_BUFFERS(b) { | ||||||
|     rv.items[i++] = BUFFER_OBJ(b->handle); |     ADD_C(rv, BUFFER_OBJ(b->handle)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return rv; |   return rv; | ||||||
| @@ -880,20 +886,19 @@ void nvim_set_current_buf(Buffer buffer, Error *err) | |||||||
| /// Gets the current list of window handles. | /// Gets the current list of window handles. | ||||||
| /// | /// | ||||||
| /// @return List of window handles | /// @return List of window handles | ||||||
| ArrayOf(Window) nvim_list_wins(void) | ArrayOf(Window) nvim_list_wins(Arena *arena) | ||||||
|   FUNC_API_SINCE(1) |   FUNC_API_SINCE(1) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   size_t n = 0; | ||||||
|  |  | ||||||
|   FOR_ALL_TAB_WINDOWS(tp, wp) { |   FOR_ALL_TAB_WINDOWS(tp, wp) { | ||||||
|     rv.size++; |     n++; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   rv.items = xmalloc(sizeof(Object) * rv.size); |   Array rv = arena_array(arena, n); | ||||||
|   size_t i = 0; |  | ||||||
|  |  | ||||||
|   FOR_ALL_TAB_WINDOWS(tp, wp) { |   FOR_ALL_TAB_WINDOWS(tp, wp) { | ||||||
|     rv.items[i++] = WINDOW_OBJ(wp->handle); |     ADD_C(rv, WINDOW_OBJ(wp->handle)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return rv; |   return rv; | ||||||
| @@ -1117,20 +1122,19 @@ void nvim_chan_send(Integer chan, String data, Error *err) | |||||||
| /// Gets the current list of tabpage handles. | /// Gets the current list of tabpage handles. | ||||||
| /// | /// | ||||||
| /// @return List of tabpage handles | /// @return List of tabpage handles | ||||||
| ArrayOf(Tabpage) nvim_list_tabpages(void) | ArrayOf(Tabpage) nvim_list_tabpages(Arena *arena) | ||||||
|   FUNC_API_SINCE(1) |   FUNC_API_SINCE(1) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   size_t n = 0; | ||||||
|  |  | ||||||
|   FOR_ALL_TABS(tp) { |   FOR_ALL_TABS(tp) { | ||||||
|     rv.size++; |     n++; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   rv.items = xmalloc(sizeof(Object) * rv.size); |   Array rv = arena_array(arena, n); | ||||||
|   size_t i = 0; |  | ||||||
|  |  | ||||||
|   FOR_ALL_TABS(tp) { |   FOR_ALL_TABS(tp) { | ||||||
|     rv.items[i++] = TABPAGE_OBJ(tp->handle); |     ADD_C(rv, TABPAGE_OBJ(tp->handle)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   return rv; |   return rv; | ||||||
| @@ -1201,14 +1205,13 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error | |||||||
|   VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { |   VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { | ||||||
|     return false; |     return false; | ||||||
|   }); |   }); | ||||||
|   Array lines = ARRAY_DICT_INIT; |  | ||||||
|   if (phase == -1 || phase == 1) {  // Start of paste-stream. |   if (phase == -1 || phase == 1) {  // Start of paste-stream. | ||||||
|     draining = false; |     draining = false; | ||||||
|   } else if (draining) { |   } else if (draining) { | ||||||
|     // Skip remaining chunks.  Report error only once per "stream". |     // Skip remaining chunks.  Report error only once per "stream". | ||||||
|     goto theend; |     goto theend; | ||||||
|   } |   } | ||||||
|   lines = string_to_array(data, crlf); |   Array lines = string_to_array(data, crlf, arena); | ||||||
|   MAXSIZE_TEMP_ARRAY(args, 2); |   MAXSIZE_TEMP_ARRAY(args, 2); | ||||||
|   ADD_C(args, ARRAY_OBJ(lines)); |   ADD_C(args, ARRAY_OBJ(lines)); | ||||||
|   ADD_C(args, INTEGER_OBJ(phase)); |   ADD_C(args, INTEGER_OBJ(phase)); | ||||||
| @@ -1239,7 +1242,6 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error | |||||||
|     AppendCharToRedobuff(ESC);  // Dot-repeat. |     AppendCharToRedobuff(ESC);  // Dot-repeat. | ||||||
|   } |   } | ||||||
| theend: | theend: | ||||||
|   api_free_array(lines); |  | ||||||
|   if (cancel || phase == -1 || phase == 3) {  // End of paste-stream. |   if (cancel || phase == -1 || phase == 3) {  // End of paste-stream. | ||||||
|     draining = false; |     draining = false; | ||||||
|   } |   } | ||||||
| @@ -1260,24 +1262,27 @@ theend: | |||||||
| /// @param after  If true insert after cursor (like |p|), or before (like |P|). | /// @param after  If true insert after cursor (like |p|), or before (like |P|). | ||||||
| /// @param follow  If true place cursor at end of inserted text. | /// @param follow  If true place cursor at end of inserted text. | ||||||
| /// @param[out] err Error details, if any | /// @param[out] err Error details, if any | ||||||
| void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err) | void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Arena *arena, | ||||||
|  |               Error *err) | ||||||
|   FUNC_API_SINCE(6) |   FUNC_API_SINCE(6) | ||||||
|   FUNC_API_TEXTLOCK_ALLOW_CMDWIN |   FUNC_API_TEXTLOCK_ALLOW_CMDWIN | ||||||
| { | { | ||||||
|   yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); |   yankreg_T reg[1] = { 0 }; | ||||||
|   VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { |   VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { | ||||||
|     goto cleanup; |     return; | ||||||
|   }); |   }); | ||||||
|   if (lines.size == 0) { |   if (lines.size == 0) { | ||||||
|     goto cleanup;  // Nothing to do. |     return;  // Nothing to do. | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   reg->y_array = arena_alloc(arena, lines.size * sizeof(uint8_t *), true); | ||||||
|  |   reg->y_size = lines.size; | ||||||
|   for (size_t i = 0; i < lines.size; i++) { |   for (size_t i = 0; i < lines.size; i++) { | ||||||
|     VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { |     VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { | ||||||
|       goto cleanup; |       return; | ||||||
|     }); |     }); | ||||||
|     String line = lines.items[i].data.string; |     String line = lines.items[i].data.string; | ||||||
|     reg->y_array[i] = xmemdupz(line.data, line.size); |     reg->y_array[i] = arena_memdupz(arena, line.data, line.size); | ||||||
|     memchrsub(reg->y_array[i], NUL, NL, line.size); |     memchrsub(reg->y_array[i], NUL, NL, line.size); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -1290,10 +1295,6 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, | |||||||
|     msg_silent--; |     msg_silent--; | ||||||
|     VIsual_active = VIsual_was_active; |     VIsual_active = VIsual_was_active; | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
| cleanup: |  | ||||||
|   free_register(reg); |  | ||||||
|   xfree(reg); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Subscribes to event broadcasts. | /// Subscribes to event broadcasts. | ||||||
| @@ -1583,13 +1584,12 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena) | |||||||
| /// | /// | ||||||
| /// @param[out] err Error details, if any | /// @param[out] err Error details, if any | ||||||
| void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type, | void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type, | ||||||
|                           Dictionary methods, Dictionary attributes, Error *err) |                           Dictionary methods, Dictionary attributes, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY |   FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY | ||||||
| { | { | ||||||
|   Dictionary info = ARRAY_DICT_INIT; |   MAXSIZE_TEMP_DICT(info, 5); | ||||||
|   PUT(info, "name", copy_object(STRING_OBJ(name), NULL)); |   PUT_C(info, "name", STRING_OBJ(name)); | ||||||
|  |  | ||||||
|   version = copy_dictionary(version, NULL); |  | ||||||
|   bool has_major = false; |   bool has_major = false; | ||||||
|   for (size_t i = 0; i < version.size; i++) { |   for (size_t i = 0; i < version.size; i++) { | ||||||
|     if (strequal(version.items[i].key.data, "major")) { |     if (strequal(version.items[i].key.data, "major")) { | ||||||
| @@ -1598,15 +1598,21 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   if (!has_major) { |   if (!has_major) { | ||||||
|     PUT(version, "major", INTEGER_OBJ(0)); |     Dictionary v = arena_dict(arena, version.size + 1); | ||||||
|  |     if (version.size) { | ||||||
|  |       memcpy(v.items, version.items, version.size * sizeof(v.items[0])); | ||||||
|  |       v.size = version.size; | ||||||
|     } |     } | ||||||
|   PUT(info, "version", DICTIONARY_OBJ(version)); |     PUT_C(v, "major", INTEGER_OBJ(0)); | ||||||
|  |     version = v; | ||||||
|  |   } | ||||||
|  |   PUT_C(info, "version", DICTIONARY_OBJ(version)); | ||||||
|  |  | ||||||
|   PUT(info, "type", copy_object(STRING_OBJ(type), NULL)); |   PUT_C(info, "type", STRING_OBJ(type)); | ||||||
|   PUT(info, "methods", DICTIONARY_OBJ(copy_dictionary(methods, NULL))); |   PUT_C(info, "methods", DICTIONARY_OBJ(methods)); | ||||||
|   PUT(info, "attributes", DICTIONARY_OBJ(copy_dictionary(attributes, NULL))); |   PUT_C(info, "attributes", DICTIONARY_OBJ(attributes)); | ||||||
|  |  | ||||||
|   rpc_set_client_info(channel_id, info); |   rpc_set_client_info(channel_id, copy_dictionary(info, NULL)); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Gets information about a channel. | /// Gets information about a channel. | ||||||
|   | |||||||
| @@ -6499,8 +6499,6 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines) | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   reg->y_array = xcalloc(lines, sizeof(uint8_t *)); |  | ||||||
|   reg->y_size = lines; |  | ||||||
|   reg->additional_data = NULL; |   reg->additional_data = NULL; | ||||||
|   reg->timestamp = 0; |   reg->timestamp = 0; | ||||||
|   return true; |   return true; | ||||||
| @@ -6513,7 +6511,6 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust) | |||||||
|     // but otherwise there is no line after the final newline |     // but otherwise there is no line after the final newline | ||||||
|     if (reg->y_type != kMTCharWise) { |     if (reg->y_type != kMTCharWise) { | ||||||
|       if (reg->y_type == kMTUnknown || clipboard_adjust) { |       if (reg->y_type == kMTUnknown || clipboard_adjust) { | ||||||
|         xfree(reg->y_array[reg->y_size - 1]); |  | ||||||
|         reg->y_size--; |         reg->y_size--; | ||||||
|       } |       } | ||||||
|       if (reg->y_type == kMTUnknown) { |       if (reg->y_type == kMTUnknown) { | ||||||
|   | |||||||
| @@ -574,20 +574,20 @@ static int do_in_cached_path(char *name, int flags, DoInRuntimepathCB callback, | |||||||
|   return did_one ? OK : FAIL; |   return did_one ? OK : FAIL; | ||||||
| } | } | ||||||
|  |  | ||||||
| Array runtime_inspect(void) | Array runtime_inspect(Arena *arena) | ||||||
| { | { | ||||||
|   RuntimeSearchPath path = runtime_search_path; |   RuntimeSearchPath path = runtime_search_path; | ||||||
|   Array rv = ARRAY_DICT_INIT; |   Array rv = arena_array(arena, kv_size(path)); | ||||||
|  |  | ||||||
|   for (size_t i = 0; i < kv_size(path); i++) { |   for (size_t i = 0; i < kv_size(path); i++) { | ||||||
|     SearchPathItem *item = &kv_A(path, i); |     SearchPathItem *item = &kv_A(path, i); | ||||||
|     Array entry = ARRAY_DICT_INIT; |     Array entry = ARRAY_DICT_INIT; | ||||||
|     ADD(entry, CSTR_TO_OBJ(item->path)); |     ADD_C(entry, CSTR_AS_OBJ(item->path)); | ||||||
|     ADD(entry, BOOLEAN_OBJ(item->after)); |     ADD_C(entry, BOOLEAN_OBJ(item->after)); | ||||||
|     if (item->has_lua != kNone) { |     if (item->has_lua != kNone) { | ||||||
|       ADD(entry, BOOLEAN_OBJ(item->has_lua == kTrue)); |       ADD_C(entry, BOOLEAN_OBJ(item->has_lua == kTrue)); | ||||||
|     } |     } | ||||||
|     ADD(rv, ARRAY_OBJ(entry)); |     ADD_C(rv, ARRAY_OBJ(entry)); | ||||||
|   } |   } | ||||||
|   return rv; |   return rv; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1744,25 +1744,24 @@ int do_ucmd(exarg_T *eap, bool preview) | |||||||
| /// @param buf  Buffer to inspect, or NULL to get global commands. | /// @param buf  Buffer to inspect, or NULL to get global commands. | ||||||
| /// | /// | ||||||
| /// @return Map of maps describing commands | /// @return Map of maps describing commands | ||||||
| Dictionary commands_array(buf_T *buf) | Dictionary commands_array(buf_T *buf, Arena *arena) | ||||||
| { | { | ||||||
|   Dictionary rv = ARRAY_DICT_INIT; |  | ||||||
|   char str[20]; |  | ||||||
|   garray_T *gap = (buf == NULL) ? &ucmds : &buf->b_ucmds; |   garray_T *gap = (buf == NULL) ? &ucmds : &buf->b_ucmds; | ||||||
|  |  | ||||||
|  |   Dictionary rv = arena_dict(arena, (size_t)gap->ga_len); | ||||||
|   for (int i = 0; i < gap->ga_len; i++) { |   for (int i = 0; i < gap->ga_len; i++) { | ||||||
|     char arg[2] = { 0, 0 }; |     char arg[2] = { 0, 0 }; | ||||||
|     Dictionary d = ARRAY_DICT_INIT; |     Dictionary d = arena_dict(arena, 14); | ||||||
|     ucmd_T *cmd = USER_CMD_GA(gap, i); |     ucmd_T *cmd = USER_CMD_GA(gap, i); | ||||||
|  |  | ||||||
|     PUT(d, "name", CSTR_TO_OBJ(cmd->uc_name)); |     PUT_C(d, "name", CSTR_AS_OBJ(cmd->uc_name)); | ||||||
|     PUT(d, "definition", CSTR_TO_OBJ(cmd->uc_rep)); |     PUT_C(d, "definition", CSTR_AS_OBJ(cmd->uc_rep)); | ||||||
|     PUT(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid)); |     PUT_C(d, "script_id", INTEGER_OBJ(cmd->uc_script_ctx.sc_sid)); | ||||||
|     PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_BANG))); |     PUT_C(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_BANG))); | ||||||
|     PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_TRLBAR))); |     PUT_C(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_TRLBAR))); | ||||||
|     PUT(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_REGSTR))); |     PUT_C(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_REGSTR))); | ||||||
|     PUT(d, "keepscript", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_KEEPSCRIPT))); |     PUT_C(d, "keepscript", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_KEEPSCRIPT))); | ||||||
|     PUT(d, "preview", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_PREVIEW))); |     PUT_C(d, "preview", BOOLEAN_OBJ(!!(cmd->uc_argt & EX_PREVIEW))); | ||||||
|  |  | ||||||
|     switch (cmd->uc_argt & (EX_EXTRA | EX_NOSPC | EX_NEEDARG)) { |     switch (cmd->uc_argt & (EX_EXTRA | EX_NOSPC | EX_NEEDARG)) { | ||||||
|     case 0: |     case 0: | ||||||
| @@ -1776,49 +1775,47 @@ Dictionary commands_array(buf_T *buf) | |||||||
|     case (EX_EXTRA | EX_NOSPC | EX_NEEDARG): |     case (EX_EXTRA | EX_NOSPC | EX_NEEDARG): | ||||||
|       arg[0] = '1'; break; |       arg[0] = '1'; break; | ||||||
|     } |     } | ||||||
|     PUT(d, "nargs", CSTR_TO_OBJ(arg)); |     PUT_C(d, "nargs", CSTR_TO_ARENA_OBJ(arena, arg)); | ||||||
|  |  | ||||||
|     char *cmd_compl = get_command_complete(cmd->uc_compl); |     char *cmd_compl = get_command_complete(cmd->uc_compl); | ||||||
|     PUT(d, "complete", (cmd_compl == NULL |     PUT_C(d, "complete", (cmd_compl == NULL | ||||||
|                         ? NIL : CSTR_TO_OBJ(cmd_compl))); |                           ? NIL : CSTR_AS_OBJ(cmd_compl))); | ||||||
|     PUT(d, "complete_arg", cmd->uc_compl_arg == NULL |     PUT_C(d, "complete_arg", cmd->uc_compl_arg == NULL | ||||||
|         ? NIL : CSTR_TO_OBJ(cmd->uc_compl_arg)); |           ? NIL : CSTR_AS_OBJ(cmd->uc_compl_arg)); | ||||||
|  |  | ||||||
|     Object obj = NIL; |     Object obj = NIL; | ||||||
|     if (cmd->uc_argt & EX_COUNT) { |     if (cmd->uc_argt & EX_COUNT) { | ||||||
|       if (cmd->uc_def >= 0) { |       if (cmd->uc_def >= 0) { | ||||||
|         snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def); |         obj = STRING_OBJ(arena_printf(arena, "%" PRId64, cmd->uc_def));    // -count=N | ||||||
|         obj = CSTR_TO_OBJ(str);    // -count=N |  | ||||||
|       } else { |       } else { | ||||||
|         obj = CSTR_TO_OBJ("0");    // -count |         obj = CSTR_AS_OBJ("0");    // -count | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     PUT(d, "count", obj); |     PUT_C(d, "count", obj); | ||||||
|  |  | ||||||
|     obj = NIL; |     obj = NIL; | ||||||
|     if (cmd->uc_argt & EX_RANGE) { |     if (cmd->uc_argt & EX_RANGE) { | ||||||
|       if (cmd->uc_argt & EX_DFLALL) { |       if (cmd->uc_argt & EX_DFLALL) { | ||||||
|         obj = CSTR_TO_OBJ("%");    // -range=% |         obj = STATIC_CSTR_AS_OBJ("%");    // -range=% | ||||||
|       } else if (cmd->uc_def >= 0) { |       } else if (cmd->uc_def >= 0) { | ||||||
|         snprintf(str, sizeof(str), "%" PRId64, cmd->uc_def); |         obj = STRING_OBJ(arena_printf(arena, "%" PRId64, cmd->uc_def));    // -range=N | ||||||
|         obj = CSTR_TO_OBJ(str);    // -range=N |  | ||||||
|       } else { |       } else { | ||||||
|         obj = CSTR_TO_OBJ(".");    // -range |         obj = STATIC_CSTR_AS_OBJ(".");    // -range | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     PUT(d, "range", obj); |     PUT_C(d, "range", obj); | ||||||
|  |  | ||||||
|     obj = NIL; |     obj = NIL; | ||||||
|     for (int j = 0; addr_type_complete[j].expand != ADDR_NONE; j++) { |     for (int j = 0; addr_type_complete[j].expand != ADDR_NONE; j++) { | ||||||
|       if (addr_type_complete[j].expand != ADDR_LINES |       if (addr_type_complete[j].expand != ADDR_LINES | ||||||
|           && addr_type_complete[j].expand == cmd->uc_addr_type) { |           && addr_type_complete[j].expand == cmd->uc_addr_type) { | ||||||
|         obj = CSTR_TO_OBJ(addr_type_complete[j].name); |         obj = CSTR_AS_OBJ(addr_type_complete[j].name); | ||||||
|         break; |         break; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     PUT(d, "addr", obj); |     PUT_C(d, "addr", obj); | ||||||
|  |  | ||||||
|     PUT(rv, cmd->uc_name, DICTIONARY_OBJ(d)); |     PUT_C(rv, cmd->uc_name, DICTIONARY_OBJ(d)); | ||||||
|   } |   } | ||||||
|   return rv; |   return rv; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 bfredl
					bfredl