diff options
Diffstat (limited to 'src/nvim')
240 files changed, 30968 insertions, 8321 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 7106f76a6e..29a4e1e163 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -399,6 +399,10 @@ if(JEMALLOC_FOUND) list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES}) endif() +if(POLICY CMP0069) + cmake_policy(SET CMP0069 NEW) +endif() + add_executable(nvim ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS} ${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_HEADERS}) target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) @@ -407,6 +411,14 @@ install_helper(TARGETS nvim) set_property(TARGET nvim APPEND PROPERTY INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS}) +if(ENABLE_LTO AND (POLICY CMP0069)) + include(CheckIPOSupported) + check_ipo_supported(RESULT IPO_SUPPORTED) + if(IPO_SUPPORTED AND (NOT CMAKE_BUILD_TYPE MATCHES Debug)) + set_property(TARGET nvim PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + endif() +endif() + if(WIN32) # Copy DLLs and third-party tools to bin/ and install them along with nvim add_custom_target(nvim_runtime_deps ALL @@ -648,4 +660,10 @@ add_custom_target( DEPENDS ${LINT_PRG} ${LINT_NVIM_SOURCES} ${LINT_SUPPRESS_FILE} ) +add_custom_target(generated-sources DEPENDS + ${NVIM_GENERATED_FOR_SOURCES} + ${NVIM_GENERATED_FOR_HEADERS} + ${NVIM_GENERATED_SOURCES} +) + add_subdirectory(po) diff --git a/src/nvim/README.md b/src/nvim/README.md index d668db0cdc..02464c2500 100644 --- a/src/nvim/README.md +++ b/src/nvim/README.md @@ -23,15 +23,19 @@ Logs Low-level log messages sink to `$NVIM_LOG_FILE`. -You can use `LOG_CALLSTACK();` anywhere in the source to log the current -stacktrace. To log in an alternate file, e.g. stderr, use -`LOG_CALLSTACK_TO_FILE(FILE*)`. (Currently Linux-only.) +Use `LOG_CALLSTACK()` (Linux only) to log the current stacktrace. To log to an +alternate file (e.g. stderr) use `LOG_CALLSTACK_TO_FILE(FILE*)`. -UI events are logged at level 0 (`DEBUG_LOG_LEVEL`). +UI events are logged at DEBUG level (`DEBUG_LOG_LEVEL`). rm -rf build/ make CMAKE_EXTRA_FLAGS="-DMIN_LOG_LEVEL=0" +Many log messages have a shared prefix, such as "UI" or "RPC". Use the shell to +filter the log, e.g. at DEBUG level you might want to exclude UI messages: + + tail -F ~/.local/share/nvim/log | cat -v | stdbuf -o0 grep -v UI | stdbuf -o0 tee -a log + Build with ASAN --------------- @@ -276,3 +280,25 @@ Since Nvim inherited its code from Vim, the states are not prepared to receive "arbitrary events", so we use a special key to represent those (When a state receives an "arbitrary event", it normally doesn't do anything other update the screen). + +Main loop +--------- + +The `Loop` structure (which describes `main_loop`) abstracts multiple queues +into one loop: + + uv_loop_t uv; + MultiQueue *events; + MultiQueue *thread_events; + MultiQueue *fast_events; + +`loop_poll_events` checks `Loop.uv` and `Loop.fast_events` whenever Nvim is +idle, and also at `os_breakcheck` intervals. + +MultiQueue is cool because you can attach throw-away "child queues" trivially. +For example `do_os_system()` does this (for every spawned process!) to +automatically route events onto the `main_loop`: + + Process *proc = &uvproc.process; + MultiQueue *events = multiqueue_new_child(main_loop.events); + proc->events = events; diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 8ff24b877e..487a912882 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -13,6 +13,7 @@ #include "nvim/api/private/defs.h" #include "nvim/vim.h" #include "nvim/buffer.h" +#include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/memline.h" #include "nvim/memory.h" @@ -31,11 +32,26 @@ # include "api/buffer.c.generated.h" #endif + +/// \defgroup api-buffer +/// +/// Unloaded Buffers:~ +/// +/// Buffers may be unloaded by the |:bunload| command or the buffer's +/// |'bufhidden'| option. When a buffer is unloaded its file contents are freed +/// from memory and vim cannot operate on the buffer lines until it is reloaded +/// (usually by opening the buffer again in a new window). API methods such as +/// |nvim_buf_get_lines()| and |nvim_buf_line_count()| will be affected. +/// +/// You can use |nvim_buf_is_loaded()| or |nvim_buf_line_count()| to check +/// whether a buffer is loaded. + + /// Gets the buffer line count /// /// @param buffer Buffer handle /// @param[out] err Error details, if any -/// @return Line count +/// @return Line count, or 0 for unloaded buffer. |api-buffer| Integer nvim_buf_line_count(Buffer buffer, Error *err) FUNC_API_SINCE(1) { @@ -45,6 +61,11 @@ Integer nvim_buf_line_count(Buffer buffer, Error *err) return 0; } + // return sentinel value if the buffer isn't loaded + if (buf->b_ml.ml_mfp == NULL) { + return 0; + } + return buf->b_ml.ml_line_count; } @@ -205,7 +226,7 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, /// @param end Last line index (exclusive) /// @param strict_indexing Whether out-of-bounds should be an error. /// @param[out] err Error details, if any -/// @return Array of lines +/// @return Array of lines, or empty array for unloaded buffer. ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, Buffer buffer, Integer start, @@ -221,6 +242,11 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, return rv; } + // return sentinel value if the buffer isn't loaded + if (buf->b_ml.ml_mfp == NULL) { + return rv; + } + bool oob = false; start = normalize_index(buf, start, &oob); end = normalize_index(buf, end, &oob); @@ -463,6 +489,41 @@ end: try_end(err); } +/// Returns the byte offset for a line. +/// +/// Line 1 (index=0) has offset 0. UTF-8 bytes are counted. EOL is one byte. +/// 'fileformat' and 'fileencoding' are ignored. The line index just after the +/// last line gives the total byte-count of the buffer. A final EOL byte is +/// counted if it would be written, see 'eol'. +/// +/// Unlike |line2byte()|, throws error for out-of-bounds indexing. +/// Returns -1 for unloaded buffer. +/// +/// @param buffer Buffer handle +/// @param index Line index +/// @param[out] err Error details, if any +/// @return Integer byte offset, or -1 for unloaded buffer. +Integer nvim_buf_get_offset(Buffer buffer, Integer index, Error *err) + FUNC_API_SINCE(5) +{ + buf_T *buf = find_buffer_by_handle(buffer, err); + if (!buf) { + return 0; + } + + // return sentinel value if the buffer isn't loaded + if (buf->b_ml.ml_mfp == NULL) { + return -1; + } + + if (index < 0 || index > buf->b_ml.ml_line_count) { + api_set_error(err, kErrorTypeValidation, "Index out of bounds"); + return 0; + } + + return ml_find_line_or_offset(buf, (int)index+1, NULL, true); +} + /// Gets a buffer-scoped (b:) variable. /// /// @param buffer Buffer handle @@ -745,10 +806,27 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err) } } -/// Checks if a buffer is valid +/// Checks if a buffer is valid and loaded. See |api-buffer| for more info +/// about unloaded buffers. +/// +/// @param buffer Buffer handle +/// @return true if the buffer is valid and loaded, false otherwise. +Boolean nvim_buf_is_loaded(Buffer buffer) + FUNC_API_SINCE(5) +{ + Error stub = ERROR_INIT; + buf_T *buf = find_buffer_by_handle(buffer, &stub); + api_clear_error(&stub); + return buf && buf->b_ml.ml_mfp != NULL; +} + +/// Checks if a buffer is valid. +/// +/// @note Even if a buffer is valid it may have been unloaded. See |api-buffer| +/// for more info about unloaded buffers. /// /// @param buffer Buffer handle -/// @return true if the buffer is valid, false otherwise +/// @return true if the buffer is valid, false otherwise. Boolean nvim_buf_is_valid(Buffer buffer) FUNC_API_SINCE(1) { @@ -889,7 +967,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, return src_id; } -/// Clears highlights from a given source group and a range of lines +/// Clears highlights and virtual text from a given source id and range of lines /// /// To clear a source group in the entire buffer, pass in 0 and -1 to /// line_start and line_end respectively. @@ -923,6 +1001,89 @@ void nvim_buf_clear_highlight(Buffer buffer, bufhl_clear_line_range(buf, (int)src_id, (int)line_start+1, (int)line_end); } + +/// Set the virtual text (annotation) for a buffer line. +/// +/// By default (and currently the only option) the text will be placed after +/// the buffer text. Virtual text will never cause reflow, rather virtual +/// text will be truncated at the end of the screen line. The virtual text will +/// begin after one cell to the right of the ordinary text, this will contain +/// the |lcs-eol| char if set, otherwise just be a space. +/// +/// The same src_id can be used for both virtual text and highlights added by +/// nvim_buf_add_highlight. Virtual text is cleared using +/// nvim_buf_clear_highlight. +/// +/// @param buffer Buffer handle +/// @param src_id Source group to use or 0 to use a new group, +/// or -1 for a ungrouped annotation +/// @param line Line to annotate with virtual text (zero-indexed) +/// @param chunks A list of [text, hl_group] arrays, each representing a +/// text chunk with specified highlight. `hl_group` element +/// can be omitted for no highlight. +/// @param opts Optional parameters. Currently not used. +/// @param[out] err Error details, if any +/// @return The src_id that was used +Integer nvim_buf_set_virtual_text(Buffer buffer, + Integer src_id, + Integer line, + Array chunks, + Dictionary opts, + Error *err) + FUNC_API_SINCE(5) +{ + buf_T *buf = find_buffer_by_handle(buffer, err); + if (!buf) { + return 0; + } + + if (line < 0 || line >= MAXLNUM) { + api_set_error(err, kErrorTypeValidation, "Line number outside range"); + return 0; + } + + if (opts.size > 0) { + api_set_error(err, kErrorTypeValidation, "opts dict isn't empty"); + return 0; + } + + VirtText virt_text = KV_INITIAL_VALUE; + for (size_t i = 0; i < chunks.size; i++) { + if (chunks.items[i].type != kObjectTypeArray) { + api_set_error(err, kErrorTypeValidation, "Chunk is not an array"); + goto free_exit; + } + Array chunk = chunks.items[i].data.array; + if (chunk.size == 0 || chunk.size > 2 + || chunk.items[0].type != kObjectTypeString + || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) { + api_set_error(err, kErrorTypeValidation, + "Chunk is not an array with one or two strings"); + goto free_exit; + } + + String str = chunk.items[0].data.string; + char *text = transstr(str.size > 0 ? str.data : ""); // allocates + + int hl_id = 0; + if (chunk.size == 2) { + String hl = chunk.items[1].data.string; + if (hl.size > 0) { + hl_id = syn_check_group((char_u *)hl.data, (int)hl.size); + } + } + kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id })); + } + + src_id = bufhl_add_virt_text(buf, (int)src_id, (linenr_T)line+1, + virt_text); + return src_id; + +free_exit: + kv_destroy(virt_text); + return 0; +} + // Check if deleting lines made the cursor position invalid. // Changed the lines from "lo" to "hi" and added "extra" lines (negative if // deleted). diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c index dec2b6c185..8492225a69 100644 --- a/src/nvim/api/private/dispatch.c +++ b/src/nvim/api/private/dispatch.c @@ -40,7 +40,8 @@ MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name, map_get(String, MsgpackRpcRequestHandler)(methods, m); if (!rv.fn) { - api_set_error(error, kErrorTypeException, "Invalid method: %s", + api_set_error(error, kErrorTypeException, "Invalid method: %.*s", + m.size > 0 ? (int)m.size : (int)sizeof("<empty>"), m.size > 0 ? m.data : "<empty>"); } return rv; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index f3e883de02..cd6060b5d2 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -162,7 +162,7 @@ Object dict_get_value(dict_T *dict, String key, Error *err) dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size); if (di == NULL) { - api_set_error(err, kErrorTypeValidation, "Key '%s' not found", key.data); + api_set_error(err, kErrorTypeValidation, "Key not found: %s", key.data); return (Object)OBJECT_INIT; } @@ -191,13 +191,12 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, } if (key.size == 0) { - api_set_error(err, kErrorTypeValidation, - "Empty variable names aren't allowed"); + api_set_error(err, kErrorTypeValidation, "Key name is empty"); return rv; } if (key.size > INT_MAX) { - api_set_error(err, kErrorTypeValidation, "Key length is too high"); + api_set_error(err, kErrorTypeValidation, "Key name is too long"); return rv; } @@ -220,7 +219,7 @@ Object dict_set_var(dict_T *dict, String key, Object value, bool del, // Delete the key if (di == NULL) { // Doesn't exist, fail - api_set_error(err, kErrorTypeValidation, "Key does not exist: %s", + api_set_error(err, kErrorTypeValidation, "Key not found: %s", key.data); } else { // Return the old value @@ -284,9 +283,7 @@ Object get_option_from(void *from, int type, String name, Error *err) type, from); if (!flags) { - api_set_error(err, - kErrorTypeValidation, - "Invalid option name \"%s\"", + api_set_error(err, kErrorTypeValidation, "Invalid option name: '%s'", name.data); return rv; } @@ -303,15 +300,14 @@ Object get_option_from(void *from, int type, String name, Error *err) rv.data.string.data = stringval; rv.data.string.size = strlen(stringval); } else { - api_set_error(err, - kErrorTypeException, - "Unable to get value for option \"%s\"", + api_set_error(err, kErrorTypeException, + "Failed to get value for option '%s'", name.data); } } else { api_set_error(err, kErrorTypeException, - "Unknown type for option \"%s\"", + "Unknown type for option '%s'", name.data); } @@ -336,24 +332,20 @@ void set_option_to(uint64_t channel_id, void *to, int type, int flags = get_option_value_strict(name.data, NULL, NULL, type, to); if (flags == 0) { - api_set_error(err, - kErrorTypeValidation, - "Invalid option name \"%s\"", + api_set_error(err, kErrorTypeValidation, "Invalid option name '%s'", name.data); return; } if (value.type == kObjectTypeNil) { if (type == SREQ_GLOBAL) { - api_set_error(err, - kErrorTypeException, - "Unable to unset option \"%s\"", + api_set_error(err, kErrorTypeException, "Cannot unset option '%s'", name.data); return; } else if (!(flags & SOPT_GLOBAL)) { api_set_error(err, kErrorTypeException, - "Cannot unset option \"%s\" " + "Cannot unset option '%s' " "because it doesn't have a global value", name.data); return; @@ -370,7 +362,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, if (value.type != kObjectTypeBoolean) { api_set_error(err, kErrorTypeValidation, - "Option \"%s\" requires a boolean value", + "Option '%s' requires a Boolean value", name.data); return; } @@ -378,17 +370,15 @@ void set_option_to(uint64_t channel_id, void *to, int type, numval = value.data.boolean; } else if (flags & SOPT_NUM) { if (value.type != kObjectTypeInteger) { - api_set_error(err, - kErrorTypeValidation, - "Option \"%s\" requires an integer value", + api_set_error(err, kErrorTypeValidation, + "Option '%s' requires an integer value", name.data); return; } if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { - api_set_error(err, - kErrorTypeValidation, - "Value for option \"%s\" is outside range", + api_set_error(err, kErrorTypeValidation, + "Value for option '%s' is out of range", name.data); return; } @@ -396,9 +386,8 @@ void set_option_to(uint64_t channel_id, void *to, int type, numval = (int)value.data.integer; } else { if (value.type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "Option \"%s\" requires a string value", + api_set_error(err, kErrorTypeValidation, + "Option '%s' requires a string value", name.data); return; } @@ -1168,7 +1157,7 @@ static void set_option_value_err(char *key, } void api_set_error(Error *err, ErrorType errType, const char *format, ...) - FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PRINTF(3, 4) { assert(kErrorTypeNone != errType); va_list args1; diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index b6e0b9a566..01f8c9f71c 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -16,6 +16,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/popupmnu.h" #include "nvim/cursor_shape.h" +#include "nvim/highlight.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/ui.c.generated.h" @@ -25,6 +26,12 @@ typedef struct { uint64_t channel_id; Array buffer; + + int hl_id; // current higlight for legacy put event + Integer cursor_row, cursor_col; // Intended visibule cursor position + + // Position of legacy cursor, used both for drawing and visible user cursor. + Integer client_row, client_col; } UIData; static PMap(uint64_t) *connected_uis = NULL; @@ -51,6 +58,21 @@ void remote_ui_disconnect(uint64_t channel_id) xfree(ui); } +/// Wait until ui has connected on stdio channel. +void remote_ui_wait_for_attach(void) + FUNC_API_NOEXPORT +{ + Channel *channel = find_channel(CHAN_STDIO); + if (!channel) { + // this function should only be called in --embed mode, stdio channel + // can be assumed. + abort(); + } + + LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1, + pmap_has(uint64_t)(connected_uis, CHAN_STDIO)); +} + void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictionary options, Error *err) FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY @@ -70,10 +92,9 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->width = (int)width; ui->height = (int)height; ui->rgb = true; - ui->resize = remote_ui_resize; - ui->clear = remote_ui_clear; - ui->eol_clear = remote_ui_eol_clear; - ui->cursor_goto = remote_ui_cursor_goto; + ui->grid_resize = remote_ui_grid_resize; + ui->grid_clear = remote_ui_grid_clear; + ui->grid_cursor_goto = remote_ui_grid_cursor_goto; ui->mode_info_set = remote_ui_mode_info_set; ui->update_menu = remote_ui_update_menu; ui->busy_start = remote_ui_busy_start; @@ -81,16 +102,12 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->mouse_on = remote_ui_mouse_on; ui->mouse_off = remote_ui_mouse_off; ui->mode_change = remote_ui_mode_change; - ui->set_scroll_region = remote_ui_set_scroll_region; - ui->scroll = remote_ui_scroll; - ui->highlight_set = remote_ui_highlight_set; - ui->put = remote_ui_put; + ui->grid_scroll = remote_ui_grid_scroll; + ui->hl_attr_define = remote_ui_hl_attr_define; + ui->raw_line = remote_ui_raw_line; ui->bell = remote_ui_bell; ui->visual_bell = remote_ui_visual_bell; ui->default_colors_set = remote_ui_default_colors_set; - ui->update_fg = remote_ui_update_fg; - ui->update_bg = remote_ui_update_bg; - ui->update_sp = remote_ui_update_sp; ui->flush = remote_ui_flush; ui->suspend = remote_ui_suspend; ui->set_title = remote_ui_set_title; @@ -102,16 +119,22 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, memset(ui->ui_ext, 0, sizeof(ui->ui_ext)); for (size_t i = 0; i < options.size; i++) { - ui_set_option(ui, options.items[i].key, options.items[i].value, err); + ui_set_option(ui, true, options.items[i].key, options.items[i].value, err); if (ERROR_SET(err)) { xfree(ui); return; } } + if (ui->ui_ext[kUIHlState]) { + ui->ui_ext[kUILinegrid] = true; + } + UIData *data = xmalloc(sizeof(UIData)); data->channel_id = channel_id; data->buffer = (Array)ARRAY_DICT_INIT; + data->hl_id = 0; + data->client_col = -1; ui->data = data; pmap_put(uint64_t)(connected_uis, channel_id, ui); @@ -173,13 +196,11 @@ void nvim_ui_set_option(uint64_t channel_id, String name, } UI *ui = pmap_get(uint64_t)(connected_uis, channel_id); - ui_set_option(ui, name, value, error); - if (!ERROR_SET(error)) { - ui_refresh(); - } + ui_set_option(ui, false, name, value, error); } -static void ui_set_option(UI *ui, String name, Object value, Error *error) +static void ui_set_option(UI *ui, bool init, String name, Object value, + Error *error) { if (strequal(name.data, "rgb")) { if (value.type != kObjectTypeBoolean) { @@ -187,40 +208,45 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error) return; } ui->rgb = value.data.boolean; + // A little drastic, but only legacy uis need to use this option + if (!init) { + ui_refresh(); + } return; } + // LEGACY: Deprecated option, use `ext_cmdline` instead. + bool is_popupmenu = strequal(name.data, "popupmenu_external"); + for (UIExtension i = 0; i < kUIExtCount; i++) { - if (strequal(name.data, ui_ext_names[i])) { + if (strequal(name.data, ui_ext_names[i]) + || (i == kUIPopupmenu && is_popupmenu)) { if (value.type != kObjectTypeBoolean) { - snprintf((char *)IObuff, IOSIZE, "%s must be a Boolean", - ui_ext_names[i]); - api_set_error(error, kErrorTypeValidation, (char *)IObuff); + api_set_error(error, kErrorTypeValidation, "%s must be a Boolean", + name.data); return; } - ui->ui_ext[i] = value.data.boolean; - return; - } - } - - if (strequal(name.data, "popupmenu_external")) { - // LEGACY: Deprecated option, use `ext_cmdline` instead. - if (value.type != kObjectTypeBoolean) { - api_set_error(error, kErrorTypeValidation, - "popupmenu_external must be a Boolean"); + bool boolval = value.data.boolean; + if (!init && i == kUILinegrid && boolval != ui->ui_ext[i]) { + // There shouldn't be a reason for an UI to do this ever + // so explicitly don't support this. + api_set_error(error, kErrorTypeValidation, + "ext_linegrid option cannot be changed"); + } + ui->ui_ext[i] = boolval; + if (!init) { + ui_set_ext_option(ui, i, boolval); + } return; } - ui->ui_ext[kUIPopupmenu] = value.data.boolean; - return; } api_set_error(error, kErrorTypeValidation, "No such UI option: %s", name.data); -#undef UI_EXT_OPTION } /// Pushes data into UI.UIData, to be consumed later by remote_ui_flush(). -static void push_call(UI *ui, char *name, Array args) +static void push_call(UI *ui, const char *name, Array args) { Array call = ARRAY_DICT_INIT; UIData *data = ui->data; @@ -242,27 +268,313 @@ static void push_call(UI *ui, char *name, Array args) kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call; } +static void remote_ui_grid_clear(UI *ui, Integer grid) +{ + Array args = ARRAY_DICT_INIT; + if (ui->ui_ext[kUILinegrid]) { + ADD(args, INTEGER_OBJ(grid)); + } + const char *name = ui->ui_ext[kUILinegrid] ? "grid_clear" : "clear"; + push_call(ui, name, args); +} -static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) +static void remote_ui_grid_resize(UI *ui, Integer grid, + Integer width, Integer height) { Array args = ARRAY_DICT_INIT; - Dictionary hl = hlattrs2dict(&attrs, ui->rgb); + if (ui->ui_ext[kUILinegrid]) { + ADD(args, INTEGER_OBJ(grid)); + } + ADD(args, INTEGER_OBJ(width)); + ADD(args, INTEGER_OBJ(height)); + const char *name = ui->ui_ext[kUILinegrid] ? "grid_resize" : "resize"; + push_call(ui, name, args); +} + +static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top, + Integer bot, Integer left, Integer right, + Integer rows, Integer cols) +{ + if (ui->ui_ext[kUILinegrid]) { + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(grid)); + ADD(args, INTEGER_OBJ(top)); + ADD(args, INTEGER_OBJ(bot)); + ADD(args, INTEGER_OBJ(left)); + ADD(args, INTEGER_OBJ(right)); + ADD(args, INTEGER_OBJ(rows)); + ADD(args, INTEGER_OBJ(cols)); + push_call(ui, "grid_scroll", args); + } else { + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(top)); + ADD(args, INTEGER_OBJ(bot-1)); + ADD(args, INTEGER_OBJ(left)); + ADD(args, INTEGER_OBJ(right-1)); + push_call(ui, "set_scroll_region", args); + + args = (Array)ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(rows)); + push_call(ui, "scroll", args); + + // some clients have "clear" being affected by scroll region, + // so reset it. + args = (Array)ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(0)); + ADD(args, INTEGER_OBJ(ui->height-1)); + ADD(args, INTEGER_OBJ(0)); + ADD(args, INTEGER_OBJ(ui->width-1)); + push_call(ui, "set_scroll_region", args); + } +} + +static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg, + Integer rgb_bg, Integer rgb_sp, + Integer cterm_fg, Integer cterm_bg) +{ + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(rgb_fg)); + ADD(args, INTEGER_OBJ(rgb_bg)); + ADD(args, INTEGER_OBJ(rgb_sp)); + ADD(args, INTEGER_OBJ(cterm_fg)); + ADD(args, INTEGER_OBJ(cterm_bg)); + push_call(ui, "default_colors_set", args); + + // Deprecated + if (!ui->ui_ext[kUILinegrid]) { + args = (Array)ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(ui->rgb ? rgb_fg : cterm_fg - 1)); + push_call(ui, "update_fg", args); + + args = (Array)ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(ui->rgb ? rgb_bg : cterm_bg - 1)); + push_call(ui, "update_bg", args); + + args = (Array)ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(ui->rgb ? rgb_sp : -1)); + push_call(ui, "update_sp", args); + } +} + +static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, + HlAttrs cterm_attrs, Array info) +{ + if (!ui->ui_ext[kUILinegrid]) { + return; + } + Array args = ARRAY_DICT_INIT; + + ADD(args, INTEGER_OBJ(id)); + ADD(args, DICTIONARY_OBJ(hlattrs2dict(rgb_attrs, true))); + ADD(args, DICTIONARY_OBJ(hlattrs2dict(cterm_attrs, false))); + + if (ui->ui_ext[kUIHlState]) { + ADD(args, ARRAY_OBJ(copy_array(info))); + } else { + ADD(args, ARRAY_OBJ((Array)ARRAY_DICT_INIT)); + } + + push_call(ui, "hl_attr_define", args); +} + +static void remote_ui_highlight_set(UI *ui, int id) +{ + Array args = ARRAY_DICT_INIT; + UIData *data = ui->data; + + + if (data->hl_id == id) { + return; + } + data->hl_id = id; + Dictionary hl = hlattrs2dict(syn_attr2entry(id), ui->rgb); ADD(args, DICTIONARY_OBJ(hl)); push_call(ui, "highlight_set", args); } +/// "true" cursor used only for input focus +static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row, + Integer col) +{ + if (ui->ui_ext[kUILinegrid]) { + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(grid)); + ADD(args, INTEGER_OBJ(row)); + ADD(args, INTEGER_OBJ(col)); + push_call(ui, "grid_cursor_goto", args); + } else { + UIData *data = ui->data; + data->cursor_row = row; + data->cursor_col = col; + remote_ui_cursor_goto(ui, row, col); + } +} + +/// emulated cursor used both for drawing and for input focus +static void remote_ui_cursor_goto(UI *ui, Integer row, Integer col) +{ + UIData *data = ui->data; + if (data->client_row == row && data->client_col == col) { + return; + } + data->client_row = row; + data->client_col = col; + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(row)); + ADD(args, INTEGER_OBJ(col)); + push_call(ui, "cursor_goto", args); +} + +static void remote_ui_put(UI *ui, const char *cell) +{ + UIData *data = ui->data; + data->client_col++; + Array args = ARRAY_DICT_INIT; + ADD(args, STRING_OBJ(cstr_to_string(cell))); + push_call(ui, "put", args); +} + +static void remote_ui_raw_line(UI *ui, Integer grid, Integer row, + Integer startcol, Integer endcol, + Integer clearcol, Integer clearattr, + Boolean wrap, const schar_T *chunk, + const sattr_T *attrs) +{ + UIData *data = ui->data; + if (ui->ui_ext[kUILinegrid]) { + Array args = ARRAY_DICT_INIT; + ADD(args, INTEGER_OBJ(grid)); + ADD(args, INTEGER_OBJ(row)); + ADD(args, INTEGER_OBJ(startcol)); + Array cells = ARRAY_DICT_INIT; + int repeat = 0; + size_t ncells = (size_t)(endcol-startcol); + int last_hl = -1; + for (size_t i = 0; i < ncells; i++) { + repeat++; + if (i == ncells-1 || attrs[i] != attrs[i+1] + || STRCMP(chunk[i], chunk[i+1])) { + Array cell = ARRAY_DICT_INIT; + ADD(cell, STRING_OBJ(cstr_to_string((const char *)chunk[i]))); + if (attrs[i] != last_hl || repeat > 1) { + ADD(cell, INTEGER_OBJ(attrs[i])); + last_hl = attrs[i]; + } + if (repeat > 1) { + ADD(cell, INTEGER_OBJ(repeat)); + } + ADD(cells, ARRAY_OBJ(cell)); + repeat = 0; + } + } + if (endcol < clearcol) { + Array cell = ARRAY_DICT_INIT; + ADD(cell, STRING_OBJ(cstr_to_string(" "))); + ADD(cell, INTEGER_OBJ(clearattr)); + ADD(cell, INTEGER_OBJ(clearcol-endcol)); + ADD(cells, ARRAY_OBJ(cell)); + } + ADD(args, ARRAY_OBJ(cells)); + + push_call(ui, "grid_line", args); + } else { + for (int i = 0; i < endcol-startcol; i++) { + remote_ui_cursor_goto(ui, row, startcol+i); + remote_ui_highlight_set(ui, attrs[i]); + remote_ui_put(ui, (const char *)chunk[i]); + if (utf_ambiguous_width(utf_ptr2char(chunk[i]))) { + data->client_col = -1; // force cursor update + } + } + if (endcol < clearcol) { + remote_ui_cursor_goto(ui, row, endcol); + remote_ui_highlight_set(ui, (int)clearattr); + // legacy eol_clear was only ever used with cleared attributes + // so be on the safe side + if (clearattr == 0 && clearcol == Columns) { + Array args = ARRAY_DICT_INIT; + push_call(ui, "eol_clear", args); + } else { + for (Integer c = endcol; c < clearcol; c++) { + remote_ui_put(ui, " "); + } + } + } + } +} + static void remote_ui_flush(UI *ui) { UIData *data = ui->data; if (data->buffer.size > 0) { + if (!ui->ui_ext[kUILinegrid]) { + remote_ui_cursor_goto(ui, data->cursor_row, data->cursor_col); + } + push_call(ui, "flush", (Array)ARRAY_DICT_INIT); rpc_send_event(data->channel_id, "redraw", data->buffer); data->buffer = (Array)ARRAY_DICT_INIT; } } +static Array translate_contents(UI *ui, Array contents) +{ + Array new_contents = ARRAY_DICT_INIT; + for (size_t i = 0; i < contents.size; i++) { + Array item = contents.items[i].data.array; + Array new_item = ARRAY_DICT_INIT; + int attr = (int)item.items[0].data.integer; + if (attr) { + Dictionary rgb_attrs = hlattrs2dict(syn_attr2entry(attr), ui->rgb); + ADD(new_item, DICTIONARY_OBJ(rgb_attrs)); + } else { + ADD(new_item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); + } + ADD(new_item, copy_object(item.items[1])); + ADD(new_contents, ARRAY_OBJ(new_item)); + } + return new_contents; +} + +static Array translate_firstarg(UI *ui, Array args) +{ + Array new_args = ARRAY_DICT_INIT; + Array contents = args.items[0].data.array; + + ADD(new_args, ARRAY_OBJ(translate_contents(ui, contents))); + for (size_t i = 1; i < args.size; i++) { + ADD(new_args, copy_object(args.items[i])); + } + return new_args; +} + static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) { + if (!ui->ui_ext[kUILinegrid]) { + // the representation of highlights in cmdline changed, translate back + // never consumes args + if (strequal(name, "cmdline_show")) { + Array new_args = translate_firstarg(ui, args); + push_call(ui, name, new_args); + return; + } else if (strequal(name, "cmdline_block_show")) { + Array new_args = ARRAY_DICT_INIT; + Array block = args.items[0].data.array; + Array new_block = ARRAY_DICT_INIT; + for (size_t i = 0; i < block.size; i++) { + ADD(new_block, + ARRAY_OBJ(translate_contents(ui, block.items[i].data.array))); + } + ADD(new_args, ARRAY_OBJ(new_block)); + push_call(ui, name, new_args); + return; + } else if (strequal(name, "cmdline_block_append")) { + Array new_args = translate_firstarg(ui, args); + push_call(ui, name, new_args); + return; + } + } + Array my_args = ARRAY_DICT_INIT; // Objects are currently single-reference // make a copy, but only if necessary diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 3ef16a7ac3..10331fd5c2 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -10,14 +10,6 @@ #include "nvim/func_attr.h" #include "nvim/ui.h" -void resize(Integer width, Integer height) - FUNC_API_SINCE(3); -void clear(void) - FUNC_API_SINCE(3); -void eol_clear(void) - FUNC_API_SINCE(3); -void cursor_goto(Integer row, Integer col) - FUNC_API_SINCE(3); void mode_info_set(Boolean enabled, Array cursor_styles) FUNC_API_SINCE(3); void update_menu(void) @@ -32,29 +24,12 @@ void mouse_off(void) FUNC_API_SINCE(3); void mode_change(String mode, Integer mode_idx) FUNC_API_SINCE(3); -void set_scroll_region(Integer top, Integer bot, Integer left, Integer right) - FUNC_API_SINCE(3); -void scroll(Integer count) - FUNC_API_SINCE(3); -void highlight_set(HlAttrs attrs) - FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL; -void put(String str) - FUNC_API_SINCE(3); void bell(void) FUNC_API_SINCE(3); void visual_bell(void) FUNC_API_SINCE(3); void flush(void) FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL; -void update_fg(Integer fg) - FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL; -void update_bg(Integer bg) - FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL; -void update_sp(Integer sp) - FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL; -void default_colors_set(Integer rgb_fg, Integer rgb_bg, Integer rgb_sp, - Integer cterm_fg, Integer cterm_bg) - FUNC_API_SINCE(4); void suspend(void) FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL; void set_title(String title) @@ -64,6 +39,49 @@ void set_icon(String icon) void option_set(String name, Object value) FUNC_API_SINCE(4) FUNC_API_BRIDGE_IMPL; +// First revison of the grid protocol, used by default +void update_fg(Integer fg) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void update_bg(Integer bg) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void update_sp(Integer sp) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void resize(Integer width, Integer height) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void clear(void) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void eol_clear(void) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void cursor_goto(Integer row, Integer col) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void highlight_set(HlAttrs attrs) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY FUNC_API_REMOTE_IMPL; +void put(String str) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void set_scroll_region(Integer top, Integer bot, Integer left, Integer right) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void scroll(Integer count) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; + +// Second revison of the grid protocol, used with ext_linegrid ui option +void default_colors_set(Integer rgb_fg, Integer rgb_bg, Integer rgb_sp, + Integer cterm_fg, Integer cterm_bg) + FUNC_API_SINCE(4) FUNC_API_REMOTE_IMPL; +void hl_attr_define(Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs, + Array info) + FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL; +void grid_resize(Integer grid, Integer width, Integer height) + FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; +void grid_clear(Integer grid) + FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; +void grid_cursor_goto(Integer grid, Integer row, Integer col) + FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; +void grid_line(Integer grid, Integer row, Integer col_start, Array data) + FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY; +void grid_scroll(Integer grid, Integer top, Integer bot, + Integer left, Integer right, Integer rows, Integer cols) + FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL; + void popupmenu_show(Array items, Integer selected, Integer row, Integer col) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; void popupmenu_hide(void) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 03567ddfd8..7fcccfd988 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -21,6 +21,7 @@ #include "nvim/vim.h" #include "nvim/buffer.h" #include "nvim/file_search.h" +#include "nvim/highlight.h" #include "nvim/window.h" #include "nvim/types.h" #include "nvim/ex_docmd.h" @@ -501,7 +502,7 @@ Integer nvim_strwidth(String text, Error *err) FUNC_API_SINCE(1) { if (text.size > INT_MAX) { - api_set_error(err, kErrorTypeValidation, "String length is too high"); + api_set_error(err, kErrorTypeValidation, "String is too long"); return 0; } @@ -558,7 +559,7 @@ void nvim_set_current_dir(String dir, Error *err) FUNC_API_SINCE(1) { if (dir.size >= MAXPATHL) { - api_set_error(err, kErrorTypeValidation, "Directory string is too long"); + api_set_error(err, kErrorTypeValidation, "Directory name is too long"); return; } @@ -1027,7 +1028,7 @@ Array nvim_get_api_info(uint64_t channel_id) /// @param attributes Informal attributes describing the client. Clients might /// define their own keys, but the following are suggested: /// - "website" Website of client (for instance github repository) -/// - "license" Informal descripton of the license, such as "Apache 2", +/// - "license" Informal description of the license, such as "Apache 2", /// "GPLv3" or "MIT" /// - "logo" URI or path to image, preferably small logo or icon. /// .png or .svg format is preferred. @@ -1082,7 +1083,7 @@ void nvim_set_client_info(uint64_t channel_id, String name, /// - "buffer" buffer with connected |terminal| instance (optional) /// - "client" information about the client on the other end of the /// RPC channel, if it has added it using -/// |nvim_set_client_info|. (optional) +/// |nvim_set_client_info()|. (optional) /// Dictionary nvim_get_chan_info(Integer chan, Error *err) FUNC_API_SINCE(4) @@ -1096,7 +1097,7 @@ Dictionary nvim_get_chan_info(Integer chan, Error *err) /// Get information about all open channels. /// /// @returns Array of Dictionaries, each describing a channel with -/// the format specified at |nvim_get_chan_info|. +/// the format specified at |nvim_get_chan_info()|. Array nvim_list_chans(void) FUNC_API_SINCE(4) { @@ -1135,14 +1136,14 @@ Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err) if (calls.items[i].type != kObjectTypeArray) { api_set_error(err, kErrorTypeValidation, - "All items in calls array must be arrays"); + "Items in calls array must be arrays"); goto validation_error; } Array call = calls.items[i].data.array; if (call.size != 2) { api_set_error(err, kErrorTypeValidation, - "All items in calls array must be arrays of size 2"); + "Items in calls array must be arrays of size 2"); goto validation_error; } @@ -1850,3 +1851,22 @@ Object nvim_get_proc(Integer pid, Error *err) #endif return rvobj; } + +/// NB: if your UI doesn't use hlstate, this will not return hlstate first time +Array nvim__inspect_cell(Integer row, Integer col, Error *err) +{ + Array ret = ARRAY_DICT_INIT; + if (row < 0 || row >= screen_Rows + || col < 0 || col >= screen_Columns) { + return ret; + } + size_t off = LineOffset[(size_t)row] + (size_t)col; + ADD(ret, STRING_OBJ(cstr_to_string((char *)ScreenLines[off]))); + int attr = ScreenAttrs[off]; + ADD(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, err))); + // will not work first time + if (!highlight_use_hlstate()) { + ADD(ret, ARRAY_OBJ(hl_inspect(attr))); + } + return ret; +} diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c index 7cf9025933..7f12c0c798 100644 --- a/src/nvim/arabic.c +++ b/src/nvim/arabic.c @@ -761,7 +761,7 @@ int arabic_shape(int c, int *ccp, int *c1p, int prev_c, int prev_c1, char_u buf[MB_MAXBYTES + 1]; // Update the first byte of the character - (*mb_char2bytes)(curr_c, buf); + utf_char2bytes(curr_c, buf); *ccp = buf[0]; } diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index d0a3f38c6b..a6290aaac1 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -19,14 +19,15 @@ return { 'BufWriteCmd', -- write buffer using command 'BufWritePost', -- after writing a buffer 'BufWritePre', -- before writing a buffer - 'ChanOpen', -- channel was opened 'ChanInfo', -- info was received about channel + 'ChanOpen', -- channel was opened 'CmdLineEnter', -- after entering cmdline mode 'CmdLineLeave', -- before leaving cmdline mode 'CmdUndefined', -- command undefined 'CmdWinEnter', -- after entering the cmdline window 'CmdWinLeave', -- before leaving the cmdline window 'ColorScheme', -- after loading a colorscheme + 'ColorSchemePre', -- before loading a colorscheme 'CompleteDone', -- after finishing insert complete 'CursorHold', -- cursor in same position for a while 'CursorHoldI', -- idem, in Insert mode @@ -34,6 +35,7 @@ return { 'CursorMovedI', -- cursor was moved in Insert mode 'DirChanged', -- directory changed 'EncodingChanged', -- after changing the 'encoding' option + 'ExitPre', -- before exiting 'FileAppendCmd', -- append to a file using command 'FileAppendPost', -- after appending to a file 'FileAppendPre', -- before appending to a file @@ -97,9 +99,9 @@ return { 'VimResized', -- after Vim window was resized 'VimResume', -- after Nvim is resumed 'VimSuspend', -- before Nvim is suspended - 'WinNew', -- when entering a new window 'WinEnter', -- after entering a window 'WinLeave', -- before leaving a window + 'WinNew', -- when entering a new window }, aliases = { BufCreate = 'BufAdd', @@ -107,9 +109,9 @@ return { BufWrite = 'BufWritePre', FileEncoding = 'EncodingChanged', }, - -- List of neovim-specific events or aliases for the purpose of generating + -- List of nvim-specific events or aliases for the purpose of generating -- syntax file - neovim_specific = { + nvim_specific = { DirChanged=true, TabClosed=true, TabNew=true, diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 81bbc56eb9..cd77f48320 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -45,6 +45,7 @@ #include "nvim/fold.h" #include "nvim/getchar.h" #include "nvim/hashtab.h" +#include "nvim/highlight.h" #include "nvim/indent.h" #include "nvim/indent_c.h" #include "nvim/main.h" @@ -251,7 +252,7 @@ open_buffer ( msg_silent = old_msg_silent; // Help buffer is filtered. - if (curbuf->b_help) { + if (bt_help(curbuf)) { fix_help_buffer(); } } else if (read_stdin) { @@ -295,6 +296,11 @@ open_buffer ( } save_file_ff(curbuf); // keep this fileformat + // Set last_changedtick to avoid triggering a TextChanged autocommand right + // after it was added. + curbuf->b_last_changedtick = buf_get_changedtick(curbuf); + curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf); + /* require "!" to overwrite the file, because it wasn't read completely */ if (aborting()) curbuf->b_flags |= BF_READERR; @@ -504,14 +510,20 @@ void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last) int nwindows = buf->b_nwindows; - /* decrease the link count from windows (unless not in any window) */ - if (buf->b_nwindows > 0) - --buf->b_nwindows; + // decrease the link count from windows (unless not in any window) + if (buf->b_nwindows > 0) { + buf->b_nwindows--; + } + + if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0) { + diff_buf_delete(buf); // Clear 'diff' for hidden buffer. + } /* Return when a window is displaying the buffer or when it's not * unloaded. */ - if (buf->b_nwindows > 0 || !unload_buf) + if (buf->b_nwindows > 0 || !unload_buf) { return; + } if (buf->terminal) { terminal_close(buf->terminal, NULL); @@ -829,8 +841,8 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count) * aborting() returns FALSE when closing a window. */ enter_cleanup(&cs); - /* Quitting means closing the split window, nothing else. */ - win_close(curwin, TRUE); + // Quitting means closing the split window, nothing else. + win_close(curwin, true); swap_exists_action = SEA_NONE; swap_exists_did_quit = TRUE; @@ -872,7 +884,15 @@ void handle_swap_exists(bufref_T *old_curbuf) buf = old_curbuf->br_buf; } if (buf != NULL) { + int old_msg_silent = msg_silent; + + if (shortmess(SHM_FILEINFO)) { + msg_silent = 1; // prevent fileinfo message + } enter_buffer(buf); + // restore msg_silent, so that the command line will be shown + msg_silent = old_msg_silent; + if (old_tw != curbuf->b_p_tw) { check_colorcolumn(curwin); } @@ -2647,9 +2667,8 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum) * Get alternate file name for current window. * Return NULL if there isn't any, and give error message if requested. */ -char_u * -getaltfname ( - int errmsg /* give error message */ +char_u * getaltfname( + bool errmsg // give error message ) { char_u *fname; @@ -3219,10 +3238,11 @@ int build_stl_str_hl( // Get the byte value now, in case we need it below. This is more // efficient than making a copy of the line. int byteval; - if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr)) + if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr)) { byteval = 0; - else - byteval = (*mb_ptr2char)(line_ptr + wp->w_cursor.col); + } else { + byteval = utf_ptr2char(line_ptr + wp->w_cursor.col); + } int groupdepth = 0; @@ -3602,7 +3622,7 @@ int build_stl_str_hl( // Store the current buffer number as a string variable vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum); - set_internal_string_var((char_u *)"actual_curbuf", tmp); + set_internal_string_var((char_u *)"g:actual_curbuf", tmp); buf_T *o_curbuf = curbuf; win_T *o_curwin = curwin; @@ -3711,10 +3731,11 @@ int build_stl_str_hl( case STL_OFFSET_X: base = kNumBaseHexadecimal; - // fallthrough + FALLTHROUGH; case STL_OFFSET: { - long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL); + long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL, + false); num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ? 0L : l + 1 + (!(State & INSERT) && empty_line ? 0 : (int)wp->w_cursor.col); @@ -3722,7 +3743,7 @@ int build_stl_str_hl( } case STL_BYTEVAL_X: base = kNumBaseHexadecimal; - // fallthrough + FALLTHROUGH; case STL_BYTEVAL: num = byteval; if (num == NL) @@ -4419,7 +4440,7 @@ do_arg_all ( if (i < alist->al_ga.ga_len && (AARGLIST(alist)[i].ae_fnum == buf->b_fnum || path_full_compare(alist_name(&AARGLIST(alist)[i]), - buf->b_ffname, TRUE) & kEqualFiles)) { + buf->b_ffname, true) & kEqualFiles)) { int weight = 1; if (old_curtab == curtab) { @@ -4513,9 +4534,10 @@ do_arg_all ( use_firstwin = true; } - for (i = 0; i < count && i < opened_len && !got_int; ++i) { - if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) - arg_had_last = TRUE; + for (i = 0; i < count && i < opened_len && !got_int; i++) { + if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) { + arg_had_last = true; + } if (opened[i] > 0) { /* Move the already present window to below the current window */ if (curwin->w_arg_idx != i) { @@ -4639,10 +4661,10 @@ void ex_buffer_all(exarg_T *eap) && !ONE_WINDOW && !(wp->w_closing || wp->w_buffer->b_locked > 0) ) { - win_close(wp, FALSE); - wpnext = firstwin; /* just in case an autocommand does - something strange with windows */ - tpnext = first_tabpage; /* start all over...*/ + win_close(wp, false); + wpnext = firstwin; // just in case an autocommand does + // something strange with windows + tpnext = first_tabpage; // start all over... open_wins = 0; } else ++open_wins; @@ -4711,9 +4733,9 @@ void ex_buffer_all(exarg_T *eap) * aborting() returns FALSE when closing a window. */ enter_cleanup(&cs); - /* User selected Quit at ATTENTION prompt; close this window. */ - win_close(curwin, TRUE); - --open_wins; + // User selected Quit at ATTENTION prompt; close this window. + win_close(curwin, true); + open_wins--; swap_exists_action = SEA_NONE; swap_exists_did_quit = TRUE; @@ -4918,6 +4940,12 @@ chk_modeline ( return retval; } +// Return true if "buf" is a help buffer. +bool bt_help(const buf_T *const buf) +{ + return buf != NULL && buf->b_help; +} + /* * Return special buffer name. * Returns NULL when the buffer has a normal file name. @@ -5057,13 +5085,16 @@ linenr_T buf_change_sign_type( return (linenr_T)0; } -int buf_getsigntype( - buf_T *buf, - linenr_T lnum, - int type /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ - ) +/// Gets a sign from a given line. +/// In case of multiple signs, returns the most recently placed one. +/// +/// @param buf Buffer in which to search +/// @param lnum Line in which to search +/// @param type Type of sign to look for +/// @return Identifier of the first matching sign, or 0 +int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type) { - signlist_T *sign; /* a sign in a b_signlist */ + signlist_T *sign; // a sign in a b_signlist for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { if (sign->lnum == lnum @@ -5071,7 +5102,9 @@ int buf_getsigntype( || (type == SIGN_TEXT && sign_get_text(sign->typenr) != NULL) || (type == SIGN_LINEHL - && sign_get_attr(sign->typenr, TRUE) != 0))) { + && sign_get_attr(sign->typenr, SIGN_LINEHL) != 0) + || (type == SIGN_NUMHL + && sign_get_attr(sign->typenr, SIGN_NUMHL) != 0))) { return sign->typenr; } } @@ -5357,6 +5390,45 @@ void bufhl_add_hl_pos_offset(buf_T *buf, } } +int bufhl_add_virt_text(buf_T *buf, + int src_id, + linenr_T lnum, + VirtText virt_text) +{ + static int next_src_id = 1; + if (src_id == 0) { + src_id = next_src_id++; + } + + BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true); + + bufhl_clear_virttext(&lineinfo->virt_text); + if (kv_size(virt_text) > 0) { + lineinfo->virt_text_src = src_id; + lineinfo->virt_text = virt_text; + } else { + lineinfo->virt_text_src = 0; + // currently not needed, but allow a future caller with + // 0 size and non-zero capacity + kv_destroy(virt_text); + } + + if (0 < lnum && lnum <= buf->b_ml.ml_line_count) { + changed_lines_buf(buf, lnum, lnum+1, 0); + redraw_buf_later(buf, VALID); + } + return src_id; +} + +static void bufhl_clear_virttext(VirtText *text) +{ + for (size_t i = 0; i < kv_size(*text); i++) { + xfree(kv_A(*text, i).text); + } + kv_destroy(*text); + *text = (VirtText)KV_INITIAL_VALUE; +} + /// Clear bufhl highlights from a given source group and range of lines. /// /// @param buf The buffer to remove highlights from @@ -5412,6 +5484,7 @@ void bufhl_clear_line_range(buf_T *buf, static BufhlLineStatus bufhl_clear_line(BufhlLine *lineinfo, int src_id, linenr_T lnum) { + BufhlLineStatus changed = kBLSUnchanged; size_t oldsize = kv_size(lineinfo->items); if (src_id < 0) { kv_size(lineinfo->items) = 0; @@ -5427,14 +5500,25 @@ static BufhlLineStatus bufhl_clear_line(BufhlLine *lineinfo, int src_id, } kv_size(lineinfo->items) = newidx; } + if (kv_size(lineinfo->items) != oldsize) { + changed = kBLSChanged; + } + + if (kv_size(lineinfo->virt_text) != 0 + && (src_id < 0 || src_id == lineinfo->virt_text_src)) { + bufhl_clear_virttext(&lineinfo->virt_text); + lineinfo->virt_text_src = 0; + changed = kBLSChanged; + } - if (kv_size(lineinfo->items) == 0) { + if (kv_size(lineinfo->items) == 0 && kv_size(lineinfo->virt_text) == 0) { kv_destroy(lineinfo->items); return kBLSDeleted; } - return kv_size(lineinfo->items) != oldsize ? kBLSChanged : kBLSUnchanged; + return changed; } + /// Remove all highlights and free the highlight data void bufhl_clear_all(buf_T *buf) { @@ -5509,8 +5593,8 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, BufhlLineInfo *info) return false; } info->valid_to = -1; - info->entries = lineinfo->items; - return kv_size(info->entries) > 0; + info->line = lineinfo; + return true; } /// get highlighting at column col @@ -5530,8 +5614,8 @@ int bufhl_get_attr(BufhlLineInfo *info, colnr_T col) } int attr = 0; info->valid_to = MAXCOL; - for (size_t i = 0; i < kv_size(info->entries); i++) { - BufhlItem entry = kv_A(info->entries, i); + for (size_t i = 0; i < kv_size(info->line->items); i++) { + BufhlItem entry = kv_A(info->line->items, i); if (entry.start <= col && col <= entry.stop) { int entry_attr = syn_id2attr(entry.hl_id); attr = hl_combine_attr(attr, entry_attr); diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 057f99e341..e86eaf010f 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -94,6 +94,7 @@ typedef struct { typedef struct window_S win_T; typedef struct wininfo_S wininfo_T; typedef struct frame_S frame_T; +typedef uint16_t disptick_T; // display tick type // for struct memline (it needs memfile_T) #include "nvim/memline_defs.h" @@ -425,7 +426,7 @@ typedef struct { synstate_T *b_sst_firstfree; int b_sst_freecount; linenr_T b_sst_check_lnum; - uint16_t b_sst_lasttick; /* last display tick */ + disptick_T b_sst_lasttick; // last display tick // for spell checking garray_T b_langp; // list of pointers to slang_T, see spell.c @@ -982,9 +983,11 @@ struct window_S { used to try to stay in the same column for up/down cursor motions. */ - int w_set_curswant; /* If set, then update w_curswant the next - time through cursupdate() to the - current virtual column */ + int w_set_curswant; // If set, then update w_curswant the next + // time through cursupdate() to the + // current virtual column + + linenr_T w_last_cursorline; ///< where last 'cursorline' was drawn // the next seven are used to update the visual part char w_old_visual_mode; ///< last known VIsual_mode diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index 18b53a0685..9d9c998a68 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -180,7 +180,7 @@ void buf_updates_send_changes(buf_T *buf, // change notifications are so frequent that many dead channels will be // cleared up quickly. if (badchannelid != 0) { - ELOG("Disabling buffer updates for dead channel %llu", badchannelid); + ELOG("Disabling buffer updates for dead channel %"PRIu64, badchannelid); buf_updates_unregister(buf, badchannelid); } } diff --git a/src/nvim/bufhl_defs.h b/src/nvim/bufhl_defs.h index 14b1afa7d9..d0fb40ab88 100644 --- a/src/nvim/bufhl_defs.h +++ b/src/nvim/bufhl_defs.h @@ -14,16 +14,23 @@ typedef struct { colnr_T stop; // last column to highlight } BufhlItem; -typedef kvec_t(BufhlItem) BufhlItemVec; +typedef struct { + char *text; + int hl_id; +} VirtTextChunk; + +typedef kvec_t(VirtTextChunk) VirtText; typedef struct { linenr_T line; - BufhlItemVec items; + kvec_t(BufhlItem) items; + int virt_text_src; + VirtText virt_text; } BufhlLine; -#define BUFHLLINE_INIT(l) { l, KV_INITIAL_VALUE } +#define BUFHLLINE_INIT(l) { l, KV_INITIAL_VALUE, 0, KV_INITIAL_VALUE } typedef struct { - BufhlItemVec entries; + BufhlLine *line; int current; colnr_T valid_to; } BufhlLineInfo; diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 67306d7e11..e191f838e0 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -284,6 +284,8 @@ Channel *channel_job_start(char **argv, CallbackReader on_stdout, uint16_t pty_width, uint16_t pty_height, char *term_name, varnumber_T *status_out) { + assert(cwd == NULL || os_isdir_executable(cwd)); + Channel *chan = channel_alloc(kChannelStreamProc); chan->on_stdout = on_stdout; chan->on_stderr = on_stderr; @@ -432,7 +434,7 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, const char **error) FUNC_ATTR_NONNULL_ALL { - if (!headless_mode) { + if (!headless_mode && !embedded_mode) { *error = _("can only be opened in headless mode"); return 0; } @@ -605,12 +607,15 @@ static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf, } rbuffer_consumed(buf, count); - // if buffer wasn't consumed, a pending callback is stalled. Aggregate the - // received data and avoid a "burst" of multiple callbacks. - bool buffer_set = reader->buffer.ga_len > 0; - ga_concat_len(&reader->buffer, ptr, count); - if (!reader->buffered && !buffer_set && callback_reader_set(*reader)) { - process_channel_event(chan, &reader->cb, type, reader, 0); + + if (callback_reader_set(*reader) || reader->buffered) { + // if buffer wasn't consumed, a pending callback is stalled. Aggregate the + // received data and avoid a "burst" of multiple callbacks. + bool buffer_set = reader->buffer.ga_len > 0; + ga_concat_len(&reader->buffer, ptr, count); + if (callback_reader_set(*reader) && !reader->buffered && !buffer_set) { + process_channel_event(chan, &reader->cb, type, reader, 0); + } } } @@ -791,7 +796,7 @@ Dictionary channel_info(uint64_t id) case kChannelStreamInternal: PUT(info, "internal", BOOLEAN_OBJ(true)); - // FALLTHROUGH + FALLTHROUGH; case kChannelStreamSocket: stream_desc = "socket"; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index a02d2a812d..4e8bb3b0d7 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -30,7 +30,7 @@ #include "nvim/state.h" #include "nvim/strings.h" #include "nvim/path.h" - +#include "nvim/cursor.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "charset.c.generated.h" @@ -1344,7 +1344,11 @@ colnr_T getvcol_nolist(pos_T *posp) colnr_T vcol; curwin->w_p_list = false; - getvcol(curwin, posp, NULL, &vcol, NULL); + if (posp->coladd) { + getvvcol(curwin, posp, NULL, &vcol, NULL); + } else { + getvcol(curwin, posp, NULL, &vcol, NULL); + } curwin->w_p_list = list_save; return vcol; } @@ -1375,7 +1379,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, ptr = ml_get_buf(wp->w_buffer, pos->lnum, false); if (pos->col < (colnr_T)STRLEN(ptr)) { - int c = (*mb_ptr2char)(ptr + pos->col); + int c = utf_ptr2char(ptr + pos->col); if ((c != TAB) && vim_isprintc(c)) { endadd = (colnr_T)(char2cells(c) - 1); if (coladd > endadd) { @@ -1461,6 +1465,18 @@ char_u *skipwhite(const char_u *q) return (char_u *)p; } +// getwhitecols: return the number of whitespace +// columns (bytes) at the start of a given line +intptr_t getwhitecols_curline(void) +{ + return getwhitecols(get_cursor_line_ptr()); +} + +intptr_t getwhitecols(const char_u *p) +{ + return skipwhite(p) - p; +} + /// Skip over digits /// /// @param[in] q String to skip digits in. diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c index 177f167d74..0fda941a51 100644 --- a/src/nvim/cursor.c +++ b/src/nvim/cursor.c @@ -476,9 +476,7 @@ bool leftcol_changed(void) int gchar_cursor(void) { - if (has_mbyte) - return (*mb_ptr2char)(get_cursor_pos_ptr()); - return (int)*get_cursor_pos_ptr(); + return utf_ptr2char(get_cursor_pos_ptr()); } /* @@ -507,4 +505,3 @@ char_u *get_cursor_pos_ptr(void) return ml_get_buf(curbuf, curwin->w_cursor.lnum, false) + curwin->w_cursor.col; } - diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c index b45e7002f7..cf79005a37 100644 --- a/src/nvim/cursor_shape.c +++ b/src/nvim/cursor_shape.c @@ -64,6 +64,9 @@ Array mode_style_array(void) PUT(dic, "blinkoff", INTEGER_OBJ(cur->blinkoff)); PUT(dic, "hl_id", INTEGER_OBJ(cur->id)); PUT(dic, "id_lm", INTEGER_OBJ(cur->id_lm)); + PUT(dic, "attr_id", INTEGER_OBJ(cur->id ? syn_id2attr(cur->id) : 0)); + PUT(dic, "attr_id_lm", INTEGER_OBJ(cur->id_lm ? syn_id2attr(cur->id_lm) + : 0)); } PUT(dic, "name", STRING_OBJ(cstr_to_string(cur->full_name))); PUT(dic, "short_name", STRING_OBJ(cstr_to_string(cur->name))); @@ -258,15 +261,30 @@ char_u *parse_shape_opt(int what) /// @return -1 in case of failure, else the matching SHAPE_ID* integer int cursor_mode_str2int(const char *mode) { - for (int current_mode = 0; current_mode < SHAPE_IDX_COUNT; current_mode++) { - if (strcmp(shape_table[current_mode].full_name, mode) == 0) { - return current_mode; + for (int mode_idx = 0; mode_idx < SHAPE_IDX_COUNT; mode_idx++) { + if (strcmp(shape_table[mode_idx].full_name, mode) == 0) { + return mode_idx; } } WLOG("Unknown mode %s", mode); return -1; } +/// Check if a syntax id is used as a cursor style. +bool cursor_mode_uses_syn_id(int syn_id) +{ + if (*p_guicursor == NUL) { + return false; + } + for (int mode_idx = 0; mode_idx < SHAPE_IDX_COUNT; mode_idx++) { + if (shape_table[mode_idx].id == syn_id + || shape_table[mode_idx].id_lm == syn_id) { + return true; + } + } + return false; +} + /// Return the index into shape_table[] for the current mode. int cursor_get_mode_idx(void) diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 61e0b76558..4bfe67c9d3 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -44,13 +44,14 @@ static int diff_busy = FALSE; // ex_diffgetput() is busy #define DIFF_IWHITE 4 // ignore change in white space #define DIFF_HORIZONTAL 8 // horizontal splits #define DIFF_VERTICAL 16 // vertical splits +#define DIFF_HIDDEN_OFF 32 // diffoff when hidden static int diff_flags = DIFF_FILLER; #define LBUFLEN 50 // length of line in diff file -// TRUE when "diff -a" works, FALSE when it doesn't work, MAYBE when not -// checked yet -static int diff_a_works = MAYBE; +// kTrue when "diff -a" works, kFalse when it doesn't work, +// kNone when not checked yet +static TriState diff_a_works = kNone; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -686,9 +687,9 @@ void ex_diffupdate(exarg_T *eap) // there are differences. // May try twice, first with "-a" and then without. int io_error = false; - bool ok = false; + TriState ok = kFalse; for (;;) { - ok = false; + ok = kFalse; FILE *fd = mch_fopen(tmp_orig, "w"); if (fd == NULL) { @@ -722,7 +723,7 @@ void ex_diffupdate(exarg_T *eap) } if (STRNCMP(linebuf, "1c1", 3) == 0) { - ok = TRUE; + ok = kTrue; } } fclose(fd); @@ -739,7 +740,7 @@ void ex_diffupdate(exarg_T *eap) } // If we checked if "-a" works already, break here. - if (diff_a_works != MAYBE) { + if (diff_a_works != kNone) { break; } diff_a_works = ok; @@ -755,7 +756,7 @@ void ex_diffupdate(exarg_T *eap) EMSG(_("E810: Cannot read or write temp files")); } EMSG(_("E97: Cannot create diffs")); - diff_a_works = MAYBE; + diff_a_works = kNone; goto theend; } @@ -830,7 +831,7 @@ static void diff_file(const char *const tmp_orig, const char *const tmp_new, * differences are of no use. Ignore errors, diff returns * non-zero when differences have been found. */ vim_snprintf(cmd, len, "diff %s%s%s%s%s %s", - diff_a_works ? "-a " : "", + diff_a_works == kFalse ? "" : "-a ", "", (diff_flags & DIFF_IWHITE) ? "-b " : "", (diff_flags & DIFF_ICASE) ? "-i " : "", @@ -1486,7 +1487,7 @@ int diff_check(win_T *wp, linenr_T lnum) } // A closed fold never has filler lines. - if (hasFoldingWin(wp, lnum, NULL, NULL, TRUE, NULL)) { + if (hasFoldingWin(wp, lnum, NULL, NULL, true, NULL)) { return 0; } @@ -1597,6 +1598,34 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2) return true; } +// Compare the characters at "p1" and "p2". If they are equal (possibly +// ignoring case) return true and set "len" to the number of bytes. +static bool diff_equal_char(const char_u *const p1, const char_u *const p2, + int *const len) +{ + const int l = utfc_ptr2len(p1); + + if (l != utfc_ptr2len(p2)) { + return false; + } + if (l > 1) { + if (STRNCMP(p1, p2, l) != 0 + && (!(diff_flags & DIFF_ICASE) + || utf_fold(utf_ptr2char(p1)) != utf_fold(utf_ptr2char(p2)))) { + return false; + } + *len = l; + } else { + if ((*p1 != *p2) + && (!(diff_flags & DIFF_ICASE) + || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2))) { + return false; + } + *len = 1; + } + return true; +} + /// Compare strings "s1" and "s2" according to 'diffopt'. /// Return non-zero when they are different. /// @@ -1623,30 +1652,12 @@ static int diff_cmp(char_u *s1, char_u *s2) p1 = skipwhite(p1); p2 = skipwhite(p2); } else { - int l = (*mb_ptr2len)(p1); - if (l != (*mb_ptr2len)(p2)) { + int l; + if (!diff_equal_char(p1, p2, &l)) { break; } - - if (l > 1) { - if ((STRNCMP(p1, p2, l) != 0) - && (!enc_utf8 - || !(diff_flags & DIFF_ICASE) - || (utf_fold(utf_ptr2char(p1)) - != utf_fold(utf_ptr2char(p2))))) { - break; - } - p1 += l; - p2 += l; - } else { - if ((*p1 != *p2) - && (!(diff_flags & DIFF_ICASE) - || (TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))) { - break; - } - ++p1; - ++p2; - } + p1 += l; + p2 += l; } } @@ -1793,7 +1804,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin) check_topfill(towin, false); (void)hasFoldingWin(towin, towin->w_topline, &towin->w_topline, - NULL, TRUE, NULL); + NULL, true, NULL); } /// This is called when 'diffopt' is changed. @@ -1828,6 +1839,9 @@ int diffopt_changed(void) } else if ((STRNCMP(p, "foldcolumn:", 11) == 0) && ascii_isdigit(p[11])) { p += 11; diff_foldcolumn_new = getdigits_int(&p); + } else if (STRNCMP(p, "hiddenoff", 9) == 0) { + p += 9; + diff_flags_new |= DIFF_HIDDEN_OFF; } if ((*p != ',') && (*p != NUL)) { @@ -1870,6 +1884,12 @@ bool diffopt_horizontal(void) return (diff_flags & DIFF_HORIZONTAL) != 0; } +// Return true if 'diffopt' contains "hiddenoff". +bool diffopt_hiddenoff(void) +{ + return (diff_flags & DIFF_HIDDEN_OFF) != 0; +} + /// Find the difference within a changed line. /// /// @param wp window whose current buffer to check @@ -1887,6 +1907,7 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) int ei_org; int ei_new; bool added = true; + int l; // Make a copy of the line, the next ml_get() will invalidate it. char_u *line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE)); @@ -1933,20 +1954,18 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) si_org = (int)(skipwhite(line_org + si_org) - line_org); si_new = (int)(skipwhite(line_new + si_new) - line_new); } else { - if (line_org[si_org] != line_new[si_new]) { + if (!diff_equal_char(line_org + si_org, line_new + si_new, &l)) { break; } - ++si_org; - ++si_new; + si_org += l; + si_new += l; } } - if (has_mbyte) { - // Move back to first byte of character in both lines (may - // have "nn^" in line_org and "n^ in line_new). - si_org -= (*mb_head_off)(line_org, line_org + si_org); - si_new -= (*mb_head_off)(line_new, line_new + si_new); - } + // Move back to first byte of character in both lines (may + // have "nn^" in line_org and "n^ in line_new). + si_org -= utf_head_off(line_org, line_org + si_org); + si_new -= utf_head_off(line_new, line_new + si_new); if (*startp > si_org) { *startp = si_org; @@ -1972,11 +1991,17 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp) ei_new--; } } else { - if (line_org[ei_org] != line_new[ei_new]) { + const char_u *p1 = line_org + ei_org; + const char_u *p2 = line_new + ei_new; + + p1 -= utf_head_off(line_org, p1); + p2 -= utf_head_off(line_new, p2); + + if (!diff_equal_char(p1, p2, &l)) { break; } - ei_org--; - ei_new--; + ei_org -= l; + ei_new -= l; } } diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c index 218a3f0604..3329290634 100644 --- a/src/nvim/digraph.c +++ b/src/nvim/digraph.c @@ -1359,6 +1359,12 @@ static digr_T digraphdefault[] = { 'f', 't', 0xfb05 }, { 's', 't', 0xfb06 }, + // extra alternatives, easier to remember + { 'W', '`', 0x1e80 }, + { 'w', '`', 0x1e81 }, + { 'Y', '`', 0x1ef2 }, + { 'y', '`', 0x1ef3 }, + // Vim 5.x compatible digraphs that don't conflict with the above { '~', '!', 161 }, // ¡ { 'c', '|', 162 }, // ¢ @@ -1391,7 +1397,7 @@ static digr_T digraphdefault[] = { 'O', '`', 210 }, // Ò { 'O', '^', 212 }, // Ô { 'O', '~', 213 }, // Õ - { '/', '\\', 215 }, // × - multiplication symbol in ISO 8859-1 + { '/', '\\', 215 }, // × - multiplication symbol in ISO 8859-1 { 'U', '`', 217 }, // Ù { 'U', '^', 219 }, // Û { 'I', 'p', 222 }, // Þ @@ -1442,6 +1448,33 @@ int do_digraph(int c) return c; } +/// Find a digraph for "val". If found return the string to display it. +/// If not found return NULL. +char_u *get_digraph_for_char(int val) +{ + digr_T *dp; + static char_u r[3]; + + for (int use_defaults = 0; use_defaults <= 1; use_defaults++) { + if (use_defaults == 0) { + dp = (digr_T *)user_digraphs.ga_data; + } else { + dp = digraphdefault; + } + for (int i = 0; + use_defaults ? dp->char1 != NUL : i < user_digraphs.ga_len; i++) { + if (dp->result == val) { + r[0] = dp->char1; + r[1] = dp->char2; + r[2] = NUL; + return r; + } + dp++; + } + } + return NULL; +} + /// Get a digraph. Used after typing CTRL-K on the command line or in normal /// mode. /// @@ -1520,34 +1553,6 @@ static int getexactdigraph(int char1, int char2, int meta_char) } } - if ((retval != 0) && !enc_utf8) { - char_u buf[6], *to; - vimconv_T vc; - - // Convert the Unicode digraph to 'encoding'. - int i = utf_char2bytes(retval, buf); - retval = 0; - vc.vc_type = CONV_NONE; - - if (convert_setup(&vc, (char_u *)"utf-8", p_enc) == OK) { - vc.vc_fail = true; - assert(i >= 0); - size_t len = (size_t)i; - to = string_convert(&vc, buf, &len); - - if (to != NULL) { - retval = (*mb_ptr2char)(to); - xfree(to); - } - (void)convert_setup(&vc, NULL, NULL); - } - } - - // Ignore multi-byte characters when not in multi-byte mode. - if (!has_mbyte && (retval > 0xff)) { - retval = 0; - } - if (retval == 0) { // digraph deleted or not found if ((char1 == ' ') && meta_char) { @@ -1654,8 +1659,7 @@ void listdigraphs(void) tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE); if ((tmp.result != 0) - && (tmp.result != tmp.char2) - && (has_mbyte || (tmp.result <= 255))) { + && (tmp.result != tmp.char2)) { printdigraph(&tmp); } dp++; @@ -1668,9 +1672,6 @@ void listdigraphs(void) os_breakcheck(); dp++; } - // clear screen, because some digraphs may be wrong, in which case we messed - // up ScreenLines - must_redraw = CLEAR; } static void printdigraph(digr_T *dp) @@ -1708,7 +1709,7 @@ static void printdigraph(digr_T *dp) if (utf_iscomposing(dp->result)) { *p++ = ' '; } - p += (*mb_char2bytes)(dp->result, p); + p += utf_char2bytes(dp->result, p); *p = NUL; msg_outtrans_attr(buf, HL_ATTR(HLF_8)); diff --git a/src/nvim/edit.c b/src/nvim/edit.c index bf80f12bd0..d20660bfb9 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -227,7 +227,7 @@ static int last_insert_skip; /* nr of chars in front of previous insert */ static int new_insert_skip; /* nr of chars in front of current insert */ static int did_restart_edit; /* "restart_edit" when calling edit() */ -static int can_cindent; /* may do cindenting on this line */ +static bool can_cindent; // may do cindenting on this line static int old_indent = 0; /* for ^^D command in insert mode */ @@ -240,10 +240,10 @@ static int ins_need_undo; /* call u_save() before inserting a char. Set when edit() is called. after that arrow_used is used. */ -static int did_add_space = FALSE; /* auto_format() added an extra space - under the cursor */ -static int dont_sync_undo = false; // CTRL-G U prevents syncing undo - // for the next left/right cursor +static bool did_add_space = false; // auto_format() added an extra space + // under the cursor +static TriState dont_sync_undo = kFalse; // CTRL-G U prevents syncing undo + // for the next left/right cursor static linenr_T o_lnum = 0; @@ -276,7 +276,7 @@ static void insert_enter(InsertState *s) set_vim_var_string(VV_INSERTMODE, (char *) s->ptr, 1); set_vim_var_string(VV_CHAR, NULL, -1); - apply_autocmds(EVENT_INSERTENTER, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_INSERTENTER); // Make sure the cursor didn't move. Do call check_cursor_col() in // case the text was modified. Since Insert mode was not started yet @@ -298,7 +298,7 @@ static void insert_enter(InsertState *s) // Check if the cursor line needs redrawing before changing State. If // 'concealcursor' is "n" it needs to be redrawn without concealing. - conceal_check_cursur_line(); + conceal_check_cursor_line(); // When doing a paste with the middle mouse button, Insstart is set to // where the paste started. @@ -468,8 +468,11 @@ static void insert_enter(InsertState *s) } foldUpdateAfterInsert(); - if (s->cmdchar != 'r' && s->cmdchar != 'v') { - apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, false, curbuf); + // When CTRL-C was typed got_int will be set, with the result + // that the autocommands won't be executed. When mapped got_int + // is not set, but let's keep the behavior the same. + if (s->cmdchar != 'r' && s->cmdchar != 'v' && s->c != Ctrl_C) { + ins_apply_autocmds(EVENT_INSERTLEAVE); } did_cursorhold = false; } @@ -595,10 +598,10 @@ static int insert_check(VimState *state) s->lastc = s->c; // remember previous char for CTRL-D // After using CTRL-G U the next cursor key will not break undo. - if (dont_sync_undo == MAYBE) { - dont_sync_undo = true; + if (dont_sync_undo == kNone) { + dont_sync_undo = kTrue; } else { - dont_sync_undo = false; + dont_sync_undo = kFalse; } return 1; @@ -775,7 +778,7 @@ static int insert_handle_key(InsertState *s) if (echeck_abbr(ESC + ABBR_OFF)) { break; } - // FALLTHROUGH + FALLTHROUGH; case Ctrl_C: // End input mode if (s->c == Ctrl_C && cmdwin_type != 0) { @@ -851,7 +854,7 @@ static int insert_handle_key(InsertState *s) if (mod_mask != MOD_MASK_CTRL) { goto normalchar; } - // FALLTHROUGH + FALLTHROUGH; case K_ZERO: // Insert the previously inserted text. case NUL: case Ctrl_A: @@ -890,7 +893,7 @@ static int insert_handle_key(InsertState *s) insert_do_complete(s); break; } - // FALLTHROUGH + FALLTHROUGH; case Ctrl_T: // Make indent one shiftwidth greater. if (s->c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) { @@ -997,7 +1000,7 @@ static int insert_handle_key(InsertState *s) if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) { ins_s_left(); } else { - ins_left(dont_sync_undo == false); + ins_left(dont_sync_undo == kFalse); } break; @@ -1010,7 +1013,7 @@ static int insert_handle_key(InsertState *s) if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) { ins_s_right(); } else { - ins_right(dont_sync_undo == false); + ins_right(dont_sync_undo == kFalse); } break; @@ -1062,7 +1065,7 @@ static int insert_handle_key(InsertState *s) case K_S_TAB: // When not mapped, use like a normal TAB s->c = TAB; - // FALLTHROUGH + FALLTHROUGH; case TAB: // TAB or Complete patterns along path if (ctrl_x_mode == CTRL_X_PATH_PATTERNS) { @@ -1078,7 +1081,7 @@ static int insert_handle_key(InsertState *s) case K_KENTER: // <Enter> s->c = CAR; - // FALLTHROUGH + FALLTHROUGH; case CAR: case NL: // In a quickfix window a <CR> jumps to the error under the @@ -1096,7 +1099,7 @@ static int insert_handle_key(InsertState *s) cmdwin_result = CAR; return 0; } - if (ins_eol(s->c) && !p_im) { + if (!ins_eol(s->c) && !p_im) { return 0; // out of memory } auto_format(false, false); @@ -1157,7 +1160,7 @@ static int insert_handle_key(InsertState *s) } goto normalchar; } - // FALLTHROUGH + FALLTHROUGH; case Ctrl_P: // Do previous/next pattern completion case Ctrl_N: @@ -1376,7 +1379,7 @@ ins_redraw ( // Make sure curswant is correct, an autocommand may call // getcurpos() update_curswant(); - apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_CURSORMOVEDI); } if (curwin->w_p_cole > 0) { conceal_old_cursor_line = last_cursormoved.lnum; @@ -1390,8 +1393,18 @@ ins_redraw ( if (ready && has_event(EVENT_TEXTCHANGEDI) && curbuf->b_last_changedtick != buf_get_changedtick(curbuf) && !pum_visible()) { + aco_save_T aco; + varnumber_T tick = buf_get_changedtick(curbuf); + + // save and restore curwin and curbuf, in case the autocmd changes them + aucmd_prepbuf(&aco, curbuf); apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf); + aucmd_restbuf(&aco); curbuf->b_last_changedtick = buf_get_changedtick(curbuf); + if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds() + u_save(curwin->w_cursor.lnum, + (linenr_T)(curwin->w_cursor.lnum + 1)); + } } // Trigger TextChangedP if changedtick differs. When the popupmenu closes @@ -1400,8 +1413,18 @@ ins_redraw ( if (ready && has_event(EVENT_TEXTCHANGEDP) && curbuf->b_last_changedtick_pum != buf_get_changedtick(curbuf) && pum_visible()) { - apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, false, curbuf); - curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf); + aco_save_T aco; + varnumber_T tick = buf_get_changedtick(curbuf); + + // save and restore curwin and curbuf, in case the autocmd changes them + aucmd_prepbuf(&aco, curbuf); + apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, false, curbuf); + aucmd_restbuf(&aco); + curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf); + if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds() + u_save(curwin->w_cursor.lnum, + (linenr_T)(curwin->w_cursor.lnum + 1)); + } } if (must_redraw) @@ -1514,12 +1537,14 @@ void edit_putchar(int c, int highlight) void edit_unputchar(void) { if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) { - if (pc_status == PC_STATUS_RIGHT) - ++curwin->w_wcol; - if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) - redrawWinline(curwin->w_cursor.lnum, FALSE); - else + if (pc_status == PC_STATUS_RIGHT) { + curwin->w_wcol++; + } + if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) { + redrawWinline(curwin, curwin->w_cursor.lnum, false); + } else { screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr); + } } } @@ -1536,14 +1561,11 @@ void display_dollar(colnr_T col) save_col = curwin->w_cursor.col; curwin->w_cursor.col = col; - if (has_mbyte) { - char_u *p; - /* If on the last byte of a multi-byte move to the first byte. */ - p = get_cursor_line_ptr(); - curwin->w_cursor.col -= (*mb_head_off)(p, p + col); - } - curs_columns(FALSE); /* recompute w_wrow and w_wcol */ + // If on the last byte of a multi-byte move to the first byte. + char_u *p = get_cursor_line_ptr(); + curwin->w_cursor.col -= utf_head_off(p, p + col); + curs_columns(false); // Recompute w_wrow and w_wcol if (curwin->w_wcol < curwin->w_width) { edit_putchar('$', FALSE); dollar_vcol = curwin->w_virtcol; @@ -1559,7 +1581,7 @@ static void undisplay_dollar(void) { if (dollar_vcol >= 0) { dollar_vcol = -1; - redrawWinline(curwin->w_cursor.lnum, FALSE); + redrawWinline(curwin, curwin->w_cursor.lnum, false); } } @@ -1766,8 +1788,8 @@ change_indent ( /* We only put back the new line up to the cursor */ new_line[curwin->w_cursor.col] = NUL; - /* Put back original line */ - ml_replace(curwin->w_cursor.lnum, orig_line, FALSE); + // Put back original line + ml_replace(curwin->w_cursor.lnum, orig_line, false); curwin->w_cursor.col = orig_col; /* Backspace from cursor to start of line */ @@ -2114,11 +2136,7 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int char_u *p = IObuff; i = 0; while (i < actual_len && (p - IObuff + 6) < IOSIZE) { - if (has_mbyte) { - p += (*mb_char2bytes)(wca[i++], p); - } else { - *(p++) = wca[i++]; - } + p += utf_char2bytes(wca[i++], p); } *p = NUL; } @@ -2311,24 +2329,14 @@ static void ins_compl_longest_match(compl_T *match) p = compl_leader; s = match->cp_str; while (*p != NUL) { - if (has_mbyte) { - c1 = mb_ptr2char(p); - c2 = mb_ptr2char(s); - } else { - c1 = *p; - c2 = *s; - } - if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2)) - : (c1 != c2)) { + c1 = utf_ptr2char(p); + c2 = utf_ptr2char(s); + + if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2)) : (c1 != c2)) { break; } - if (has_mbyte) { - MB_PTR_ADV(p); - MB_PTR_ADV(s); - } else { - ++p; - ++s; - } + MB_PTR_ADV(p); + MB_PTR_ADV(s); } if (*p != NUL) { @@ -3077,10 +3085,10 @@ static void ins_compl_addleader(int c) if (stop_arrow() == FAIL) { return; } - if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) { + if ((cc = utf_char2len(c)) > 1) { char_u buf[MB_MAXBYTES + 1]; - (*mb_char2bytes)(c, buf); + utf_char2bytes(c, buf); buf[cc] = NUL; ins_char_bytes(buf, cc); } else { @@ -3264,7 +3272,7 @@ static bool ins_compl_prep(int c) compl_cont_status |= CONT_LOCAL; else if (compl_cont_mode != 0) compl_cont_status &= ~CONT_LOCAL; - /* FALLTHROUGH */ + FALLTHROUGH; default: /* If we have typed at least 2 ^X's... for modes != 0, we set * compl_cont_status = 0 (eg, as if we had just started ^X @@ -3402,12 +3410,12 @@ static bool ins_compl_prep(int c) do_c_expr_indent(); /* Trigger the CompleteDone event to give scripts a chance to act * upon the completion. */ - apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); + ins_apply_autocmds(EVENT_COMPLETEDONE); } } else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) /* Trigger the CompleteDone event to give scripts a chance to act * upon the (possibly failed) completion. */ - apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf); + ins_apply_autocmds(EVENT_COMPLETEDONE); /* reset continue_* if we left expansion-mode, if we stay they'll be * (re)set properly in ins_complete() */ @@ -3438,10 +3446,10 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg) } if (compl_orig_text != NULL) { p = compl_orig_text; - for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len) - ; - if (len > 0) - len -= (*mb_head_off)(p, p + len); + for (len = 0; p[len] != NUL && p[len] == ptr[len]; len++) {} + if (len > 0) { + len -= utf_head_off(p, p + len); + } for (p += len; *p != NUL; MB_PTR_ADV(p)) { AppendCharToRedobuff(K_BS); } @@ -4456,7 +4464,7 @@ static int ins_complete(int c, bool enable_pum) int save_w_wrow; int save_w_leftcol; int insert_match; - int save_did_ai = did_ai; + const bool save_did_ai = did_ai; compl_direction = ins_compl_key2dir(c); insert_match = ins_compl_use_match(c); @@ -4464,12 +4472,13 @@ static int ins_complete(int c, bool enable_pum) if (!compl_started) { /* First time we hit ^N or ^P (in a row, I mean) */ - did_ai = FALSE; - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; - if (stop_arrow() == FAIL) + did_ai = false; + did_si = false; + can_si = false; + can_si_back = false; + if (stop_arrow() == FAIL) { return FAIL; + } line = ml_get(curwin->w_cursor.lnum); curs_col = curwin->w_cursor.col; @@ -4495,7 +4504,7 @@ static int ins_complete(int c, bool enable_pum) * first non_blank in the line, if it is not a wordchar * include it to get a better pattern, but then we don't * want the "\\<" prefix, check it bellow */ - compl_col = (colnr_T)(skipwhite(line) - line); + compl_col = (colnr_T)getwhitecols(line); compl_startpos.col = compl_col; compl_startpos.lnum = curwin->w_cursor.lnum; compl_cont_status &= ~CONT_SOL; /* clear SOL if present */ @@ -4576,24 +4585,17 @@ static int ins_complete(int c, bool enable_pum) compl_col += curs_col; compl_length = 0; } else { - /* Search the point of change class of multibyte character - * or not a word single byte character backward. */ - if (has_mbyte) { - int base_class; - int head_off; - - startcol -= (*mb_head_off)(line, line + startcol); - base_class = mb_get_class(line + startcol); - while (--startcol >= 0) { - head_off = (*mb_head_off)(line, line + startcol); - if (base_class != mb_get_class(line + startcol - - head_off)) - break; - startcol -= head_off; + // Search the point of change class of multibyte character + // or not a word single byte character backward. + startcol -= utf_head_off(line, line + startcol); + int base_class = mb_get_class(line + startcol); + while (--startcol >= 0) { + int head_off = utf_head_off(line, line + startcol); + if (base_class != mb_get_class(line + startcol - head_off)) { + break; } - } else - while (--startcol >= 0 && vim_iswordc(line[startcol])) - ; + startcol -= head_off; + } compl_col += ++startcol; compl_length = (int)curs_col - startcol; if (compl_length == 1) { @@ -4614,7 +4616,7 @@ static int ins_complete(int c, bool enable_pum) } } } else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { - compl_col = (colnr_T)(skipwhite(line) - line); + compl_col = (colnr_T)getwhitecols(line); compl_length = (int)curs_col - (int)compl_col; if (compl_length < 0) /* cursor in indent: empty pattern */ compl_length = 0; @@ -4968,16 +4970,16 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len) if (ctrl_x_mode == CTRL_X_DICTIONARY || ctrl_x_mode == CTRL_X_THESAURUS) break; - // fallthrough + FALLTHROUGH; case '~': if (!p_magic) /* quote these only if magic is set */ break; - // fallthrough + FALLTHROUGH; case '\\': if (ctrl_x_mode == CTRL_X_DICTIONARY || ctrl_x_mode == CTRL_X_THESAURUS) break; - // fallthrough + FALLTHROUGH; case '^': // currently it's not needed. case '$': m++; @@ -5269,10 +5271,10 @@ insertchar ( } end_comment_pending = NUL; - did_ai = FALSE; - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; + did_ai = false; + did_si = false; + can_si = false; + can_si_back = false; // If there's any pending input, grab up to INPUT_BUFLEN at once. // This speeds up normal text input considerably. @@ -5333,10 +5335,10 @@ insertchar ( } else { int cc; - if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) { + if ((cc = utf_char2len(c)) > 1) { char_u buf[MB_MAXBYTES + 1]; - (*mb_char2bytes)(c, buf); + utf_char2bytes(c, buf); buf[cc] = NUL; ins_char_bytes(buf, cc); AppendCharToRedobuff(c); @@ -5367,7 +5369,7 @@ internal_format ( { int cc; int save_char = NUL; - int haveto_redraw = FALSE; + bool haveto_redraw = false; int fo_ins_blank = has_format_option(FO_INS_BLANK); int fo_multibyte = has_format_option(FO_MBYTE_BREAK); int fo_white_par = has_format_option(FO_WHITE_PAR); @@ -5655,13 +5657,13 @@ internal_format ( curwin->w_cursor.col = len; } - haveto_redraw = TRUE; - can_cindent = TRUE; - /* moved the cursor, don't autoindent or cindent now */ - did_ai = FALSE; - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; + haveto_redraw = true; + can_cindent = true; + // moved the cursor, don't autoindent or cindent now + did_ai = false; + did_si = false; + can_si = false; + can_si_back = false; line_breakcheck(); } @@ -5702,8 +5704,8 @@ auto_format ( pos = curwin->w_cursor; old = get_cursor_line_ptr(); - /* may remove added space */ - check_auto_format(FALSE); + // may remove added space + check_auto_format(false); /* Don't format in Insert mode when the cursor is on a trailing blank, the * user might insert normal text next. Also skip formatting when "1" is @@ -5769,12 +5771,13 @@ auto_format ( pnew = vim_strnsave(new, len + 2); pnew[len] = ' '; pnew[len + 1] = NUL; - ml_replace(curwin->w_cursor.lnum, pnew, FALSE); - /* remove the space later */ - did_add_space = TRUE; - } else - /* may remove added space */ - check_auto_format(FALSE); + ml_replace(curwin->w_cursor.lnum, pnew, false); + // remove the space later + did_add_space = true; + } else { + // may remove added space + check_auto_format(false); + } } check_cursor(); @@ -5785,9 +5788,8 @@ auto_format ( * delete it now. The space must be under the cursor, just after the insert * position. */ -static void -check_auto_format ( - int end_insert /* TRUE when ending Insert mode */ +static void check_auto_format( + bool end_insert // true when ending Insert mode ) { int c = ' '; @@ -5795,19 +5797,19 @@ check_auto_format ( if (did_add_space) { cc = gchar_cursor(); - if (!WHITECHAR(cc)) - /* Somehow the space was removed already. */ - did_add_space = FALSE; - else { + if (!WHITECHAR(cc)) { + // Somehow the space was removed already. + did_add_space = false; + } else { if (!end_insert) { inc_cursor(); c = gchar_cursor(); dec_cursor(); } if (c != NUL) { - /* The space is no longer at the end of the line, delete it. */ - del_char(FALSE); - did_add_space = FALSE; + // The space is no longer at the end of the line, delete it. + del_char(false); + did_add_space = false; } } } @@ -5912,7 +5914,7 @@ static void check_spell_redraw(void) linenr_T lnum = spell_redraw_lnum; spell_redraw_lnum = 0; - redrawWinline(lnum, FALSE); + redrawWinline(curwin, lnum, false); } } @@ -6032,8 +6034,8 @@ stop_insert ( } } - /* If a space was inserted for auto-formatting, remove it now. */ - check_auto_format(TRUE); + // If a space was inserted for auto-formatting, remove it now. + check_auto_format(true); /* If we just did an auto-indent, remove the white space from the end * of the line, and put the cursor back. @@ -6052,10 +6054,12 @@ stop_insert ( if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) --curwin->w_cursor.col; cc = gchar_cursor(); - if (!ascii_iswhite(cc)) + if (!ascii_iswhite(cc)) { break; - if (del_char(TRUE) == FAIL) - break; /* should not happen */ + } + if (del_char(true) == FAIL) { + break; // should not happen + } } if (curwin->w_cursor.lnum != tpos.lnum) curwin->w_cursor = tpos; @@ -6080,10 +6084,10 @@ stop_insert ( } } } - did_ai = FALSE; - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; + did_ai = false; + did_si = false; + can_si = false; + can_si_back = false; /* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are * now in a different buffer. */ @@ -6197,12 +6201,10 @@ int oneright(void) /* Adjust for multi-wide char (excluding TAB) */ ptr = get_cursor_pos_ptr(); - coladvance(getviscol() + ((*ptr != TAB && vim_isprintc( - (*mb_ptr2char)(ptr) - )) - ? ptr2cells(ptr) : 1)); - curwin->w_set_curswant = TRUE; - /* Return OK if the cursor moved, FAIL otherwise (at window edge). */ + coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ? + ptr2cells(ptr) : 1)); + curwin->w_set_curswant = true; + // Return OK if the cursor moved, FAIL otherwise (at window edge). return (prevpos.col != curwin->w_cursor.col || prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL; } @@ -6257,10 +6259,10 @@ int oneleft(void) /* Adjust for multi-wide char (not a TAB) */ ptr = get_cursor_pos_ptr(); - if (*ptr != TAB && vim_isprintc( - (*mb_ptr2char)(ptr) - ) && ptr2cells(ptr) > 1) + if (*ptr != TAB && vim_isprintc(utf_ptr2char(ptr)) + && ptr2cells(ptr) > 1) { curwin->w_cursor.coladd = 0; + } } curwin->w_set_curswant = TRUE; @@ -6407,8 +6409,10 @@ stuff_inserted ( /* may want to stuff the command character, to start Insert mode */ if (c != NUL) stuffcharReadbuff(c); - if ((esc_ptr = (char_u *)vim_strrchr(ptr, ESC)) != NULL) - *esc_ptr = NUL; /* remove the ESC */ + if ((esc_ptr = STRRCHR(ptr, ESC)) != NULL) { + // remove the ESC. + *esc_ptr = NUL; + } /* when the last char is either "0" or "^" it will be quoted if no ESC * comes after it OR if it will inserted more than once and "ptr" @@ -6709,8 +6713,8 @@ static void replace_do_bs(int limit_col) * text aligned. */ curwin->w_cursor.col += ins_len; while (vcol > orig_vcols && gchar_cursor() == ' ') { - del_char(FALSE); - ++orig_vcols; + del_char(false); + orig_vcols++; } curwin->w_cursor.col -= ins_len; } @@ -6906,7 +6910,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) p = look + STRLEN(look); if ((try_match || try_match_word) && curwin->w_cursor.col >= (colnr_T)(p - look)) { - int match = FALSE; + bool match = false; if (keytyped == KEY_COMPLETE) { char_u *s; @@ -6931,29 +6935,30 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) && (icase ? mb_strnicmp(s, look, (size_t)(p - look)) : STRNCMP(s, look, p - look)) == 0) - match = TRUE; - } else - /* TODO: multi-byte */ - if (keytyped == (int)p[-1] || (icase && keytyped < 256 - && TOLOWER_LOC(keytyped) == - TOLOWER_LOC((int)p[-1]))) { - line = get_cursor_pos_ptr(); - assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX); - if ((curwin->w_cursor.col == (colnr_T)(p - look) - || !vim_iswordc(line[-(p - look) - 1])) - && (icase - ? mb_strnicmp(line - (p - look), look, (size_t)(p - look)) - : STRNCMP(line - (p - look), look, p - look)) - == 0) - match = TRUE; + match = true; + } else { + // TODO(@brammool): multi-byte + if (keytyped == (int)p[-1] + || (icase && keytyped < 256 + && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1]))) { + line = get_cursor_pos_ptr(); + assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX); + if ((curwin->w_cursor.col == (colnr_T)(p - look) + || !vim_iswordc(line[-(p - look) - 1])) + && (icase + ? mb_strnicmp(line - (p - look), look, (size_t)(p - look)) + : STRNCMP(line - (p - look), look, p - look)) == 0) { + match = true; + } + } } if (match && try_match_word && !try_match) { /* "0=word": Check if there are only blanks before the * word. */ - line = get_cursor_line_ptr(); - if ((int)(skipwhite(line) - line) != - (int)(curwin->w_cursor.col - (p - look))) - match = FALSE; + if (getwhitecols_curline() != + (int)(curwin->w_cursor.col - (p - look))) { + match = false; + } } if (match) { return true; @@ -7174,7 +7179,7 @@ static void ins_ctrl_g(void) case 'U': // Allow one left/right cursor movement with the next char, // without breaking undo. - dont_sync_undo = MAYBE; + dont_sync_undo = kNone; break; /* Unknown CTRL-G command, reserved for future expansion. */ @@ -7368,7 +7373,7 @@ static bool ins_start_select(int c) case K_KPAGEDOWN: if (!(mod_mask & MOD_MASK_SHIFT)) break; - // FALLTHROUGH + FALLTHROUGH; case K_S_LEFT: case K_S_RIGHT: case K_S_UP: @@ -7406,7 +7411,7 @@ static void ins_insert(int replaceState) set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" : replaceState == VREPLACE ? "v" : "r"), 1); - apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, false, curbuf); + ins_apply_autocmds(EVENT_INSERTCHANGE); if (State & REPLACE_FLAG) { State = INSERT | (State & LANGMAP); } else { @@ -7452,46 +7457,55 @@ static void ins_shift(int c, int lastc) */ if (c == Ctrl_D && (lastc == '0' || lastc == '^') && curwin->w_cursor.col > 0) { - --curwin->w_cursor.col; - (void)del_char(FALSE); /* delete the '^' or '0' */ - /* In Replace mode, restore the characters that '^' or '0' replaced. */ - if (State & REPLACE_FLAG) + curwin->w_cursor.col--; + (void)del_char(false); // delete the '^' or '0' + // In Replace mode, restore the characters that '^' or '0' replaced. + if (State & REPLACE_FLAG) { replace_pop_ins(); - if (lastc == '^') - old_indent = get_indent(); /* remember curr. indent */ + } + if (lastc == '^') { + old_indent = get_indent(); // remember curr. indent + } change_indent(INDENT_SET, 0, TRUE, 0, TRUE); } else change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE); - if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) - did_ai = FALSE; - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; - can_cindent = FALSE; /* no cindenting after ^D or ^T */ + if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) { + did_ai = false; + } + did_si = false; + can_si = false; + can_si_back = false; + can_cindent = false; // no cindenting after ^D or ^T } static void ins_del(void) { - int temp; - - if (stop_arrow() == FAIL) + if (stop_arrow() == FAIL) { return; - if (gchar_cursor() == NUL) { /* delete newline */ - temp = curwin->w_cursor.col; + } + if (gchar_cursor() == NUL) { // delete newline + const int temp = curwin->w_cursor.col; if (!can_bs(BS_EOL) // only if "eol" included || do_join(2, false, true, false, false) == FAIL) { vim_beep(BO_BS); } else { curwin->w_cursor.col = temp; + // Adjust orig_line_count in case more lines have been deleted than + // have been added. That makes sure, that open_line() later + // can access all buffer lines correctly + if (State & VREPLACE_FLAG + && orig_line_count > curbuf->b_ml.ml_line_count) { + orig_line_count = curbuf->b_ml.ml_line_count; + } } } else if (del_char(false) == FAIL) { // delete char under cursor vim_beep(BO_BS); } - did_ai = FALSE; - did_si = FALSE; - can_si = FALSE; - can_si_back = FALSE; + did_ai = false; + did_si = false; + can_si = false; + can_si_back = false; AppendCharToRedobuff(K_DEL); } @@ -7509,8 +7523,9 @@ static void ins_bs_one(colnr_T *vcolp) if (curwin->w_cursor.lnum != Insstart.lnum || curwin->w_cursor.col >= Insstart.col) replace_do_bs(-1); - } else - (void)del_char(FALSE); + } else { + (void)del_char(false); + } } /// Handle Backspace, delete-word and delete-line in Insert mode. @@ -7658,7 +7673,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) State = oldState; } } - did_ai = FALSE; + did_ai = false; } else { /* * Delete character(s) before the cursor. @@ -7774,16 +7789,16 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) else { const bool l_enc_utf8 = enc_utf8; const int l_p_deco = p_deco; - if (l_enc_utf8 && l_p_deco) + if (l_enc_utf8 && l_p_deco) { (void)utfc_ptr2char(get_cursor_pos_ptr(), cpc); - (void)del_char(FALSE); - /* - * If there are combining characters and 'delcombine' is set - * move the cursor back. Don't back up before the base - * character. - */ - if (l_enc_utf8 && l_p_deco && cpc[0] != NUL) + } + (void)del_char(false); + // If there are combining characters and 'delcombine' is set + // move the cursor back. Don't back up before the base + // character. + if (l_enc_utf8 && l_p_deco && cpc[0] != NUL) { inc_cursor(); + } if (revins_chars) { revins_chars--; revins_legal++; @@ -7862,7 +7877,7 @@ static void ins_mouse(int c) curwin = new_curwin; curbuf = curwin->w_buffer; } - can_cindent = TRUE; + can_cindent = true; } /* redraw status lines (in case another window became active) */ @@ -7871,20 +7886,20 @@ static void ins_mouse(int c) static void ins_mousescroll(int dir) { - pos_T tpos; - win_T *old_curwin = curwin; - int did_scroll = FALSE; - - tpos = curwin->w_cursor; + win_T *const old_curwin = curwin; + bool did_scroll = false; + pos_T tpos = curwin->w_cursor; if (mouse_row >= 0 && mouse_col >= 0) { - int row, col; + int row = mouse_row; + int col = mouse_col; - row = mouse_row; - col = mouse_col; - - /* find the window at the pointer coordinates */ - curwin = mouse_find_win(&row, &col); + // find the window at the pointer coordinates + win_T *const wp = mouse_find_win(&row, &col); + if (wp == NULL) { + return; + } + curwin = wp; curbuf = curwin->w_buffer; } if (curwin == old_curwin) @@ -7903,7 +7918,7 @@ static void ins_mousescroll(int dir) } else { mouse_scroll_horiz(dir); } - did_scroll = TRUE; + did_scroll = true; } curwin->w_redr_status = TRUE; @@ -7921,7 +7936,7 @@ static void ins_mousescroll(int dir) if (!equalpos(curwin->w_cursor, tpos)) { start_arrow(&tpos); - can_cindent = TRUE; + can_cindent = true; } } @@ -7954,7 +7969,7 @@ static void ins_left(bool end_change) } else { vim_beep(BO_CRSR); } - dont_sync_undo = false; + dont_sync_undo = kFalse; } static void ins_home(int c) @@ -8039,7 +8054,7 @@ static void ins_right(bool end_change) } else { vim_beep(BO_CRSR); } - dont_sync_undo = false; + dont_sync_undo = kFalse; } static void ins_s_right(void) @@ -8344,14 +8359,14 @@ static bool ins_tab(void) /// Handle CR or NL in insert mode. /// -/// @return true when it can't undo. +/// @return false when it can't undo. static bool ins_eol(int c) { if (echeck_abbr(c + ABBR_OFF)) { - return false; + return true; } if (stop_arrow() == FAIL) { - return true; + return false; } undisplay_dollar(); @@ -8389,11 +8404,11 @@ static bool ins_eol(int c) has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0, old_indent); old_indent = 0; - can_cindent = TRUE; - /* When inserting a line the cursor line must never be in a closed fold. */ + can_cindent = true; + // When inserting a line the cursor line must never be in a closed fold. foldOpenCursor(); - return !i; + return i; } /* @@ -8494,7 +8509,7 @@ int ins_copychar(linenr_T lnum) if ((colnr_T)temp > curwin->w_virtcol) ptr = prev_ptr; - c = (*mb_ptr2char)(ptr); + c = utf_ptr2char(ptr); if (c == NUL) { vim_beep(BO_COPY); } @@ -8646,24 +8661,20 @@ static char_u *do_insert_char_pre(int c) if (!has_event(EVENT_INSERTCHARPRE)) { return NULL; } - if (has_mbyte) { - buf[(*mb_char2bytes)(c, (char_u *) buf)] = NUL; - } else { - buf[0] = c; - buf[1] = NUL; - } + buf[utf_char2bytes(c, (char_u *)buf)] = NUL; // Lock the text to avoid weird things from happening. textlock++; set_vim_var_string(VV_CHAR, buf, -1); char_u *res = NULL; - if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) { - /* Get the value of v:char. It may be empty or more than one - * character. Only use it when changed, otherwise continue with the - * original character to avoid breaking autoindent. */ - if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) + if (ins_apply_autocmds(EVENT_INSERTCHARPRE)) { + // Get the value of v:char. It may be empty or more than one + // character. Only use it when changed, otherwise continue with the + // original character to avoid breaking autoindent. + if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) { res = vim_strsave(get_vim_var_str(VV_CHAR)); + } } set_vim_var_string(VV_CHAR, NULL, -1); @@ -8672,6 +8683,23 @@ static char_u *do_insert_char_pre(int c) return res; } +/// Trigger "event" and take care of fixing undo. +static int ins_apply_autocmds(event_T event) +{ + varnumber_T tick = buf_get_changedtick(curbuf); + int r; + + r = apply_autocmds(event, NULL, NULL, false, curbuf); + + // If u_savesub() was called then we are not prepared to start + // a new line. Call u_save() with no contents to fix that. + if (tick != buf_get_changedtick(curbuf)) { + u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1)); + } + + return r; +} + static void show_pum(int prev_w_wrow, int prev_w_leftcol) { // RedrawingDisabled may be set when invoked through complete(). diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e6880f58e7..9c7af0a87d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -344,11 +344,11 @@ static struct vimvar { VV(VV_COUNT, "count", VAR_NUMBER, VV_RO), VV(VV_COUNT1, "count1", VAR_NUMBER, VV_RO), VV(VV_PREVCOUNT, "prevcount", VAR_NUMBER, VV_RO), - VV(VV_ERRMSG, "errmsg", VAR_STRING, VV_COMPAT), + VV(VV_ERRMSG, "errmsg", VAR_STRING, 0), VV(VV_WARNINGMSG, "warningmsg", VAR_STRING, 0), VV(VV_STATUSMSG, "statusmsg", VAR_STRING, 0), - VV(VV_SHELL_ERROR, "shell_error", VAR_NUMBER, VV_COMPAT+VV_RO), - VV(VV_THIS_SESSION, "this_session", VAR_STRING, VV_COMPAT), + VV(VV_SHELL_ERROR, "shell_error", VAR_NUMBER, VV_RO), + VV(VV_THIS_SESSION, "this_session", VAR_STRING, 0), VV(VV_VERSION, "version", VAR_NUMBER, VV_COMPAT+VV_RO), VV(VV_LNUM, "lnum", VAR_NUMBER, VV_RO_SBX), VV(VV_TERMRESPONSE, "termresponse", VAR_STRING, VV_RO), @@ -496,7 +496,7 @@ typedef enum { #define FNE_CHECK_START 2 /* find_name_end(): check name starts with valid character */ -static uint64_t last_timer_id = 0; +static uint64_t last_timer_id = 1; static PMap(uint64_t) *timers = NULL; /// Dummy va_list for passing to vim_snprintf @@ -1186,7 +1186,7 @@ int call_vim_function( const char_u *func, int argc, const char_u *const *const argv, - int safe, // use the sandbox + bool safe, // use the sandbox int str_arg_only, // all arguments are strings typval_T *rettv ) @@ -1210,8 +1210,12 @@ int call_vim_function( if (str_arg_only) { len = 0; } else { - // Recognize a number argument, the others must be strings. + // Recognize a number argument, the others must be strings. A dash + // is a string too. vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0); + if (len == 1 && *argv[i] == '-') { + len = 0; + } } if (len != 0 && len == (int)STRLEN(argv[i])) { argvars[i].v_type = VAR_NUMBER; @@ -1276,9 +1280,9 @@ varnumber_T call_func_retnr(char_u *func, int argc, /// /// @return [allocated] NULL when calling function fails, allocated string /// otherwise. -char *call_func_retstr(const char *const func, const int argc, - const char_u *const *const argv, - const bool safe) +char *call_func_retstr(const char *const func, int argc, + const char_u *const *argv, + bool safe) FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { typval_T rettv; @@ -1302,8 +1306,8 @@ char *call_func_retstr(const char *const func, const int argc, /// /// @return [allocated] NULL when calling function fails or return tv is not a /// List, allocated List otherwise. -void *call_func_retlist(char_u *func, int argc, const char_u *const *const argv, - int safe) +void *call_func_retlist(char_u *func, int argc, const char_u *const *argv, + bool safe) { typval_T rettv; @@ -1908,6 +1912,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, if ((opt_type == 1 && *op == '.') || (opt_type == 0 && *op != '.')) { EMSG2(_(e_letwrong), op); + s = NULL; // don't set the value } else { if (opt_type == 1) { // number if (*op == '+') { @@ -1938,7 +1943,7 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv, emsgf(_(e_letwrong), op); } else if (endchars != NULL && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) { - emsgf(_(e_letunexp)); + EMSG(_(e_letunexp)); } else { char_u *s; @@ -2072,7 +2077,11 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, return p; } - v = find_var(lp->ll_name, lp->ll_name_len, &ht, flags & GLV_NO_AUTOLOAD); + // Only pass &ht when we would write to the variable, it prevents autoload + // as well. + v = find_var(lp->ll_name, lp->ll_name_len, + (flags & GLV_READ_ONLY) ? NULL : &ht, + flags & GLV_NO_AUTOLOAD); if (v == NULL && !quiet) { emsgf(_("E121: Undefined variable: %.*s"), (int)lp->ll_name_len, lp->ll_name); @@ -2143,7 +2152,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, if (rettv != NULL && (rettv->v_type != VAR_LIST || rettv->vval.v_list == NULL)) { if (!quiet) { - emsgf(_("E709: [:] requires a List value")); + EMSG(_("E709: [:] requires a List value")); } tv_clear(&var1); return NULL; @@ -2170,7 +2179,7 @@ static char_u *get_lval(char_u *const name, typval_T *const rettv, if (*p != ']') { if (!quiet) { - emsgf(_(e_missbrac)); + EMSG(_(e_missbrac)); } tv_clear(&var1); tv_clear(&var2); @@ -2719,6 +2728,12 @@ void ex_call(exarg_T *eap) lnum = eap->line1; for (; lnum <= eap->line2; lnum++) { if (eap->addr_count > 0) { // -V560 + if (lnum > curbuf->b_ml.ml_line_count) { + // If the function deleted lines or switched to another buffer + // the line number may become invalid. + EMSG(_(e_invrange)); + break; + } curwin->w_cursor.lnum = lnum; curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; @@ -2809,6 +2824,18 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep) lval_T lv; do { + if (*arg == '$') { + const char *name = (char *)++arg; + + if (get_env_len((const char_u **)&arg) == 0) { + EMSG2(_(e_invarg2), name - 1); + return; + } + os_unsetenv(name); + arg = skipwhite(arg); + continue; + } + // Parse the name and find the end. char_u *const name_end = (char_u *)get_lval(arg, NULL, &lv, true, eap->skip || error, @@ -3304,7 +3331,7 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate) * Check for the ":". */ if ((*arg)[0] != ':') { - emsgf(_("E109: Missing ':' after '?'")); + EMSG(_("E109: Missing ':' after '?'")); if (evaluate && result) { tv_clear(rettv); } @@ -4347,7 +4374,7 @@ eval_index( if (evaluate) { return FAIL; } - // fallthrough + FALLTHROUGH; } case VAR_STRING: case VAR_NUMBER: @@ -4412,7 +4439,7 @@ eval_index( /* Check for the ']'. */ if (**arg != ']') { if (verbose) { - emsgf(_(e_missbrac)); + EMSG(_(e_missbrac)); } tv_clear(&var1); if (range) { @@ -4524,7 +4551,7 @@ eval_index( case VAR_DICT: { if (range) { if (verbose) { - emsgf(_(e_dictrange)); + EMSG(_(e_dictrange)); } if (len == -1) { tv_clear(&var1); @@ -4714,10 +4741,11 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) ++p; /* For "\u" store the number according to * 'encoding'. */ - if (c != 'X') - name += (*mb_char2bytes)(nr, name); - else + if (c != 'X') { + name += utf_char2bytes(nr, name); + } else { *name++ = nr; + } } break; @@ -4745,7 +4773,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) name += extra; break; } - // FALLTHROUGH + FALLTHROUGH; default: MB_COPY_CHAR(p, name); break; @@ -7210,7 +7238,7 @@ static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = -1; } else { rettv->vval.v_number = (varnumber_T)ml_find_line_or_offset(curbuf, 0, - &boff); + &boff, false); } } @@ -7592,9 +7620,38 @@ static void f_copy(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) { long n = 0; - int ic = FALSE; + int ic = 0; + bool error = false; - if (argvars[0].v_type == VAR_LIST) { + if (argvars[2].v_type != VAR_UNKNOWN) { + ic = tv_get_number_chk(&argvars[2], &error); + } + + if (argvars[0].v_type == VAR_STRING) { + const char_u *expr = (char_u *)tv_get_string_chk(&argvars[1]); + const char_u *p = argvars[0].vval.v_string; + + if (!error && expr != NULL && *expr != NUL && p != NULL) { + if (ic) { + const size_t len = STRLEN(expr); + + while (*p != NUL) { + if (mb_strnicmp(p, expr, len) == 0) { + n++; + p += len; + } else { + MB_PTR_ADV(p); + } + } + } else { + char_u *next; + while ((next = (char_u *)strstr((char *)p, (char *)expr)) != NULL) { + n++; + p = next + STRLEN(expr); + } + } + } + } else if (argvars[0].v_type == VAR_LIST) { listitem_T *li; list_T *l; long idx; @@ -7602,9 +7659,6 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) if ((l = argvars[0].vval.v_list) != NULL) { li = tv_list_first(l); if (argvars[2].v_type != VAR_UNKNOWN) { - bool error = false; - - ic = tv_get_number_chk(&argvars[2], &error); if (argvars[3].v_type != VAR_UNKNOWN) { idx = tv_get_number_chk(&argvars[3], &error); if (!error) { @@ -7630,10 +7684,7 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) hashitem_T *hi; if ((d = argvars[0].vval.v_dict) != NULL) { - bool error = false; - if (argvars[2].v_type != VAR_UNKNOWN) { - ic = tv_get_number_chk(&argvars[2], &error); if (argvars[3].v_type != VAR_UNKNOWN) { EMSG(_(e_invarg)); } @@ -7649,8 +7700,9 @@ static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } - } else + } else { EMSG2(_(e_listdictarg), "count()"); + } rettv->vval.v_number = n; } @@ -7749,7 +7801,7 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr) noref = tv_get_number_chk(&argvars[1], NULL); } if (noref < 0 || noref > 1) { - emsgf(_(e_invarg)); + EMSG(_(e_invarg)); } else { var_item_copy(NULL, &argvars[0], rettv, true, (noref == 0 ? get_copyID() @@ -7789,7 +7841,7 @@ static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr) // delete a directory recursively rettv->vval.v_number = delete_recursive(name); } else { - EMSG2(_(e_invexpr2), flags); + emsgf(_(e_invexpr2), flags); } } @@ -8844,9 +8896,14 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u buf[FOLD_TEXT_LEN]; foldinfo_T foldinfo; int fold_count; + static bool entered = false; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (entered) { + return; // reject recursive use + } + entered = true; linenr_T lnum = tv_get_lnum(argvars); // Treat illegal types and illegal string values for {lnum} the same. if (lnum < 0) { @@ -8860,6 +8917,8 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) } rettv->vval.v_string = text; } + + entered = false; } /* @@ -8910,7 +8969,7 @@ static void common_function(typval_T *argvars, typval_T *rettv, } else if (trans_name != NULL && (is_funcref ? find_func(trans_name) == NULL : !translated_function_exists((const char *)trans_name))) { - EMSG2(_("E700: Unknown function: %s"), s); + emsgf(_("E700: Unknown function: %s"), s); } else { int dict_idx = 0; int arg_idx = 0; @@ -9449,10 +9508,9 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) temp[i++] = K_SPECIAL; temp[i++] = K_SECOND(n); temp[i++] = K_THIRD(n); - } else if (has_mbyte) - i += (*mb_char2bytes)(n, temp + i); - else - temp[i++] = n; + } else { + i += utf_char2bytes(n, temp + i); + } temp[i++] = NUL; rettv->v_type = VAR_STRING; rettv->vval.v_string = vim_strsave(temp); @@ -9469,6 +9527,9 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) /* Find the window at the mouse coordinates and compute the * text position. */ win = mouse_find_win(&row, &col); + if (win == NULL) { + return; + } (void)mouse_comp_pos(win, &row, &col, &lnum); for (wp = firstwin; wp != win; wp = wp->w_next) ++winnr; @@ -9706,14 +9767,14 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (from) { break; } - // fallthrough + FALLTHROUGH; case kCdScopeTab: assert(tp); from = tp->tp_localdir; if (from) { break; } - // fallthrough + FALLTHROUGH; case kCdScopeGlobal: if (globaldir) { // `globaldir` is not always set. from = globaldir; @@ -9847,7 +9908,7 @@ static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr) # endif # ifdef S_ISSOCK else if (S_ISSOCK(mode)) - t = "fifo"; + t = "socket"; # endif else t = "other"; @@ -9912,7 +9973,7 @@ static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, if (what_arg->v_type == VAR_UNKNOWN) { tv_list_alloc_ret(rettv, kListLenMayKnow); if (is_qf || wp != NULL) { - (void)get_errorlist(wp, -1, rettv->vval.v_list); + (void)get_errorlist(NULL, wp, -1, rettv->vval.v_list); } } else { tv_dict_alloc_ret(rettv); @@ -9979,7 +10040,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (cur->conceal_char) { char buf[MB_MAXBYTES + 1]; - buf[(*mb_char2bytes)((int)cur->conceal_char, (char_u *)buf)] = NUL; + buf[utf_char2bytes((int)cur->conceal_char, (char_u *)buf)] = NUL; tv_dict_add_str(dict, S_LEN("conceal"), buf); } @@ -10183,32 +10244,34 @@ static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { win_T *oldcurwin; - tabpage_T *tp, *oldtabpage; - dictitem_T *v; + tabpage_T *oldtabpage; bool done = false; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; const char *const varname = tv_get_string_chk(&argvars[1]); - tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); + tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL)); if (tp != NULL && varname != NULL) { // Set tp to be our tabpage, temporarily. Also set the window to the // first window in the tabpage, otherwise the window is not valid. - win_T *window = tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin; + win_T *const window = tp == curtab || tp->tp_firstwin == NULL + ? firstwin + : tp->tp_firstwin; if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) { // look up the variable // Let gettabvar({nr}, "") return the "t:" dictionary. - v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', - varname, strlen(varname), false); + const dictitem_T *const v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', + varname, strlen(varname), + false); if (v != NULL) { tv_copy(&v->di_tv, rettv); done = true; } } - /* restore previous notion of curwin */ - restore_win(oldcurwin, oldtabpage, TRUE); + // restore previous notion of curwin + restore_win(oldcurwin, oldtabpage, true); } if (!done && argvars[2].v_type != VAR_UNKNOWN) { @@ -10233,8 +10296,10 @@ static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) tv_dict_add_nr(dict, S_LEN("winnr"), winnr); tv_dict_add_nr(dict, S_LEN("winid"), wp->handle); tv_dict_add_nr(dict, S_LEN("height"), wp->w_height); + tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow); tv_dict_add_nr(dict, S_LEN("width"), wp->w_width); tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum); + tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol); tv_dict_add_nr(dict, S_LEN("quickfix"), bt_quickfix(wp->w_buffer)); tv_dict_add_nr(dict, S_LEN("loclist"), @@ -10281,6 +10346,15 @@ static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } +// "win_screenpos()" function +static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + tv_list_alloc_ret(rettv, 2); + const win_T *const wp = find_win_by_nr(&argvars[0], NULL); + tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1); + tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1); +} + /* * "getwinposx()" function */ @@ -10565,6 +10639,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) #ifdef HAVE_ACL "acl", #endif + "autochdir", "arabic", "autocmd", "browsefilter", @@ -11121,7 +11196,7 @@ void get_user_input(const typval_T *const argvars, char def[1] = { 0 }; if (argvars[0].v_type == VAR_DICT) { if (argvars[1].v_type != VAR_UNKNOWN) { - emsgf(_("E5050: {opts} must be the only argument")); + EMSG(_("E5050: {opts} must be the only argument")); return; } dict_T *const dict = argvars[0].vval.v_dict; @@ -11190,7 +11265,7 @@ void get_user_input(const typval_T *const argvars, } } - int cmd_silent_save = cmd_silent; + const bool cmd_silent_save = cmd_silent; cmd_silent = false; // Want to see the prompt. // Only the part of the message after the last NL is considered as @@ -11430,7 +11505,7 @@ static void dict_list(typval_T *const tv, typval_T *const rettv, const DictListType what) { if (tv->v_type != VAR_DICT) { - emsgf(_(e_dictreq)); + EMSG(_(e_dictreq)); return; } if (tv->vval.v_dict == NULL) { @@ -11649,7 +11724,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && strlen(new_cwd) > 0) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir((char_u *)cwd)) { + if (!os_isdir_executable((const char *)cwd)) { EMSG2(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -11860,7 +11935,7 @@ static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } if (json_decode_string(s, len, rettv) == FAIL) { - emsgf(_("E474: Failed to parse %.*s"), (int) len, s); + emsgf(_("E474: Failed to parse %.*s"), (int)len, s); rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; } @@ -12015,7 +12090,7 @@ static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) { rettv->vval.v_number = -1; } else { - rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); + rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL, false); } if (rettv->vval.v_number >= 0) { rettv->vval.v_number++; @@ -12093,8 +12168,12 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) if (!get_dict) { // Return a string. if (rhs != NULL) { - rettv->vval.v_string = (char_u *)str2special_save( - (const char *)rhs, false, false); + if (*rhs == NUL) { + rettv->vval.v_string = vim_strsave((char_u *)"<Nop>"); + } else { + rettv->vval.v_string = (char_u *)str2special_save( + (char *)rhs, false, false); + } } } else { @@ -12198,7 +12277,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, long start = 0; long nth = 1; colnr_T startcol = 0; - int match = 0; + bool match = false; list_T *l = NULL; listitem_T *li = NULL; long idx = 0; @@ -12296,7 +12375,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, for (;; ) { if (l != NULL) { if (li == NULL) { - match = FALSE; + match = false; break; } xfree(tofree); @@ -12322,7 +12401,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, startcol = (colnr_T)(regmatch.startp[0] + (*mb_ptr2len)(regmatch.startp[0]) - str); if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) { - match = FALSE; + match = false; break; } } @@ -12395,13 +12474,13 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, vim_regfree(regmatch.regprog); } - if (type == kSomeMatchStrPos && l == NULL) { +theend: + if (type == kSomeMatchStrPos && l == NULL && rettv->vval.v_list != NULL) { // matchstrpos() without a list: drop the second item list_T *const ret_l = rettv->vval.v_list; tv_list_item_remove(ret_l, TV_LIST_ITEM_NEXT(ret_l, tv_list_first(ret_l))); } -theend: xfree(tofree); p_cpo = save_cpo; } @@ -12846,7 +12925,7 @@ static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } if (num < 0) { - emsgf(_("E5070: Character number must not be less than zero")); + EMSG(_("E5070: Character number must not be less than zero")); return; } if (num > INT_MAX) { @@ -12992,9 +13071,9 @@ static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; // Type error; errmsg already given. } if (stride == 0) { - emsgf(_("E726: Stride is zero")); + EMSG(_("E726: Stride is zero")); } else if (stride > 0 ? end + 1 < start : end - 1 > start) { - emsgf(_("E727: Start past end")); + EMSG(_("E727: Start past end")); } else { tv_list_alloc_ret(rettv, (end - start) / stride); for (i = start; stride > 0 ? i <= end : i >= end; i += stride) { @@ -13331,7 +13410,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } if (li == NULL) { // Didn't find "item2" after "item". - emsgf(_(e_invrange)); + EMSG(_(e_invrange)); } else { tv_list_move_items(l, item, item2, tv_list_alloc_ret(rettv, cnt), cnt); @@ -14603,6 +14682,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) static char *e_invact = N_("E927: Invalid action: '%s'"); const char *title = NULL; int action = ' '; + static int recursive = 0; rettv->vval.v_number = -1; dict_T *d = NULL; @@ -14610,6 +14690,9 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) if (list_arg->v_type != VAR_LIST) { EMSG(_(e_listreq)); return; + } else if (recursive != 0) { + EMSG(_(e_au_recursive)); + return; } typval_T *action_arg = &args[1]; @@ -14642,7 +14725,7 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) } else if (title_arg->v_type == VAR_DICT) { d = title_arg->vval.v_dict; } else { - emsgf(_(e_dictreq)); + EMSG(_(e_dictreq)); return; } @@ -14651,10 +14734,12 @@ skip_args: title = (wp ? "setloclist()" : "setqflist()"); } + recursive++; list_T *const l = list_arg->vval.v_list; if (set_errorlist(wp, l, action, (char_u *)title, d) == OK) { rettv->vval.v_number = 0; } + recursive--; } /* @@ -15869,7 +15954,7 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) while (charidx >= 0 && byteidx < len) { if (charidx == 0) { - rettv->vval.v_number = mb_ptr2char((const char_u *)str + byteidx); + rettv->vval.v_number = utf_ptr2char((const char_u *)str + byteidx); break; } charidx--; @@ -16138,7 +16223,7 @@ static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr) } if (no < 0 || no >= NSUBEXP) { - EMSGN(_("E935: invalid submatch number: %d"), no); + emsgf(_("E935: invalid submatch number: %d"), no); return; } int retList = 0; @@ -16377,9 +16462,13 @@ static list_T *string_to_list(const char *str, size_t len, const bool keepempty) return list; } +// os_system wrapper. Handles 'verbose', :profile, and v:shell_error. static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, bool retlist) { + proftime_T wait_time; + bool profiling = do_profiling == PROF_YES; + rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; @@ -16406,11 +16495,28 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv, return; // Already did emsg. } + if (p_verbose > 3) { + char *cmdstr = shell_argv_to_str(argv); + verbose_enter_scroll(); + smsg(_("Executing command: \"%s\""), cmdstr); + msg_puts("\n\n"); + verbose_leave_scroll(); + xfree(cmdstr); + } + + if (profiling) { + prof_child_enter(&wait_time); + } + // execute the command size_t nread = 0; char *res = NULL; int status = os_system(argv, input, input_len, &res, &nread); + if (profiling) { + prof_child_exit(&wait_time); + } + xfree(input); set_vim_var_nr(VV_SHELL_ERROR, (long) status); @@ -16663,7 +16769,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (new_cwd && *new_cwd != NUL) { cwd = new_cwd; // The new cwd must be a directory. - if (!os_isdir((const char_u *)cwd)) { + if (!os_isdir_executable((const char *)cwd)) { EMSG2(_(e_invarg2), "expected valid directory"); shell_free_argv(argv); return; @@ -17168,6 +17274,69 @@ error: return; } +// "trim({expr})" function +static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + char buf1[NUMBUFLEN]; + char buf2[NUMBUFLEN]; + const char_u *head = (const char_u *)tv_get_string_buf_chk(&argvars[0], buf1); + const char_u *mask = NULL; + const char_u *tail; + const char_u *prev; + const char_u *p; + int c1; + + rettv->v_type = VAR_STRING; + if (head == NULL) { + rettv->vval.v_string = NULL; + return; + } + + if (argvars[1].v_type == VAR_STRING) { + mask = (const char_u *)tv_get_string_buf_chk(&argvars[1], buf2); + } + + while (*head != NUL) { + c1 = PTR2CHAR(head); + if (mask == NULL) { + if (c1 > ' ' && c1 != 0xa0) { + break; + } + } else { + for (p = mask; *p != NUL; MB_PTR_ADV(p)) { + if (c1 == PTR2CHAR(p)) { + break; + } + } + if (*p == NUL) { + break; + } + } + MB_PTR_ADV(head); + } + + for (tail = head + STRLEN(head); tail > head; tail = prev) { + prev = tail; + MB_PTR_BACK(head, prev); + c1 = PTR2CHAR(prev); + if (mask == NULL) { + if (c1 > ' ' && c1 != 0xa0) { + break; + } + } else { + for (p = mask; *p != NUL; MB_PTR_ADV(p)) { + if (c1 == PTR2CHAR(p)) { + break; + } + } + if (*p == NUL) { + break; + } + } + } + rettv->vval.v_string = vim_strnsave(head, (int)(tail - head)); +} + /* * "type(expr)" function */ @@ -17419,7 +17588,7 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[0].v_type != VAR_DICT || (dict = argvars[0].vval.v_dict) == NULL) { - emsgf(_(e_invarg)); + EMSG(_(e_invarg)); } else { dictitem_T *di; if ((di = tv_dict_find(dict, S_LEN("lnum"))) != NULL) { @@ -18186,9 +18355,9 @@ varnumber_T get_vim_var_nr(int idx) FUNC_ATTR_PURE return vimvars[idx].vv_nr; } -/* - * Get string v: variable value. Uses a static buffer, can only be used once. - */ +// Get string v: variable value. Uses a static buffer, can only be used once. +// If the String variable has never been set, return an empty string. +// Never returns NULL; char_u *get_vim_var_str(int idx) FUNC_ATTR_PURE FUNC_ATTR_NONNULL_RET { return (char_u *)tv_get_string(&vimvars[idx].vv_tv); @@ -18217,12 +18386,7 @@ void set_vim_var_char(int c) { char buf[MB_MAXBYTES + 1]; - if (has_mbyte) { - buf[(*mb_char2bytes)(c, (char_u *) buf)] = NUL; - } else { - buf[0] = c; - buf[1] = NUL; - } + buf[utf_char2bytes(c, (char_u *)buf)] = NUL; set_vim_var_string(VV_CHAR, buf, -1); } @@ -19210,7 +19374,7 @@ static bool var_check_fixed(const int flags, const char *name, } else if (name_len == TV_CSTRING) { name_len = strlen(name); } - emsgf(_("E795: Cannot delete variable %.*s"), (int)name_len, name); + EMSG3(_("E795: Cannot delete variable %.*s"), (int)name_len, name); return true; } return false; @@ -19680,7 +19844,7 @@ void ex_function(exarg_T *eap) // s:func script-local function name // g:func global function name, same as "func" p = eap->arg; - name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); + name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL); paren = (vim_strchr(p, '(') != NULL); if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) { /* @@ -19819,7 +19983,7 @@ void ex_function(exarg_T *eap) if (*p == '\n') { line_arg = p + 1; } else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) { - emsgf(_(e_trailing)); + EMSG(_(e_trailing)); } /* @@ -20224,7 +20388,7 @@ trans_function_name( } // Note that TFN_ flags use the same values as GLV_ flags. - end = get_lval((char_u *)start, NULL, &lv, false, skip, flags, + end = get_lval((char_u *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY, lead > 2 ? 0 : FNE_CHECK_START); if (end == start) { if (!skip) @@ -21640,15 +21804,15 @@ void ex_return(exarg_T *eap) } else { tv_clear(&rettv); } - } - /* It's safer to return also on error. */ - else if (!eap->skip) { - /* - * Return unless the expression evaluation has been cancelled due to an - * aborting error, an interrupt, or an exception. - */ - if (!aborting()) - returning = do_return(eap, FALSE, TRUE, NULL); + } else if (!eap->skip) { // It's safer to return also on error. + // In return statement, cause_abort should be force_abort. + update_force_abort(); + + // Return unless the expression evaluation has been cancelled due to an + // aborting error, an interrupt, or an exception. + if (!aborting()) { + returning = do_return(eap, false, true, NULL); + } } /* When skipping or the return gets pending, advance to the next command diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 801d2cc468..e72bb7b870 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -222,7 +222,7 @@ return { pathshorten={args=1}, pow={args=2}, prevnonblank={args=1}, - printf={args=varargs(2)}, + printf={args=varargs(1)}, pumvisible={}, py3eval={args=1}, pyeval={args=1}, @@ -323,6 +323,7 @@ return { tolower={args=1}, toupper={args=1}, tr={args=3}, + trim={args={1,2}}, trunc={args=1, func="float_op_wrapper", data="&trunc"}, type={args=1}, undofile={args=1}, @@ -337,6 +338,7 @@ return { win_gotoid={args=1}, win_id2tabwin={args=1}, win_id2win={args=1}, + win_screenpos={args=1}, winbufnr={args=1}, wincol={}, winheight={args=1}, diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 9bae436e3d..2563e38258 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -609,14 +609,14 @@ static inline int convert_to_json_string(garray_T *const gap, if (ch > 0x7F && shift == 1) { emsgf(_("E474: String \"%.*s\" contains byte that does not start " "any UTF-8 character"), - utf_len - (i - shift), utf_buf + i - shift); + (int)(utf_len - (i - shift)), utf_buf + i - shift); xfree(tofree); return FAIL; } else if ((SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END) || (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END)) { emsgf(_("E474: UTF-8 string contains code point which belongs " "to a surrogate pair: %.*s"), - utf_len - (i - shift), utf_buf + i - shift); + (int)(utf_len - (i - shift)), utf_buf + i - shift); xfree(tofree); return FAIL; } else if (ENCODE_RAW(ch)) { diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index b151357196..6a93b20345 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -991,7 +991,7 @@ const char *tv_list_find_str(list_T *const l, const int n) { const listitem_T *const li = tv_list_find(l, n); if (li == NULL) { - emsgf(_(e_listidx), (int64_t)n); + EMSG2(_(e_listidx), (int64_t)n); return NULL; } return tv_get_string(TV_LIST_ITEM_TV(li)); @@ -1532,7 +1532,7 @@ bool tv_dict_get_callback(dict_T *const d, } if (!tv_is_func(di->di_tv) && di->di_tv.v_type != VAR_STRING) { - emsgf(_("E6000: Argument is not a function or function name")); + EMSG(_("E6000: Argument is not a function or function name")); return false; } @@ -2298,7 +2298,7 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock) static int recurse = 0; if (recurse >= DICT_MAXNEST) { - emsgf(_("E743: variable nested too deep for (un)lock")); + EMSG(_("E743: variable nested too deep for (un)lock")); return; } if (deep == 0) { @@ -2546,28 +2546,28 @@ bool tv_check_str_or_nr(const typval_T *const tv) return true; } case VAR_FLOAT: { - emsgf(_("E805: Expected a Number or a String, Float found")); + EMSG(_("E805: Expected a Number or a String, Float found")); return false; } case VAR_PARTIAL: case VAR_FUNC: { - emsgf(_("E703: Expected a Number or a String, Funcref found")); + EMSG(_("E703: Expected a Number or a String, Funcref found")); return false; } case VAR_LIST: { - emsgf(_("E745: Expected a Number or a String, List found")); + EMSG(_("E745: Expected a Number or a String, List found")); return false; } case VAR_DICT: { - emsgf(_("E728: Expected a Number or a String, Dictionary found")); + EMSG(_("E728: Expected a Number or a String, Dictionary found")); return false; } case VAR_SPECIAL: { - emsgf(_("E5300: Expected a Number or a String")); + EMSG(_("E5300: Expected a Number or a String")); return false; } case VAR_UNKNOWN: { - emsgf(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)"); + EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)"); return false; } } @@ -2611,7 +2611,7 @@ bool tv_check_num(const typval_T *const tv) case VAR_DICT: case VAR_FLOAT: case VAR_UNKNOWN: { - emsgf(_(num_errors[tv->v_type])); + EMSG(_(num_errors[tv->v_type])); return false; } } @@ -2632,7 +2632,7 @@ static const char *const str_errors[] = { #undef FUNC_ERROR -/// Check that given value is a string or can be converted to it +/// Check that given value is a VimL String or can be "cast" to it. /// /// Error messages are compatible with tv_get_string_chk() previously used for /// the same purpose. @@ -2655,7 +2655,7 @@ bool tv_check_str(const typval_T *const tv) case VAR_DICT: case VAR_FLOAT: case VAR_UNKNOWN: { - emsgf(_(str_errors[tv->v_type])); + EMSG(_(str_errors[tv->v_type])); return false; } } @@ -2702,7 +2702,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) case VAR_LIST: case VAR_DICT: case VAR_FLOAT: { - emsgf(_(num_errors[tv->v_type])); + EMSG(_(num_errors[tv->v_type])); break; } case VAR_NUMBER: { @@ -2778,23 +2778,23 @@ float_T tv_get_float(const typval_T *const tv) } case VAR_PARTIAL: case VAR_FUNC: { - emsgf(_("E891: Using a Funcref as a Float")); + EMSG(_("E891: Using a Funcref as a Float")); break; } case VAR_STRING: { - emsgf(_("E892: Using a String as a Float")); + EMSG(_("E892: Using a String as a Float")); break; } case VAR_LIST: { - emsgf(_("E893: Using a List as a Float")); + EMSG(_("E893: Using a List as a Float")); break; } case VAR_DICT: { - emsgf(_("E894: Using a Dictionary as a Float")); + EMSG(_("E894: Using a Dictionary as a Float")); break; } case VAR_SPECIAL: { - emsgf(_("E907: Using a special value as a Float")); + EMSG(_("E907: Using a special value as a Float")); break; } case VAR_UNKNOWN: { @@ -2805,7 +2805,7 @@ float_T tv_get_float(const typval_T *const tv) return 0; } -/// Get the string value of a VimL object +/// Get the string value of a "stringish" VimL object. /// /// @param[in] tv Object to get value of. /// @param buf Buffer used to hold numbers and special variables converted to @@ -2840,14 +2840,14 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf) case VAR_DICT: case VAR_FLOAT: case VAR_UNKNOWN: { - emsgf(_(str_errors[tv->v_type])); + EMSG(_(str_errors[tv->v_type])); return false; } } return NULL; } -/// Get the string value of a VimL object +/// Get the string value of a "stringish" VimL object. /// /// @warning For number and special values it uses a single, static buffer. It /// may be used only once, next call to get_tv_string may reuse it. Use @@ -2866,7 +2866,7 @@ const char *tv_get_string_chk(const typval_T *const tv) return tv_get_string_buf_chk(tv, mybuf); } -/// Get the string value of a VimL object +/// Get the string value of a "stringish" VimL object. /// /// @warning For number and special values it uses a single, static buffer. It /// may be used only once, next call to get_tv_string may reuse it. Use @@ -2888,7 +2888,7 @@ const char *tv_get_string(const typval_T *const tv) return tv_get_string_buf((typval_T *)tv, mybuf); } -/// Get the string value of a VimL object +/// Get the string value of a "stringish" VimL object. /// /// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but /// return NULL on error. diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index 664bf7332c..e99289c430 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -162,19 +162,20 @@ struct listwatch_S { }; /// Structure to hold info about a list +/// Order of members is optimized to reduce padding. struct listvar_S { listitem_T *lv_first; ///< First item, NULL if none. listitem_T *lv_last; ///< Last item, NULL if none. - int lv_refcount; ///< Reference count. - int lv_len; ///< Number of items. listwatch_T *lv_watch; ///< First watcher, NULL if none. - int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx]. listitem_T *lv_idx_item; ///< When not NULL item at index "lv_idx". - int lv_copyID; ///< ID used by deepcopy(). list_T *lv_copylist; ///< Copied list used by deepcopy(). - VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED. list_T *lv_used_next; ///< next list in used lists list. list_T *lv_used_prev; ///< Previous list in used lists list. + int lv_refcount; ///< Reference count. + int lv_len; ///< Number of items. + int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx]. + int lv_copyID; ///< ID used by deepcopy(). + VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED. }; // Static list with 10 items. Use tv_list_init_static10() to initialize. diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index 4556ce8193..623bdfc93b 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -741,6 +741,7 @@ typval_encode_stop_converting_one_item: case kMPConvPartial: { partial_T *const pt = cur_mpsv->data.p.pt; tv = cur_mpsv->tv; + (void)tv; switch (cur_mpsv->data.p.stage) { case kMPConvPartialArgs: { TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h index cc875d74b9..fdd4f17d5c 100644 --- a/src/nvim/event/defs.h +++ b/src/nvim/event/defs.h @@ -4,7 +4,7 @@ #include <assert.h> #include <stdarg.h> -#define EVENT_HANDLER_MAX_ARGC 6 +#define EVENT_HANDLER_MAX_ARGC 10 typedef void (*argv_callback)(void **argv); typedef struct message { diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 7998e0b8d0..609c723c57 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -34,6 +34,7 @@ void loop_init(Loop *loop, void *data) /// Processes one `Loop.uv` event (at most). /// Processes all `Loop.fast_events` events. +/// Does NOT process `Loop.events`, that is an application-specific decision. /// /// @returns true if `ms` timeout was reached bool loop_poll_events(Loop *loop, int ms) diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 115df815c6..0a9b6ecc57 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -34,6 +34,7 @@ #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/getchar.h" +#include "nvim/highlight.h" #include "nvim/indent.h" #include "nvim/buffer_updates.h" #include "nvim/main.h" @@ -113,6 +114,7 @@ typedef struct { /// ":ascii" and "ga" implementation void do_ascii(const exarg_T *const eap) { + char_u *dig; int cc[MAX_MCO]; int c = utfc_ptr2char(get_cursor_pos_ptr(), cc); if (c == NUL) { @@ -140,10 +142,22 @@ void do_ascii(const exarg_T *const eap) } char buf2[20]; buf2[0] = NUL; - iobuff_len += ( - vim_snprintf((char *)IObuff + iobuff_len, sizeof(IObuff) - iobuff_len, - _("<%s>%s%s %d, Hex %02x, Octal %03o"), - transchar(c), buf1, buf2, cval, cval, cval)); + + dig = get_digraph_for_char(cval); + if (dig != NULL) { + iobuff_len += ( + vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + _("<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"), + transchar(c), buf1, buf2, cval, cval, cval, dig)); + } else { + iobuff_len += ( + vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + _("<%s>%s%s %d, Hex %02x, Octal %03o"), + transchar(c), buf1, buf2, cval, cval, cval)); + } + c = cc[ci++]; } @@ -178,11 +192,25 @@ void do_ascii(const exarg_T *const eap) IObuff[iobuff_len++] = ' '; // Draw composing char on top of a space. } iobuff_len += utf_char2bytes(c, IObuff + iobuff_len); - iobuff_len += ( - vim_snprintf((char *)IObuff + iobuff_len, sizeof(IObuff) - iobuff_len, - (c < 0x10000 - ? _("> %d, Hex %04x, Octal %o") - : _("> %d, Hex %08x, Octal %o")), c, c, c)); + + dig = get_digraph_for_char(c); + if (dig != NULL) { + iobuff_len += ( + vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + (c < 0x10000 + ? _("> %d, Hex %04x, Oct %o, Digr %s") + : _("> %d, Hex %08x, Oct %o, Digr %s")), + c, c, c, dig)); + } else { + iobuff_len += ( + vim_snprintf((char *)IObuff + iobuff_len, + sizeof(IObuff) - iobuff_len, + (c < 0x10000 + ? _("> %d, Hex %04x, Octal %o") + : _("> %d, Hex %08x, Octal %o")), + c, c, c)); + } if (ci == MAX_MCO) { break; } @@ -306,9 +334,12 @@ static int linelen(int *has_tab) ; save = *last; *last = NUL; - len = linetabsize(line); /* get line length */ - if (has_tab != NULL) /* check for embedded TAB */ - *has_tab = (vim_strrchr(first, TAB) != NULL); + // Get line length. + len = linetabsize(line); + // Check for embedded TAB. + if (has_tab != NULL) { + *has_tab = STRRCHR(first, TAB) != NULL; + } *last = save; return len; @@ -420,6 +451,7 @@ void ex_sort(exarg_T *eap) sort_abort = sort_ic = sort_rx = sort_nr = sort_flt = 0; size_t format_found = 0; + bool change_occurred = false; // Buffer contents changed. for (p = eap->arg; *p != NUL; ++p) { if (ascii_iswhite(*p)) { @@ -580,8 +612,16 @@ void ex_sort(exarg_T *eap) // Insert the lines in the sorted order below the last one. lnum = eap->line2; - for (i = 0; i < count; ++i) { - s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum); + for (i = 0; i < count; i++) { + const linenr_T get_lnum = nrs[eap->forceit ? count - i - 1 : i].lnum; + + // If the original line number of the line being placed is not the same + // as "lnum" (accounting for offset), we know that the buffer changed. + if (get_lnum + ((linenr_T)count - 1) != lnum) { + change_occurred = true; + } + + s = ml_get(get_lnum); if (!unique || i == 0 || (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0) { // Copy the line into a buffer, it may become invalid in @@ -610,10 +650,13 @@ void ex_sort(exarg_T *eap) if (deleted > 0) { mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted, false); + msgmore(-deleted); } else if (deleted < 0) { mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, false); } - changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); + if (change_occurred || deleted != 0) { + changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true); + } curwin->w_cursor.lnum = eap->line1; beginline(BL_WHITE | BL_FIX); @@ -715,11 +758,13 @@ void ex_retab(exarg_T *eap) memmove(new_line + start_col + len, ptr + col, (size_t)(old_len - col + 1)); ptr = new_line + start_col; - for (col = 0; col < len; col++) + for (col = 0; col < len; col++) { ptr[col] = (col < num_tabs) ? '\t' : ' '; - ml_replace(lnum, new_line, FALSE); - if (first_line == 0) + } + ml_replace(lnum, new_line, false); + if (first_line == 0) { first_line = lnum; + } last_line = lnum; ptr = new_line; col = start_col + len; @@ -771,10 +816,23 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) linenr_T last_line; // Last line in file after adding new text if (dest >= line1 && dest < line2) { - EMSG(_("E134: Move lines into themselves")); + EMSG(_("E134: Cannot move a range of lines into itself")); return FAIL; } + // Do nothing if we are not actually moving any lines. This will prevent + // the 'modified' flag from being set without cause. + if (dest == line1 - 1 || dest == line2) { + // Move the cursor as if lines were moved (see below) to be backwards + // compatible. + if (dest >= line1) { + curwin->w_cursor.lnum = dest; + } else { + curwin->w_cursor.lnum = dest + (line2 - line1) + 1; + } + return OK; + } + num_lines = line2 - line1 + 1; /* @@ -1170,16 +1228,6 @@ static void do_filter( cmd_buf = make_filter_cmd(cmd, itmp, otmp); ui_cursor_goto((int)Rows - 1, 0); - /* - * When not redirecting the output the command can write anything to the - * screen. If 'shellredir' is equal to ">", screen may be messed up by - * stderr output of external command. Clear the screen later. - * If do_in is FALSE, this could be something like ":r !cat", which may - * also mess up the screen, clear it later. - */ - if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in) - redraw_later_clear(); - if (do_out) { if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL) { xfree(cmd_buf); @@ -1189,19 +1237,8 @@ static void do_filter( } read_linecount = curbuf->b_ml.ml_line_count; - // When call_shell() fails wait_return() is called to give the user a chance - // to read the error messages. Otherwise errors are ignored, so you can see - // the error messages from the command that appear on stdout; use 'u' to fix - // the text. // Pass on the kShellOptDoOut flag when the output is being redirected. - if (call_shell( - cmd_buf, - kShellOptFilter | shell_flags, - NULL - )) { - redraw_later_clear(); - wait_return(FALSE); - } + call_shell(cmd_buf, kShellOptFilter | shell_flags, NULL); xfree(cmd_buf); did_check_timestamps = FALSE; @@ -1302,23 +1339,17 @@ filterend: xfree(otmp); } -/* - * Call a shell to execute a command. - * When "cmd" is NULL start an interactive shell. - */ +// Call a shell to execute a command. +// When "cmd" is NULL start an interactive shell. void do_shell( char_u *cmd, int flags // may be SHELL_DOOUT when output is redirected ) { - int save_nwr; - - /* - * Disallow shell commands in restricted mode (-Z) - * Disallow shell commands from .exrc and .vimrc in current directory for - * security reasons. - */ + // Disallow shell commands in restricted mode (-Z) + // Disallow shell commands from .exrc and .vimrc in current directory for + // security reasons. if (check_restricted() || check_secure()) { msg_end(); return; @@ -1356,38 +1387,31 @@ do_shell( msg_row = Rows - 1; msg_col = 0; - if (autocmd_busy) { - if (msg_silent == 0) - redraw_later_clear(); - } else { - /* - * For ":sh" there is no need to call wait_return(), just redraw. - * Also for the Win32 GUI (the output is in a console window). - * Otherwise there is probably text on the screen that the user wants - * to read before redrawing, so call wait_return(). - */ - if (cmd == NULL - ) { - if (msg_silent == 0) - redraw_later_clear(); - need_wait_return = FALSE; - } else { - /* - * If we switch screens when starttermcap() is called, we really - * want to wait for "hit return to continue". - */ - save_nwr = no_wait_return; - wait_return(msg_silent == 0); - no_wait_return = save_nwr; - } - } - - /* display any error messages now */ + // display any error messages now display_errors(); apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf); } +#if !defined(UNIX) +static char *find_pipe(const char *cmd) +{ + bool inquote = false; + + for (const char *p = cmd; *p != NUL; p++) { + if (!inquote && *p == '|') { + return p; + } + if (*p == '"') { + inquote = !inquote; + } else if (rem_backslash((const char_u *)p)) { + p++; + } + } + return NULL; +} +#endif + /// Create a shell command from a command string, input redirection file and /// output redirection file. /// @@ -1441,7 +1465,7 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp) // Don't do this when 'shellquote' is not empty, otherwise the // redirection would be inside the quotes. if (*p_shq == NUL) { - char *const p = strchr(buf, '|'); + char *const p = find_pipe(buf); if (p != NULL) { *p = NUL; } @@ -1449,7 +1473,7 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp) xstrlcat(buf, " < ", len); xstrlcat(buf, (const char *)itmp, len); if (*p_shq == NUL) { - const char *const p = strchr((const char *)cmd, '|'); + const char *const p = find_pipe((const char *)cmd); if (p != NULL) { xstrlcat(buf, " ", len - 1); // Insert a space before the '|' for DOS xstrlcat(buf, p, len - 1); @@ -1589,12 +1613,14 @@ void ex_file(exarg_T *eap) } if (*eap->arg != NUL || eap->addr_count == 1) { - if (rename_buffer(eap->arg) == FAIL) + if (rename_buffer(eap->arg) == FAIL) { return; + } + redraw_tabline = true; } - if (!shortmess(SHM_FILEINFO)) { - // print full file name if :cd used + // print file name if no argument or 'F' is not in 'shortmess' + if (*eap->arg == NUL || !shortmess(SHM_FILEINFO)) { fileinfo(false, false, eap->forceit); } } @@ -2538,11 +2564,17 @@ int do_ecmd( } check_arg_idx(curwin); - // If autocommands change the cursor position or topline, we should keep - // it. Also when it moves within a line. + // If autocommands change the cursor position or topline, we should + // keep it. Also when it moves within a line. But not when it moves + // to the first non-blank. if (!equalpos(curwin->w_cursor, orig_pos)) { - newlnum = curwin->w_cursor.lnum; - newcol = curwin->w_cursor.col; + const char_u *text = get_cursor_line_ptr(); + + if (curwin->w_cursor.lnum != orig_pos.lnum + || curwin->w_cursor.col != (int)(skipwhite(text) - text)) { + newlnum = curwin->w_cursor.lnum; + newcol = curwin->w_cursor.col; + } } if (curwin->w_topline == topline) topline = 0; @@ -3307,7 +3339,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, endcolumn = (curwin->w_curswant == MAXCOL); } - if (sub_joining_lines(eap, pat, sub, cmd, !preview)) { + if (sub != NULL && sub_joining_lines(eap, pat, sub, cmd, !preview)) { return NULL; } @@ -3623,7 +3655,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, // before the cursor. len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line); curwin->w_cursor.col += len_change; - ml_replace(lnum, new_line, FALSE); + ml_replace(lnum, new_line, false); } search_match_lines = regmatch.endpos[0].lnum @@ -3665,17 +3697,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, msg_col = 0; gotocmdline(TRUE); - /* restore the line */ - if (orig_line != NULL) - ml_replace(lnum, orig_line, FALSE); + // restore the line + if (orig_line != NULL) { + ml_replace(lnum, orig_line, false); + } } - need_wait_return = FALSE; /* no hit-return prompt */ - if (typed == 'q' || typed == ESC || typed == Ctrl_C -#ifdef UNIX - || typed == intr_char -#endif - ) { + need_wait_return = false; // no hit-return prompt + if (typed == 'q' || typed == ESC || typed == Ctrl_C) { got_quit = true; break; } @@ -3924,9 +3953,10 @@ skip: prev_matchcol = (colnr_T)STRLEN(sub_firstline) - prev_matchcol; - if (u_savesub(lnum) != OK) + if (u_savesub(lnum) != OK) { break; - ml_replace(lnum, new_start, TRUE); + } + ml_replace(lnum, new_start, true); if (nmatch_tl > 0) { /* @@ -4432,7 +4462,7 @@ void ex_help(exarg_T *eap) buf_T *buf; int len; char_u *lang; - int old_KeyTyped = KeyTyped; + const bool old_KeyTyped = KeyTyped; if (eap != NULL) { /* @@ -4504,7 +4534,7 @@ void ex_help(exarg_T *eap) * Re-use an existing help window or open a new one. * Always open a new one for ":tab help". */ - if (!curwin->w_buffer->b_help + if (!bt_help(curwin->w_buffer) || cmdmod.tab != 0 ) { if (cmdmod.tab != 0) { @@ -4512,7 +4542,7 @@ void ex_help(exarg_T *eap) } else { wp = NULL; FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) { - if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) { + if (bt_help(wp2->w_buffer)) { wp = wp2; break; } @@ -4665,49 +4695,66 @@ static int help_compare(const void *s1, const void *s2) return strcmp(p1, p2); } -/* - * Find all help tags matching "arg", sort them and return in matches[], with - * the number of matches in num_matches. - * The matches will be sorted with a "best" match algorithm. - * When "keep_lang" is TRUE try keeping the language of the current buffer. - */ -int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_lang) +// Find all help tags matching "arg", sort them and return in matches[], with +// the number of matches in num_matches. +// The matches will be sorted with a "best" match algorithm. +// When "keep_lang" is true try keeping the language of the current buffer. +int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches, + bool keep_lang) { - char_u *s, *d; int i; - static char *(mtable[]) = {"*", "g*", "[*", "]*", - "/*", "/\\*", "\"*", "**", - "/\\(\\)", "/\\%(\\)", - "?", ":?", "?<CR>", "g?", "g?g?", "g??", - "/\\?", "/\\z(\\)", "\\=", ":s\\=", - "[count]", "[quotex]", - "[range]", ":[range]", - "[pattern]", "\\|", "\\%$", - "s/\\~", "s/\\U", "s/\\L", - "s/\\1", "s/\\2", "s/\\3", "s/\\9"}; - static char *(rtable[]) = {"star", "gstar", "[star", "]star", - "/star", "/\\\\star", "quotestar", "starstar", - "/\\\\(\\\\)", "/\\\\%(\\\\)", - "?", ":?", "?<CR>", "g?", "g?g?", "g??", - "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=", - "\\[count]", "\\[quotex]", - "\\[range]", ":\\[range]", - "\\[pattern]", "\\\\bar", "/\\\\%\\$", - "s/\\\\\\~", "s/\\\\U", "s/\\\\L", - "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"}; - int flags; - - d = IObuff; /* assume IObuff is long enough! */ - - /* - * Recognize a few exceptions to the rule. Some strings that contain '*' - * with "star". Otherwise '*' is recognized as a wildcard. - */ - for (i = (int)ARRAY_SIZE(mtable); --i >= 0; ) - if (STRCMP(arg, mtable[i]) == 0) { - STRCPY(d, rtable[i]); - break; + static const char *(mtable[]) = { + "*", "g*", "[*", "]*", + "/*", "/\\*", "\"*", "**", + "/\\(\\)", "/\\%(\\)", + "?", ":?", "?<CR>", "g?", "g?g?", "g??", + "-?", "q?", "v_g?", + "/\\?", "/\\z(\\)", "\\=", ":s\\=", + "[count]", "[quotex]", + "[range]", ":[range]", + "[pattern]", "\\|", "\\%$", + "s/\\~", "s/\\U", "s/\\L", + "s/\\1", "s/\\2", "s/\\3", "s/\\9" + }; + static const char *(rtable[]) = { + "star", "gstar", "[star", "]star", + "/star", "/\\\\star", "quotestar", "starstar", + "/\\\\(\\\\)", "/\\\\%(\\\\)", + "?", ":?", "?<CR>", "g?", "g?g?", "g??", + "-?", "q?", "v_g?", + "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=", + "\\[count]", "\\[quotex]", + "\\[range]", ":\\[range]", + "\\[pattern]", "\\\\bar", "/\\\\%\\$", + "s/\\\\\\~", "s/\\\\U", "s/\\\\L", + "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9" + }; + static const char *(expr_table[]) = { + "!=?", "!~?", "<=?", "<?", "==?", "=~?", + ">=?", ">?", "is?", "isnot?" + }; + char_u *d = IObuff; // assume IObuff is long enough! + + if (STRNICMP(arg, "expr-", 5) == 0) { + // When the string starting with "expr-" and containing '?' and matches + // the table, it is taken literally. Otherwise '?' is recognized as a + // wildcard. + for (i = (int)ARRAY_SIZE(expr_table); --i >= 0; ) { + if (STRCMP(arg + 5, expr_table[i]) == 0) { + STRCPY(d, arg); + break; + } } + } else { + // Recognize a few exceptions to the rule. Some strings that contain + // '*' with "star". Otherwise '*' is recognized as a wildcard. + for (i = (int)ARRAY_SIZE(mtable); --i >= 0; ) { + if (STRCMP(arg, mtable[i]) == 0) { + STRCPY(d, rtable[i]); + break; + } + } + } if (i < 0) { /* no match in table */ /* Replace "\S" with "/\\S", etc. Otherwise every tag is matched. @@ -4739,7 +4786,7 @@ int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_la if (*arg == '(' && arg[1] == '\'') { arg++; } - for (s = arg; *s; s++) { + for (const char_u *s = arg; *s; s++) { // Replace "|" with "bar" and '"' with "quote" to match the name of // the tags for these commands. // Replace "*" with ".*" and "?" with "." to match command line @@ -4848,9 +4895,10 @@ int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_la *matches = (char_u **)""; *num_matches = 0; - flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE; - if (keep_lang) + int flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE; + if (keep_lang) { flags |= TAG_KEEP_LANG; + } if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == OK && *num_matches > 0) { /* Sort the matches found on the heuristic number that is after the @@ -4912,11 +4960,7 @@ void fix_help_buffer(void) { linenr_T lnum; char_u *line; - int in_example = FALSE; - int len; - char_u *fname; - char_u *p; - char_u *rt; + bool in_example = false; // Set filetype to "help". if (STRCMP(curbuf->b_p_ft, "help") != 0) { @@ -4926,9 +4970,9 @@ void fix_help_buffer(void) } if (!syntax_present(curwin)) { - for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) { - line = ml_get_buf(curbuf, lnum, FALSE); - len = (int)STRLEN(line); + for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) { + line = ml_get_buf(curbuf, lnum, false); + const size_t len = STRLEN(line); if (in_example && len > 0 && !ascii_iswhite(line[0])) { /* End of example: non-white or '<' in first column. */ if (line[0] == '<') { @@ -4936,14 +4980,14 @@ void fix_help_buffer(void) line = ml_get_buf(curbuf, lnum, TRUE); line[0] = ' '; } - in_example = FALSE; + in_example = false; } if (!in_example && len > 0) { if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' ')) { /* blank-out a '>' in the last column (start of example) */ line = ml_get_buf(curbuf, lnum, TRUE); line[len - 1] = ' '; - in_example = TRUE; + in_example = true; } else if (line[len - 1] == '~') { /* blank-out a '~' at the end of line (header marker) */ line = ml_get_buf(curbuf, lnum, TRUE); @@ -4957,7 +5001,7 @@ void fix_help_buffer(void) * In the "help.txt" and "help.abx" file, add the locally added help * files. This uses the very first line in the help file. */ - fname = path_tail(curbuf->b_fname); + char_u *const fname = path_tail(curbuf->b_fname); if (fnamecmp(fname, "help.txt") == 0 || (fnamencmp(fname, "help.", 5) == 0 && ASCII_ISALPHA(fname[5]) @@ -4972,16 +5016,15 @@ void fix_help_buffer(void) /* Go through all directories in 'runtimepath', skipping * $VIMRUNTIME. */ - p = p_rtp; + char_u *p = p_rtp; while (*p != NUL) { copy_option_part(&p, NameBuff, MAXPATHL, ","); - rt = (char_u *)vim_getenv("VIMRUNTIME"); - if (path_full_compare(rt, NameBuff, FALSE) != kEqualFiles) { + char_u *const rt = (char_u *)vim_getenv("VIMRUNTIME"); + if (rt != NULL + && path_full_compare(rt, NameBuff, false) != kEqualFiles) { int fcount; char_u **fnames; - FILE *fd; char_u *s; - int fi; vimconv_T vc; char_u *cp; @@ -4999,29 +5042,22 @@ void fix_help_buffer(void) if (gen_expand_wildcards(1, buff_list, &fcount, &fnames, EW_FILE|EW_SILENT) == OK && fcount > 0) { - int i1; - int i2; - char_u *f1; - char_u *f2; - char_u *t1; - char_u *e1; - char_u *e2; - - /* If foo.abx is found use it instead of foo.txt in - * the same directory. */ - for (i1 = 0; i1 < fcount; ++i1) { - for (i2 = 0; i2 < fcount; ++i2) { - if (i1 == i2) + // If foo.abx is found use it instead of foo.txt in + // the same directory. + for (int i1 = 0; i1 < fcount; i1++) { + for (int i2 = 0; i2 < fcount; i2++) { + if (i1 == i2) { continue; - if (fnames[i1] == NULL || fnames[i2] == NULL) - continue; - f1 = fnames[i1]; - f2 = fnames[i2]; - t1 = path_tail(f1); - if (fnamencmp(f1, f2, t1 - f1) != 0) + } + if (fnames[i1] == NULL || fnames[i2] == NULL) { continue; - e1 = vim_strrchr(t1, '.'); - e2 = vim_strrchr(path_tail(f2), '.'); + } + const char_u *const f1 = fnames[i1]; + const char_u *const f2 = fnames[i2]; + const char_u *const t1 = path_tail(f1); + const char_u *const t2 = path_tail(f2); + const char_u *const e1 = STRRCHR(t1, '.'); + const char_u *const e2 = STRRCHR(t2, '.'); if (e1 == NULL || e2 == NULL) { continue; } @@ -5032,8 +5068,10 @@ void fix_help_buffer(void) fnames[i1] = NULL; continue; } - if (fnamencmp(f1, f2, e1 - f1) != 0) + if (e1 - f1 != e2 - f2 + || fnamencmp(f1, f2, e1 - f1) != 0) { continue; + } if (fnamecmp(e1, ".txt") == 0 && fnamecmp(e2, fname + 4) == 0) { /* use .abx instead of .txt */ @@ -5042,10 +5080,12 @@ void fix_help_buffer(void) } } } - for (fi = 0; fi < fcount; ++fi) { - if (fnames[fi] == NULL) + for (int fi = 0; fi < fcount; fi++) { + if (fnames[fi] == NULL) { continue; - fd = mch_fopen((char *)fnames[fi], "r"); + } + + FILE *const fd = mch_fopen((char *)fnames[fi], "r"); if (fd == NULL) { continue; } @@ -5053,9 +5093,9 @@ void fix_help_buffer(void) if (IObuff[0] == '*' && (s = vim_strchr(IObuff + 1, '*')) != NULL) { - int this_utf = MAYBE; - /* Change tag definition to a - * reference and remove <CR>/<NL>. */ + TriState this_utf = kNone; + // Change tag definition to a + // reference and remove <CR>/<NL>. IObuff[0] = '|'; *s = '|'; while (*s != NUL) { @@ -5065,13 +5105,12 @@ void fix_help_buffer(void) * above 127 is found and no * illegal byte sequence is found. */ - if (*s >= 0x80 && this_utf != FALSE) { - int l; - - this_utf = TRUE; - l = utf_ptr2len(s); - if (l == 1) - this_utf = FALSE; + if (*s >= 0x80 && this_utf != kFalse) { + this_utf = kTrue; + const int l = utf_ptr2len(s); + if (l == 1) { + this_utf = kFalse; + } s += l - 1; } ++s; @@ -5080,18 +5119,20 @@ void fix_help_buffer(void) * conversion to the current * 'encoding' may be required. */ vc.vc_type = CONV_NONE; - convert_setup(&vc, (char_u *)( - this_utf == TRUE ? "utf-8" - : "latin1"), p_enc); - if (vc.vc_type == CONV_NONE) - /* No conversion needed. */ + convert_setup( + &vc, + (char_u *)(this_utf == kTrue ? "utf-8" : "latin1"), + p_enc); + if (vc.vc_type == CONV_NONE) { + // No conversion needed. cp = IObuff; - else { - /* Do the conversion. If it fails - * use the unconverted text. */ + } else { + // Do the conversion. If it fails + // use the unconverted text. cp = string_convert(&vc, IObuff, NULL); - if (cp == NULL) + if (cp == NULL) { cp = IObuff; + } } convert_setup(&vc, NULL, NULL); @@ -5136,22 +5177,16 @@ void ex_viusage(exarg_T *eap) /// @param tagname Name of the tags file ("tags" for English, "tags-fr" for /// French) /// @param add_help_tags Whether to add the "help-tags" tag -static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, - bool add_help_tags) +static void helptags_one(char_u *const dir, const char_u *const ext, + const char_u *const tagfname, const bool add_help_tags) { - FILE *fd_tags; - FILE *fd; garray_T ga; int filecount; char_u **files; char_u *p1, *p2; - int fi; char_u *s; - char_u *fname; - int utf8 = MAYBE; - int this_utf8; - int firstline; - int mix = FALSE; /* detected mixed encodings */ + TriState utf8 = kNone; + bool mix = false; // detected mixed encodings // Find all *.txt files. size_t dirlen = STRLCPY(NameBuff, dir, sizeof(NameBuff)); @@ -5184,7 +5219,8 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, EMSG(_(e_fnametoolong)); return; } - fd_tags = mch_fopen((char *)NameBuff, "w"); + + FILE *const fd_tags = mch_fopen((char *)NameBuff, "w"); if (fd_tags == NULL) { EMSG2(_("E152: Cannot open %s for writing"), NameBuff); FreeWild(filecount, files); @@ -5196,8 +5232,9 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, * add the "help-tags" tag. */ ga_init(&ga, (int)sizeof(char_u *), 100); - if (add_help_tags || path_full_compare((char_u *)"$VIMRUNTIME/doc", - dir, FALSE) == kEqualFiles) { + if (add_help_tags + || path_full_compare((char_u *)"$VIMRUNTIME/doc", + dir, false) == kEqualFiles) { s = xmalloc(18 + STRLEN(tagfname)); sprintf((char *)s, "help-tags\t%s\t1\n", tagfname); GA_APPEND(char_u *, &ga, s); @@ -5206,44 +5243,44 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, /* * Go over all the files and extract the tags. */ - for (fi = 0; fi < filecount && !got_int; ++fi) { - fd = mch_fopen((char *)files[fi], "r"); + for (int fi = 0; fi < filecount && !got_int; fi++) { + FILE *const fd = mch_fopen((char *)files[fi], "r"); if (fd == NULL) { EMSG2(_("E153: Unable to open %s for reading"), files[fi]); continue; } - fname = files[fi] + dirlen + 1; + const char_u *const fname = files[fi] + dirlen + 1; - firstline = TRUE; + bool firstline = true; while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) { if (firstline) { - /* Detect utf-8 file by a non-ASCII char in the first line. */ - this_utf8 = MAYBE; - for (s = IObuff; *s != NUL; ++s) + // Detect utf-8 file by a non-ASCII char in the first line. + TriState this_utf8 = kNone; + for (s = IObuff; *s != NUL; s++) { if (*s >= 0x80) { - int l; - - this_utf8 = TRUE; - l = utf_ptr2len(s); + this_utf8 = kTrue; + const int l = utf_ptr2len(s); if (l == 1) { - /* Illegal UTF-8 byte sequence. */ - this_utf8 = FALSE; + // Illegal UTF-8 byte sequence. + this_utf8 = kFalse; break; } s += l - 1; } - if (this_utf8 == MAYBE) /* only ASCII characters found */ - this_utf8 = FALSE; - if (utf8 == MAYBE) /* first file */ + } + if (this_utf8 == kNone) { // only ASCII characters found + this_utf8 = kFalse; + } + if (utf8 == kNone) { // first file utf8 = this_utf8; - else if (utf8 != this_utf8) { + } else if (utf8 != this_utf8) { EMSG2(_( "E670: Mix of help file encodings within a language: %s"), files[fi]); mix = !got_int; got_int = TRUE; } - firstline = FALSE; + firstline = false; } p1 = vim_strchr(IObuff, '*'); /* find first '*' */ while (p1 != NULL) { @@ -5313,8 +5350,9 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname, } } - if (utf8 == TRUE) + if (utf8 == kTrue) { fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n"); + } /* * Write the tags into the file. @@ -5473,13 +5511,14 @@ void ex_helptags(exarg_T *eap) struct sign { - sign_T *sn_next; /* next sign in list */ - int sn_typenr; /* type number of sign */ - char_u *sn_name; /* name of sign */ - char_u *sn_icon; /* name of pixmap */ - char_u *sn_text; /* text used instead of pixmap */ - int sn_line_hl; /* highlight ID for line */ - int sn_text_hl; /* highlight ID for text */ + sign_T *sn_next; // next sign in list + int sn_typenr; // type number of sign + char_u *sn_name; // name of sign + char_u *sn_icon; // name of pixmap + char_u *sn_text; // text used instead of pixmap + int sn_line_hl; // highlight ID for line + int sn_text_hl; // highlight ID for text + int sn_num_hl; // highlight ID for line number }; static sign_T *first_sign = NULL; @@ -5491,8 +5530,8 @@ static int next_sign_typenr = 1; void ex_helpclose(exarg_T *eap) { FOR_ALL_WINDOWS_IN_TAB(win, curtab) { - if (win->w_buffer->b_help) { - win_close(win, FALSE); + if (bt_help(win->w_buffer)) { + win_close(win, false); return; } } @@ -5649,11 +5688,11 @@ void ex_sign(exarg_T *eap) // Count cells and check for non-printable chars cells = 0; - for (s = arg; s < p; s += (*mb_ptr2len)(s)) { - if (!vim_isprintc((*mb_ptr2char)(s))) { + for (s = arg; s < p; s += utfc_ptr2len(s)) { + if (!vim_isprintc(utf_ptr2char(s))) { break; } - cells += (*mb_ptr2cells)(s); + cells += utf_ptr2cells(s); } // Currently must be one or two display cells if (s != p || cells < 1 || cells > 2) { @@ -5677,6 +5716,9 @@ void ex_sign(exarg_T *eap) } else if (STRNCMP(arg, "texthl=", 7) == 0) { arg += 7; sp->sn_text_hl = syn_check_group(arg, (int)(p - arg)); + } else if (STRNCMP(arg, "numhl=", 6) == 0) { + arg += 6; + sp->sn_num_hl = syn_check_group(arg, (int)(p - arg)); } else { EMSG2(_(e_invarg2), arg); return; @@ -5903,6 +5945,16 @@ static void sign_list_defined(sign_T *sp) msg_puts(p); } } + if (sp->sn_num_hl > 0) { + msg_puts(" numhl="); + const char *const p = get_highlight_name_ext(NULL, + sp->sn_num_hl - 1, false); + if (p == NULL) { + msg_puts("NONE"); + } else { + msg_puts(p); + } + } } /* @@ -5920,25 +5972,33 @@ static void sign_undefine(sign_T *sp, sign_T *sp_prev) xfree(sp); } -/* - * Get highlighting attribute for sign "typenr". - * If "line" is TRUE: line highl, if FALSE: text highl. - */ -int sign_get_attr(int typenr, int line) +/// Gets highlighting attribute for sign "typenr" corresponding to "type". +int sign_get_attr(int typenr, SignType type) { sign_T *sp; + int sign_hl = 0; - for (sp = first_sign; sp != NULL; sp = sp->sn_next) + for (sp = first_sign; sp != NULL; sp = sp->sn_next) { if (sp->sn_typenr == typenr) { - if (line) { - if (sp->sn_line_hl > 0) - return syn_id2attr(sp->sn_line_hl); - } else { - if (sp->sn_text_hl > 0) - return syn_id2attr(sp->sn_text_hl); + switch (type) { + case SIGN_TEXT: + sign_hl = sp->sn_text_hl; + break; + case SIGN_LINEHL: + sign_hl = sp->sn_line_hl; + break; + case SIGN_NUMHL: + sign_hl = sp->sn_num_hl; + break; + default: + abort(); + } + if (sign_hl > 0) { + return syn_id2attr(sign_hl); } break; } + } return 0; } @@ -5999,7 +6059,8 @@ char_u * get_sign_name(expand_T *xp, int idx) case EXP_SUBCMD: return (char_u *)cmds[idx]; case EXP_DEFINE: { - char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", NULL }; + char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=", + NULL }; return (char_u *)define_arg[idx]; } case EXP_PLACE: { @@ -6122,7 +6183,8 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg) { case SIGNCMD_DEFINE: if (STRNCMP(last, "texthl", p - last) == 0 - || STRNCMP(last, "linehl", p - last) == 0) { + || STRNCMP(last, "linehl", p - last) == 0 + || STRNCMP(last, "numhl", p - last) == 0) { xp->xp_context = EXPAND_HIGHLIGHT; } else if (STRNCMP(last, "icon", p - last) == 0) { xp->xp_context = EXPAND_FILES; diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index f07bc0e137..a148f51527 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -123,7 +123,7 @@ void do_debug(char_u *cmd) int save_msg_scroll = msg_scroll; int save_State = State; int save_did_emsg = did_emsg; - int save_cmd_silent = cmd_silent; + const bool save_cmd_silent = cmd_silent; int save_msg_silent = msg_silent; int save_emsg_silent = emsg_silent; int save_redir_off = redir_off; @@ -1209,7 +1209,7 @@ int autowrite(buf_T *buf, int forceit) return r; } -/// flush all buffers, except the ones that are readonly +/// Flush all buffers, except the ones that are readonly or are never written. void autowrite_all(void) { if (!(p_aw || p_awa) || !p_write) { @@ -1217,7 +1217,7 @@ void autowrite_all(void) } FOR_ALL_BUFFERS(buf) { - if (bufIsChanged(buf) && !buf->b_p_ro) { + if (bufIsChanged(buf) && !buf->b_p_ro && !bt_dontwrite(buf)) { bufref_T bufref; set_bufref(&bufref, buf); (void)buf_write_all(buf, false); @@ -1279,15 +1279,13 @@ bool check_changed(buf_T *buf, int flags) /// /// @param buf /// @param checkall may abandon all changed buffers -void dialog_changed(buf_T *buf, int checkall) +void dialog_changed(buf_T *buf, bool checkall) { char_u buff[DIALOG_MSG_SIZE]; int ret; exarg_T ea; - dialog_msg(buff, _("Save changes to \"%s\"?"), - (buf->b_fname != NULL) ? - buf->b_fname : (char_u *)_("Untitled")); + dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname); if (checkall) { ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1); } else { @@ -2254,6 +2252,15 @@ static int alist_add_list(int count, char_u **files, int after) } } +// Function given to ExpandGeneric() to obtain the possible arguments of the +// argedit and argdelete commands. +char_u *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx) +{ + if (idx >= ARGCOUNT) { + return NULL; + } + return alist_name(&ARGLIST[idx]); +} /// ":compiler[!] {name}" void ex_compiler(exarg_T *eap) @@ -2693,19 +2700,33 @@ void ex_packloadall(exarg_T *eap) /// ":packadd[!] {name}" void ex_packadd(exarg_T *eap) { - static const char *plugpat = "pack/*/opt/%s"; // NOLINT + static const char *plugpat = "pack/*/%s/%s"; // NOLINT + int res = OK; - size_t len = STRLEN(plugpat) + STRLEN(eap->arg); - char *pat = (char *)xmallocz(len); - vim_snprintf(pat, len, plugpat, eap->arg); - do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR + DIP_ERR, add_pack_plugin, - eap->forceit ? &APP_ADD_DIR : &APP_BOTH); - xfree(pat); + // Round 1: use "start", round 2: use "opt". + for (int round = 1; round <= 2; round++) { + // Only look under "start" when loading packages wasn't done yet. + if (round == 1 && did_source_packages) { + continue; + } + + const size_t len = STRLEN(plugpat) + STRLEN(eap->arg) + 5; + char *pat = xmallocz(len); + vim_snprintf(pat, len, plugpat, round == 1 ? "start" : "opt", eap->arg); + // The first round don't give a "not found" error, in the second round + // only when nothing was found in the first round. + res = do_in_path(p_pp, (char_u *)pat, + DIP_ALL + DIP_DIR + + (round == 2 && res == FAIL ? DIP_ERR : 0), + add_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH); + xfree(pat); + } } /// ":options" void ex_options(exarg_T *eap) { + vim_setenv("OPTWIN_CMD", cmdmod.tab ? "tab" : ""); cmd_source((char_u *)SYS_OPTWIN_FILE, NULL); } @@ -3485,7 +3506,12 @@ static char *get_locale_val(int what) } #endif - +// Return true when "lang" starts with a valid language name. +// Rejects NULL, empty string, "C", "C.UTF-8" and others. +static bool is_valid_mess_lang(char *lang) +{ + return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]); +} /// Obtain the current messages language. Used to set the default for /// 'helplang'. May return NULL or an empty string. @@ -3505,14 +3531,14 @@ char *get_mess_lang(void) # endif # else p = os_getenv("LC_ALL"); - if (p == NULL) { + if (!is_valid_mess_lang(p)) { p = os_getenv("LC_MESSAGES"); - if (p == NULL) { + if (!is_valid_mess_lang(p)) { p = os_getenv("LANG"); } } # endif - return p; + return is_valid_mess_lang(p) ? p : NULL; } // Complicated #if; matches with where get_mess_env() is used below. diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index c1b9eff697..6361267d9b 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -208,8 +208,8 @@ void do_exmode(int improved) return; save_msg_scroll = msg_scroll; - ++RedrawingDisabled; /* don't redisplay the window */ - ++no_wait_return; /* don't wait for return */ + RedrawingDisabled++; // don't redisplay the window + no_wait_return++; // don't wait for return MSG(_("Entering Ex mode. Type \"visual\" to go to Normal mode.")); while (exmode_active) { @@ -253,10 +253,11 @@ void do_exmode(int improved) } } - --RedrawingDisabled; - --no_wait_return; - update_screen(CLEAR); - need_wait_return = FALSE; + RedrawingDisabled--; + no_wait_return--; + redraw_all_later(NOT_VALID); + update_screen(NOT_VALID); + need_wait_return = false; msg_scroll = save_msg_scroll; } @@ -400,7 +401,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, */ if (!(flags & DOCMD_KEYTYPED) && !getline_equal(fgetline, cookie, getexline)) - KeyTyped = FALSE; + KeyTyped = false; /* * Continue executing command lines: @@ -973,8 +974,8 @@ static char_u *get_loop_line(int c, void *cookie, int indent) return line; } - KeyTyped = FALSE; - ++cp->current_line; + KeyTyped = false; + cp->current_line++; wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line; sourcing_lnum = wp->lnum; return vim_strsave(wp->line); @@ -1803,15 +1804,19 @@ static char_u * do_one_cmd(char_u **cmdlinep, errormsg = (char_u *)_(get_text_locked_msg()); goto doend; } - /* Disallow editing another buffer when "curbuf_lock" is set. - * Do allow ":edit" (check for argument later). - * Do allow ":checktime" (it's postponed). */ + + // Disallow editing another buffer when "curbuf_lock" is set. + // Do allow ":checktime" (it is postponed). + // Do allow ":edit" (check for an argument later). + // Do allow ":file" with no arguments (check for an argument later). if (!(ea.argt & CMDWIN) - && ea.cmdidx != CMD_edit && ea.cmdidx != CMD_checktime + && ea.cmdidx != CMD_edit + && ea.cmdidx != CMD_file && !IS_USER_CMDIDX(ea.cmdidx) - && curbuf_locked()) + && curbuf_locked()) { goto doend; + } if (!ni && !(ea.argt & RANGE) && ea.addr_count > 0) { /* no range allowed */ @@ -1883,6 +1888,11 @@ static char_u * do_one_cmd(char_u **cmdlinep, else ea.arg = skipwhite(p); + // ":file" cannot be run with an argument when "curbuf_lock" is set + if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) { + goto doend; + } + /* * Check for "++opt=val" argument. * Must be first, allow ":w ++enc=utf8 !cmd" @@ -2665,8 +2675,8 @@ const char * set_one_cmd_context( size_t len = 0; exarg_T ea; int context = EXPAND_NOTHING; - int forceit = false; - int usefilter = false; // Filter instead of file name. + bool forceit = false; + bool usefilter = false; // Filter instead of file name. ExpandInit(xp); xp->xp_pattern = (char_u *)buff; @@ -2786,9 +2796,9 @@ const char * set_one_cmd_context( xp->xp_context = EXPAND_NOTHING; /* Default now that we're past command */ - if (*p == '!') { /* forced commands */ - forceit = TRUE; - ++p; + if (*p == '!') { // forced commands + forceit = true; + p++; } /* @@ -2813,10 +2823,10 @@ const char * set_one_cmd_context( } if (ea.cmdidx == CMD_read) { - usefilter = forceit; /* :r! filter if forced */ - if (*arg == '!') { /* :r !filter */ - ++arg; - usefilter = TRUE; + usefilter = forceit; // :r! filter if forced + if (*arg == '!') { // :r !filter + arg++; + usefilter = true; } } @@ -2899,11 +2909,7 @@ const char * set_one_cmd_context( xp->xp_pattern = skipwhite((const char_u *)arg); p = (const char *)xp->xp_pattern; while (*p != NUL) { - if (has_mbyte) { - c = mb_ptr2char((const char_u *)p); - } else { - c = (uint8_t)(*p); - } + c = utf_ptr2char((const char_u *)p); if (c == '\\' && p[1] != NUL) { p++; } else if (c == '`') { @@ -2921,19 +2927,11 @@ const char * set_one_cmd_context( || ascii_iswhite(c)) { len = 0; /* avoid getting stuck when space is in 'isfname' */ while (*p != NUL) { - if (has_mbyte) { - c = mb_ptr2char((const char_u *)p); - } else { - c = *p; - } + c = utf_ptr2char((const char_u *)p); if (c == '`' || vim_isfilec_or_wc(c)) { break; } - if (has_mbyte) { - len = (size_t)(*mb_ptr2len)((const char_u *)p); - } else { - len = 1; - } + len = (size_t)utfc_ptr2len((const char_u *)p); MB_PTR_ADV(p); } if (in_quote) { @@ -2990,7 +2988,7 @@ const char * set_one_cmd_context( // A full match ~user<Tab> will be replaced by user's home // directory i.e. something like ~user<Tab> -> /home/user/ if (*p == NUL && p > (const char *)xp->xp_pattern + 1 - && match_user(xp->xp_pattern + 1) == 1) { + && match_user(xp->xp_pattern + 1) >= 1) { xp->xp_context = EXPAND_USER; ++xp->xp_pattern; } @@ -3272,8 +3270,15 @@ const char * set_one_cmd_context( while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) { arg = (const char *)xp->xp_pattern + 1; } + xp->xp_context = EXPAND_USER_VARS; xp->xp_pattern = (char_u *)arg; + + if (*xp->xp_pattern == '$') { + xp->xp_context = EXPAND_ENV_VARS; + xp->xp_pattern++; + } + break; case CMD_function: @@ -3302,7 +3307,7 @@ const char * set_one_cmd_context( while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) { arg = (const char *)xp->xp_pattern + 1; } - // FALLTHROUGH + FALLTHROUGH; case CMD_buffer: case CMD_sbuffer: case CMD_checktime: @@ -3362,6 +3367,19 @@ const char * set_one_cmd_context( case CMD_xunmap: return (const char *)set_context_in_map_cmd( xp, (char_u *)cmd, (char_u *)arg, forceit, false, true, ea.cmdidx); + case CMD_mapclear: + case CMD_nmapclear: + case CMD_vmapclear: + case CMD_omapclear: + case CMD_imapclear: + case CMD_cmapclear: + case CMD_lmapclear: + case CMD_smapclear: + case CMD_xmapclear: + xp->xp_context = EXPAND_MAPCLEAR; + xp->xp_pattern = (char_u *)arg; + break; + case CMD_abbreviate: case CMD_noreabbrev: case CMD_cabbrev: case CMD_cnoreabbrev: case CMD_iabbrev: case CMD_inoreabbrev: @@ -3453,6 +3471,13 @@ const char * set_one_cmd_context( xp->xp_pattern = (char_u *)arg; break; + case CMD_argdelete: + while ((xp->xp_pattern = vim_strchr((const char_u *)arg, ' ')) != NULL) { + arg = (const char *)(xp->xp_pattern + 1); + } + xp->xp_context = EXPAND_ARGLIST; + xp->xp_pattern = (char_u *)arg; + break; default: break; @@ -3656,17 +3681,18 @@ static linenr_T get_address(exarg_T *eap, */ if (lnum != MAXLNUM) curwin->w_cursor.lnum = lnum; - /* - * Start a forward search at the end of the line. - * Start a backward search at the start of the line. - * This makes sure we never match in the current - * line, and can match anywhere in the - * next/previous line. - */ - if (c == '/') + + // Start a forward search at the end of the line (unless + // before the first line). + // Start a backward search at the start of the line. + // This makes sure we never match in the current + // line, and can match anywhere in the + // next/previous line. + if (c == '/' && curwin->w_cursor.lnum > 0) { curwin->w_cursor.col = MAXCOL; - else + } else { curwin->w_cursor.col = 0; + } searchcmdlen = 0; if (!do_search(NULL, c, cmd, 1L, SEARCH_HIS | SEARCH_MSG, NULL)) { @@ -4858,6 +4884,7 @@ static struct { */ static const char *command_complete[] = { + [EXPAND_ARGLIST] = "arglist", [EXPAND_AUGROUP] = "augroup", [EXPAND_BEHAVE] = "behave", [EXPAND_BUFFERS] = "buffer", @@ -4882,6 +4909,7 @@ static const char *command_complete[] = #ifdef HAVE_WORKING_LIBINTL [EXPAND_LOCALES] = "locale", #endif + [EXPAND_MAPCLEAR] = "mapclear", [EXPAND_MAPPINGS] = "mapping", [EXPAND_MENUS] = "menu", [EXPAND_MESSAGES] = "messages", @@ -5178,9 +5206,10 @@ static void ex_command(exarg_T *eap) while (*p == '-') { ++p; end = skiptowhite(p); - if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg, &addr_type_arg) - == FAIL) + if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg, + &addr_type_arg) == FAIL) { return; + } p = skipwhite(end); } @@ -5211,9 +5240,10 @@ static void ex_command(exarg_T *eap) || (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0)) { EMSG(_("E841: Reserved name, cannot be used for user defined command")); return; - } else + } else { uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg, addr_type_arg, eap->forceit); + } } /* @@ -5387,8 +5417,18 @@ uc_check_code( char_u *p = code + 1; size_t l = len - 2; int quote = 0; - enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_MODS, - ct_REGISTER, ct_LT, ct_NONE } type = ct_NONE; + enum { + ct_ARGS, + ct_BANG, + ct_COUNT, + ct_LINE1, + ct_LINE2, + ct_RANGE, + ct_MODS, + ct_REGISTER, + ct_LT, + ct_NONE + } type = ct_NONE; if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') { quote = (*p == 'q' || *p == 'Q') ? 1 : 2; @@ -5409,6 +5449,8 @@ uc_check_code( type = ct_LINE1; } else if (STRNICMP(p, "line2>", l) == 0) { type = ct_LINE2; + } else if (STRNICMP(p, "range>", l) == 0) { + type = ct_RANGE; } else if (STRNICMP(p, "lt>", l) == 0) { type = ct_LT; } else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0) { @@ -5496,11 +5538,13 @@ uc_check_code( case ct_LINE1: case ct_LINE2: + case ct_RANGE: case ct_COUNT: { char num_buf[20]; long num = (type == ct_LINE1) ? eap->line1 : (type == ct_LINE2) ? eap->line2 : + (type == ct_RANGE) ? eap->addr_count : (eap->addr_count > 0) ? eap->line2 : cmd->uc_def; size_t num_len; @@ -5954,9 +5998,35 @@ void not_exiting(void) exiting = FALSE; } -/* - * ":quit": quit current window, quit Vim if the last window is closed. - */ +static bool before_quit_autocmds(win_T *wp, bool quit_all, int forceit) +{ + apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer); + + // Bail out when autocommands closed the window. + // Refuse to quit when the buffer in the last window is being closed (can + // only happen in autocommands). + if (!win_valid(wp) + || curbuf_locked() + || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) { + return true; + } + + if (quit_all + || (check_more(false, forceit) == OK && only_one_window())) { + apply_autocmds(EVENT_EXITPRE, NULL, NULL, false, curbuf); + // Refuse to quit when locked or when the buffer in the last window is + // being closed (can only happen in autocommands). + if (curbuf_locked() + || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) { + return true; + } + } + + return false; +} + +// ":quit": quit current window, quit Vim if the last window is closed. +// ":{nr}quit": quit window {nr} static void ex_quit(exarg_T *eap) { if (cmdwin_type != 0) { @@ -5986,11 +6056,9 @@ static void ex_quit(exarg_T *eap) if (curbuf_locked()) { return; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer); - // Refuse to quit when locked or when the buffer in the last window is - // being closed (can only happen in autocommands). - if (!win_valid(wp) - || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) { + + // Trigger QuitPre and maybe ExitPre + if (before_quit_autocmds(wp, false, eap->forceit)) { return; } @@ -6015,6 +6083,7 @@ static void ex_quit(exarg_T *eap) if (only_one_window() && (ONE_WINDOW || eap->addr_count == 0)) { getout(0); } + not_exiting(); // close window; may free buffer win_close(wp, !buf_hide(wp->w_buffer) || eap->forceit); } @@ -6047,10 +6116,8 @@ static void ex_quit_all(exarg_T *eap) text_locked_msg(); return; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, curbuf); - // Refuse to quit when locked or when the buffer in the last window is - // being closed (can only happen in autocommands). - if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) { + + if (before_quit_autocmds(curwin, true, eap->forceit)) { return; } @@ -6309,9 +6376,7 @@ static void ex_hide(exarg_T *eap) } } -/* - * ":stop" and ":suspend": Suspend Vim. - */ +/// ":stop" and ":suspend": Suspend Vim. static void ex_stop(exarg_T *eap) { // Disallow suspending in restricted mode (-Z) @@ -6320,23 +6385,22 @@ static void ex_stop(exarg_T *eap) autowrite_all(); } apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL); + + // TODO(bfredl): the TUI should do this on suspend ui_cursor_goto((int)Rows - 1, 0); - ui_linefeed(); + ui_call_grid_scroll(1, 0, Rows, 0, Columns, 1, 0); ui_flush(); ui_call_suspend(); // call machine specific function ui_flush(); maketitle(); resettitle(); // force updating the title - redraw_later_clear(); ui_refresh(); // may have resized window apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL); } } -/* - * ":exit", ":xit" and ":wq": Write file and exit Vim. - */ +// ":exit", ":xit" and ":wq": Write file and quite the current window. static void ex_exit(exarg_T *eap) { if (cmdwin_type != 0) { @@ -6348,10 +6412,8 @@ static void ex_exit(exarg_T *eap) text_locked_msg(); return; } - apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, curbuf); - // Refuse to quit when locked or when the buffer in the last window is - // being closed (can only happen in autocommands). - if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) { + + if (before_quit_autocmds(curwin, false, eap->forceit)) { return; } @@ -6370,6 +6432,7 @@ static void ex_exit(exarg_T *eap) // quit last window, exit Vim getout(0); } + not_exiting(); // Quit current window, may free the buffer. win_close(curwin, !buf_hide(curwin->w_buffer)); } @@ -6490,6 +6553,13 @@ void alist_expand(int *fnum_list, int fnum_len) void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum_list, int fnum_len) { int i; + static int recursive = 0; + + if (recursive) { + EMSG(_(e_au_recursive)); + return; + } + recursive++; alist_clear(al); ga_grow(&al->al_ga, count); @@ -6514,8 +6584,10 @@ void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum xfree(files); } - if (al == &global_alist) - arg_had_last = FALSE; + if (al == &global_alist) { + arg_had_last = false; + } + recursive--; } /* @@ -6795,7 +6867,8 @@ static void ex_tabs(exarg_T *eap) static void ex_mode(exarg_T *eap) { if (*eap->arg == NUL) { - ui_refresh(); + must_redraw = CLEAR; + ex_redraw(eap); } else { EMSG(_(e_screenmode)); } @@ -6901,7 +6974,7 @@ do_exedit( no_wait_return = 0; need_wait_return = FALSE; msg_scroll = 0; - must_redraw = CLEAR; + redraw_all_later(NOT_VALID); normal_enter(false, true); @@ -7393,7 +7466,7 @@ static void ex_operators(exarg_T *eap) oa.end.lnum = eap->line2; oa.line_count = eap->line2 - eap->line1 + 1; oa.motion_type = kMTLineWise; - virtual_op = false; + virtual_op = kFalse; if (eap->cmdidx != CMD_yank) { // position cursor for undo setpcmark(); curwin->w_cursor.lnum = eap->line1; @@ -7424,7 +7497,7 @@ static void ex_operators(exarg_T *eap) op_shift(&oa, FALSE, eap->amount); break; } - virtual_op = MAYBE; + virtual_op = kNone; ex_may_print(eap); } @@ -7565,10 +7638,11 @@ static void ex_bang(exarg_T *eap) */ static void ex_undo(exarg_T *eap) { - if (eap->addr_count == 1) /* :undo 123 */ - undo_time(eap->line2, FALSE, FALSE, TRUE); - else + if (eap->addr_count == 1) { // :undo 123 + undo_time(eap->line2, false, false, true); + } else { u_undo(1); + } } static void ex_wundo(exarg_T *eap) @@ -7601,8 +7675,8 @@ static void ex_redo(exarg_T *eap) static void ex_later(exarg_T *eap) { long count = 0; - int sec = FALSE; - int file = FALSE; + bool sec = false; + bool file = false; char_u *p = eap->arg; if (*p == NUL) @@ -7610,11 +7684,11 @@ static void ex_later(exarg_T *eap) else if (isdigit(*p)) { count = getdigits_long(&p); switch (*p) { - case 's': ++p; sec = TRUE; break; - case 'm': ++p; sec = TRUE; count *= 60; break; - case 'h': ++p; sec = TRUE; count *= 60 * 60; break; - case 'd': ++p; sec = TRUE; count *= 24 * 60 * 60; break; - case 'f': ++p; file = TRUE; break; + case 's': ++p; sec = true; break; + case 'm': ++p; sec = true; count *= 60; break; + case 'h': ++p; sec = true; count *= 60 * 60; break; + case 'd': ++p; sec = true; count *= 24 * 60 * 60; break; + case 'f': ++p; file = true; break; } } @@ -7622,7 +7696,7 @@ static void ex_later(exarg_T *eap) EMSG2(_(e_invarg2), eap->arg); else undo_time(eap->cmdidx == CMD_earlier ? -count : count, - sec, file, FALSE); + sec, file, false); } /* @@ -7719,11 +7793,14 @@ static void ex_redraw(exarg_T *eap) p_lz = FALSE; validate_cursor(); update_topline(); - update_screen(eap->forceit ? CLEAR : - VIsual_active ? INVERTED : - 0); - if (need_maketitle) + if (eap->forceit) { + redraw_all_later(NOT_VALID); + } + update_screen(eap->forceit ? NOT_VALID + : VIsual_active ? INVERTED : 0); + if (need_maketitle) { maketitle(); + } RedrawingDisabled = r; p_lz = p; @@ -7918,7 +7995,7 @@ static void ex_mkrc(exarg_T *eap) if (failed) { EMSG(_(e_write)); } else if (eap->cmdidx == CMD_mksession) { - // successful session write - set this_session var + // successful session write - set v:this_session char *const tbuf = xmalloc(MAXPATHL); if (vim_FullName(fname, tbuf, MAXPATHL, false) == OK) { set_vim_var_string(VV_THIS_SESSION, tbuf, -1); @@ -8141,6 +8218,10 @@ static void ex_normal(exarg_T *eap) static void ex_startinsert(exarg_T *eap) { if (eap->forceit) { + // cursor line can be zero on startup + if (!curwin->w_cursor.lnum) { + curwin->w_cursor.lnum = 1; + } coladvance((colnr_T)MAXCOL); curwin->w_curswant = MAXCOL; curwin->w_set_curswant = FALSE; @@ -8380,23 +8461,25 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen) "%", #define SPEC_PERC 0 "#", -#define SPEC_HASH 1 - "<cword>", /* cursor word */ -#define SPEC_CWORD 2 - "<cWORD>", /* cursor WORD */ -#define SPEC_CCWORD 3 - "<cfile>", /* cursor path name */ -#define SPEC_CFILE 4 - "<sfile>", /* ":so" file name */ -#define SPEC_SFILE 5 - "<slnum>", /* ":so" file line number */ -#define SPEC_SLNUM 6 - "<afile>", /* autocommand file name */ -# define SPEC_AFILE 7 - "<abuf>", /* autocommand buffer number */ -# define SPEC_ABUF 8 - "<amatch>", /* autocommand match name */ -# define SPEC_AMATCH 9 +#define SPEC_HASH (SPEC_PERC + 1) + "<cword>", // cursor word +#define SPEC_CWORD (SPEC_HASH + 1) + "<cWORD>", // cursor WORD +#define SPEC_CCWORD (SPEC_CWORD + 1) + "<cexpr>", // expr under cursor +#define SPEC_CEXPR (SPEC_CCWORD + 1) + "<cfile>", // cursor path name +#define SPEC_CFILE (SPEC_CEXPR + 1) + "<sfile>", // ":so" file name +#define SPEC_SFILE (SPEC_CFILE + 1) + "<slnum>", // ":so" file line number +#define SPEC_SLNUM (SPEC_SFILE + 1) + "<afile>", // autocommand file name +#define SPEC_AFILE (SPEC_SLNUM + 1) + "<abuf>", // autocommand buffer number +#define SPEC_ABUF (SPEC_AFILE + 1) + "<amatch>", // autocommand match name +#define SPEC_AMATCH (SPEC_ABUF + 1) }; for (size_t i = 0; i < ARRAY_SIZE(spec_str); ++i) { @@ -8477,10 +8560,16 @@ eval_vars ( /* * word or WORD under cursor */ - if (spec_idx == SPEC_CWORD || spec_idx == SPEC_CCWORD) { - resultlen = find_ident_under_cursor(&result, (spec_idx == SPEC_CWORD - ? (FIND_IDENT|FIND_STRING) - : FIND_STRING)); + if (spec_idx == SPEC_CWORD + || spec_idx == SPEC_CCWORD + || spec_idx == SPEC_CEXPR) { + resultlen = find_ident_under_cursor( + &result, + spec_idx == SPEC_CWORD + ? (FIND_IDENT | FIND_STRING) + : (spec_idx == SPEC_CEXPR + ? (FIND_IDENT | FIND_STRING | FIND_EVAL) + : FIND_STRING)); if (resultlen == 0) { *errormsg = (char_u *)""; return NULL; @@ -8517,9 +8606,13 @@ eval_vars ( if (*s == '<') /* "#<99" uses v:oldfiles */ ++s; i = getdigits_int(&s); - *usedlen = (size_t)(s - src); /* length of what we expand */ + if (s == src + 2 && src[1] == '-') { + // just a minus sign, don't skip over it + s--; + } + *usedlen = (size_t)(s - src); // length of what we expand - if (src[1] == '<') { + if (src[1] == '<' && i != 0) { if (*usedlen < 2) { /* Should we give an error message for #<text? */ *usedlen = 1; @@ -8532,6 +8625,9 @@ eval_vars ( return NULL; } } else { + if (i == 0 && src[1] == '<' && *usedlen > 1) { + *usedlen = 1; + } buf = buflist_findnr(i); if (buf == NULL) { *errormsg = (char_u *)_( @@ -8617,11 +8713,14 @@ eval_vars ( break; } - resultlen = STRLEN(result); /* length of new string */ - if (src[*usedlen] == '<') { /* remove the file name extension */ - ++*usedlen; - if ((s = vim_strrchr(result, '.')) != NULL && s >= path_tail(result)) + // Length of new string. + resultlen = STRLEN(result); + // Remove the file name extension. + if (src[*usedlen] == '<') { + (*usedlen)++; + if ((s = STRRCHR(result, '.')) != NULL && s >= path_tail(result)) { resultlen = (size_t)(s - result); + } } else if (!skip_mod) { valid |= modify_fname(src, usedlen, &result, &resultbuf, &resultlen); if (result == NULL) { @@ -8680,7 +8779,7 @@ static char_u *arg_all(void) #ifndef BACKSLASH_IN_FILENAME || *p == '\\' #endif - ) { + || *p == '`') { // insert a backslash if (retval != NULL) { retval[len] = '\\'; @@ -8782,15 +8881,15 @@ makeopens( if (ssop_flags & SSOP_BUFFERS) only_save_windows = FALSE; /* Save ALL buffers */ - /* - * Begin by setting the this_session variable, and then other - * sessionable variables. - */ - if (put_line(fd, "let v:this_session=expand(\"<sfile>:p\")") == FAIL) + // Begin by setting v:this_session, and then other sessionable variables. + if (put_line(fd, "let v:this_session=expand(\"<sfile>:p\")") == FAIL) { return FAIL; - if (ssop_flags & SSOP_GLOBALS) - if (store_session_globals(fd) == FAIL) + } + if (ssop_flags & SSOP_GLOBALS) { + if (store_session_globals(fd) == FAIL) { return FAIL; + } + } /* * Close all windows but one. @@ -8971,8 +9070,10 @@ makeopens( // cursor can be set. This is done again below. // winminheight and winminwidth need to be set to avoid an error if the // user has set winheight or winwidth. - if (put_line(fd, "set winminheight=1 winminwidth=1 winheight=1 winwidth=1") - == FAIL) { + if (put_line(fd, "set winminheight=0") == FAIL + || put_line(fd, "set winheight=1") == FAIL + || put_line(fd, "set winminwidth=0") == FAIL + || put_line(fd, "set winwidth=1") == FAIL) { return FAIL; } if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) { @@ -9204,6 +9305,18 @@ static int ses_do_win(win_T *wp) return true; } +static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces) +{ + int r; + + if (wp->w_curswant == MAXCOL) { + r = fprintf(fd, "%snormal! $", spaces); + } else { + r = fprintf(fd, "%snormal! 0%d|", spaces, wp->w_virtcol + 1); + } + return r < 0 || put_eol(fd) == FAIL ? FAIL : OK; +} + /* * Write commands to "fd" to restore the view of a window. * Caller must make sure 'scrolloff' is zero. @@ -9370,14 +9483,11 @@ put_view( (int64_t)(wp->w_virtcol + 1)) < 0 || put_eol(fd) == FAIL || put_line(fd, "else") == FAIL - || fprintf(fd, " normal! 0%d|", wp->w_virtcol + 1) < 0 - || put_eol(fd) == FAIL + || put_view_curpos(fd, wp, " ") == FAIL || put_line(fd, "endif") == FAIL) return FAIL; - } else { - if (fprintf(fd, "normal! 0%d|", wp->w_virtcol + 1) < 0 - || put_eol(fd) == FAIL) - return FAIL; + } else if (put_view_curpos(fd, wp, "") == FAIL) { + return FAIL; } } } @@ -9662,6 +9772,14 @@ char_u *get_messages_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx) return NULL; } +char_u *get_mapclear_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx) +{ + if (idx == 0) { + return (char_u *)"<buffer>"; + } + return NULL; +} + static TriState filetype_detect = kNone; static TriState filetype_plugin = kNone; static TriState filetype_indent = kNone; @@ -9944,6 +10062,7 @@ bool cmd_can_preview(char_u *cmd) } exarg_T ea; + memset(&ea, 0, sizeof(ea)); // parse the command line ea.cmd = skip_range(cmd, NULL); if (*ea.cmd == '*') { diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 4b9ef5d819..19a52c913a 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -31,6 +31,7 @@ #include "nvim/fileio.h" #include "nvim/func_attr.h" #include "nvim/getchar.h" +#include "nvim/highlight.h" #include "nvim/if_cscope.h" #include "nvim/indent.h" #include "nvim/main.h" @@ -176,10 +177,6 @@ typedef struct command_line_state { int break_ctrl_c; expand_T xpc; long *b_im_ptr; - // Everything that may work recursively should save and restore the - // current command line in save_ccline. That includes update_screen(), a - // custom status line may invoke ":normal". - struct cmdline_info save_ccline; } CommandLineState; typedef struct cmdline_info CmdlineInfo; @@ -200,7 +197,10 @@ static Array cmdline_block = ARRAY_DICT_INIT; /* * Type used by call_user_expand_func */ -typedef void *(*user_expand_func_T)(char_u *, int, char_u **, int); +typedef void *(*user_expand_func_T)(const char_u *, + int, + const char_u * const *, + bool); static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL}; static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */ @@ -219,11 +219,19 @@ static bool getln_interrupted_highlight = false; # include "ex_getln.c.generated.h" #endif -static int cmd_hkmap = 0; /* Hebrew mapping during command line */ +static int cmd_hkmap = 0; // Hebrew mapping during command line +static int cmd_fkmap = 0; // Farsi mapping during command line -static int cmd_fkmap = 0; /* Farsi mapping during command line */ +/// Internal entry point for cmdline mode. +/// +/// caller must use save_cmdline and restore_cmdline. Best is to use +/// getcmdline or getcmdline_prompt, instead of calling this directly. static uint8_t *command_line_enter(int firstc, long count, int indent) { + // can be invoked recursively, identify each level + static int cmdline_level = 0; + cmdline_level++; + CommandLineState state, *s = &state; memset(s, 0, sizeof(CommandLineState)); s->firstc = firstc; @@ -251,7 +259,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) } ccline.prompt_id = last_prompt_id++; - ccline.level++; + ccline.level = cmdline_level; ccline.overstrike = false; // always start in insert mode clearpos(&s->match_end); s->save_cursor = curwin->w_cursor; // may be restored later @@ -483,19 +491,14 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) sb_text_end_cmdline(); - { - char_u *p = ccline.cmdbuff; - - // Make ccline empty, getcmdline() may try to use it. - ccline.cmdbuff = NULL; + char_u *p = ccline.cmdbuff; - if (ui_is_external(kUICmdline)) { - ccline.redraw_state = kCmdRedrawNone; - ui_call_cmdline_hide(ccline.level); - } - ccline.level--; - return p; + if (ui_is_external(kUICmdline)) { + ui_call_cmdline_hide(ccline.level); } + + cmdline_level--; + return p; } static int command_line_check(VimState *state) @@ -505,6 +508,10 @@ static int command_line_check(VimState *state) // completion may switch it on. quit_more = false; // reset after CTRL-D which had a more-prompt + did_emsg = false; // There can't really be a reason why an error + // that occurs while typing a command should + // cause the command not to be executed. + cursorcmd(); // set the cursor on the right spot ui_cursor_shape(); return 1; @@ -618,7 +625,7 @@ static int command_line_execute(VimState *state, int key) } s->wim_index = 0; if (p_wmnu && wild_menu_showing != 0) { - int skt = KeyTyped; + const bool skt = KeyTyped; int old_RedrawingDisabled = RedrawingDisabled; if (ccline.input_fn) { @@ -635,9 +642,7 @@ static int command_line_execute(VimState *state, int key) p_ls = save_p_ls; p_wmh = save_p_wmh; last_status(false); - save_cmdline(&s->save_ccline); update_screen(VALID); // redraw the screen NOW - restore_cmdline(&s->save_ccline); redrawcmd(); save_p_ls = -1; wild_menu_showing = 0; @@ -719,9 +724,7 @@ static int command_line_execute(VimState *state, int key) s->j = ccline.cmdpos; s->i = (int)(s->xpc.xp_pattern - ccline.cmdbuff); while (--s->j > s->i) { - if (has_mbyte) { - s->j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + s->j); - } + s->j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + s->j); if (vim_ispathsep(ccline.cmdbuff[s->j])) { found = true; break; @@ -741,9 +744,7 @@ static int command_line_execute(VimState *state, int key) s->j = ccline.cmdpos - 1; s->i = (int)(s->xpc.xp_pattern - ccline.cmdbuff); while (--s->j > s->i) { - if (has_mbyte) { - s->j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + s->j); - } + s->j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + s->j); if (vim_ispathsep(ccline.cmdbuff[s->j]) #ifdef BACKSLASH_IN_FILENAME && vim_strchr((const char_u *)" *?[{`$%#", ccline.cmdbuff[s->j + 1]) @@ -794,9 +795,11 @@ static int command_line_execute(VimState *state, int key) no_mapping--; // CTRL-\ e doesn't work when obtaining an expression, unless it // is in a mapping. - if (s->c != Ctrl_N && s->c != Ctrl_G && (s->c != 'e' - || (ccline.cmdfirstc == '=' - && KeyTyped))) { + if (s->c != Ctrl_N + && s->c != Ctrl_G + && (s->c != 'e' + || (ccline.cmdfirstc == '=' && KeyTyped) + || cmdline_star > 0)) { vungetc(s->c); s->c = Ctrl_BSL; } else if (s->c == 'e') { @@ -812,18 +815,17 @@ static int command_line_execute(VimState *state, int key) new_cmdpos = ccline.cmdpos; } - save_cmdline(&s->save_ccline); s->c = get_expr_register(); - restore_cmdline(&s->save_ccline); if (s->c == '=') { // Need to save and restore ccline. And set "textlock" // to avoid nasty things like going to another buffer when // evaluating an expression. - save_cmdline(&s->save_ccline); - ++textlock; + CmdlineInfo save_ccline; + save_cmdline(&save_ccline); + textlock++; p = get_expr_line(); - --textlock; - restore_cmdline(&s->save_ccline); + textlock--; + restore_cmdline(&save_ccline); if (p != NULL) { len = (int)STRLEN(p); @@ -1352,13 +1354,15 @@ static int command_line_handle_key(CommandLineState *s) // a new one... new_cmdpos = -1; if (s->c == '=') { - if (ccline.cmdfirstc == '=') { // can't do this recursively + if (ccline.cmdfirstc == '=' // can't do this recursively + || cmdline_star > 0) { // or when typing a password beep_flush(); s->c = ESC; } else { - save_cmdline(&s->save_ccline); + CmdlineInfo save_ccline; + save_cmdline(&save_ccline); s->c = get_expr_register(); - restore_cmdline(&s->save_ccline); + restore_cmdline(&save_ccline); } } @@ -1429,20 +1433,17 @@ static int command_line_handle_key(CommandLineState *s) return command_line_not_changed(s); } do { - --ccline.cmdpos; - if (has_mbyte) { // move to first byte of char - ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff, - ccline.cmdbuff + ccline.cmdpos); - } + ccline.cmdpos--; + // Move to first byte of possibly multibyte char. + ccline.cmdpos -= utf_head_off(ccline.cmdbuff, + ccline.cmdbuff + ccline.cmdpos); ccline.cmdspos -= cmdline_charsize(ccline.cmdpos); } while (ccline.cmdpos > 0 && (s->c == K_S_LEFT || s->c == K_C_LEFT || (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))) && ccline.cmdbuff[ccline.cmdpos - 1] != ' '); - if (has_mbyte) { - set_cmdspos_cursor(); - } + set_cmdspos_cursor(); return command_line_not_changed(s); @@ -1473,7 +1474,7 @@ static int command_line_handle_key(CommandLineState *s) if (s->ignore_drag_release) { return command_line_not_changed(s); } - // FALLTHROUGH + FALLTHROUGH; case K_LEFTMOUSE: case K_RIGHTMOUSE: if (s->c == K_LEFTRELEASE || s->c == K_RIGHTRELEASE) { @@ -1591,7 +1592,7 @@ static int command_line_handle_key(CommandLineState *s) } return command_line_not_changed(s); } - // fallthrough + FALLTHROUGH; case K_UP: case K_DOWN: @@ -1766,14 +1767,9 @@ static int command_line_handle_key(CommandLineState *s) if (IS_SPECIAL(s->c) || mod_mask != 0) { put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true); } else { - if (has_mbyte) { - s->j = (*mb_char2bytes)(s->c, IObuff); - IObuff[s->j] = NUL; // exclude composing chars - put_on_cmdline(IObuff, s->j, true); - } else { - IObuff[0] = s->c; - put_on_cmdline(IObuff, 1, true); - } + s->j = utf_char2bytes(s->c, IObuff); + IObuff[s->j] = NUL; // exclude composing chars + put_on_cmdline(IObuff, s->j, true); } return command_line_changed(s); } @@ -1796,7 +1792,7 @@ static int command_line_not_changed(CommandLineState *s) /// as a trailing \|, which can happen while typing a pattern. static int empty_pattern(char_u *p) { - int n = STRLEN(p); + size_t n = STRLEN(p); // remove trailing \v and the like while (n >= 2 && p[n - 2] == '\\' @@ -1893,9 +1889,7 @@ static int command_line_changed(CommandLineState *s) curwin->w_redr_status = true; } - save_cmdline(&s->save_ccline); update_screen(SOME_VALID); - restore_cmdline(&s->save_ccline); restore_last_search_pattern(); // Leave it at the end to make CTRL-R CTRL-W work. @@ -1990,7 +1984,14 @@ getcmdline ( int indent // indent for inside conditionals ) { - return command_line_enter(firstc, count, indent); + // Be prepared for situations where cmdline can be invoked recursively. + // That includes cmd mappings, event handlers, as well as update_screen() + // (custom status line eval), which all may invoke ":normal :". + CmdlineInfo save_ccline; + save_cmdline(&save_ccline); + char_u *retval = command_line_enter(firstc, count, indent); + restore_cmdline(&save_ccline); + return retval; } /// Get a command line with a prompt @@ -2014,7 +2015,7 @@ char *getcmdline_prompt(const char firstc, const char *const prompt, { const int msg_col_save = msg_col; - struct cmdline_info save_ccline; + CmdlineInfo save_ccline; save_cmdline(&save_ccline); ccline.prompt_id = last_prompt_id++; @@ -2028,7 +2029,7 @@ char *getcmdline_prompt(const char firstc, const char *const prompt, int msg_silent_saved = msg_silent; msg_silent = 0; - char *const ret = (char *)getcmdline(firstc, 1L, 0); + char *const ret = (char *)command_line_enter(firstc, 1L, 0); restore_cmdline(&save_ccline); msg_silent = msg_silent_saved; @@ -2151,10 +2152,11 @@ static void set_cmdspos_cursor(void) */ static void correct_cmdspos(int idx, int cells) { - if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1 - && (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1 - && ccline.cmdspos % Columns + cells > Columns) + if (utfc_ptr2len(ccline.cmdbuff + idx) > 1 + && utf_ptr2cells(ccline.cmdbuff + idx) > 1 + && ccline.cmdspos % Columns + cells > Columns) { ccline.cmdspos++; + } } /* @@ -2170,6 +2172,7 @@ getexline ( /* When executing a register, remove ':' that's in front of each line. */ if (exec_from_reg && vpeekc() == ':') (void)vgetc(); + return getcmdline(c, 1L, indent); } @@ -2262,14 +2265,10 @@ getexmodeline ( if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) { if (!GA_EMPTY(&line_ga)) { - if (has_mbyte) { - p = (char_u *)line_ga.ga_data; - p[line_ga.ga_len] = NUL; - len = (*mb_head_off)(p, p + line_ga.ga_len - 1) + 1; - line_ga.ga_len -= len; - } else { - line_ga.ga_len--; - } + p = (char_u *)line_ga.ga_data; + p[line_ga.ga_len] = NUL; + len = utf_head_off(p, p + line_ga.ga_len - 1) + 1; + line_ga.ga_len -= len; goto redraw; } continue; @@ -2373,16 +2372,11 @@ redraw: if (IS_SPECIAL(c1)) { c1 = '?'; } - if (has_mbyte) { - len = (*mb_char2bytes)(c1, (char_u *)line_ga.ga_data + line_ga.ga_len); - } else { - len = 1; - ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1; - } - if (c1 == '\n') + len = utf_char2bytes(c1, (char_u *)line_ga.ga_data + line_ga.ga_len); + if (c1 == '\n') { msg_putchar('\n'); - else if (c1 == TAB) { - /* Don't use chartabsize(), 'ts' can be different */ + } else if (c1 == TAB) { + // Don't use chartabsize(), 'ts' can be different. do { msg_putchar(' '); } while (++vcol % 8); @@ -2704,7 +2698,7 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) } const list_T *const l = TV_LIST_ITEM_TV(li)->vval.v_list; if (tv_list_len(l) != 3) { - PRINT_ERRMSG(_("E5402: List item %i has incorrect length: %li /= 3"), + PRINT_ERRMSG(_("E5402: List item %i has incorrect length: %d /= 3"), i, tv_list_len(l)); goto color_cmdline_error; } @@ -2898,12 +2892,12 @@ static void draw_cmdline(int start, int len) u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc); - newlen += (*mb_char2bytes)(u8c, arshape_buf + newlen); + newlen += utf_char2bytes(u8c, arshape_buf + newlen); if (u8cc[0] != 0) { - newlen += (*mb_char2bytes)(u8cc[0], arshape_buf + newlen); - if (u8cc[1] != 0) - newlen += (*mb_char2bytes)(u8cc[1], - arshape_buf + newlen); + newlen += utf_char2bytes(u8cc[0], arshape_buf + newlen); + if (u8cc[1] != 0) { + newlen += utf_char2bytes(u8cc[1], arshape_buf + newlen); + } } } else { prev_c = u8c; @@ -2943,30 +2937,22 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) char *buf = xmallocz(len); memset(buf, '*', len); Array item = ARRAY_DICT_INIT; - ADD(item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); + ADD(item, INTEGER_OBJ(0)); ADD(item, STRING_OBJ(((String) { .data = buf, .size = len }))); ADD(content, ARRAY_OBJ(item)); } else if (kv_size(line->last_colors.colors)) { for (size_t i = 0; i < kv_size(line->last_colors.colors); i++) { CmdlineColorChunk chunk = kv_A(line->last_colors.colors, i); Array item = ARRAY_DICT_INIT; + ADD(item, INTEGER_OBJ(chunk.attr)); - if (chunk.attr) { - HlAttrs *aep = syn_cterm_attr2entry(chunk.attr); - // TODO(bfredl): this desicion could be delayed by making attr_code a - // recognized type - Dictionary rgb_attrs = hlattrs2dict(aep, true); - ADD(item, DICTIONARY_OBJ(rgb_attrs)); - } else { - ADD(item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); - } ADD(item, STRING_OBJ(cbuf_to_string((char *)line->cmdbuff + chunk.start, chunk.end-chunk.start))); ADD(content, ARRAY_OBJ(item)); } } else { Array item = ARRAY_DICT_INIT; - ADD(item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); + ADD(item, INTEGER_OBJ(0)); ADD(item, STRING_OBJ(cstr_to_string((char *)(line->cmdbuff)))); ADD(content, ARRAY_OBJ(item)); } @@ -2989,7 +2975,7 @@ void ui_ext_cmdline_block_append(int indent, const char *line) memcpy(buf + indent, line, strlen(line)); // -V575 Array item = ARRAY_DICT_INIT; - ADD(item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); + ADD(item, INTEGER_OBJ(0)); ADD(item, STRING_OBJ(cstr_as_string(buf))); Array content = ARRAY_DICT_INIT; ADD(content, ARRAY_OBJ(item)); @@ -3021,16 +3007,16 @@ void cmdline_screen_cleared(void) } int prev_level = ccline.level-1; - CmdlineInfo *prev_ccline = ccline.prev_ccline; - while (prev_level > 0 && prev_ccline) { - if (prev_ccline->level == prev_level) { + CmdlineInfo *line = ccline.prev_ccline; + while (prev_level > 0 && line) { + if (line->level == prev_level) { // don't redraw a cmdline already shown in the cmdline window if (prev_level != cmdwin_level) { - prev_ccline->redraw_state = kCmdRedrawAll; + line->redraw_state = kCmdRedrawAll; } prev_level--; } - prev_ccline = prev_ccline->prev_ccline; + line = line->prev_ccline; } } @@ -3156,18 +3142,15 @@ void put_on_cmdline(char_u *str, int len, int redraw) i = 0; c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); while (ccline.cmdpos > 0 && utf_iscomposing(c)) { - i = (*mb_head_off)(ccline.cmdbuff, - ccline.cmdbuff + ccline.cmdpos - 1) + 1; + i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos - 1) + 1; ccline.cmdpos -= i; len += i; c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos); } if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c)) { - /* Check the previous character for Arabic combining pair. */ - i = (*mb_head_off)(ccline.cmdbuff, - ccline.cmdbuff + ccline.cmdpos - 1) + 1; - if (arabic_combine(utf_ptr2char(ccline.cmdbuff - + ccline.cmdpos - i), c)) { + // Check the previous character for Arabic combining pair. + i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos - 1) + 1; + if (arabic_combine(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos - i), c)) { ccline.cmdpos -= i; len += i; } else @@ -3244,6 +3227,7 @@ static void save_cmdline(struct cmdline_info *ccp) ccline.cmdprompt = NULL; ccline.xpc = NULL; ccline.special_char = NUL; + ccline.level = 0; } /* @@ -3286,17 +3270,18 @@ void restore_cmdline_alloc(char_u *p) /// @returns FAIL for failure, OK otherwise static bool cmdline_paste(int regname, bool literally, bool remcr) { - long i; char_u *arg; char_u *p; - int allocated; + bool allocated; struct cmdline_info save_ccline; /* check for valid regname; also accept special characters for CTRL-R in * the command line */ if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W - && regname != Ctrl_A && !valid_yank_reg(regname, false)) + && regname != Ctrl_A && regname != Ctrl_L + && !valid_yank_reg(regname, false)) { return FAIL; + } /* A register containing CTRL-R can cause an endless loop. Allow using * CTRL-C to break the loop. */ @@ -3308,9 +3293,9 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) /* Need to save and restore ccline. And set "textlock" to avoid nasty * things like going to another buffer when evaluating an expression. */ save_cmdline(&save_ccline); - ++textlock; - i = get_spec_reg(regname, &arg, &allocated, TRUE); - --textlock; + textlock++; + const bool i = get_spec_reg(regname, &arg, &allocated, true); + textlock--; restore_cmdline(&save_ccline); if (i) { @@ -3327,16 +3312,11 @@ static bool cmdline_paste(int regname, bool literally, bool remcr) /* Locate start of last word in the cmd buffer. */ for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) { - if (has_mbyte) { - len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1; - if (!vim_iswordc(mb_ptr2char(w - len))) - break; - w -= len; - } else { - if (!vim_iswordc(w[-1])) - break; - --w; + len = utf_head_off(ccline.cmdbuff, w - 1) + 1; + if (!vim_iswordc(utf_ptr2char(w - len))) { + break; } + w -= len; } len = (int)((ccline.cmdbuff + ccline.cmdpos) - w); if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0) @@ -3377,9 +3357,6 @@ void cmdline_paste_str(char_u *s, int literally) } if (cv == Ctrl_V || c == ESC || c == Ctrl_C || c == CAR || c == NL || c == Ctrl_L -#ifdef UNIX - || c == intr_char -#endif || (c == Ctrl_BSL && *s == Ctrl_N)) { stuffcharReadbuff(Ctrl_V); } @@ -3500,6 +3477,7 @@ static void cursorcmd(void) if (ccline.redraw_state < kCmdRedrawPos) { ccline.redraw_state = kCmdRedrawPos; } + setcursor(); return; } @@ -3541,10 +3519,28 @@ void gotocmdline(int clr) */ static int ccheck_abbr(int c) { - if (p_paste || no_abbr) /* no abbreviations or in paste mode */ - return FALSE; + int spos = 0; + + if (p_paste || no_abbr) { // no abbreviations or in paste mode + return false; + } - return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0); + // Do not consider '<,'> be part of the mapping, skip leading whitespace. + // Actually accepts any mark. + while (ascii_iswhite(ccline.cmdbuff[spos]) && spos < ccline.cmdlen) { + spos++; + } + if (ccline.cmdlen - spos > 5 + && ccline.cmdbuff[spos] == '\'' + && ccline.cmdbuff[spos + 2] == ',' + && ccline.cmdbuff[spos + 3] == '\'') { + spos += 5; + } else { + // check abbreviation from the beginning of the commandline + spos = 0; + } + + return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, spos); } static int sort_func_compare(const void *s1, const void *s2) @@ -3833,24 +3829,13 @@ ExpandOne ( // Find longest common part if (mode == WILD_LONGEST && xp->xp_numfiles > 0) { - size_t len; - size_t mb_len = 1; - int c0; - int ci; + size_t len = 0; - for (len = 0; xp->xp_files[0][len]; len += mb_len) { - if (has_mbyte) { - mb_len = (* mb_ptr2len)(&xp->xp_files[0][len]); - c0 = (* mb_ptr2char)(&xp->xp_files[0][len]); - } else { - c0 = xp->xp_files[0][len]; - } - for (i = 1; i < xp->xp_numfiles; ++i) { - if (has_mbyte) { - ci =(* mb_ptr2char)(&xp->xp_files[i][len]); - } else { - ci = xp->xp_files[i][len]; - } + for (size_t mb_len; xp->xp_files[0][len]; len += mb_len) { + mb_len = utfc_ptr2len(&xp->xp_files[0][len]); + int c0 = utf_ptr2char(&xp->xp_files[0][len]); + for (i = 1; i < xp->xp_numfiles; i++) { + int ci = utf_ptr2char(&xp->xp_files[i][len]); if (p_fic && (xp->xp_context == EXPAND_DIRECTORIES || xp->xp_context == EXPAND_FILES @@ -4697,7 +4682,7 @@ ExpandFromContext ( /* With an empty argument we would get all the help tags, which is * very slow. Get matches for "help" instead. */ if (find_help_tags(*pat == NUL ? (char_u *)"help" : pat, - num_file, file, FALSE) == OK) { + num_file, file, false) == OK) { cleanup_help_tags(*num_file, *file); return OK; } @@ -4768,6 +4753,7 @@ ExpandFromContext ( } tab[] = { { EXPAND_COMMANDS, get_command_name, false, true }, { EXPAND_BEHAVE, get_behave_arg, true, true }, + { EXPAND_MAPCLEAR, get_mapclear_arg, true, true }, { EXPAND_MESSAGES, get_messages_arg, true, true }, { EXPAND_HISTORY, get_history_arg, true, true }, { EXPAND_USER_COMMANDS, get_user_commands, false, true }, @@ -4795,6 +4781,7 @@ ExpandFromContext ( #endif { EXPAND_ENV_VARS, get_env_name, true, true }, { EXPAND_USER, get_users, true, false }, + { EXPAND_ARGLIST, get_arglist_name, true, false }, }; int i; @@ -5045,7 +5032,10 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, ccline.cmdprompt = NULL; current_SID = xp->xp_scriptID; - ret = user_expand_func(xp->xp_arg, 3, args, FALSE); + ret = user_expand_func(xp->xp_arg, + 3, + (const char_u * const *)args, + false); ccline = save_ccline; current_SID = save_current_SID; @@ -5061,38 +5051,34 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func, */ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file) { - char_u *retstr; - char_u *s; - char_u *e; - char_u keep; - garray_T ga; + char_u *e; + garray_T ga; + + char_u *const retstr = call_user_expand_func( + (user_expand_func_T)call_func_retstr, xp, num_file, file); - retstr = call_user_expand_func((user_expand_func_T)call_func_retstr, xp, - num_file, file); if (retstr == NULL) { return FAIL; } ga_init(&ga, (int)sizeof(char *), 3); - for (s = retstr; *s != NUL; s = e) { + for (char_u *s = retstr; *s != NUL; s = e) { e = vim_strchr(s, '\n'); if (e == NULL) e = s + STRLEN(s); - keep = *e; - *e = 0; + const int keep = *e; + *e = NUL; - if (xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0) { - *e = keep; - if (*e != NUL) - ++e; - continue; + const bool skip = xp->xp_pattern[0] + && vim_regexec(regmatch, s, (colnr_T)0) == 0; + *e = keep; + if (!skip) { + GA_APPEND(char_u *, &ga, vim_strnsave(s, (int)(e - s))); } - GA_APPEND(char_u *, &ga, vim_strnsave(s, (int)(e - s))); - - *e = keep; - if (*e != NUL) - ++e; + if (*e != NUL) { + e++; + } } xfree(retstr); *file = ga.ga_data; @@ -5619,6 +5605,9 @@ static struct cmdline_info *get_ccline_ptr(void) */ char_u *get_cmdline_str(void) { + if (cmdline_star > 0) { + return NULL; + } struct cmdline_info *p = get_ccline_ptr(); if (p == NULL) @@ -6097,7 +6086,7 @@ static int open_cmdwin(void) /* Replace the empty last line with the current command-line and put the * cursor there. */ - ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE); + ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, true); curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; curwin->w_cursor.col = ccline.cmdpos; changed_line_abv_curs(); @@ -6137,7 +6126,7 @@ static int open_cmdwin(void) RedrawingDisabled = i; restore_batch_count(save_count); - int save_KeyTyped = KeyTyped; + const bool save_KeyTyped = KeyTyped; /* Trigger CmdwinLeave autocommands. */ apply_autocmds(EVENT_CMDWINLEAVE, typestr, typestr, FALSE, curbuf); @@ -6211,7 +6200,7 @@ static int open_cmdwin(void) wp = curwin; set_bufref(&bufref, curbuf); win_goto(old_curwin); - win_close(wp, TRUE); + win_close(wp, true); // win_close() may have already wiped the buffer when 'bh' is // set to 'wipe'. diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c index 6de84fbf4d..3d714f0fa6 100644 --- a/src/nvim/farsi.c +++ b/src/nvim/farsi.c @@ -1081,7 +1081,7 @@ int fkmap(int c) if (gchar_cursor() == _LAM) { chg_l_toXor_X(); - del_char(FALSE); + del_char(false); AppendCharToRedobuff(K_BS); if (!p_ri) { @@ -1602,7 +1602,7 @@ static void conv_to_pvim(void) do_cmdline_cmd("%s/\201\231/\370\334/ge"); // Assume the screen has been messed up: clear it and redraw. - redraw_later(CLEAR); + redraw_later(NOT_VALID); MSG_ATTR((const char *)farsi_text_1, HL_ATTR(HLF_S)); } @@ -1623,7 +1623,7 @@ static void conv_to_pstd(void) } // Assume the screen has been messed up: clear it and redraw. - redraw_later(CLEAR); + redraw_later(NOT_VALID); msg_attr((const char *)farsi_text_2, HL_ATTR(HLF_S)); } diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 5b17b58781..ee775bab4a 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -577,7 +577,7 @@ char_u *vim_findfile(void *search_ctx_arg) char_u *file_path; char_u *rest_of_wildcards; char_u *path_end = NULL; - ff_stack_T *stackp; + ff_stack_T *stackp = NULL; size_t len; char_u *p; char_u *suf; @@ -683,28 +683,40 @@ char_u *vim_findfile(void *search_ctx_arg) dirptrs[0] = file_path; dirptrs[1] = NULL; - /* if we have a start dir copy it in */ + // if we have a start dir copy it in if (!vim_isAbsName(stackp->ffs_fix_path) && search_ctx->ffsc_start_dir) { + if (STRLEN(search_ctx->ffsc_start_dir) + 1 >= MAXPATHL) { + goto fail; + } STRCPY(file_path, search_ctx->ffsc_start_dir); - add_pathsep((char *)file_path); + if (!add_pathsep((char *)file_path)) { + goto fail; + } } - /* append the fix part of the search path */ + // append the fix part of the search path + if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 >= MAXPATHL) { + goto fail; + } STRCAT(file_path, stackp->ffs_fix_path); - add_pathsep((char *)file_path); + if (!add_pathsep((char *)file_path)) { + goto fail; + } rest_of_wildcards = stackp->ffs_wc_path; if (*rest_of_wildcards != NUL) { len = STRLEN(file_path); if (STRNCMP(rest_of_wildcards, "**", 2) == 0) { - /* pointer to the restrict byte - * The restrict byte is not a character! - */ + // pointer to the restrict byte + // The restrict byte is not a character! p = rest_of_wildcards + 2; if (*p > 0) { (*p)--; + if (len + 1 >= MAXPATHL) { + goto fail; + } file_path[len++] = '*'; } @@ -729,8 +741,12 @@ char_u *vim_findfile(void *search_ctx_arg) * on the stack again for further search. */ while (*rest_of_wildcards - && !vim_ispathsep(*rest_of_wildcards)) + && !vim_ispathsep(*rest_of_wildcards)) { + if (len + 1 >= MAXPATHL) { + goto fail; + } file_path[len++] = *rest_of_wildcards++; + } file_path[len] = NUL; if (vim_ispathsep(*rest_of_wildcards)) @@ -773,10 +789,15 @@ char_u *vim_findfile(void *search_ctx_arg) && !os_isdir(stackp->ffs_filearray[i])) continue; /* not a directory */ - /* prepare the filename to be checked for existence - * below */ + // prepare the filename to be checked for existence below + if (STRLEN(stackp->ffs_filearray[i]) + 1 + + STRLEN(search_ctx->ffsc_file_to_search) >= MAXPATHL) { + goto fail; + } STRCPY(file_path, stackp->ffs_filearray[i]); - add_pathsep((char *)file_path); + if (!add_pathsep((char *)file_path)) { + goto fail; + } STRCAT(file_path, search_ctx->ffsc_file_to_search); /* @@ -924,8 +945,14 @@ char_u *vim_findfile(void *search_ctx_arg) if (*search_ctx->ffsc_start_dir == 0) break; + if (STRLEN(search_ctx->ffsc_start_dir) + 1 + + STRLEN(search_ctx->ffsc_fix_path) >= MAXPATHL) { + goto fail; + } STRCPY(file_path, search_ctx->ffsc_start_dir); - add_pathsep((char *)file_path); + if (!add_pathsep((char *)file_path)) { + goto fail; + } STRCAT(file_path, search_ctx->ffsc_fix_path); /* create a new stack entry */ @@ -936,6 +963,8 @@ char_u *vim_findfile(void *search_ctx_arg) break; } +fail: + ff_free_stack_element(stackp); xfree(file_path); return NULL; } @@ -1192,14 +1221,19 @@ static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx) /* * free the given stack element */ -static void ff_free_stack_element(ff_stack_T *stack_ptr) +static void ff_free_stack_element(ff_stack_T *const stack_ptr) { - /* free handles possible NULL pointers */ + if (stack_ptr == NULL) { + return; + } + + // free handles possible NULL pointers xfree(stack_ptr->ffs_fix_path); xfree(stack_ptr->ffs_wc_path); - if (stack_ptr->ffs_filearray != NULL) + if (stack_ptr->ffs_filearray != NULL) { FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray); + } xfree(stack_ptr); } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 0858436db3..7e8a7d1a35 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1380,15 +1380,15 @@ retry: } } else if (fio_flags & FIO_UCS4) { if (fio_flags & FIO_ENDIAN_L) { - u8c = (*--p << 24); - u8c += (*--p << 16); - u8c += (*--p << 8); + u8c = (unsigned)(*--p) << 24; + u8c += (unsigned)(*--p) << 16; + u8c += (unsigned)(*--p) << 8; u8c += *--p; } else { /* big endian */ u8c = *--p; - u8c += (*--p << 8); - u8c += (*--p << 16); - u8c += (*--p << 24); + u8c += (unsigned)(*--p) << 8; + u8c += (unsigned)(*--p) << 16; + u8c += (unsigned)(*--p) << 24; } } else { /* UTF-8 */ if (*--p < 0x80) @@ -2267,15 +2267,16 @@ buf_write ( char_u smallbuf[SMBUFSIZE]; char_u *backup_ext; int bufsize; - long perm; /* file permissions */ + long perm; // file permissions int retval = OK; - int newfile = FALSE; /* TRUE if file doesn't exist yet */ + int newfile = false; // TRUE if file doesn't exist yet int msg_save = msg_scroll; - int overwriting; /* TRUE if writing over original */ - int no_eol = FALSE; /* no end-of-line written */ - int device = FALSE; /* writing to a device */ + int overwriting; // TRUE if writing over original + int no_eol = false; // no end-of-line written + int device = false; // writing to a device int prev_got_int = got_int; - bool file_readonly = false; /* overwritten file is read-only */ + int checking_conversion; + bool file_readonly = false; // overwritten file is read-only static char *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions')"; #if defined(UNIX) @@ -3156,298 +3157,328 @@ nobackup: notconverted = TRUE; } - /* - * Open the file "wfname" for writing. - * We may try to open the file twice: If we can't write to the - * file and forceit is TRUE we delete the existing file and try to create - * a new one. If this still fails we may have lost the original file! - * (this may happen when the user reached his quotum for number of files). - * Appending will fail if the file does not exist and forceit is FALSE. - */ - while ((fd = os_open((char *)wfname, O_WRONLY | (append - ? (forceit ? ( - O_APPEND | - O_CREAT) : - O_APPEND) - : (O_CREAT | - O_TRUNC)) - , perm < 0 ? 0666 : (perm & 0777))) < 0) { - /* - * A forced write will try to create a new file if the old one is - * still readonly. This may also happen when the directory is - * read-only. In that case the os_remove() will fail. - */ - if (errmsg == NULL) { + // If conversion is taking place, we may first pretend to write and check + // for conversion errors. Then loop again to write for real. + // When not doing conversion this writes for real right away. + for (checking_conversion = true; ; checking_conversion = false) { + // There is no need to check conversion when: + // - there is no conversion + // - we make a backup file, that can be restored in case of conversion + // failure. + if (!converted || dobackup) { + checking_conversion = false; + } + + if (checking_conversion) { + // Make sure we don't write anything. + fd = -1; + write_info.bw_fd = fd; + } else { + // Open the file "wfname" for writing. + // We may try to open the file twice: If we can't write to the file + // and forceit is TRUE we delete the existing file and try to + // create a new one. If this still fails we may have lost the + // original file! (this may happen when the user reached his + // quotum for number of files). + // Appending will fail if the file does not exist and forceit is + // FALSE. + while ((fd = os_open((char *)wfname, + O_WRONLY | + (append ? + (forceit ? (O_APPEND | O_CREAT) : O_APPEND) + : (O_CREAT | O_TRUNC)) + , perm < 0 ? 0666 : (perm & 0777))) < 0) { + // A forced write will try to create a new file if the old one + // is still readonly. This may also happen when the directory + // is read-only. In that case the mch_remove() will fail. + if (errmsg == NULL) { #ifdef UNIX - FileInfo file_info; + FileInfo file_info; - // Don't delete the file when it's a hard or symbolic link. - if ((!newfile && os_fileinfo_hardlinks(&file_info_old) > 1) - || (os_fileinfo_link((char *)fname, &file_info) - && !os_fileinfo_id_equal(&file_info, &file_info_old))) { - SET_ERRMSG(_("E166: Can't open linked file for writing")); - } else { + // Don't delete the file when it's a hard or symbolic link. + if ((!newfile && os_fileinfo_hardlinks(&file_info_old) > 1) + || (os_fileinfo_link((char *)fname, &file_info) + && !os_fileinfo_id_equal(&file_info, &file_info_old))) { + SET_ERRMSG(_("E166: Can't open linked file for writing")); + } else { #endif - SET_ERRMSG_ARG(_("E212: Can't open file for writing: %s"), fd); - if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL - && perm >= 0) { + SET_ERRMSG_ARG(_("E212: Can't open file for writing: %s"), fd); + if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL + && perm >= 0) { #ifdef UNIX - /* we write to the file, thus it should be marked - writable after all */ - if (!(perm & 0200)) - made_writable = TRUE; - perm |= 0200; - if (file_info_old.stat.st_uid != getuid() - || file_info_old.stat.st_gid != getgid()) { - perm &= 0777; - } + // we write to the file, thus it should be marked + // writable after all + if (!(perm & 0200)) { + made_writable = true; + } + perm |= 0200; + if (file_info_old.stat.st_uid != getuid() + || file_info_old.stat.st_gid != getgid()) { + perm &= 0777; + } #endif - if (!append) /* don't remove when appending */ - os_remove((char *)wfname); - continue; - } + if (!append) { // don't remove when appending + os_remove((char *)wfname); + } + continue; + } #ifdef UNIX - } + } #endif - } + } restore_backup: - { - /* - * If we failed to open the file, we don't need a backup. Throw it - * away. If we moved or removed the original file try to put the - * backup in its place. - */ - if (backup != NULL && wfname == fname) { - if (backup_copy) { - /* - * There is a small chance that we removed the original, - * try to move the copy in its place. - * This may not work if the vim_rename() fails. - * In that case we leave the copy around. - */ - // If file does not exist, put the copy in its place - if (!os_path_exists(fname)) { - vim_rename(backup, fname); + { + // If we failed to open the file, we don't need a backup. Throw it + // away. If we moved or removed the original file try to put the + // backup in its place. + if (backup != NULL && wfname == fname) { + if (backup_copy) { + // There is a small chance that we removed the original, + // try to move the copy in its place. + // This may not work if the vim_rename() fails. + // In that case we leave the copy around. + // If file does not exist, put the copy in its place + if (!os_path_exists(fname)) { + vim_rename(backup, fname); + } + // if original file does exist throw away the copy + if (os_path_exists(fname)) { + os_remove((char *)backup); + } + } else { + // try to put the original file back + vim_rename(backup, fname); + } } - // if original file does exist throw away the copy - if (os_path_exists(fname)) { - os_remove((char *)backup); + + // if original file no longer exists give an extra warning + if (!newfile && !os_path_exists(fname)) { + end = 0; } - } else { - /* try to put the original file back */ - vim_rename(backup, fname); } - } - // if original file no longer exists give an extra warning - if (!newfile && !os_path_exists(fname)) { - end = 0; + if (wfname != fname) { + xfree(wfname); + } + goto fail; } + write_info.bw_fd = fd; } + SET_ERRMSG(NULL); - if (wfname != fname) - xfree(wfname); - goto fail; - } - SET_ERRMSG(NULL); - - - write_info.bw_fd = fd; - write_info.bw_buf = buffer; - nchars = 0; + write_info.bw_buf = buffer; + nchars = 0; - /* use "++bin", "++nobin" or 'binary' */ - if (eap != NULL && eap->force_bin != 0) - write_bin = (eap->force_bin == FORCE_BIN); - else - write_bin = buf->b_p_bin; - - /* - * Skip the BOM when appending and the file already existed, the BOM - * only makes sense at the start of the file. - */ - if (buf->b_p_bomb && !write_bin && (!append || perm < 0)) { - write_info.bw_len = make_bom(buffer, fenc); - if (write_info.bw_len > 0) { - /* don't convert */ - write_info.bw_flags = FIO_NOCONVERT | wb_flags; - if (buf_write_bytes(&write_info) == FAIL) - end = 0; - else - nchars += write_info.bw_len; + // use "++bin", "++nobin" or 'binary' + if (eap != NULL && eap->force_bin != 0) { + write_bin = (eap->force_bin == FORCE_BIN); + } else { + write_bin = buf->b_p_bin; + } + + // Skip the BOM when appending and the file already existed, the BOM + // only makes sense at the start of the file. + if (buf->b_p_bomb && !write_bin && (!append || perm < 0)) { + write_info.bw_len = make_bom(buffer, fenc); + if (write_info.bw_len > 0) { + // don't convert + write_info.bw_flags = FIO_NOCONVERT | wb_flags; + if (buf_write_bytes(&write_info) == FAIL) { + end = 0; + } else { + nchars += write_info.bw_len; + } + } } - } - write_info.bw_start_lnum = start; + write_info.bw_start_lnum = start; - write_undo_file = (buf->b_p_udf && overwriting && !append - && !filtering && reset_changed); - if (write_undo_file) - /* Prepare for computing the hash value of the text. */ - sha256_start(&sha_ctx); + write_undo_file = (buf->b_p_udf && overwriting && !append + && !filtering && reset_changed && !checking_conversion); + if (write_undo_file) { + // Prepare for computing the hash value of the text. + sha256_start(&sha_ctx); + } - write_info.bw_len = bufsize; + write_info.bw_len = bufsize; #ifdef HAS_BW_FLAGS - write_info.bw_flags = wb_flags; + write_info.bw_flags = wb_flags; #endif - fileformat = get_fileformat_force(buf, eap); - s = buffer; - len = 0; - for (lnum = start; lnum <= end; ++lnum) { - /* - * The next while loop is done once for each character written. - * Keep it fast! - */ - ptr = ml_get_buf(buf, lnum, FALSE) - 1; - if (write_undo_file) - sha256_update(&sha_ctx, ptr + 1, (uint32_t)(STRLEN(ptr + 1) + 1)); - while ((c = *++ptr) != NUL) { - if (c == NL) - *s = NUL; /* replace newlines with NULs */ - else if (c == CAR && fileformat == EOL_MAC) - *s = NL; /* Mac: replace CRs with NLs */ - else - *s = c; - ++s; - if (++len != bufsize) - continue; - if (buf_write_bytes(&write_info) == FAIL) { - end = 0; /* write error: break loop */ + fileformat = get_fileformat_force(buf, eap); + s = buffer; + len = 0; + for (lnum = start; lnum <= end; lnum++) { + // The next while loop is done once for each character written. + // Keep it fast! + ptr = ml_get_buf(buf, lnum, false) - 1; + if (write_undo_file) { + sha256_update(&sha_ctx, ptr + 1, (uint32_t)(STRLEN(ptr + 1) + 1)); + } + while ((c = *++ptr) != NUL) { + if (c == NL) { + *s = NUL; // replace newlines with NULs + } else if (c == CAR && fileformat == EOL_MAC) { + *s = NL; // Mac: replace CRs with NLs + } else { + *s = c; + } + s++; + if (++len != bufsize) { + continue; + } + if (buf_write_bytes(&write_info) == FAIL) { + end = 0; // write error: break loop + break; + } + nchars += bufsize; + s = buffer; + len = 0; + write_info.bw_start_lnum = lnum; + } + // write failed or last line has no EOL: stop here + if (end == 0 + || (lnum == end + && (write_bin || !buf->b_p_fixeol) + && (lnum == buf->b_no_eol_lnum + || (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol)))) { + lnum++; // written the line, count it + no_eol = true; break; } - nchars += bufsize; - s = buffer; - len = 0; - write_info.bw_start_lnum = lnum; - } - /* write failed or last line has no EOL: stop here */ - if (end == 0 - || (lnum == end - && (write_bin || !buf->b_p_fixeol) - && (lnum == buf->b_no_eol_lnum - || (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol)))) { - ++lnum; /* written the line, count it */ - no_eol = TRUE; - break; - } - if (fileformat == EOL_UNIX) - *s++ = NL; - else { - *s++ = CAR; /* EOL_MAC or EOL_DOS: write CR */ - if (fileformat == EOL_DOS) { /* write CR-NL */ - if (++len == bufsize) { - if (buf_write_bytes(&write_info) == FAIL) { - end = 0; /* write error: break loop */ - break; + if (fileformat == EOL_UNIX) { + *s++ = NL; + } else { + *s++ = CAR; // EOL_MAC or EOL_DOS: write CR + if (fileformat == EOL_DOS) { // write CR-NL + if (++len == bufsize) { + if (buf_write_bytes(&write_info) == FAIL) { + end = 0; // write error: break loop + break; + } + nchars += bufsize; + s = buffer; + len = 0; } - nchars += bufsize; - s = buffer; - len = 0; + *s++ = NL; + } + } + if (++len == bufsize) { + if (buf_write_bytes(&write_info) == FAIL) { + end = 0; // Write error: break loop. + break; + } + nchars += bufsize; + s = buffer; + len = 0; + + os_breakcheck(); + if (got_int) { + end = 0; // Interrupted, break loop. + break; } - *s++ = NL; } } - if (++len == bufsize) { + if (len > 0 && end > 0) { + write_info.bw_len = len; if (buf_write_bytes(&write_info) == FAIL) { - end = 0; // Write error: break loop. - break; + end = 0; // write error } - nchars += bufsize; - s = buffer; - len = 0; + nchars += len; + } - os_breakcheck(); - if (got_int) { - end = 0; // Interrupted, break loop. + // Stop when writing done or an error was encountered. + if (!checking_conversion || end == 0) { break; - } } - } - if (len > 0 && end > 0) { - write_info.bw_len = len; - if (buf_write_bytes(&write_info) == FAIL) - end = 0; /* write error */ - nchars += len; - } - // On many journalling file systems there is a bug that causes both the - // original and the backup file to be lost when halting the system right - // after writing the file. That's because only the meta-data is - // journalled. Syncing the file slows down the system, but assures it has - // been written to disk and we don't lose it. - // For a device do try the fsync() but don't complain if it does not work - // (could be a pipe). - // If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. - int error; - if (p_fs && (error = os_fsync(fd)) != 0 && !device) { - SET_ERRMSG_ARG(_("E667: Fsync failed: %s"), error); - end = 0; + // If no error happened until now, writing should be ok, so loop to + // really write the buffer. } + // If we started writing, finish writing. Also when an error was + // encountered. + if (!checking_conversion) { + // On many journalling file systems there is a bug that causes both the + // original and the backup file to be lost when halting the system right + // after writing the file. That's because only the meta-data is + // journalled. Syncing the file slows down the system, but assures it has + // been written to disk and we don't lose it. + // For a device do try the fsync() but don't complain if it does not work + // (could be a pipe). + // If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. + int error; + if (p_fs && (error = os_fsync(fd)) != 0 && !device) { + SET_ERRMSG_ARG(_("E667: Fsync failed: %s"), error); + end = 0; + } + #ifdef HAVE_SELINUX - /* Probably need to set the security context. */ - if (!backup_copy) - mch_copy_sec(backup, wfname); + // Probably need to set the security context. + if (!backup_copy) { + mch_copy_sec(backup, wfname); + } #endif #ifdef UNIX - /* When creating a new file, set its owner/group to that of the original - * file. Get the new device and inode number. */ - if (backup != NULL && !backup_copy) { - /* don't change the owner when it's already OK, some systems remove - * permission or ACL stuff */ - FileInfo file_info; - if (!os_fileinfo((char *)wfname, &file_info) - || file_info.stat.st_uid != file_info_old.stat.st_uid - || file_info.stat.st_gid != file_info_old.stat.st_gid) { - os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid); - if (perm >= 0) { // Set permission again, may have changed. - (void)os_setperm((const char *)wfname, perm); + // When creating a new file, set its owner/group to that of the original + // file. Get the new device and inode number. + if (backup != NULL && !backup_copy) { + // don't change the owner when it's already OK, some systems remove + // permission or ACL stuff + FileInfo file_info; + if (!os_fileinfo((char *)wfname, &file_info) + || file_info.stat.st_uid != file_info_old.stat.st_uid + || file_info.stat.st_gid != file_info_old.stat.st_gid) { + os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid); + if (perm >= 0) { // Set permission again, may have changed. + (void)os_setperm((const char *)wfname, perm); + } } + buf_set_file_id(buf); + } else if (!buf->file_id_valid) { + // Set the file_id when creating a new file. + buf_set_file_id(buf); } - buf_set_file_id(buf); - } else if (!buf->file_id_valid) { - // Set the file_id when creating a new file. - buf_set_file_id(buf); - } #endif - if ((error = os_close(fd)) != 0) { - SET_ERRMSG_ARG(_("E512: Close failed: %s"), error); - end = 0; - } + if ((error = os_close(fd)) != 0) { + SET_ERRMSG_ARG(_("E512: Close failed: %s"), error); + end = 0; + } #ifdef UNIX - if (made_writable) - perm &= ~0200; /* reset 'w' bit for security reasons */ + if (made_writable) { + perm &= ~0200; // reset 'w' bit for security reasons + } #endif - if (perm >= 0) { // Set perm. of new file same as old file. - (void)os_setperm((const char *)wfname, perm); - } + if (perm >= 0) { // Set perm. of new file same as old file. + (void)os_setperm((const char *)wfname, perm); + } #ifdef HAVE_ACL - /* Probably need to set the ACL before changing the user (can't set the - * ACL on a file the user doesn't own). */ - if (!backup_copy) - mch_set_acl(wfname, acl); + // Probably need to set the ACL before changing the user (can't set the + // ACL on a file the user doesn't own). + if (!backup_copy) { + mch_set_acl(wfname, acl); + } #endif - if (wfname != fname) { - /* - * The file was written to a temp file, now it needs to be converted - * with 'charconvert' to (overwrite) the output file. - */ - if (end != 0) { - if (eval_charconvert(enc_utf8 ? "utf-8" : (char *) p_enc, (char *) fenc, - (char *) wfname, (char *) fname) == FAIL) { - write_info.bw_conv_error = true; - end = 0; + if (wfname != fname) { + // The file was written to a temp file, now it needs to be converted + // with 'charconvert' to (overwrite) the output file. + if (end != 0) { + if (eval_charconvert(enc_utf8 ? "utf-8" : (char *)p_enc, (char *)fenc, + (char *)wfname, (char *)fname) == FAIL) { + write_info.bw_conv_error = true; + end = 0; + } } + os_remove((char *)wfname); + xfree(wfname); } - os_remove((char *)wfname); - xfree(wfname); } if (end == 0) { + // Error encountered. if (errmsg == NULL) { if (write_info.bw_conv_error) { if (write_info.bw_conv_error_lnum == 0) { @@ -3470,46 +3501,48 @@ restore_backup: } } - /* - * If we have a backup file, try to put it in place of the new file, - * because the new file is probably corrupt. This avoids losing the - * original file when trying to make a backup when writing the file a - * second time. - * When "backup_copy" is set we need to copy the backup over the new - * file. Otherwise rename the backup file. - * If this is OK, don't give the extra warning message. - */ + // If we have a backup file, try to put it in place of the new file, + // because the new file is probably corrupt. This avoids losing the + // original file when trying to make a backup when writing the file a + // second time. + // When "backup_copy" is set we need to copy the backup over the new + // file. Otherwise rename the backup file. + // If this is OK, don't give the extra warning message. if (backup != NULL) { if (backup_copy) { - /* This may take a while, if we were interrupted let the user - * know we got the message. */ + // This may take a while, if we were interrupted let the user + // know we got the message. if (got_int) { MSG(_(e_interr)); ui_flush(); } if ((fd = os_open((char *)backup, O_RDONLY, 0)) >= 0) { if ((write_info.bw_fd = os_open((char *)fname, - O_WRONLY | O_CREAT | O_TRUNC, - perm & 0777)) >= 0) { - /* copy the file. */ + O_WRONLY | O_CREAT | O_TRUNC, + perm & 0777)) >= 0) { + // copy the file. write_info.bw_buf = smallbuf; #ifdef HAS_BW_FLAGS write_info.bw_flags = FIO_NOCONVERT; #endif while ((write_info.bw_len = read_eintr(fd, smallbuf, - SMBUFSIZE)) > 0) - if (buf_write_bytes(&write_info) == FAIL) + SMBUFSIZE)) > 0) { + if (buf_write_bytes(&write_info) == FAIL) { break; + } + } if (close(write_info.bw_fd) >= 0 - && write_info.bw_len == 0) - end = 1; /* success */ + && write_info.bw_len == 0) { + end = 1; // success + } } - close(fd); /* ignore errors for closing read file */ + close(fd); // ignore errors for closing read file } } else { - if (vim_rename(backup, fname) == 0) + if (vim_rename(backup, fname) == 0) { end = 1; + } } } goto fail; @@ -3686,7 +3719,7 @@ nofail: } else if (errmsgarg != 0) { emsgf(errmsg, os_strerror(errmsgarg)); } else { - emsgf(errmsg); + EMSG(errmsg); } if (errmsg_allocated) { xfree(errmsg); @@ -4099,6 +4132,10 @@ static int buf_write_bytes(struct bw_info *ip) # endif } + if (ip->bw_fd < 0) { + // Only checking conversion, which is OK if we get here. + return OK; + } wlen = write_eintr(ip->bw_fd, buf, len); return (wlen < len) ? FAIL : OK; } @@ -4311,38 +4348,46 @@ static int make_bom(char_u *buf, char_u *name) return (int)(p - buf); } +/// Shorten filename of a buffer. +/// When "force" is TRUE: Use full path from now on for files currently being +/// edited, both for file name and swap file name. Try to shorten the file +/// names a bit, if safe to do so. +/// When "force" is FALSE: Only try to shorten absolute file names. +/// For buffers that have buftype "nofile" or "scratch": never change the file +/// name. +void shorten_buf_fname(buf_T *buf, char_u *dirname, int force) +{ + char_u *p; + + if (buf->b_fname != NULL + && !bt_nofile(buf) + && !path_with_url((char *)buf->b_fname) + && (force + || buf->b_sfname == NULL + || path_is_absolute(buf->b_sfname))) { + xfree(buf->b_sfname); + buf->b_sfname = NULL; + p = path_shorten_fname(buf->b_ffname, dirname); + if (p != NULL) { + buf->b_sfname = vim_strsave(p); + buf->b_fname = buf->b_sfname; + } + if (p == NULL || buf->b_fname == NULL) { + buf->b_fname = buf->b_ffname; + } + } +} + /* * Shorten filenames for all buffers. - * When "force" is TRUE: Use full path from now on for files currently being - * edited, both for file name and swap file name. Try to shorten the file - * names a bit, if safe to do so. - * When "force" is FALSE: Only try to shorten absolute file names. - * For buffers that have buftype "nofile" or "scratch": never change the file - * name. */ void shorten_fnames(int force) { char_u dirname[MAXPATHL]; - char_u *p; os_dirname(dirname, MAXPATHL); FOR_ALL_BUFFERS(buf) { - if (buf->b_fname != NULL - && !bt_nofile(buf) - && !path_with_url((char *)buf->b_fname) - && (force - || buf->b_sfname == NULL - || path_is_absolute(buf->b_sfname))) { - xfree(buf->b_sfname); - buf->b_sfname = NULL; - p = path_shorten_fname(buf->b_ffname, dirname); - if (p != NULL) { - buf->b_sfname = vim_strsave(p); - buf->b_fname = buf->b_sfname; - } - if (p == NULL || buf->b_fname == NULL) - buf->b_fname = buf->b_ffname; - } + shorten_buf_fname(buf, dirname, force); /* Always make the swap file name a full path, a "nofile" buffer may * also have a swap file. */ @@ -4486,48 +4531,83 @@ bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL } /// Read 2 bytes from "fd" and turn them into an int, MSB first. +/// Returns -1 when encountering EOF. int get2c(FILE *fd) { - int n; - - n = getc(fd); - n = (n << 8) + getc(fd); - return n; + const int n = getc(fd); + if (n == EOF) { + return -1; + } + const int c = getc(fd); + if (c == EOF) { + return -1; + } + return (n << 8) + c; } /// Read 3 bytes from "fd" and turn them into an int, MSB first. +/// Returns -1 when encountering EOF. int get3c(FILE *fd) { - int n; - - n = getc(fd); - n = (n << 8) + getc(fd); - n = (n << 8) + getc(fd); - return n; + int n = getc(fd); + if (n == EOF) { + return -1; + } + int c = getc(fd); + if (c == EOF) { + return -1; + } + n = (n << 8) + c; + c = getc(fd); + if (c == EOF) { + return -1; + } + return (n << 8) + c; } /// Read 4 bytes from "fd" and turn them into an int, MSB first. +/// Returns -1 when encountering EOF. int get4c(FILE *fd) { // Use unsigned rather than int otherwise result is undefined // when left-shift sets the MSB. unsigned n; - n = (unsigned)getc(fd); - n = (n << 8) + (unsigned)getc(fd); - n = (n << 8) + (unsigned)getc(fd); - n = (n << 8) + (unsigned)getc(fd); + int c = getc(fd); + if (c == EOF) { + return -1; + } + n = (unsigned)c; + c = getc(fd); + if (c == EOF) { + return -1; + } + n = (n << 8) + (unsigned)c; + c = getc(fd); + if (c == EOF) { + return -1; + } + n = (n << 8) + (unsigned)c; + c = getc(fd); + if (c == EOF) { + return -1; + } + n = (n << 8) + (unsigned)c; return (int)n; } /// Read 8 bytes from `fd` and turn them into a time_t, MSB first. +/// Returns -1 when encountering EOF. time_t get8ctime(FILE *fd) { time_t n = 0; - int i; - for (i = 0; i < 8; i++) { - n = (n << 8) + getc(fd); + for (int i = 0; i < 8; i++) { + const int c = getc(fd); + if (c == EOF) { + return -1; + } + n = (n << 8) + c; } return n; } @@ -4892,10 +4972,12 @@ buf_check_timestamp ( )) { retval = 1; - /* set b_mtime to stop further warnings (e.g., when executing - * FileChangedShell autocmd) */ + // set b_mtime to stop further warnings (e.g., when executing + // FileChangedShell autocmd) if (!file_info_ok) { - buf->b_mtime = 0; + // When 'autoread' is set we'll check the file again to see if it + // re-appears. + buf->b_mtime = buf->b_p_ar; buf->b_orig_size = 0; buf->b_orig_mode = 0; } else { @@ -5885,19 +5967,19 @@ void au_event_restore(char_u *old_ei) * will be automatically executed for <event> * when editing a file matching <pat>, in * the current group. - * :autocmd <event> <pat> Show the auto-commands associated with + * :autocmd <event> <pat> Show the autocommands associated with * <event> and <pat>. - * :autocmd <event> Show the auto-commands associated with + * :autocmd <event> Show the autocommands associated with * <event>. - * :autocmd Show all auto-commands. - * :autocmd! <event> <pat> <cmd> Remove all auto-commands associated with + * :autocmd Show all autocommands. + * :autocmd! <event> <pat> <cmd> Remove all autocommands associated with * <event> and <pat>, and add the command * <cmd>, for the current group. - * :autocmd! <event> <pat> Remove all auto-commands associated with + * :autocmd! <event> <pat> Remove all autocommands associated with * <event> and <pat> for the current group. - * :autocmd! <event> Remove all auto-commands associated with + * :autocmd! <event> Remove all autocommands associated with * <event> for the current group. - * :autocmd! Remove ALL auto-commands for the current + * :autocmd! Remove ALL autocommands for the current * group. * * Multiple events and patterns may be given separated by commas. Here are @@ -5990,8 +6072,8 @@ void do_autocmd(char_u *arg_in, int forceit) * Print header when showing autocommands. */ if (!forceit && *cmd == NUL) { - /* Highlight title */ - MSG_PUTS_TITLE(_("\n--- Auto-Commands ---")); + // Highlight title + MSG_PUTS_TITLE(_("\n--- Autocommands ---")); } /* @@ -6206,8 +6288,8 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd, /* refuse to add buffer-local ap if buffer number is invalid */ if (is_buflocal && (buflocal_nr == 0 || buflist_findnr(buflocal_nr) == NULL)) { - EMSGN(_("E680: <buffer=%d>: invalid buffer number "), - buflocal_nr); + emsgf(_("E680: <buffer=%d>: invalid buffer number "), + buflocal_nr); return FAIL; } @@ -6697,6 +6779,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, proftime_T wait_time; bool did_save_redobuff = false; save_redo_T save_redo; + const bool save_KeyTyped = KeyTyped; // Quickly return if there are no autocommands for this event or // autocommands are blocked. @@ -6768,7 +6851,9 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, * invalid. */ if (fname_io == NULL) { - if (event == EVENT_COLORSCHEME || event == EVENT_OPTIONSET) { + if (event == EVENT_COLORSCHEME + || event == EVENT_COLORSCHEMEPRE + || event == EVENT_OPTIONSET) { autocmd_fname = NULL; } else if (fname != NULL && !ends_excmd(*fname)) { autocmd_fname = fname; @@ -6819,6 +6904,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, sfname = vim_strsave(fname); // Don't try expanding the following events. if (event == EVENT_COLORSCHEME + || event == EVENT_COLORSCHEMEPRE || event == EVENT_DIRCHANGED || event == EVENT_FILETYPE || event == EVENT_FUNCUNDEFINED @@ -6856,8 +6942,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, autocmd_match = fname; - /* Don't redraw while doing auto commands. */ - ++RedrawingDisabled; + // Don't redraw while doing autocommands. + RedrawingDisabled++; save_sourcing_name = sourcing_name; sourcing_name = NULL; /* don't free this one */ save_sourcing_lnum = sourcing_lnum; @@ -6956,6 +7042,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io, restore_funccal(save_funccalp); if (do_profiling == PROF_YES) prof_child_exit(&wait_time); + KeyTyped = save_KeyTyped; xfree(fname); xfree(sfname); --nesting; /* see matching increment above */ @@ -7067,7 +7154,7 @@ auto_next_pat ( apc->tail, ap->allow_dirs) : ap->buflocal_nr == apc->arg_bufnr) { const char *const name = event_nr2name(apc->event); - s = _("%s Auto commands for \"%s\""); + s = _("%s Autocommands for \"%s\""); const size_t sourcing_name_len = (STRLEN(s) + strlen(name) + ap->patlen + 1); sourcing_name = xmalloc(sourcing_name_len); diff --git a/src/nvim/fold.c b/src/nvim/fold.c index ef8750d061..39975308d7 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -44,14 +44,14 @@ * The info stored in both growarrays is the same: An array of fold_T. */ typedef struct { - linenr_T fd_top; /* first line of fold; for nested fold - * relative to parent */ - linenr_T fd_len; /* number of lines in the fold */ - garray_T fd_nested; /* array of nested folds */ - char fd_flags; /* see below */ - char fd_small; /* TRUE, FALSE or MAYBE: fold smaller than - 'foldminlines'; MAYBE applies to nested - folds too */ + linenr_T fd_top; // first line of fold; for nested fold + // relative to parent + linenr_T fd_len; // number of lines in the fold + garray_T fd_nested; // array of nested folds + char fd_flags; // see below + TriState fd_small; // kTrue, kFalse, or kNone: fold smaller than + // 'foldminlines'; kNone applies to nested + // folds too } fold_T; #define FD_OPEN 0 /* fold is open (nested ones can be closed) */ @@ -76,8 +76,8 @@ typedef struct { this line (copy of "end" of prev. line) */ } fline_T; -/* Flag is set when redrawing is needed. */ -static int fold_changed; +// Flag is set when redrawing is needed. +static bool fold_changed; /* Function used by foldUpdateIEMSRecurse */ typedef void (*LevelGetter)(fline_T *); @@ -147,35 +147,32 @@ int hasAnyFolding(win_T *win) */ bool hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp) { - return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL); + return hasFoldingWin(curwin, lnum, firstp, lastp, true, NULL); } /* hasFoldingWin() {{{2 */ bool hasFoldingWin( - win_T *win, - linenr_T lnum, - linenr_T *firstp, - linenr_T *lastp, - int cache, /* when TRUE: use cached values of window */ - foldinfo_T *infop /* where to store fold info */ + win_T *const win, + const linenr_T lnum, + linenr_T *const firstp, + linenr_T *const lastp, + const bool cache, // when true: use cached values of window + foldinfo_T *const infop // where to store fold info ) { - int had_folded = FALSE; + bool had_folded = false; linenr_T first = 0; linenr_T last = 0; linenr_T lnum_rel = lnum; - int x; fold_T *fp; int level = 0; - int use_level = FALSE; - int maybe_small = FALSE; - garray_T *gap; + bool use_level = false; + bool maybe_small = false; int low_level = 0; checkupdate(win); - /* - * Return quickly when there is no folding at all in this window. - */ + + // Return quickly when there is no folding at all in this window. if (!hasAnyFolding(win)) { if (infop != NULL) infop->fi_level = 0; @@ -187,7 +184,7 @@ bool hasFoldingWin( * First look in cached info for displayed lines. This is probably * the fastest, but it can only be used if the entry is still valid. */ - x = find_wl_entry(win, lnum); + const int x = find_wl_entry(win, lnum); if (x >= 0) { first = win->w_lines[x].wl_lnum; last = win->w_lines[x].wl_lastlnum; @@ -199,7 +196,7 @@ bool hasFoldingWin( /* * Recursively search for a fold that contains "lnum". */ - gap = &win->w_folds; + garray_T *gap = &win->w_folds; for (;; ) { if (!foldFind(gap, lnum_rel, &fp)) break; @@ -274,14 +271,11 @@ int foldLevel(linenr_T lnum) return foldLevelWin(curwin, lnum); } -/* lineFolded() {{{2 */ -/* - * Low level function to check if a line is folded. Doesn't use any caching. - * Return TRUE if line is folded. - * Return FALSE if line is not folded. - * Return MAYBE if the line is folded when next to a folded line. - */ -int lineFolded(win_T *win, linenr_T lnum) +// lineFolded() {{{2 +// Low level function to check if a line is folded. Doesn't use any caching. +// Return true if line is folded. +// Return false if line is not folded. +bool lineFolded(win_T *const win, const linenr_T lnum) { return foldedCount(win, lnum, NULL) != 0; } @@ -299,8 +293,9 @@ long foldedCount(win_T *win, linenr_T lnum, foldinfo_T *infop) { linenr_T last; - if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop)) + if (hasFoldingWin(win, lnum, NULL, &last, false, infop)) { return (long)(last - lnum + 1); + } return 0; } @@ -649,7 +644,7 @@ void foldCreate(linenr_T start, linenr_T end) if (!use_level) curwin->w_fold_manual = true; fp->fd_flags = FD_CLOSED; - fp->fd_small = MAYBE; + fp->fd_small = kNone; /* redraw */ changed_window_setting(); @@ -663,36 +658,31 @@ void foldCreate(linenr_T start, linenr_T end) * When "end" is not 0, delete all folds from "start" to "end". * When "recursive" is TRUE delete recursively. */ -void -deleteFold( - linenr_T start, - linenr_T end, - int recursive, - int had_visual // TRUE when Visual selection used +void deleteFold( + const linenr_T start, + const linenr_T end, + const int recursive, + const bool had_visual // true when Visual selection used ) { - garray_T *gap; fold_T *fp; - garray_T *found_ga; fold_T *found_fp = NULL; linenr_T found_off = 0; - int use_level; - int maybe_small = FALSE; + bool maybe_small = false; int level = 0; linenr_T lnum = start; - linenr_T lnum_off; - int did_one = FALSE; + bool did_one = false; linenr_T first_lnum = MAXLNUM; linenr_T last_lnum = 0; checkupdate(curwin); while (lnum <= end) { - /* Find the deepest fold for "start". */ - gap = &curwin->w_folds; - found_ga = NULL; - lnum_off = 0; - use_level = FALSE; + // Find the deepest fold for "start". + garray_T *gap = &curwin->w_folds; + garray_T *found_ga = NULL; + linenr_T lnum_off = 0; + bool use_level = false; for (;; ) { if (!foldFind(gap, lnum - lnum_off, &fp)) break; @@ -728,7 +718,7 @@ deleteFold( parseMarker(curwin); deleteFoldMarkers(found_fp, recursive, found_off); } - did_one = TRUE; + did_one = true; /* redraw window */ changed_window_setting(); @@ -787,8 +777,8 @@ void foldUpdate(win_T *wp, linenr_T top, linenr_T bot) (void)foldFind(&wp->w_folds, top, &fp); while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len && fp->fd_top < bot) { - fp->fd_small = MAYBE; - ++fp; + fp->fd_small = kNone; + fp++; } if (foldmethodIsIndent(wp) @@ -831,44 +821,34 @@ void foldUpdateAll(win_T *win) redraw_win_later(win, NOT_VALID); } -/* foldMoveTo() {{{2 */ -/* - * If "updown" is FALSE: Move to the start or end of the fold. - * If "updown" is TRUE: move to fold at the same level. - * If not moved return FAIL. - */ -int -foldMoveTo( - int updown, - int dir, // FORWARD or BACKWARD - long count +// foldMoveTo() {{{2 +// +// If "updown" is false: Move to the start or end of the fold. +// If "updown" is true: move to fold at the same level. +// If not moved return FAIL. +int foldMoveTo( + const bool updown, + const int dir, // FORWARD or BACKWARD + const long count ) { - long n; int retval = FAIL; - linenr_T lnum_off; - linenr_T lnum_found; linenr_T lnum; - int use_level; - int maybe_small; - garray_T *gap; fold_T *fp; - int level; - int last; checkupdate(curwin); - /* Repeat "count" times. */ - for (n = 0; n < count; ++n) { - /* Find nested folds. Stop when a fold is closed. The deepest fold - * that moves the cursor is used. */ - lnum_off = 0; - gap = &curwin->w_folds; - use_level = FALSE; - maybe_small = FALSE; - lnum_found = curwin->w_cursor.lnum; - level = 0; - last = FALSE; + // Repeat "count" times. + for (long n = 0; n < count; n++) { + // Find nested folds. Stop when a fold is closed. The deepest fold + // that moves the cursor is used. + linenr_T lnum_off = 0; + garray_T *gap = &curwin->w_folds; + bool use_level = false; + bool maybe_small = false; + linenr_T lnum_found = curwin->w_cursor.lnum; + int level = 0; + bool last = false; for (;; ) { if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp)) { if (!updown) @@ -886,14 +866,15 @@ foldMoveTo( } /* don't look for contained folds, they will always move * the cursor too far. */ - last = TRUE; + last = true; } if (!last) { /* Check if this fold is closed. */ if (check_closed(curwin, fp, &use_level, level, - &maybe_small, lnum_off)) - last = TRUE; + &maybe_small, lnum_off)) { + last = true; + } /* "[z" and "]z" stop at closed fold */ if (last && !updown) @@ -1306,25 +1287,21 @@ static void foldOpenNested(fold_T *fpr) } } -/* deleteFoldEntry() {{{2 */ -/* - * Delete fold "idx" from growarray "gap". - * When "recursive" is TRUE also delete all the folds contained in it. - * When "recursive" is FALSE contained folds are moved one level up. - */ -static void deleteFoldEntry(garray_T *gap, int idx, int recursive) +// deleteFoldEntry() {{{2 +// Delete fold "idx" from growarray "gap". +// When "recursive" is true also delete all the folds contained in it. +// When "recursive" is false contained folds are moved one level up. +static void deleteFoldEntry(garray_T *const gap, const int idx, + const bool recursive) { - fold_T *fp; - int i; - fold_T *nfp; - - fp = (fold_T *)gap->ga_data + idx; + fold_T *fp = (fold_T *)gap->ga_data + idx; if (recursive || GA_EMPTY(&fp->fd_nested)) { - /* recursively delete the contained folds */ + // recursively delete the contained folds deleteFoldRecurse(&fp->fd_nested); - --gap->ga_len; - if (idx < gap->ga_len) - memmove(fp, fp + 1, sizeof(fold_T) * (size_t)(gap->ga_len - idx)); + gap->ga_len--; + if (idx < gap->ga_len) { + memmove(fp, fp + 1, sizeof(*fp) * (size_t)(gap->ga_len - idx)); + } } else { /* Move nested folds one level up, to overwrite the fold that is * deleted. */ @@ -1334,22 +1311,24 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive) /* Get "fp" again, the array may have been reallocated. */ fp = (fold_T *)gap->ga_data + idx; - /* adjust fd_top and fd_flags for the moved folds */ - nfp = (fold_T *)fp->fd_nested.ga_data; - for (i = 0; i < moved; ++i) { + // adjust fd_top and fd_flags for the moved folds + fold_T *nfp = (fold_T *)fp->fd_nested.ga_data; + for (int i = 0; i < moved; i++) { nfp[i].fd_top += fp->fd_top; if (fp->fd_flags == FD_LEVEL) nfp[i].fd_flags = FD_LEVEL; - if (fp->fd_small == MAYBE) - nfp[i].fd_small = MAYBE; + if (fp->fd_small == kNone) { + nfp[i].fd_small = kNone; + } } - /* move the existing folds down to make room */ - if (idx + 1 < gap->ga_len) + // move the existing folds down to make room + if (idx + 1 < gap->ga_len) { memmove(fp + moved, fp + 1, - sizeof(fold_T) * (size_t)(gap->ga_len - (idx + 1))); - /* move the contained folds one level up */ - memmove(fp, nfp, sizeof(fold_T) * (size_t)moved); + sizeof(*fp) * (size_t)(gap->ga_len - (idx + 1))); + } + // move the contained folds one level up + memmove(fp, nfp, sizeof(*fp) * (size_t)moved); xfree(nfp); gap->ga_len += moved - 1; } @@ -1429,14 +1408,15 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2, fp->fd_top += amount_after; } else { if (fp->fd_top >= top && last <= line2) { - /* 4. fold completely contained in range */ + // 4. fold completely contained in range if (amount == MAXLNUM) { - /* Deleting lines: delete the fold completely */ - deleteFoldEntry(gap, i, TRUE); - --i; /* adjust index for deletion */ - --fp; - } else + // Deleting lines: delete the fold completely + deleteFoldEntry(gap, i, true); + i--; // adjust index for deletion + fp--; + } else { fp->fd_top += amount; + } } else { if (fp->fd_top < top) { /* 2 or 3: need to correct nested folds too */ @@ -1505,36 +1485,40 @@ static int getDeepestNestingRecurse(garray_T *gap) /* * Check if a fold is closed and update the info needed to check nested folds. */ -static int -check_closed( - win_T *win, - fold_T *fp, - int *use_levelp, // TRUE: outer fold had FD_LEVEL - int level, // folding depth - int *maybe_smallp, // TRUE: outer this had fd_small == MAYBE - linenr_T lnum_off // line number offset for fp->fd_top +static bool check_closed( + win_T *const win, + fold_T *const fp, + bool *const use_levelp, // true: outer fold had FD_LEVEL + const int level, // folding depth + bool *const maybe_smallp, // true: outer this had fd_small == kNone + const linenr_T lnum_off // line number offset for fp->fd_top ) { - int closed = FALSE; + bool closed = false; /* Check if this fold is closed. If the flag is FD_LEVEL this * fold and all folds it contains depend on 'foldlevel'. */ if (*use_levelp || fp->fd_flags == FD_LEVEL) { - *use_levelp = TRUE; - if (level >= win->w_p_fdl) - closed = TRUE; - } else if (fp->fd_flags == FD_CLOSED) - closed = TRUE; - - /* Small fold isn't closed anyway. */ - if (fp->fd_small == MAYBE) - *maybe_smallp = TRUE; + *use_levelp = true; + if (level >= win->w_p_fdl) { + closed = true; + } + } else if (fp->fd_flags == FD_CLOSED) { + closed = true; + } + + // Small fold isn't closed anyway. + if (fp->fd_small == kNone) { + *maybe_smallp = true; + } if (closed) { - if (*maybe_smallp) - fp->fd_small = MAYBE; + if (*maybe_smallp) { + fp->fd_small = kNone; + } checkSmall(win, fp, lnum_off); - if (fp->fd_small == TRUE) - closed = FALSE; + if (fp->fd_small == kTrue) { + closed = false; + } } return closed; } @@ -1545,43 +1529,38 @@ check_closed( */ static void checkSmall( - win_T *wp, - fold_T *fp, - linenr_T lnum_off // offset for fp->fd_top + win_T *const wp, + fold_T *const fp, + const linenr_T lnum_off // offset for fp->fd_top ) { - int count; - int n; - - if (fp->fd_small == MAYBE) { - /* Mark any nested folds to maybe-small */ + if (fp->fd_small == kNone) { + // Mark any nested folds to maybe-small setSmallMaybe(&fp->fd_nested); - if (fp->fd_len > curwin->w_p_fml) - fp->fd_small = FALSE; - else { - count = 0; - for (n = 0; n < fp->fd_len; ++n) { + if (fp->fd_len > curwin->w_p_fml) { + fp->fd_small = kFalse; + } else { + int count = 0; + for (int n = 0; n < fp->fd_len; n++) { count += plines_win_nofold(wp, fp->fd_top + lnum_off + n); if (count > curwin->w_p_fml) { - fp->fd_small = FALSE; + fp->fd_small = kFalse; return; } } - fp->fd_small = TRUE; + fp->fd_small = kTrue; } } } -/* setSmallMaybe() {{{2 */ -/* - * Set small flags in "gap" to MAYBE. - */ +// setSmallMaybe() {{{2 +// Set small flags in "gap" to kNone. static void setSmallMaybe(garray_T *gap) { fold_T *fp = (fold_T *)gap->ga_data; - for (int i = 0; i < gap->ga_len; ++i) { - fp[i].fd_small = MAYBE; + for (int i = 0; i < gap->ga_len; i++) { + fp[i].fd_small = kNone; } } @@ -1707,7 +1686,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen) assert(p >= line); memcpy(newline, line, (size_t)(p - line)); STRCPY(newline + (p - line), p + len); - ml_replace(lnum, newline, FALSE); + ml_replace(lnum, newline, false); } break; } @@ -1783,12 +1762,13 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, if (text != NULL) { /* Replace unprintable characters, if there are any. But * replace a TAB with a space. */ - for (p = text; *p != NUL; ++p) { - int len; + for (p = text; *p != NUL; p++) { + int len = utfc_ptr2len(p); - if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) { - if (!vim_isprintc((*mb_ptr2char)(p))) + if (len > 1) { + if (!vim_isprintc(utf_ptr2char(p))) { break; + } p += len - 1; } else if (*p == TAB) *p = ' '; @@ -1896,13 +1876,10 @@ void foldtext_cleanup(char_u *str) * Update the folding for window "wp", at least from lines "top" to "bot". * Return TRUE if any folds did change. */ -static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) +static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) { - linenr_T start; - linenr_T end; fline_T fline; void (*getlevel)(fline_T *); - int level; fold_T *fp; /* Avoid problems when being called recursively. */ @@ -1928,12 +1905,13 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) bot += diff_context; } - /* When deleting lines at the end of the buffer "top" can be past the end - * of the buffer. */ - if (top > wp->w_buffer->b_ml.ml_line_count) + // When deleting lines at the end of the buffer "top" can be past the end + // of the buffer. + if (top > wp->w_buffer->b_ml.ml_line_count) { top = wp->w_buffer->b_ml.ml_line_count; + } - fold_changed = FALSE; + fold_changed = false; fline.wp = wp; fline.off = 0; fline.lvl = 0; @@ -1954,8 +1932,8 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) /* Need to get the level of the line above top, it is used if there is * no marker at the top. */ if (top > 1) { - /* Get the fold level at top - 1. */ - level = foldLevelWin(wp, top - 1); + // Get the fold level at top - 1. + const int level = foldLevelWin(wp, top - 1); /* The fold may end just above the top, check for that. */ fline.lnum = top - 1; @@ -2031,11 +2009,12 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) } } - start = fline.lnum; - end = bot; - /* Do at least one line. */ - if (start > end && end < wp->w_buffer->b_ml.ml_line_count) + linenr_T start = fline.lnum; + linenr_T end = bot; + // Do at least one line. + if (start > end && end < wp->w_buffer->b_ml.ml_line_count) { end = start; + } while (!got_int) { /* Always stop at the end of the file ("end" can be past the end of * the file). */ @@ -2126,22 +2105,21 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot) * Returns bot, which may have been increased for lines that also need to be * updated as a result of a detected change in the fold. */ -static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, - linenr_T startlnum, fline_T *flp, - LevelGetter getlevel, - linenr_T bot, - char topflags /* containing fold flags */ - ) +static linenr_T foldUpdateIEMSRecurse( + garray_T *const gap, const int level, const linenr_T startlnum, + fline_T *const flp, LevelGetter getlevel, linenr_T bot, + const char topflags // containing fold flags +) { linenr_T ll; fold_T *fp = NULL; fold_T *fp2; int lvl = level; linenr_T startlnum2 = startlnum; - linenr_T firstlnum = flp->lnum; /* first lnum we got */ + const linenr_T firstlnum = flp->lnum; // first lnum we got int i; - int finish = FALSE; - linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off; + bool finish = false; + const linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off; int concat; /* @@ -2309,8 +2287,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, * found. */ if (getlevel == foldlevelMarker || getlevel == foldlevelExpr - || getlevel == foldlevelSyntax) - finish = TRUE; + || getlevel == foldlevelSyntax) { + finish = true; + } } if (fp->fd_top == startlnum && concat) { i = (int)(fp - (fold_T *)gap->ga_data); @@ -2325,19 +2304,18 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, break; } if (fp->fd_top >= startlnum) { - /* A fold that starts at or after startlnum and stops - * before the new fold must be deleted. Continue - * looking for the next one. */ - deleteFoldEntry(gap, - (int)(fp - (fold_T *)gap->ga_data), TRUE); + // A fold that starts at or after startlnum and stops + // before the new fold must be deleted. Continue + // looking for the next one. + deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true); } else { /* A fold has some lines above startlnum, truncate it * to stop just above startlnum. */ fp->fd_len = startlnum - fp->fd_top; foldMarkAdjustRecurse(&fp->fd_nested, - (linenr_T)fp->fd_len, (linenr_T)MAXLNUM, - (linenr_T)MAXLNUM, 0L); - fold_changed = TRUE; + (linenr_T)fp->fd_len, (linenr_T)MAXLNUM, + (linenr_T)MAXLNUM, 0L); + fold_changed = true; } } else { /* Insert new fold. Careful: ga_data may be NULL and it @@ -2361,14 +2339,15 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, flp->wp->w_fold_manual = true; } else fp->fd_flags = (fp - 1)->fd_flags; - fp->fd_small = MAYBE; - /* If using the "marker", "expr" or "syntax" method, we - * need to continue until the end of the fold is found. */ + fp->fd_small = kNone; + // If using the "marker", "expr" or "syntax" method, we + // need to continue until the end of the fold is found. if (getlevel == foldlevelMarker || getlevel == foldlevelExpr - || getlevel == foldlevelSyntax) - finish = TRUE; - fold_changed = TRUE; + || getlevel == foldlevelSyntax) { + finish = true; + } + fold_changed = true; break; } } @@ -2387,12 +2366,11 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, * Check "fp" for safety. */ if (lvl > level && fp != NULL) { - /* - * There is a nested fold, handle it recursively. - */ - /* At least do one line (can happen when finish is TRUE). */ - if (bot < flp->lnum) + // There is a nested fold, handle it recursively. + // At least do one line (can happen when finish is true). + if (bot < flp->lnum) { bot = flp->lnum; + } /* Line numbers in the nested fold are relative to the start of * this fold. */ @@ -2454,8 +2432,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, /* Current fold at least extends until lnum. */ if (fp->fd_len < flp->lnum - fp->fd_top) { fp->fd_len = flp->lnum - fp->fd_top; - fp->fd_small = MAYBE; - fold_changed = TRUE; + fp->fd_small = kNone; + fold_changed = true; } /* Delete contained folds from the end of the last one found until where @@ -2482,8 +2460,9 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, foldSplit(gap, i, flp->lnum, bot); fp = (fold_T *)gap->ga_data + i; } - } else + } else { fp->fd_len = flp->lnum - fp->fd_top; + } fold_changed = true; } } @@ -2502,7 +2481,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, (linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum)); fp2->fd_len -= flp->lnum - fp2->fd_top; fp2->fd_top = flp->lnum; - fold_changed = TRUE; + fold_changed = true; } if (lvl >= level) { @@ -2511,8 +2490,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level, } break; } - fold_changed = TRUE; - deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); + fold_changed = true; + deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true); } /* Need to redraw the lines we inspected, which might be further down than @@ -2548,36 +2527,32 @@ static void foldInsert(garray_T *gap, int i) * The caller must first have taken care of any nested folds from "top" to * "bot"! */ -static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot) +static void foldSplit(garray_T *const gap, const int i, const linenr_T top, + const linenr_T bot) { - fold_T *fp; fold_T *fp2; - garray_T *gap1; - garray_T *gap2; - int idx; - int len; /* The fold continues below bot, need to split it. */ foldInsert(gap, i + 1); - fp = (fold_T *)gap->ga_data + i; + fold_T *const fp = (fold_T *)gap->ga_data + i; fp[1].fd_top = bot + 1; // check for wrap around (MAXLNUM, and 32bit) assert(fp[1].fd_top > bot); fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top); fp[1].fd_flags = fp->fd_flags; - fp[1].fd_small = MAYBE; - fp->fd_small = MAYBE; + fp[1].fd_small = kNone; + fp->fd_small = kNone; /* Move nested folds below bot to new fold. There can't be * any between top and bot, they have been removed by the caller. */ - gap1 = &fp->fd_nested; - gap2 = &fp[1].fd_nested; + garray_T *const gap1 = &fp->fd_nested; + garray_T *const gap2 = &fp[1].fd_nested; (void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2)); - len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2); + const int len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2); if (len > 0) { ga_grow(gap2, len); - for (idx = 0; idx < len; ++idx) { + for (int idx = 0; idx < len; idx++) { ((fold_T *)gap2->ga_data)[idx] = fp2[idx]; ((fold_T *)gap2->ga_data)[idx].fd_top -= fp[1].fd_top - fp->fd_top; @@ -2586,7 +2561,7 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot) gap1->ga_len -= len; } fp->fd_len = top - fp->fd_top; - fold_changed = TRUE; + fold_changed = true; } /* foldRemove() {{{2 */ @@ -2848,8 +2823,8 @@ static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2) } fp1->fd_len += fp2->fd_len; - deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE); - fold_changed = TRUE; + deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true); + fold_changed = true; } /* foldlevelIndent() {{{2 */ @@ -2875,8 +2850,9 @@ static void foldlevelIndent(fline_T *flp) flp->lvl = 0; else flp->lvl = -1; - } else - flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf); + } else { + flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(buf); + } if (flp->lvl > flp->wp->w_p_fdn) { flp->lvl = (int) MAX(0, flp->wp->w_p_fdn); } @@ -2907,7 +2883,6 @@ static void foldlevelExpr(fline_T *flp) int n; int c; linenr_T lnum = flp->lnum + flp->off; - int save_keytyped; win = curwin; curwin = flp->wp; @@ -2922,7 +2897,7 @@ static void foldlevelExpr(fline_T *flp) /* KeyTyped may be reset to 0 when calling a function which invokes * do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */ - save_keytyped = KeyTyped; + const bool save_keytyped = KeyTyped; n = (int)eval_foldexpr(flp->wp->w_p_fde, &c); KeyTyped = save_keytyped; diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h index bd26205d6d..6e5e47c060 100644 --- a/src/nvim/func_attr.h +++ b/src/nvim/func_attr.h @@ -99,6 +99,10 @@ # undef FUNC_ATTR_NO_SANITIZE_UNDEFINED #endif +#ifdef FUNC_ATTR_PRINTF +# undef FUNC_ATTR_PRINTF +#endif + #ifndef DID_REAL_ATTR # define DID_REAL_ATTR # ifdef __GNUC__ @@ -117,6 +121,7 @@ # define REAL_FATTR_NONNULL_ALL __attribute__((nonnull)) # define REAL_FATTR_NONNULL_ARG(...) __attribute__((nonnull(__VA_ARGS__))) # define REAL_FATTR_NORETURN __attribute__((noreturn)) +# define REAL_FATTR_PRINTF(x, y) __attribute__((format (printf, x, y))) # if NVIM_HAS_ATTRIBUTE(returns_nonnull) # define REAL_FATTR_NONNULL_RET __attribute__((returns_nonnull)) @@ -193,6 +198,10 @@ # ifndef REAL_FATTR_NO_SANITIZE_UNDEFINED # define REAL_FATTR_NO_SANITIZE_UNDEFINED # endif + +# ifndef REAL_FATTR_PRINTF +# define REAL_FATTR_PRINTF(x, y) +# endif #endif #ifdef DEFINE_FUNC_ATTRIBUTES @@ -215,6 +224,7 @@ # define FUNC_ATTR_NONNULL_RET REAL_FATTR_NONNULL_RET # define FUNC_ATTR_NORETURN REAL_FATTR_NORETURN # define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED +# define FUNC_ATTR_PRINTF(x, y) REAL_FATTR_PRINTF(x, y) #elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES) # define FUNC_ATTR_MALLOC # define FUNC_ATTR_ALLOC_SIZE(x) @@ -230,4 +240,5 @@ # define FUNC_ATTR_NONNULL_RET # define FUNC_ATTR_NORETURN # define FUNC_ATTR_NO_SANITIZE_UNDEFINED +# define FUNC_ATTR_PRINTF(x, y) #endif diff --git a/src/nvim/garray.h b/src/nvim/garray.h index 94e1b61671..58738df691 100644 --- a/src/nvim/garray.h +++ b/src/nvim/garray.h @@ -37,7 +37,7 @@ typedef struct growarray { static inline void *ga_append_via_ptr(garray_T *gap, size_t item_size) { if ((int)item_size != gap->ga_itemsize) { - WLOG("wrong item size (%d), should be %d", item_size, gap->ga_itemsize); + WLOG("wrong item size (%zu), should be %d", item_size, gap->ga_itemsize); } ga_grow(gap, 1); return ((char *)gap->ga_data) + (item_size * (size_t)gap->ga_len++); diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 15fcafb584..bd9650e4d1 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -190,6 +190,9 @@ for i = 1, #functions do output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Error *error)') output:write('\n{') + output:write('\n#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL') + output:write('\n logmsg(DEBUG_LOG_LEVEL, "RPC: ", NULL, -1, true, "invoke '..fn.name..'");') + output:write('\n#endif') output:write('\n Object ret = NIL;') -- Declare/initialize variables that will hold converted arguments for j = 1, #fn.parameters do diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua index 2666ca6e6f..e76b601d8a 100644 --- a/src/nvim/generators/gen_api_ui_events.lua +++ b/src/nvim/generators/gen_api_ui_events.lua @@ -132,19 +132,21 @@ for i = 1, #events do end end - call_output:write('void ui_call_'..ev.name) - write_signature(call_output, ev, '') - call_output:write('\n{\n') - if ev.remote_only then - write_arglist(call_output, ev, false) - call_output:write(' UI_LOG('..ev.name..', 0);\n') - call_output:write(' ui_event("'..ev.name..'", args);\n') - else - call_output:write(' UI_CALL') - write_signature(call_output, ev, ev.name, true) - call_output:write(";\n") + if not (ev.remote_only and ev.remote_impl) then + call_output:write('void ui_call_'..ev.name) + write_signature(call_output, ev, '') + call_output:write('\n{\n') + if ev.remote_only then + write_arglist(call_output, ev, false) + call_output:write(' UI_LOG('..ev.name..', 0);\n') + call_output:write(' ui_event("'..ev.name..'", args);\n') + else + call_output:write(' UI_CALL') + write_signature(call_output, ev, ev.name, true) + call_output:write(";\n") + end + call_output:write("}\n\n") end - call_output:write("}\n\n") end diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 563608dd1d..94702a9a3a 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -315,7 +315,7 @@ static void add_char_buff(buffheader_T *buf, int c) if (IS_SPECIAL(c)) { len = 1; } else { - len = mb_char2bytes(c, bytes); + len = utf_char2bytes(c, bytes); } for (int i = 0; i < len; i++) { @@ -420,7 +420,7 @@ void typeahead_noflush(int c) * typeahead buffer (used in case of an error). If "flush_typeahead" is true, * flush all typeahead characters (used when interrupted by a CTRL-C). */ -void flush_buffers(int flush_typeahead) +void flush_buffers(flush_buffers_T flush_typeahead) { init_typebuf(); @@ -428,24 +428,28 @@ void flush_buffers(int flush_typeahead) while (read_readbuffers(TRUE) != NUL) { } - if (flush_typeahead) { /* remove all typeahead */ - /* - * We have to get all characters, because we may delete the first part - * of an escape sequence. - * In an xterm we get one char at a time and we have to get them all. - */ - while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L, - typebuf.tb_change_cnt) != 0) - ; - typebuf.tb_off = MAXMAPLEN; - typebuf.tb_len = 0; - } else { /* remove mapped characters at the start only */ + if (flush_typeahead == FLUSH_MINIMAL) { + // remove mapped characters at the start only typebuf.tb_off += typebuf.tb_maplen; typebuf.tb_len -= typebuf.tb_maplen; + } else { + // remove typeahead + if (flush_typeahead == FLUSH_INPUT) { + // We have to get all characters, because we may delete the first + // part of an escape sequence. In an xterm we get one char at a + // time and we have to get them all. + while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0) { + } + } + typebuf.tb_off = MAXMAPLEN; + typebuf.tb_len = 0; + // Reset the flag that text received from a client or from feedkeys() + // was inserted in the typeahead buffer. + typebuf_was_filled = false; } typebuf.tb_maplen = 0; typebuf.tb_silent = 0; - cmd_silent = FALSE; + cmd_silent = false; typebuf.tb_no_abbr_cnt = 0; } @@ -649,15 +653,13 @@ void stuffnumReadbuff(long n) add_num_buff(&readbuf1, n); } -/* - * Read a character from the redo buffer. Translates K_SPECIAL, CSI and - * multibyte characters. - * The redo buffer is left as it is. - * If init is TRUE, prepare for redo, return FAIL if nothing to redo, OK - * otherwise. - * If old is TRUE, use old_redobuff instead of redobuff. - */ -static int read_redo(int init, int old_redo) +// Read a character from the redo buffer. Translates K_SPECIAL, CSI and +// multibyte characters. +// The redo buffer is left as it is. +// If init is true, prepare for redo, return FAIL if nothing to redo, OK +// otherwise. +// If old_redo is true, use old_redobuff instead of redobuff. +static int read_redo(bool init, bool old_redo) { static buffblock_T *bp; static char_u *p; @@ -698,7 +700,7 @@ static int read_redo(int init, int old_redo) buf[i] = (char_u)c; if (i == n - 1) { // last byte of a character if (n != 1) { - c = (*mb_ptr2char)(buf); + c = utf_ptr2char(buf); } break; } @@ -710,38 +712,35 @@ static int read_redo(int init, int old_redo) return c; } -/* - * Copy the rest of the redo buffer into the stuff buffer (in a slow way). - * If old_redo is TRUE, use old_redobuff instead of redobuff. - * The escaped K_SPECIAL and CSI are copied without translation. - */ -static void copy_redo(int old_redo) +// Copy the rest of the redo buffer into the stuff buffer (in a slow way). +// If old_redo is true, use old_redobuff instead of redobuff. +// The escaped K_SPECIAL and CSI are copied without translation. +static void copy_redo(bool old_redo) { int c; - while ((c = read_redo(FALSE, old_redo)) != NUL) { + while ((c = read_redo(false, old_redo)) != NUL) { add_char_buff(&readbuf2, c); } } -/* - * Stuff the redo buffer into readbuf2. - * Insert the redo count into the command. - * If "old_redo" is TRUE, the last but one command is repeated - * instead of the last command (inserting text). This is used for - * CTRL-O <.> in insert mode - * - * return FAIL for failure, OK otherwise - */ -int start_redo(long count, int old_redo) +// Stuff the redo buffer into readbuf2. +// Insert the redo count into the command. +// If "old_redo" is true, the last but one command is repeated +// instead of the last command (inserting text). This is used for +// CTRL-O <.> in insert mode +// +// return FAIL for failure, OK otherwise +int start_redo(long count, bool old_redo) { int c; - /* init the pointers; return if nothing to redo */ - if (read_redo(TRUE, old_redo) == FAIL) + // init the pointers; return if nothing to redo + if (read_redo(true, old_redo) == FAIL) { return FAIL; + } - c = read_redo(FALSE, old_redo); + c = read_redo(false, old_redo); /* copy the buffer name, if present */ if (c == '"') { @@ -752,22 +751,30 @@ int start_redo(long count, int old_redo) if (c >= '1' && c < '9') ++c; add_char_buff(&readbuf2, c); - c = read_redo(FALSE, old_redo); + + // the expression register should be re-evaluated + if (c == '=') { + add_char_buff(&readbuf2, CAR); + cmd_silent = true; + } + + c = read_redo(false, old_redo); } if (c == 'v') { /* redo Visual */ VIsual = curwin->w_cursor; - VIsual_active = TRUE; - VIsual_select = FALSE; - VIsual_reselect = TRUE; - redo_VIsual_busy = TRUE; - c = read_redo(FALSE, old_redo); + VIsual_active = true; + VIsual_select = false; + VIsual_reselect = true; + redo_VIsual_busy = true; + c = read_redo(false, old_redo); } - /* try to enter the count (in place of a previous count) */ + // try to enter the count (in place of a previous count) if (count) { - while (ascii_isdigit(c)) /* skip "old" count */ - c = read_redo(FALSE, old_redo); + while (ascii_isdigit(c)) { // skip "old" count + c = read_redo(false, old_redo); + } add_num_buff(&readbuf2, count); } @@ -786,12 +793,13 @@ int start_redo_ins(void) { int c; - if (read_redo(TRUE, FALSE) == FAIL) + if (read_redo(true, false) == FAIL) { return FAIL; + } start_stuff(); - /* skip the count and the command character */ - while ((c = read_redo(FALSE, FALSE)) != NUL) { + // skip the count and the command character + while ((c = read_redo(false, false)) != NUL) { if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) { if (c == 'O' || c == 'o') { add_buff(&readbuf2, NL_STR, -1L); @@ -800,9 +808,9 @@ int start_redo_ins(void) } } - /* copy the typed text from the redo buffer into the stuff buffer */ - copy_redo(FALSE); - block_redo = TRUE; + // copy the typed text from the redo buffer into the stuff buffer + copy_redo(false); + block_redo = true; return OK; } @@ -949,7 +957,7 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent) typebuf.tb_maplen += addlen; if (silent || typebuf.tb_silent > offset) { typebuf.tb_silent += addlen; - cmd_silent = TRUE; + cmd_silent = true; } if (typebuf.tb_no_abbr_cnt && offset == 0) /* and not used for abbrev.s */ typebuf.tb_no_abbr_cnt += addlen; @@ -972,7 +980,7 @@ void ins_char_typebuf(int c) buf[2] = (char_u)K_THIRD(c); buf[3] = NUL; } else { - buf[(*mb_char2bytes)(c, buf)] = NUL; + buf[utf_char2bytes(c, buf)] = NUL; } (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent); } @@ -1077,9 +1085,10 @@ void del_typebuf(int len, int offset) /* Reset the flag that text received from a client or from feedkeys() * was inserted in the typeahead buffer. */ - typebuf_was_filled = FALSE; - if (++typebuf.tb_change_cnt == 0) + typebuf_was_filled = false; + if (++typebuf.tb_change_cnt == 0) { typebuf.tb_change_cnt = 1; + } } /* @@ -1482,7 +1491,7 @@ int vgetc(void) } } no_mapping--; - c = (*mb_ptr2char)(buf); + c = utf_ptr2char(buf); } break; @@ -1531,6 +1540,7 @@ int plain_vgetc(void) * Check if a character is available, such that vgetc() will not block. * If the next character is a special character or multi-byte, the returned * character is not valid!. + * Returns NUL if no character is available. */ int vpeekc(void) { @@ -1595,7 +1605,8 @@ vungetc ( /* unget one character (can only be done once!) */ /// KeyTyped is set to TRUE in the case the user typed the key. /// KeyStuffed is TRUE if the character comes from the stuff buffer. /// if "advance" is FALSE (vpeekc()): -/// just look whether there is a character available. +/// Just look whether there is a character available. +/// Return NUL if not. /// /// When `no_mapping` (global) is zero, checks for mappings in the current mode. /// Only returns one byte (of a multi-byte character). @@ -1663,7 +1674,7 @@ static int vgetorpeek(int advance) } if (c != NUL && !got_int) { if (advance) { - // KeyTyped = FALSE; When the command that stuffed something + // KeyTyped = false; When the command that stuffed something // was typed, behave like the stuffed command was typed. // needed for CTRL-W CTRL-] to open a fold, for example. KeyStuffed = true; @@ -1689,22 +1700,20 @@ static int vgetorpeek(int advance) os_breakcheck(); /* check for CTRL-C */ keylen = 0; if (got_int) { - /* flush all input */ - c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L, - typebuf.tb_change_cnt); - /* - * If inchar() returns TRUE (script file was active) or we - * are inside a mapping, get out of insert mode. - * Otherwise we behave like having gotten a CTRL-C. - * As a result typing CTRL-C in insert mode will - * really insert a CTRL-C. - */ + // flush all input + c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L); + // If inchar() returns TRUE (script file was active) or we + // are inside a mapping, get out of insert mode. + // Otherwise we behave like having gotten a CTRL-C. + // As a result typing CTRL-C in insert mode will + // really insert a CTRL-C. if ((c || typebuf.tb_maplen) - && (State & (INSERT + CMDLINE))) + && (State & (INSERT + CMDLINE))) { c = ESC; - else + } else { c = Ctrl_C; - flush_buffers(TRUE); /* flush all typeahead */ + } + flush_buffers(FLUSH_INPUT); // flush all typeahead if (advance) { /* Also record this character, it might be needed to @@ -1712,7 +1721,7 @@ static int vgetorpeek(int advance) *typebuf.tb_buf = (char_u)c; gotchars(typebuf.tb_buf, 1); } - cmd_silent = FALSE; + cmd_silent = false; break; } else if (typebuf.tb_len > 0) { @@ -1965,8 +1974,8 @@ static int vgetorpeek(int advance) redrawcmdline(); else setcursor(); - flush_buffers(FALSE); - mapdepth = 0; /* for next one */ + flush_buffers(FLUSH_MINIMAL); + mapdepth = 0; // for next one c = -1; break; } @@ -2067,18 +2076,17 @@ static int vgetorpeek(int advance) c = 0; new_wcol = curwin->w_wcol; new_wrow = curwin->w_wrow; - if ( advance - && typebuf.tb_len == 1 - && typebuf.tb_buf[typebuf.tb_off] == ESC - && !no_mapping - && ex_normal_busy == 0 - && typebuf.tb_maplen == 0 - && (State & INSERT) - && (p_timeout - || (keylen == KEYLEN_PART_KEY && p_ttimeout)) - && (c = inchar(typebuf.tb_buf + typebuf.tb_off - + typebuf.tb_len, 3, 25L, - typebuf.tb_change_cnt)) == 0) { + if (advance + && typebuf.tb_len == 1 + && typebuf.tb_buf[typebuf.tb_off] == ESC + && !no_mapping + && ex_normal_busy == 0 + && typebuf.tb_maplen == 0 + && (State & INSERT) + && (p_timeout + || (keylen == KEYLEN_PART_KEY && p_ttimeout)) + && (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, + 3, 25L)) == 0) { colnr_T col = 0, vcol; char_u *ptr; @@ -2125,13 +2133,14 @@ static int vgetorpeek(int advance) curwin->w_wcol = curwin->w_width - 1; col = curwin->w_cursor.col - 1; } - if (has_mbyte && col > 0 && curwin->w_wcol > 0) { - /* Correct when the cursor is on the right halve - * of a double-wide character. */ + if (col > 0 && curwin->w_wcol > 0) { + // Correct when the cursor is on the right halve + // of a double-wide character. ptr = get_cursor_line_ptr(); - col -= (*mb_head_off)(ptr, ptr + col); - if ((*mb_ptr2cells)(ptr + col) > 1) - --curwin->w_wcol; + col -= utf_head_off(ptr, ptr + col); + if (utf_ptr2cells(ptr + col) > 1) { + curwin->w_wcol--; + } } } setcursor(); @@ -2249,6 +2258,11 @@ static int vgetorpeek(int advance) /* * get a character: 3. from the user - get it */ + if (typebuf.tb_len == 0) { + // timedout may have been set while waiting for a mapping + // that has a <Nop> RHS. + timedout = false; + } wait_tb_len = typebuf.tb_len; c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len, typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1, @@ -2260,7 +2274,7 @@ static int vgetorpeek(int advance) ? -1L : ((keylen == KEYLEN_PART_KEY && p_ttm >= 0) ? p_ttm - : p_tm)), typebuf.tb_change_cnt); + : p_tm))); if (i != 0) pop_showcmd(); @@ -2341,16 +2355,15 @@ static int vgetorpeek(int advance) * Return the number of obtained characters. * Return -1 when end of input script reached. */ -int -inchar ( +int inchar( char_u *buf, int maxlen, - long wait_time, /* milli seconds */ - int tb_change_cnt + long wait_time // milli seconds ) { int len = 0; // Init for GCC. int retesc = false; // Return ESC with gotint. + const int tb_change_cnt = typebuf.tb_change_cnt; if (wait_time == -1L || wait_time > 100L) { // flush output before waiting @@ -2421,10 +2434,19 @@ inchar ( len = os_inchar(buf, maxlen / 3, (int)wait_time, tb_change_cnt); } + // If the typebuf was changed further down, it is like nothing was added by + // this call. if (typebuf_changed(tb_change_cnt)) { return 0; } + // Note the change in the typeahead buffer, this matters for when + // vgetorpeek() is called recursively, e.g. using getchar(1) in a timer + // function. + if (len > 0 && ++typebuf.tb_change_cnt == 0) { + typebuf.tb_change_cnt = 1; + } + return fix_input_buffer(buf, len); } @@ -3637,16 +3659,14 @@ int check_abbr(int c, char_u *ptr, int col, int mincol) tb[j++] = (char_u)K_SECOND(c); tb[j++] = (char_u)K_THIRD(c); } else { - if (c < ABBR_OFF && (c < ' ' || c > '~')) - tb[j++] = Ctrl_V; /* special char needs CTRL-V */ - if (has_mbyte) { - /* if ABBR_OFF has been added, remove it here */ - if (c >= ABBR_OFF) - c -= ABBR_OFF; - j += (*mb_char2bytes)(c, tb + j); - } else { - tb[j++] = (char_u)c; + if (c < ABBR_OFF && (c < ' ' || c > '~')) { + tb[j++] = Ctrl_V; // special char needs CTRL-V + } + // if ABBR_OFF has been added, remove it here. + if (c >= ABBR_OFF) { + c -= ABBR_OFF; } + j += utf_char2bytes(c, tb + j); } tb[j] = NUL; /* insert the last typed char */ @@ -4299,8 +4319,14 @@ char_u * getcmdkeycmd(int promptc, void *cookie, int indent) EMSG(e_cmdmap_repeated); aborted = true; } else if (IS_SPECIAL(c1)) { - EMSG2(e_cmdmap_key, get_special_key_name(c1, cmod)); - aborted = true; + if (c1 == K_SNR) { + ga_append(&line_ga, (char)K_SPECIAL); + ga_append(&line_ga, (char)KS_EXTRA); + ga_append(&line_ga, (char)KE_SNR); + } else { + EMSG2(e_cmdmap_key, get_special_key_name(c1, cmod)); + aborted = true; + } } else { ga_append(&line_ga, (char)c1); } diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h index 38a2e75663..4f548d975a 100644 --- a/src/nvim/getchar.h +++ b/src/nvim/getchar.h @@ -16,6 +16,13 @@ enum { REMAP_SKIP = -3, ///< No remapping for first char. } RemapValues; +// Argument for flush_buffers(). +typedef enum { + FLUSH_MINIMAL, + FLUSH_TYPEAHEAD, // flush current typebuf contents + FLUSH_INPUT // flush typebuf and inchar() input +} flush_buffers_T; + #define KEYLEN_PART_KEY -1 /* keylen value for incomplete key-code */ #define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */ #define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */ diff --git a/src/nvim/globals.h b/src/nvim/globals.h index d9103f516c..df74e8b2ff 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -191,8 +191,6 @@ EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */ EXTERN int exec_from_reg INIT(= FALSE); /* executing register */ -EXTERN int screen_cleared INIT(= FALSE); /* screen has been cleared */ - /* * When '$' is included in 'cpoptions' option set: * When a change command is given that deletes only part of a line, a dollar @@ -280,13 +278,9 @@ EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and nothing written since then */ EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */ -EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */ -#if defined(UNIX) || defined(MACOS_X) -EXTERN int newline_on_exit INIT(= FALSE); /* did msg in altern. screen */ -EXTERN int intr_char INIT(= 0); /* extra interrupt character */ -#endif -EXTERN int ex_keep_indent INIT(= FALSE); /* getexmodeline(): keep indent */ -EXTERN int vgetc_busy INIT(= 0); /* when inside vgetc() then > 0 */ +EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg +EXTERN int ex_keep_indent INIT(= false); // getexmodeline(): keep indent +EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0 EXTERN int didset_vim INIT(= FALSE); /* did set $VIM ourselves */ EXTERN int didset_vimruntime INIT(= FALSE); /* idem for $VIMRUNTIME */ @@ -532,8 +526,8 @@ EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer */ EXTERN alist_T global_alist; /* global argument list */ EXTERN int max_alist_id INIT(= 0); ///< the previous argument list id -EXTERN int arg_had_last INIT(= FALSE); /* accessed last file in - global_alist */ +EXTERN bool arg_had_last INIT(= false); // accessed last file in + // global_alist EXTERN int ru_col; /* column for ruler */ EXTERN int ru_wid; /* 'rulerfmt' width of ruler when non-zero */ @@ -604,7 +598,7 @@ EXTERN pos_T where_paste_started; * reset when any other editing is done on the line. If an <ESC> or <RETURN> * is received, and did_ai is TRUE, the line is truncated. */ -EXTERN int did_ai INIT(= FALSE); +EXTERN bool did_ai INIT(= false); /* * Column of first char after autoindent. 0 when no autoindent done. Used @@ -632,19 +626,19 @@ EXTERN int did_syncbind INIT(= FALSE); * This flag is set when a smart indent has been performed. When the next typed * character is a '{' the inserted tab will be deleted again. */ -EXTERN int did_si INIT(= FALSE); +EXTERN bool did_si INIT(= false); /* * This flag is set after an auto indent. If the next typed character is a '}' * one indent will be removed. */ -EXTERN int can_si INIT(= FALSE); +EXTERN bool can_si INIT(= false); /* * This flag is set after an "O" command. If the next typed character is a '{' * one indent will be removed. */ -EXTERN int can_si_back INIT(= FALSE); +EXTERN bool can_si_back INIT(= false); // w_cursor before formatting text. EXTERN pos_T saved_cursor INIT(= INIT_POS_T(0, 0, 0)); @@ -751,7 +745,7 @@ EXTERN cmdmod_T cmdmod; /* Ex command modifiers */ EXTERN int msg_silent INIT(= 0); // don't print messages EXTERN int emsg_silent INIT(= 0); // don't print error messages EXTERN bool emsg_noredir INIT(= false); // don't redirect error messages -EXTERN int cmd_silent INIT(= false); // don't echo the command line +EXTERN bool cmd_silent INIT(= false); // don't echo the command line /* Values for swap_exists_action: what to do when swap file already exists */ #define SEA_NONE 0 /* don't use dialog */ @@ -789,7 +783,7 @@ EXTERN int ex_normal_busy INIT(= 0); // recursiveness of ex_normal() EXTERN int ex_normal_lock INIT(= 0); // forbid use of ex_normal() EXTERN int ignore_script INIT(= false); // ignore script input EXTERN int stop_insert_mode; // for ":stopinsert" and 'insertmode' -EXTERN int KeyTyped; // TRUE if user typed current char +EXTERN bool KeyTyped; // true if user typed current char EXTERN int KeyStuffed; // TRUE if current char from stuffbuf EXTERN int maptick INIT(= 0); // tick for each non-mapped char @@ -942,8 +936,8 @@ EXTERN int no_hlsearch INIT(= FALSE); EXTERN linenr_T printer_page_num; -EXTERN int typebuf_was_filled INIT(= FALSE); /* received text from client - or from feedkeys() */ +EXTERN bool typebuf_was_filled INIT(= false); // received text from client + // or from feedkeys() #ifdef BACKSLASH_IN_FILENAME @@ -952,9 +946,9 @@ EXTERN char psepcN INIT(= '/'); // abnormal path separator character EXTERN char pseps[2] INIT(= { '\\', 0 }); // normal path separator string #endif -/* Set to TRUE when an operator is being executed with virtual editing, MAYBE - * when no operator is being executed, FALSE otherwise. */ -EXTERN int virtual_op INIT(= MAYBE); +// Set to kTrue when an operator is being executed with virtual editing +// kNone when no operator is being executed, kFalse otherwise. +EXTERN TriState virtual_op INIT(= kNone); /* Display tick, incremented for each call to update_screen() */ EXTERN disptick_T display_tick INIT(= 0); @@ -1103,6 +1097,8 @@ EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set")); EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name")); EXTERN char_u e_dirnotf[] INIT(= N_( "E919: Directory not found in '%s': \"%s\"")); +EXTERN char_u e_au_recursive[] INIT(= N_( + "E952: Autocommand caused recursive behavior")); EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported")); EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long")); EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String")); diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index b3a9eabdb8..a8731d5bd7 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -134,9 +134,9 @@ static int current_syn_id; #define PRCOLOR_BLACK 0 #define PRCOLOR_WHITE 0xffffff -static int curr_italic; -static int curr_bold; -static int curr_underline; +static TriState curr_italic; +static TriState curr_bold; +static TriState curr_underline; static uint32_t curr_bg; static uint32_t curr_fg; static int page_count; @@ -417,7 +417,8 @@ static void prt_set_bg(uint32_t bg) } } -static void prt_set_font(int bold, int italic, int underline) +static void prt_set_font(const TriState bold, const TriState italic, + const TriState underline) { if (curr_bold != bold || curr_italic != italic @@ -429,34 +430,32 @@ static void prt_set_font(int bold, int italic, int underline) } } -/* - * Print the line number in the left margin. - */ -static void prt_line_number(prt_settings_T *psettings, int page_line, linenr_T lnum) +// Print the line number in the left margin. +static void prt_line_number(prt_settings_T *const psettings, + const int page_line, const linenr_T lnum) { - int i; - char_u tbuf[20]; - prt_set_fg(psettings->number.fg_color); prt_set_bg(psettings->number.bg_color); prt_set_font(psettings->number.bold, psettings->number.italic, - psettings->number.underline); - mch_print_start_line(TRUE, page_line); + psettings->number.underline); + mch_print_start_line(true, page_line); - /* Leave two spaces between the number and the text; depends on - * PRINT_NUMBER_WIDTH. */ - sprintf((char *)tbuf, "%6ld", (long)lnum); - for (i = 0; i < 6; i++) + // Leave two spaces between the number and the text; depends on + // PRINT_NUMBER_WIDTH. + char_u tbuf[20]; + snprintf((char *)tbuf, sizeof(tbuf), "%6ld", (long)lnum); + for (int i = 0; i < 6; i++) { (void)mch_print_text_out(&tbuf[i], 1); + } - if (psettings->do_syntax) - /* Set colors for next character. */ + if (psettings->do_syntax) { + // Set colors for next character. current_syn_id = -1; - else { - /* Set colors and font back to normal. */ + } else { + // Set colors and font back to normal. prt_set_fg(PRCOLOR_BLACK); prt_set_bg(PRCOLOR_WHITE); - prt_set_font(FALSE, FALSE, FALSE); + prt_set_font(kFalse, kFalse, kFalse); } } @@ -499,22 +498,20 @@ int prt_get_unit(int idx) return u; } -/* - * Print the page header. - */ -static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum) +// Print the page header. +static void prt_header(prt_settings_T *const psettings, const int pagenum, + const linenr_T lnum) { int width = psettings->chars_per_line; - int page_line; - char_u *tbuf; - char_u *p; - /* Also use the space for the line number. */ - if (prt_use_number()) + // Also use the space for the line number. + if (prt_use_number()) { width += PRINT_NUMBER_WIDTH; + } assert(width >= 0); - tbuf = xmalloc((size_t)width + IOSIZE); + const size_t tbuf_size = (size_t)width + IOSIZE; + char_u *tbuf = xmalloc(tbuf_size); if (*p_header != NUL) { linenr_T tmp_lnum, tmp_topline, tmp_botline; @@ -543,38 +540,40 @@ static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum) curwin->w_cursor.lnum = tmp_lnum; curwin->w_topline = tmp_topline; curwin->w_botline = tmp_botline; - } else - sprintf((char *)tbuf, _("Page %d"), pagenum); + } else { + snprintf((char *)tbuf, tbuf_size, _("Page %d"), pagenum); + } prt_set_fg(PRCOLOR_BLACK); prt_set_bg(PRCOLOR_WHITE); - prt_set_font(TRUE, FALSE, FALSE); + prt_set_font(kTrue, kFalse, kFalse); - /* Use a negative line number to indicate printing in the top margin. */ - page_line = 0 - prt_header_height(); - mch_print_start_line(TRUE, page_line); - for (p = tbuf; *p != NUL; ) { - int l = (*mb_ptr2len)(p); + // Use a negative line number to indicate printing in the top margin. + int page_line = 0 - prt_header_height(); + mch_print_start_line(true, page_line); + for (char_u *p = tbuf; *p != NUL; ) { + const int l = (*mb_ptr2len)(p); assert(l >= 0); if (mch_print_text_out(p, (size_t)l)) { - ++page_line; - if (page_line >= 0) /* out of room in header */ + page_line++; + if (page_line >= 0) { // out of room in header break; - mch_print_start_line(TRUE, page_line); + } + mch_print_start_line(true, page_line); } p += l; } xfree(tbuf); - if (psettings->do_syntax) - /* Set colors for next character. */ + if (psettings->do_syntax) { + // Set colors for next character. current_syn_id = -1; - else { - /* Set colors and font back to normal. */ + } else { + // Set colors and font back to normal. prt_set_fg(PRCOLOR_BLACK); prt_set_bg(PRCOLOR_WHITE); - prt_set_font(FALSE, FALSE, FALSE); + prt_set_font(kFalse, kFalse, kFalse); } } @@ -640,21 +639,19 @@ void ex_hardcopy(exarg_T *eap) else settings.do_syntax = settings.has_color; - /* Set up printing attributes for line numbers */ + // Set up printing attributes for line numbers settings.number.fg_color = PRCOLOR_BLACK; settings.number.bg_color = PRCOLOR_WHITE; - settings.number.bold = FALSE; - settings.number.italic = TRUE; - settings.number.underline = FALSE; - /* - * Syntax highlighting of line numbers. - */ - if (prt_use_number() && settings.do_syntax) { - int id; + settings.number.bold = kFalse; + settings.number.italic = kTrue; + settings.number.underline = kFalse; - id = syn_name2id((char_u *)"LineNr"); - if (id > 0) + // Syntax highlighting of line numbers. + if (prt_use_number() && settings.do_syntax) { + int id = syn_name2id((char_u *)"LineNr"); + if (id > 0) { id = syn_get_final_id(id); + } prt_get_attr(id, &settings.number, settings.modec); } @@ -672,13 +669,13 @@ void ex_hardcopy(exarg_T *eap) /* Set colors and font to normal. */ curr_bg = 0xffffffff; curr_fg = 0xffffffff; - curr_italic = MAYBE; - curr_bold = MAYBE; - curr_underline = MAYBE; + curr_italic = kNone; + curr_bold = kNone; + curr_underline = kNone; prt_set_fg(PRCOLOR_BLACK); prt_set_bg(PRCOLOR_WHITE); - prt_set_font(FALSE, FALSE, FALSE); + prt_set_font(kFalse, kFalse, kFalse); current_syn_id = -1; jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present @@ -841,7 +838,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T tab_spaces = ppos->lead_spaces; } - mch_print_start_line(0, page_line); + mch_print_start_line(false, page_line); line = ml_get(ppos->file_line); /* @@ -895,10 +892,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T need_break = 1; } else { need_break = mch_print_text_out(line + col, (size_t)outputlen); - if (has_mbyte) - print_pos += (*mb_ptr2cells)(line + col); - else - print_pos++; + print_pos += utf_ptr2cells(line + col); } } @@ -1266,8 +1260,8 @@ static int prt_do_moveto; static int prt_need_font; static int prt_font; static int prt_need_underline; -static int prt_underline; -static int prt_do_underline; +static TriState prt_underline; +static TriState prt_do_underline; static int prt_need_fgcol; static uint32_t prt_fgcol; static int prt_need_bgcol; @@ -2855,7 +2849,7 @@ int mch_print_begin_page(char_u *str) /* We have reset the font attributes, force setting them again. */ curr_bg = 0xffffffff; curr_fg = 0xffffffff; - curr_bold = MAYBE; + curr_bold = kNone; return !prt_file_error; } @@ -2868,11 +2862,12 @@ int mch_print_blank_page(void) static double prt_pos_x = 0; static double prt_pos_y = 0; -void mch_print_start_line(int margin, int page_line) +void mch_print_start_line(const bool margin, const int page_line) { prt_pos_x = prt_left_margin; - if (margin) + if (margin) { prt_pos_x -= prt_number_width; + } prt_pos_y = prt_top_margin - prt_first_line_height - page_line * prt_line_height; @@ -2882,17 +2877,13 @@ void mch_print_start_line(int margin, int page_line) prt_half_width = FALSE; } -int mch_print_text_out(char_u *p, size_t len) +int mch_print_text_out(char_u *const textp, size_t len) { - int need_break; + char_u *p = textp; char_u ch; char_u ch_buff[8]; - double char_width; - double next_pos; - int in_ascii; - int half_width; - - char_width = prt_char_width; + char_u *tofree = NULL; + double char_width = prt_char_width; /* Ideally VIM would create a rearranged CID font to combine a Roman and * CJKV font to do what VIM is doing here - use a Roman font for characters @@ -2902,7 +2893,7 @@ int mch_print_text_out(char_u *p, size_t len) * years! If they ever do, a lot of this code will disappear. */ if (prt_use_courier) { - in_ascii = (len == 1 && *p < 0x80); + const bool in_ascii = (len == 1 && *p < 0x80); if (prt_in_ascii) { if (!in_ascii) { /* No longer in ASCII range - need to switch font */ @@ -2918,9 +2909,10 @@ int mch_print_text_out(char_u *p, size_t len) } } if (prt_out_mbyte) { - half_width = ((*mb_ptr2cells)(p) == 1); - if (half_width) + const bool half_width = (utf_ptr2cells(p) == 1); + if (half_width) { char_width /= 2; + } if (prt_half_width) { if (!half_width) { prt_half_width = FALSE; @@ -2993,23 +2985,24 @@ int mch_print_text_out(char_u *p, size_t len) } if (prt_do_conv) { - /* Convert from multi-byte to 8-bit encoding */ - p = string_convert(&prt_conv, p, &len); - if (p == NULL) - p = (char_u *)xstrdup(""); + // Convert from multi-byte to 8-bit encoding + tofree = p = string_convert(&prt_conv, p, &len); + if (p == NULL) { + p = (char_u *)""; + len = 0; + } } if (prt_out_mbyte) { - /* Multi-byte character strings are represented more efficiently as hex - * strings when outputting clean 8 bit PS. - */ - do { + // Multi-byte character strings are represented more efficiently as hex + // strings when outputting clean 8 bit PS. + while (len-- > 0) { ch = prt_hexchar[(unsigned)(*p) >> 4]; ga_append(&prt_ps_buffer, (char)ch); ch = prt_hexchar[(*p) & 0xf]; ga_append(&prt_ps_buffer, (char)ch); p++; - } while (--len); + } } else { /* Add next character to buffer of characters to output. * Note: One printed character may require several PS characters to @@ -3043,25 +3036,26 @@ int mch_print_text_out(char_u *p, size_t len) ga_append(&prt_ps_buffer, (char)ch); } - /* Need to free any translated characters */ - if (prt_do_conv) - xfree(p); + // Need to free any translated characters + xfree(tofree); prt_text_run += char_width; prt_pos_x += char_width; // The downside of fp - use relative error on right margin check - next_pos = prt_pos_x + prt_char_width; - need_break = ((next_pos > prt_right_margin) - && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5))); + const double next_pos = prt_pos_x + prt_char_width; + const bool need_break = (next_pos > prt_right_margin) + && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5)); - if (need_break) + if (need_break) { prt_flush_buffer(); + } return need_break; } -void mch_print_set_font(int iBold, int iItalic, int iUnderline) +void mch_print_set_font(const TriState iBold, const TriState iItalic, + const TriState iUnderline) { int font = 0; diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h index a70b20e6f5..c6a3321b08 100644 --- a/src/nvim/hardcopy.h +++ b/src/nvim/hardcopy.h @@ -2,10 +2,11 @@ #define NVIM_HARDCOPY_H #include <stdint.h> -#include <stdlib.h> // for size_t +#include <stdlib.h> // for size_t -#include "nvim/types.h" // for char_u -#include "nvim/ex_cmds_defs.h" // for exarg_T +#include "nvim/globals.h" // for TriState +#include "nvim/types.h" // for char_u +#include "nvim/ex_cmds_defs.h" // for exarg_T /* * Structure to hold printing color and font attributes. @@ -13,9 +14,9 @@ typedef struct { uint32_t fg_color; uint32_t bg_color; - int bold; - int italic; - int underline; + TriState bold; + TriState italic; + TriState underline; int undercurl; } prt_text_attr_T; diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c new file mode 100644 index 0000000000..a104137d9e --- /dev/null +++ b/src/nvim/highlight.c @@ -0,0 +1,403 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +// highlight.c: low level code for UI and syntax highlighting + +#include "nvim/vim.h" +#include "nvim/highlight.h" +#include "nvim/highlight_defs.h" +#include "nvim/map.h" +#include "nvim/screen.h" +#include "nvim/syntax.h" +#include "nvim/ui.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "highlight.c.generated.h" +#endif + +static bool hlstate_active = false; + +static kvec_t(HlEntry) attr_entries = KV_INITIAL_VALUE; + +static Map(HlEntry, int) *attr_entry_ids; +static Map(int, int) *combine_attr_entries; + +void highlight_init(void) +{ + attr_entry_ids = map_new(HlEntry, int)(); + combine_attr_entries = map_new(int, int)(); + + // index 0 is no attribute, add dummy entry: + kv_push(attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlUnknown, + .id1 = 0, .id2 = 0 })); +} + +/// @return TRUE if hl table was reset +bool highlight_use_hlstate(void) +{ + if (hlstate_active) { + return false; + } + hlstate_active = true; + // hl tables must now be rebuilt. + clear_hl_tables(true); + return true; +} + +/// Return the attr number for a set of colors and font, and optionally +/// a semantic description (see ext_hlstate documentation). +/// Add a new entry to the attr_entries array if the combination is new. +/// @return 0 for error. +static int get_attr_entry(HlEntry entry) +{ + if (!hlstate_active) { + // This information will not be used, erase it and reduce the table size. + entry.kind = kHlUnknown; + entry.id1 = 0; + entry.id2 = 0; + } + + int id = map_get(HlEntry, int)(attr_entry_ids, entry); + if (id > 0) { + return id; + } + + static bool recursive = false; + if (kv_size(attr_entries) > MAX_TYPENR) { + // Running out of attribute entries! remove all attributes, and + // compute new ones for all groups. + // When called recursively, we are really out of numbers. + if (recursive) { + EMSG(_("E424: Too many different highlighting attributes in use")); + return 0; + } + recursive = true; + + clear_hl_tables(true); + + recursive = false; + if (entry.kind == kHlCombine) { + // This entry is now invalid, don't put it + return 0; + } + } + + id = (int)kv_size(attr_entries); + kv_push(attr_entries, entry); + + map_put(HlEntry, int)(attr_entry_ids, entry, id); + + Array inspect = hl_inspect(id); + + // Note: internally we don't distinguish between cterm and rgb attributes, + // remote_ui_hl_attr_define will however. + ui_call_hl_attr_define(id, entry.attr, entry.attr, inspect); + api_free_array(inspect); + return id; +} + +/// When a UI connects, we need to send it the table of higlights used so far. +void ui_send_all_hls(UI *ui) +{ + for (size_t i = 1; i < kv_size(attr_entries); i++) { + Array inspect = hl_inspect((int)i); + ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr, + kv_A(attr_entries, i).attr, inspect); + api_free_array(inspect); + } +} + +/// Get attribute code for a syntax group. +int hl_get_syn_attr(int idx, HlAttrs at_en) +{ + // TODO(bfredl): should we do this unconditionally + if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0 + || at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1 + || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0 + || at_en.rgb_ae_attr != 0) { + return get_attr_entry((HlEntry){ .attr = at_en, .kind = kHlSyntax, + .id1 = idx, .id2 = 0 }); + } else { + // If all the fields are cleared, clear the attr field back to default value + return 0; + } +} + +/// Get attribute code for a builtin highlight group. +/// +/// The final syntax group could be modified by hi-link or 'winhighlight'. +int hl_get_ui_attr(int idx, int final_id, bool optional) +{ + HlAttrs attrs = HLATTRS_INIT; + bool available = false; + + int syn_attr = syn_id2attr(final_id); + if (syn_attr != 0) { + attrs = syn_attr2entry(syn_attr); + available = true; + } + if (optional && !available) { + return 0; + } + return get_attr_entry((HlEntry){ .attr = attrs, .kind = kHlUI, + .id1 = idx, .id2 = final_id }); +} + +void update_window_hl(win_T *wp, bool invalid) +{ + if (!wp->w_hl_needs_update && !invalid) { + return; + } + wp->w_hl_needs_update = false; + + // determine window specific background set in 'winhighlight' + if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) { + wp->w_hl_attr_normal = hl_get_ui_attr(HLF_INACTIVE, + wp->w_hl_ids[HLF_INACTIVE], true); + } else if (wp->w_hl_id_normal > 0) { + wp->w_hl_attr_normal = hl_get_ui_attr(-1, wp->w_hl_id_normal, true); + } else { + wp->w_hl_attr_normal = 0; + } + if (wp != curwin) { + wp->w_hl_attr_normal = hl_combine_attr(HL_ATTR(HLF_INACTIVE), + wp->w_hl_attr_normal); + } + + for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { + int attr; + if (wp->w_hl_ids[hlf] > 0) { + attr = hl_get_ui_attr(hlf, wp->w_hl_ids[hlf], false); + } else { + attr = HL_ATTR(hlf); + } + wp->w_hl_attrs[hlf] = attr; + } +} + +/// Get attribute code for forwarded :terminal highlights. +int get_term_attr_entry(HlAttrs *aep) +{ + return get_attr_entry((HlEntry){ .attr= *aep, .kind = kHlTerminal, + .id1 = 0, .id2 = 0 }); +} + +/// Clear all highlight tables. +void clear_hl_tables(bool reinit) +{ + if (reinit) { + kv_size(attr_entries) = 1; + map_clear(HlEntry, int)(attr_entry_ids); + map_clear(int, int)(combine_attr_entries); + highlight_attr_set_all(); + highlight_changed(); + redraw_all_later(NOT_VALID); + if (ScreenAttrs) { + // the meaning of 0 doesn't change anyway + // but the rest must be retransmitted + memset(ScreenAttrs, 0, + sizeof(*ScreenAttrs) * (size_t)(screen_Rows * screen_Columns)); + } + } else { + kv_destroy(attr_entries); + map_free(HlEntry, int)(attr_entry_ids); + map_free(int, int)(combine_attr_entries); + } +} + +// Combine special attributes (e.g., for spelling) with other attributes +// (e.g., for syntax highlighting). +// "prim_attr" overrules "char_attr". +// This creates a new group when required. +// Since we expect there to be few spelling mistakes we don't cache the +// result. +// Return the resulting attributes. +int hl_combine_attr(int char_attr, int prim_attr) +{ + if (char_attr == 0) { + return prim_attr; + } else if (prim_attr == 0) { + return char_attr; + } + + // TODO(bfredl): could use a struct for clearer intent. + int combine_tag = (char_attr << 16) + prim_attr; + int id = map_get(int, int)(combine_attr_entries, combine_tag); + if (id > 0) { + return id; + } + + HlAttrs char_aep = syn_attr2entry(char_attr); + HlAttrs spell_aep = syn_attr2entry(prim_attr); + + // start with low-priority attribute, and override colors if present below. + HlAttrs new_en = char_aep; + + new_en.cterm_ae_attr |= spell_aep.cterm_ae_attr; + new_en.rgb_ae_attr |= spell_aep.rgb_ae_attr; + + if (spell_aep.cterm_fg_color > 0) { + new_en.cterm_fg_color = spell_aep.cterm_fg_color; + } + + if (spell_aep.cterm_bg_color > 0) { + new_en.cterm_bg_color = spell_aep.cterm_bg_color; + } + + if (spell_aep.rgb_fg_color >= 0) { + new_en.rgb_fg_color = spell_aep.rgb_fg_color; + } + + if (spell_aep.rgb_bg_color >= 0) { + new_en.rgb_bg_color = spell_aep.rgb_bg_color; + } + + if (spell_aep.rgb_sp_color >= 0) { + new_en.rgb_sp_color = spell_aep.rgb_sp_color; + } + + id = get_attr_entry((HlEntry){ .attr = new_en, .kind = kHlCombine, + .id1 = char_attr, .id2 = prim_attr }); + if (id > 0) { + map_put(int, int)(combine_attr_entries, combine_tag, id); + } + + return id; +} + +/// Get highlight attributes for a attribute code +HlAttrs syn_attr2entry(int attr) +{ + if (attr <= 0 || attr >= (int)kv_size(attr_entries)) { + // invalid attribute code, or the tables were cleared + return HLATTRS_INIT; + } + return kv_A(attr_entries, attr).attr; +} + +/// Gets highlight description for id `attr_id` as a map. +Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) +{ + Dictionary dic = ARRAY_DICT_INIT; + + if (attr_id == 0) { + return dic; + } + + if (attr_id <= 0 || attr_id >= (int)kv_size(attr_entries)) { + api_set_error(err, kErrorTypeException, + "Invalid attribute id: %" PRId64, attr_id); + return dic; + } + + return hlattrs2dict(syn_attr2entry((int)attr_id), rgb); +} + +/// Converts an HlAttrs into Dictionary +/// +/// @param[in] aep data to convert +/// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*' +Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb) +{ + Dictionary hl = ARRAY_DICT_INIT; + int mask = use_rgb ? ae.rgb_ae_attr : ae.cterm_ae_attr; + + if (mask & HL_BOLD) { + PUT(hl, "bold", BOOLEAN_OBJ(true)); + } + + if (mask & HL_STANDOUT) { + PUT(hl, "standout", BOOLEAN_OBJ(true)); + } + + if (mask & HL_UNDERLINE) { + PUT(hl, "underline", BOOLEAN_OBJ(true)); + } + + if (mask & HL_UNDERCURL) { + PUT(hl, "undercurl", BOOLEAN_OBJ(true)); + } + + if (mask & HL_ITALIC) { + PUT(hl, "italic", BOOLEAN_OBJ(true)); + } + + if (mask & HL_INVERSE) { + PUT(hl, "reverse", BOOLEAN_OBJ(true)); + } + + if (use_rgb) { + if (ae.rgb_fg_color != -1) { + PUT(hl, "foreground", INTEGER_OBJ(ae.rgb_fg_color)); + } + + if (ae.rgb_bg_color != -1) { + PUT(hl, "background", INTEGER_OBJ(ae.rgb_bg_color)); + } + + if (ae.rgb_sp_color != -1) { + PUT(hl, "special", INTEGER_OBJ(ae.rgb_sp_color)); + } + } else { + if (cterm_normal_fg_color != ae.cterm_fg_color) { + PUT(hl, "foreground", INTEGER_OBJ(ae.cterm_fg_color - 1)); + } + + if (cterm_normal_bg_color != ae.cterm_bg_color) { + PUT(hl, "background", INTEGER_OBJ(ae.cterm_bg_color - 1)); + } + } + + return hl; +} + +Array hl_inspect(int attr) +{ + Array ret = ARRAY_DICT_INIT; + if (hlstate_active) { + hl_inspect_impl(&ret, attr); + } + return ret; +} + +static void hl_inspect_impl(Array *arr, int attr) +{ + Dictionary item = ARRAY_DICT_INIT; + if (attr <= 0 || attr >= (int)kv_size(attr_entries)) { + return; + } + + HlEntry e = kv_A(attr_entries, attr); + switch (e.kind) { + case kHlSyntax: + PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax"))); + PUT(item, "hi_name", + STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1)))); + break; + + case kHlUI: + PUT(item, "kind", STRING_OBJ(cstr_to_string("ui"))); + const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1]; + PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name))); + PUT(item, "hi_name", + STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2)))); + break; + + case kHlTerminal: + PUT(item, "kind", STRING_OBJ(cstr_to_string("term"))); + break; + + case kHlCombine: + // attribute combination is associative, so flatten to an array + hl_inspect_impl(arr, e.id1); + hl_inspect_impl(arr, e.id2); + return; + + case kHlUnknown: + return; + } + PUT(item, "id", INTEGER_OBJ(attr)); + ADD(*arr, DICTIONARY_OBJ(item)); +} diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h new file mode 100644 index 0000000000..6be0d6200b --- /dev/null +++ b/src/nvim/highlight.h @@ -0,0 +1,13 @@ +#ifndef NVIM_HIGHLIGHT_H +#define NVIM_HIGHLIGHT_H + +#include <stdbool.h> +#include "nvim/highlight_defs.h" +#include "nvim/api/private/defs.h" +#include "nvim/ui.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "highlight.h.generated.h" +#endif + +#endif // NVIM_HIGHLIGHT_H diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index 3518c8bdcc..0790793c94 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -8,6 +8,8 @@ typedef int32_t RgbValue; /// Highlighting attribute bits. +/// +/// sign bit should not be used here, as it identifies invalid highlight typedef enum { HL_INVERSE = 0x01, HL_BOLD = 0x02, @@ -152,4 +154,19 @@ EXTERN RgbValue normal_fg INIT(= -1); EXTERN RgbValue normal_bg INIT(= -1); EXTERN RgbValue normal_sp INIT(= -1); +typedef enum { + kHlUnknown, + kHlUI, + kHlSyntax, + kHlTerminal, + kHlCombine, +} HlKind; + +typedef struct { + HlAttrs attr; + HlKind kind; + int id1; + int id2; +} HlEntry; + #endif // NVIM_HIGHLIGHT_DEFS_H diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c index 2a215f854f..f8ce6200d7 100644 --- a/src/nvim/indent_c.c +++ b/src/nvim/indent_c.c @@ -75,11 +75,12 @@ find_start_comment ( /* XXX */ /// Find the start of a comment or raw string, not knowing if we are in a /// comment or raw string right now. /// Search starts at w_cursor.lnum and goes backwards. +/// If is_raw is given and returns start of raw_string, sets it to true. /// /// @returns NULL when not inside a comment or raw string. /// /// @note "CORS" -> Comment Or Raw String -static pos_T *ind_find_start_CORS(void) +static pos_T *ind_find_start_CORS(linenr_T *is_raw) { // XXX static pos_T comment_pos_copy; @@ -96,6 +97,9 @@ static pos_T *ind_find_start_CORS(void) // If comment_pos is before rs_pos the raw string is inside the comment. // If rs_pos is before comment_pos the comment is inside the raw string. if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos))) { + if (is_raw != NULL && rs_pos != NULL) { + *is_raw = rs_pos->lnum; + } return rs_pos; } return comment_pos; @@ -384,8 +388,9 @@ int cin_islabel(void) * it. */ curwin->w_cursor.col = 0; - if ((trypos = ind_find_start_CORS()) != NULL) /* XXX */ + if ((trypos = ind_find_start_CORS(NULL)) != NULL) { // XXX curwin->w_cursor = *trypos; + } line = get_cursor_line_ptr(); if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */ @@ -1401,10 +1406,12 @@ static pos_T *find_start_brace(void) pos = NULL; /* ignore the { if it's in a // or / * * / comment */ if ((colnr_T)cin_skip2pos(trypos) == trypos->col - && (pos = ind_find_start_CORS()) == NULL) /* XXX */ + && (pos = ind_find_start_CORS(NULL)) == NULL) { // XXX break; - if (pos != NULL) + } + if (pos != NULL) { curwin->w_cursor.lnum = pos->lnum; + } } curwin->w_cursor = cursor_save; return trypos; @@ -1443,7 +1450,7 @@ retry: pos_copy = *trypos; /* copy trypos, findmatch will change it */ trypos = &pos_copy; curwin->w_cursor = *trypos; - if ((trypos_wk = ind_find_start_CORS()) != NULL) { /* XXX */ + if ((trypos_wk = ind_find_start_CORS(NULL)) != NULL) { // XXX ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum - trypos_wk->lnum); if (ind_maxp_wk > 0) { @@ -1793,6 +1800,7 @@ int get_c_indent(void) int cont_amount = 0; /* amount for continuation line */ int original_line_islabel; int added_to_amount = 0; + linenr_T raw_string_start = 0; cpp_baseclass_cache_T cache_cpp_baseclass = { false, { MAXLNUM, 0 } }; /* make a copy, value is changed below */ @@ -2059,8 +2067,8 @@ int get_c_indent(void) } curwin->w_cursor.lnum = lnum; - /* Skip a comment or raw string. XXX */ - if ((trypos = ind_find_start_CORS()) != NULL) { + // Skip a comment or raw string. XXX + if ((trypos = ind_find_start_CORS(NULL)) != NULL) { lnum = trypos->lnum + 1; continue; } @@ -2443,7 +2451,7 @@ int get_c_indent(void) * If we're in a comment or raw string now, skip to * the start of it. */ - trypos = ind_find_start_CORS(); + trypos = ind_find_start_CORS(NULL); if (trypos != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; @@ -2552,7 +2560,7 @@ int get_c_indent(void) /* If we're in a comment or raw string now, skip * to the start of it. */ - trypos = ind_find_start_CORS(); + trypos = ind_find_start_CORS(NULL); if (trypos != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; @@ -2581,11 +2589,10 @@ int get_c_indent(void) break; } - /* - * If we're in a comment or raw string now, skip to the start - * of it. - */ /* XXX */ - if ((trypos = ind_find_start_CORS()) != NULL) { + // If we're in a comment or raw string now, skip to the start + // of it. + // XXX + if ((trypos = ind_find_start_CORS(&raw_string_start)) != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; continue; @@ -3096,7 +3103,8 @@ int get_c_indent(void) } if (lookfor != LOOKFOR_TERM && lookfor != LOOKFOR_JS_KEY - && lookfor != LOOKFOR_COMMA) { + && lookfor != LOOKFOR_COMMA + && raw_string_start != curwin->w_cursor.lnum) { lookfor = LOOKFOR_UNTERM; } } @@ -3351,11 +3359,10 @@ term_again: l = get_cursor_line_ptr(); - /* - * If we're in a comment or raw string now, skip to the start - * of it. - */ /* XXX */ - if ((trypos = ind_find_start_CORS()) != NULL) { + // If we're in a comment or raw string now, skip to the start + // of it. + // XXX + if ((trypos = ind_find_start_CORS(NULL)) != NULL) { curwin->w_cursor.lnum = trypos->lnum + 1; curwin->w_cursor.col = 0; continue; diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 628bfef221..ade5487ec8 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -462,14 +462,13 @@ char_u *get_special_key_name(int c, int modifiers) string[idx++] = '_'; string[idx++] = (char_u)KEY2TERMCAP0(c); string[idx++] = KEY2TERMCAP1(c); - } - /* Not a special key, only modifiers, output directly */ - else { - if (has_mbyte && (*mb_char2len)(c) > 1) - idx += (*mb_char2bytes)(c, string + idx); - else if (vim_isprintc(c)) + } else { + // Not a special key, only modifiers, output directly. + if (utf_char2len(c) > 1) { + idx += utf_char2bytes(c, string + idx); + } else if (vim_isprintc(c)) { string[idx++] = (char_u)c; - else { + } else { s = transchar(c); while (*s) string[idx++] = *s++; @@ -524,14 +523,12 @@ unsigned int trans_special(const char_u **srcp, const size_t src_len, dst[dlen++] = K_SPECIAL; dst[dlen++] = (char_u)KEY2TERMCAP0(key); dst[dlen++] = KEY2TERMCAP1(key); - } else if (has_mbyte && !keycode) { - dlen += (unsigned int)(*mb_char2bytes)(key, dst + dlen); - } else if (keycode) { + } else if (!keycode) { + dlen += (unsigned int)utf_char2bytes(key, dst + dlen); + } else { char_u *after = add_char2buf(key, dst + dlen); assert(after >= dst && (uintmax_t)(after - dst) <= UINT_MAX); dlen = (unsigned int)(after - dst); - } else { - dst[dlen++] = (char_u)key; } return dlen; @@ -898,7 +895,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, } // skip multibyte char correctly - for (i = (*mb_ptr2len_len)(src, (int) (end - src) + 1); i > 0; i--) { + for (i = utfc_ptr2len_len(src, (int)(end - src) + 1); i > 0; i--) { // If the character is K_SPECIAL, replace it with K_SPECIAL // KS_SPECIAL KE_FILLER. // If compiled with the GUI replace CSI with K_CSI. diff --git a/src/nvim/lib/kvec.h b/src/nvim/lib/kvec.h index 6d54c7f78d..93b2f053bc 100644 --- a/src/nvim/lib/kvec.h +++ b/src/nvim/lib/kvec.h @@ -98,14 +98,14 @@ (*kv_pushp(v) = (x)) #define kv_a(v, i) \ - (((v).capacity <= (size_t) (i) \ + (*(((v).capacity <= (size_t) (i) \ ? ((v).capacity = (v).size = (i) + 1, \ kv_roundup32((v).capacity), \ - kv_resize((v), (v).capacity), 0) \ + kv_resize((v), (v).capacity), 0UL) \ : ((v).size <= (size_t) (i) \ ? (v).size = (i) + 1 \ - : 0)), \ - (v).items[(i)]) + : 0UL)), \ + &(v).items[(i)])) /// Type of a vector with a few first members allocated on stack /// diff --git a/src/nvim/log.c b/src/nvim/log.c index 7bfe5c4089..4d912c452b 100644 --- a/src/nvim/log.c +++ b/src/nvim/log.c @@ -7,6 +7,9 @@ #include <stdbool.h> #include <stdint.h> #include <stdio.h> +#if !defined(WIN32) +# include <sys/time.h> // for gettimeofday() +#endif #include <uv.h> #include "nvim/log.h" @@ -98,14 +101,20 @@ void log_unlock(void) /// @param context description of a shared context or subsystem /// @param func_name function name, or NULL /// @param line_num source line number, or -1 -bool do_log(int log_level, const char *context, const char *func_name, +bool logmsg(int log_level, const char *context, const char *func_name, int line_num, bool eol, const char *fmt, ...) - FUNC_ATTR_UNUSED + FUNC_ATTR_UNUSED FUNC_ATTR_PRINTF(6, 7) { if (log_level < MIN_LOG_LEVEL) { return false; } +#ifdef EXITFREE + // Logging after we've already started freeing all our memory will only cause + // pain. We need access to VV_PROGPATH, homedir, etc. + assert(!entered_free_all_mem); +#endif + log_lock(); bool ret = false; FILE *log_file = open_log_file(); @@ -195,7 +204,7 @@ void log_callstack_to_file(FILE *log_file, const char *const func_name, } assert(24 + exepathlen < IOSIZE); // Must fit in `cmdbuf` below. - char cmdbuf[IOSIZE + (20 * ARRAY_SIZE(trace))]; + char cmdbuf[IOSIZE + (20 * ARRAY_SIZE(trace)) + MAXPATHL]; snprintf(cmdbuf, sizeof(cmdbuf), "addr2line -e %s -f -p", exepath); for (int i = 1; i < trace_size; i++) { char buf[20]; // 64-bit pointer 0xNNNNNNNNNNNNNNNN with leading space. @@ -236,7 +245,8 @@ end: static bool do_log_to_file(FILE *log_file, int log_level, const char *context, const char *func_name, int line_num, bool eol, - const char* fmt, ...) + const char *fmt, ...) + FUNC_ATTR_PRINTF(7, 8) { va_list args; va_start(args, fmt); @@ -260,25 +270,33 @@ static bool v_do_log_to_file(FILE *log_file, int log_level, }; assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL); - // format current timestamp in local time + // Format the timestamp. struct tm local_time; - if (os_get_localtime(&local_time) == NULL) { + if (os_localtime(&local_time) == NULL) { return false; } char date_time[20]; - if (strftime(date_time, sizeof(date_time), "%Y/%m/%d %H:%M:%S", + if (strftime(date_time, sizeof(date_time), "%Y-%m-%dT%H:%M:%S", &local_time) == 0) { return false; } - // print the log message prefixed by the current timestamp and pid + int millis = 0; +#if !defined(WIN32) + struct timeval curtime; + if (gettimeofday(&curtime, NULL) == 0) { + millis = (int)curtime.tv_usec / 1000; + } +#endif + + // Print the log message. int64_t pid = os_get_pid(); int rv = (line_num == -1 || func_name == NULL) - ? fprintf(log_file, "%s %s %" PRId64 " %s", date_time, - log_levels[log_level], pid, + ? fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s", + log_levels[log_level], date_time, millis, pid, (context == NULL ? "?:" : context)) - : fprintf(log_file, "%s %s %" PRId64 " %s%s:%d: ", date_time, - log_levels[log_level], pid, + : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ", + log_levels[log_level], date_time, millis, pid, (context == NULL ? "" : context), func_name, line_num); if (rv < 0) { diff --git a/src/nvim/log.h b/src/nvim/log.h index f378b92039..7d4c033565 100644 --- a/src/nvim/log.h +++ b/src/nvim/log.h @@ -22,42 +22,42 @@ # define MIN_LOG_LEVEL INFO_LOG_LEVEL #endif -#define LOG(level, ...) do_log((level), NULL, __func__, __LINE__, true, \ +#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, \ __VA_ARGS__) #if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL # undef DLOG # undef DLOGN -# define DLOG(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, true, \ +# define DLOG(...) logmsg(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, false, \ +# define DLOGN(...) logmsg(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif #if MIN_LOG_LEVEL <= INFO_LOG_LEVEL # undef ILOG # undef ILOGN -# define ILOG(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, true, \ +# define ILOG(...) logmsg(INFO_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define ILOGN(...) do_log(INFO_LOG_LEVEL, NULL, __func__, __LINE__, false, \ +# define ILOGN(...) logmsg(INFO_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif #if MIN_LOG_LEVEL <= WARN_LOG_LEVEL # undef WLOG # undef WLOGN -# define WLOG(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, true, \ +# define WLOG(...) logmsg(WARN_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define WLOGN(...) do_log(WARN_LOG_LEVEL, NULL, __func__, __LINE__, false, \ +# define WLOGN(...) logmsg(WARN_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif #if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL # undef ELOG # undef ELOGN -# define ELOG(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, \ +# define ELOG(...) logmsg(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, \ __VA_ARGS__) -# define ELOGN(...) do_log(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, false, \ +# define ELOGN(...) logmsg(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, false, \ __VA_ARGS__) #endif diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 02eabb9c89..a7bda9d037 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -291,7 +291,7 @@ static int nlua_print(lua_State *const lstate) return 0; nlua_print_error: emsgf(_("E5114: Error while converting print argument #%i: %.*s"), - curargidx, errmsg_len, errmsg); + curargidx, (int)errmsg_len, errmsg); ga_clear(&msg_ga); lua_pop(lstate, lua_gettop(lstate)); return 0; diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index e1bbb03d3f..47f40da72e 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -13,7 +13,7 @@ local function _os_proc_info(pid) if pid == nil or pid <= 0 or type(pid) ~= 'number' then error('invalid pid') end - local cmd = { 'ps', '-p', pid, '-o', 'ucomm=', } + local cmd = { 'ps', '-p', pid, '-o', 'comm=', } local err, name = _system(cmd) if 1 == err and string.gsub(name, '%s*', '') == '' then return {} -- Process not found. @@ -23,7 +23,7 @@ local function _os_proc_info(pid) end local _, ppid = _system({ 'ps', '-p', pid, '-o', 'ppid=', }) -- Remove trailing whitespace. - name = string.gsub(name, '%s+$', '') + name = string.gsub(string.gsub(name, '%s+$', ''), '^.*/', '') ppid = string.gsub(ppid, '%s+$', '') ppid = tonumber(ppid) == nil and -1 or tonumber(ppid) return { diff --git a/src/nvim/macros.h b/src/nvim/macros.h index 7eb58bea2a..d447bff765 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -118,7 +118,8 @@ // Advance multi-byte pointer, do not skip over composing chars. # define MB_CPTR_ADV(p) (p += utf_ptr2len(p)) // Backup multi-byte pointer. Only use with "p" > "s" ! -# define MB_PTR_BACK(s, p) (p -= mb_head_off((char_u *)s, (char_u *)p - 1) + 1) +# define MB_PTR_BACK(s, p) \ + (p -= utf_head_off((char_u *)s, (char_u *)p - 1) + 1) // get length of multi-byte char, not including composing chars # define MB_CPTR2LEN(p) utf_ptr2len(p) @@ -126,7 +127,7 @@ # define MB_CHARLEN(p) mb_charlen(p) # define MB_CHAR2LEN(c) mb_char2len(c) -# define PTR2CHAR(p) mb_ptr2char(p) +# define PTR2CHAR(p) utf_ptr2char(p) # define RESET_BINDING(wp) (wp)->w_p_scb = FALSE; (wp)->w_p_crb = FALSE diff --git a/src/nvim/main.c b/src/nvim/main.c index 6b382ae320..af54e62393 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -23,6 +23,7 @@ #include "nvim/fold.h" #include "nvim/getchar.h" #include "nvim/hashtab.h" +#include "nvim/highlight.h" #include "nvim/iconv.h" #include "nvim/if_cscope.h" #ifdef HAVE_LOCALE_H @@ -64,6 +65,7 @@ #include "nvim/msgpack_rpc/helpers.h" #include "nvim/msgpack_rpc/server.h" #include "nvim/msgpack_rpc/channel.h" +#include "nvim/api/ui.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/handle.h" @@ -160,6 +162,7 @@ bool event_teardown(void) } multiqueue_process_events(main_loop.events); + loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events. input_stop(); channel_teardown(); process_teardown(&main_loop); @@ -182,6 +185,7 @@ void early_init(void) eval_init(); // init global variables init_path(argv0 ? argv0 : "nvim"); init_normal_cmds(); // Init the table of Normal mode commands. + highlight_init(); #if defined(HAVE_LOCALE_H) // Setup to use the current locale (for ctype() and many other things). @@ -254,6 +258,14 @@ int main(int argc, char **argv) // Process the command line arguments. File names are put in the global // argument list "global_alist". command_line_scan(¶ms); + + if (embedded_mode) { + const char *err; + if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) { + abort(); + } + } + server_init(params.listen_addr); if (GARGCOUNT > 0) { @@ -301,6 +313,7 @@ int main(int argc, char **argv) // Read ex-commands if invoked with "-es". // bool reading_tty = !headless_mode + && !embedded_mode && !silent_mode && (params.input_isatty || params.output_isatty || params.err_isatty); @@ -341,6 +354,22 @@ int main(int argc, char **argv) p_lpl = false; } + // give embedders a chance to set up nvim, by processing a request before + // startup. This allows an external UI to show messages and prompts from + // --cmd and buffer loading (e.g. swap files) + bool early_ui = false; + if (embedded_mode && !headless_mode) { + TIME_MSG("waiting for embedder to make request"); + remote_ui_wait_for_attach(); + TIME_MSG("done waiting for embedder"); + + // prepare screen now, so external UIs can display messages + starting = NO_BUFFERS; + screenclear(); + early_ui = true; + TIME_MSG("initialized screen early for embedder"); + } + // Execute --cmd arguments. exe_pre_commands(¶ms); @@ -446,16 +475,17 @@ int main(int argc, char **argv) wait_return(true); } - if (!headless_mode && !silent_mode) { + if (!headless_mode && !embedded_mode && !silent_mode) { input_stop(); // Stop reading input, let the UI take over. ui_builtin_start(); } setmouse(); // may start using the mouse - ui_reset_scroll_region(); // In case Rows changed - if (exmode_active) { - must_redraw = CLEAR; // Don't clear the screen when starting in Ex mode. + if (exmode_active || early_ui) { + // Don't clear the screen when starting in Ex mode, or when an + // embedding UI might have displayed messages + must_redraw = CLEAR; } else { screenclear(); // clear screen TIME_MSG("clearing screen"); @@ -604,9 +634,14 @@ void getout(int exitval) buf_T *buf = wp->w_buffer; if (buf_get_changedtick(buf) != -1) { + bufref_T bufref; + + set_bufref(&bufref, buf); apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false, buf); - buf_set_changedtick(buf, -1); // note that we did it already + if (bufref_valid(&bufref)) { + buf_set_changedtick(buf, -1); // note that we did it already + } // start all over, autocommands may mess up the lists next_tp = first_tabpage; break; @@ -805,7 +840,7 @@ static void command_line_scan(mparm_T *parmp) } if (p == NULL) { - emsgf(_(e_outofmem)); + EMSG(_(e_outofmem)); } Object md = DICTIONARY_OBJ(api_metadata()); @@ -821,11 +856,6 @@ static void command_line_scan(mparm_T *parmp) headless_mode = true; } else if (STRICMP(argv[0] + argv_idx, "embed") == 0) { embedded_mode = true; - headless_mode = true; - const char *err; - if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) { - abort(); - } } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) { want_argument = true; argv_idx += 6; @@ -886,6 +916,7 @@ static void command_line_scan(mparm_T *parmp) set_option_value("rl", 1L, NULL, 0); break; } + case '?': // "-?" give help message (for MS-Windows) case 'h': { // "-h" give help message usage(); mch_exit(0); @@ -902,7 +933,8 @@ static void command_line_scan(mparm_T *parmp) } case 'M': { // "-M" no changes or writing of files reset_modifiable(); - } // FALLTHROUGH + FALLTHROUGH; + } case 'm': { // "-m" no writing of files p_write = false; break; @@ -1017,7 +1049,8 @@ static void command_line_scan(mparm_T *parmp) argv_idx = -1; break; } - } // FALLTHROUGH + FALLTHROUGH; + } case 'S': // "-S {file}" execute Vim script case 'i': // "-i {shada}" use for ShaDa file case 'u': // "-u {vimrc}" vim inits file @@ -1161,7 +1194,8 @@ scripterror: argv_idx = -1; break; } - } // FALLTHROUGH + FALLTHROUGH; + } case 'W': { // "-W {scriptout}" overwrite script file if (scriptout != NULL) { goto scripterror; @@ -1372,7 +1406,7 @@ static void handle_quickfix(mparm_T *paramp) paramp->use_ef, OPT_FREE, SID_CARG); vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef); if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) { - ui_linefeed(); + msg_putchar('\n'); mch_exit(3); } TIME_MSG("reading errorfile"); @@ -1533,7 +1567,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) { int arg_idx; /* index in argument list */ int i; - int advance = TRUE; + bool advance = true; win_T *win; /* @@ -1544,8 +1578,8 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) /* When w_arg_idx is -1 remove the window (see create_windows()). */ if (curwin->w_arg_idx == -1) { - win_close(curwin, TRUE); - advance = FALSE; + win_close(curwin, true); + advance = false; } arg_idx = 1; @@ -1555,9 +1589,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) } // When w_arg_idx is -1 remove the window (see create_windows()). if (curwin->w_arg_idx == -1) { - ++arg_idx; - win_close(curwin, TRUE); - advance = FALSE; + arg_idx++; + win_close(curwin, true); + advance = false; continue; } @@ -1572,7 +1606,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) win_enter(curwin->w_next, false); } } - advance = TRUE; + advance = true; // Only open the file if there is no file in this window yet (that can // happen when vimrc contains ":sall"). @@ -1591,12 +1625,13 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) did_emsg = FALSE; /* avoid hit-enter prompt */ getout(1); } - win_close(curwin, TRUE); - advance = FALSE; + win_close(curwin, true); + advance = false; + } + if (arg_idx == GARGCOUNT - 1) { + arg_had_last = true; } - if (arg_idx == GARGCOUNT - 1) - arg_had_last = TRUE; - ++arg_idx; + arg_idx++; } os_breakcheck(); if (got_int) { diff --git a/src/nvim/map.c b/src/nvim/map.c index 537b6751e2..cc264f3729 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -140,6 +140,22 @@ static inline bool String_eq(String a, String b) return memcmp(a.data, b.data, a.size) == 0; } +static inline khint_t HlEntry_hash(HlEntry ae) +{ + const uint8_t *data = (const uint8_t *)&ae; + khint_t h = 0; + for (size_t i = 0; i < sizeof(ae); i++) { + h = (h << 5) - h + data[i]; + } + return h; +} + +static inline bool HlEntry_eq(HlEntry ae1, HlEntry ae2) +{ + return memcmp(&ae1, &ae2, sizeof(ae1)) == 0; +} + + MAP_IMPL(int, int, DEFAULT_INITIALIZER) MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER) @@ -149,3 +165,4 @@ MAP_IMPL(handle_T, ptr_t, DEFAULT_INITIALIZER) #define MSGPACK_HANDLER_INITIALIZER { .fn = NULL, .async = false } MAP_IMPL(String, MsgpackRpcRequestHandler, MSGPACK_HANDLER_INITIALIZER) #define KVEC_INITIALIZER { .size = 0, .capacity = 0, .items = NULL } +MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER) diff --git a/src/nvim/map.h b/src/nvim/map.h index ac1239a548..65204a798b 100644 --- a/src/nvim/map.h +++ b/src/nvim/map.h @@ -7,6 +7,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" #include "nvim/bufhl_defs.h" +#include "nvim/highlight_defs.h" #if defined(__NetBSD__) # undef uint64_t @@ -35,6 +36,7 @@ MAP_DECLS(ptr_t, ptr_t) MAP_DECLS(uint64_t, ptr_t) MAP_DECLS(handle_T, ptr_t) MAP_DECLS(String, MsgpackRpcRequestHandler) +MAP_DECLS(HlEntry, int) #define map_new(T, U) map_##T##_##U##_new #define map_free(T, U) map_##T##_##U##_free diff --git a/src/nvim/mark.c b/src/nvim/mark.c index 49e60b5166..05f78c76bc 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -599,9 +599,10 @@ static char_u *mark_line(pos_T *mp, int lead_len) if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) return vim_strsave((char_u *)"-invalid-"); assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX); - s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns); + // Allow for up to 5 bytes per character. + s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5); - /* Truncate the line to fit it in the window */ + // Truncate the line to fit it in the window len = 0; for (p = s; *p != NUL; MB_PTR_ADV(p)) { len += ptr2cells(p); @@ -1465,12 +1466,16 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp) { if (lp->col > 0 || lp->coladd > 1) { const char_u *const p = ml_get_buf(buf, lp->lnum, false); - lp->col -= (*mb_head_off)(p, p + lp->col); + if (*p == NUL || (int)STRLEN(p) < lp->col) { + lp->col = 0; + } else { + lp->col -= utf_head_off(p, p + lp->col); + } // Reset "coladd" when the cursor would be on the right half of a // double-wide character. if (lp->coladd == 1 && p[lp->col] != TAB - && vim_isprintc((*mb_ptr2char)(p + lp->col)) + && vim_isprintc(utf_ptr2char(p + lp->col)) && ptr2cells(p + lp->col) > 1) { lp->coladd = 0; } diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index 65a1a8246c..0ee8e2bd85 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -550,7 +550,7 @@ size_t mb_string2cells(const char_u *str) size_t clen = 0; for (const char_u *p = str; *p != NUL; p += (*mb_ptr2len)(p)) { - clen += (*mb_ptr2cells)(p); + clen += utf_ptr2cells(p); } return clen; @@ -566,7 +566,9 @@ int utf_off2cells(unsigned off, unsigned max_off) /// Convert a UTF-8 byte sequence to a wide character /// /// If the sequence is illegal or truncated by a NUL then the first byte is -/// returned. Does not include composing characters for obvious reasons. +/// returned. +/// For an overlong sequence this may return zero. +/// Does not include composing characters for obvious reasons. /// /// @param[in] p String to convert. /// @@ -674,7 +676,7 @@ int mb_ptr2char_adv(const char_u **const pp) { int c; - c = (*mb_ptr2char)(*pp); + c = utf_ptr2char(*pp); *pp += (*mb_ptr2len)(*pp); return c; } @@ -687,7 +689,7 @@ int mb_cptr2char_adv(const char_u **pp) { int c; - c = (*mb_ptr2char)(*pp); + c = utf_ptr2char(*pp); *pp += utf_ptr2len(*pp); return c; } @@ -1708,13 +1710,13 @@ void mb_check_adjust_col(void *win_) win->w_cursor.col = len - 1; } // Move the cursor to the head byte. - win->w_cursor.col -= (*mb_head_off)(p, p + win->w_cursor.col); + win->w_cursor.col -= utf_head_off(p, p + win->w_cursor.col); } // Reset `coladd` when the cursor would be on the right half of a // double-wide character. if (win->w_cursor.coladd == 1 && p[win->w_cursor.col] != TAB - && vim_isprintc((*mb_ptr2char)(p + win->w_cursor.col)) + && vim_isprintc(utf_ptr2char(p + win->w_cursor.col)) && ptr2cells(p + win->w_cursor.col) > 1) { win->w_cursor.coladd = 0; } @@ -1827,8 +1829,8 @@ const char *mb_unescape(const char **const pp) */ bool mb_lefthalve(int row, int col) { - return (*mb_off2cells)(LineOffset[row] + col, - LineOffset[row] + screen_Columns) > 1; + return utf_off2cells(LineOffset[row] + col, + LineOffset[row] + screen_Columns) > 1; } /* @@ -2122,8 +2124,9 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, * conversion from 'encoding' to something else. In other * situations we don't know what to skip anyway. */ *to++ = '?'; - if ((*mb_ptr2cells)((char_u *)from) > 1) + if (utf_ptr2cells((char_u *)from) > 1) { *to++ = '?'; + } l = utfc_ptr2len_len((const char_u *)from, (int)fromlen); from += l; fromlen -= l; diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h index 99aadcacad..70073a8540 100644 --- a/src/nvim/mbyte.h +++ b/src/nvim/mbyte.h @@ -47,15 +47,8 @@ enum { MAX_MCO = 6 }; // TODO(bfredl): eventually we should keep only one of the namings #define mb_ptr2len utfc_ptr2len -#define mb_ptr2len_len utfc_ptr2len_len #define mb_char2len utf_char2len -#define mb_char2bytes utf_char2bytes -#define mb_ptr2cells utf_ptr2cells -#define mb_ptr2cells_len utf_ptr2cells_len #define mb_char2cells utf_char2cells -#define mb_off2cells utf_off2cells -#define mb_ptr2char utf_ptr2char -#define mb_head_off utf_head_off /// Flags for vimconv_T typedef enum { diff --git a/src/nvim/memline.c b/src/nvim/memline.c index fc9a1e8271..95f3b0c623 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -49,6 +49,7 @@ #include "nvim/buffer.h" #include "nvim/cursor.h" #include "nvim/eval.h" +#include "nvim/getchar.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" #include "nvim/main.h" @@ -528,17 +529,20 @@ void ml_open_file(buf_T *buf) buf->b_may_swap = false; } -/* - * If still need to create a swap file, and starting to edit a not-readonly - * file, or reading into an existing buffer, create a swap file now. - */ -void -check_need_swap ( - int newfile /* reading file into new buffer */ -) +/// If still need to create a swap file, and starting to edit a not-readonly +/// file, or reading into an existing buffer, create a swap file now. +/// +/// @param newfile reading file into new buffer +void check_need_swap(int newfile) { - if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile)) + int old_msg_silent = msg_silent; // might be reset by an E325 message + msg_silent = 0; // If swap dialog prompts for input, user needs to see it! + + if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile)) { ml_open_file(curbuf); + } + + msg_silent = old_msg_silent; } /* @@ -769,17 +773,16 @@ void ml_recover(void) called_from_main = (curbuf->b_ml.ml_mfp == NULL); attr = HL_ATTR(HLF_E); - /* - * If the file name ends in ".s[uvw][a-z]" we assume this is the swap file. - * Otherwise a search is done to find the swap file(s). - */ + // If the file name ends in ".s[a-w][a-z]" we assume this is the swap file. + // Otherwise a search is done to find the swap file(s). fname = curbuf->b_fname; if (fname == NULL) /* When there is no file name */ fname = (char_u *)""; len = (int)STRLEN(fname); if (len >= 4 && STRNICMP(fname + len - 4, ".s", 2) == 0 - && vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL + && vim_strchr((char_u *)"abcdefghijklmnopqrstuvw", + TOLOWER_ASC(fname[len - 2])) != NULL && ASCII_ISALPHA(fname[len - 1])) { directly = TRUE; fname_used = vim_strsave(fname); /* make a copy for mf_open() */ @@ -1365,11 +1368,11 @@ recover_names ( */ if (curbuf->b_ml.ml_mfp != NULL && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL) { - for (int i = 0; i < num_files; ++i) - if (path_full_compare(p, files[i], TRUE) & kEqualFiles) { - /* Remove the name from files[i]. Move further entries - * down. When the array becomes empty free it here, since - * FreeWild() won't be called below. */ + for (int i = 0; i < num_files; i++) { + if (path_full_compare(p, files[i], true) & kEqualFiles) { + // Remove the name from files[i]. Move further entries + // down. When the array becomes empty free it here, since + // FreeWild() won't be called below. xfree(files[i]); if (--num_files == 0) xfree(files); @@ -1377,6 +1380,7 @@ recover_names ( for (; i < num_files; ++i) files[i] = files[i + 1]; } + } } if (nr > 0) { file_count += num_files; @@ -1445,7 +1449,7 @@ static char *make_percent_swname(const char *dir, char *name) } #ifdef UNIX -static int process_still_running; +static bool process_still_running; #endif /* @@ -1523,8 +1527,8 @@ static time_t swapfile_info(char_u *fname) msg_outnum(char_to_long(b0.b0_pid)); #if defined(UNIX) if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0) { - MSG_PUTS(_(" (still running)")); - process_still_running = TRUE; + MSG_PUTS(_(" (STILL RUNNING)")); + process_still_running = true; } #endif } @@ -2377,7 +2381,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int message) ) set_keep_msg((char_u *)_(no_lines_msg), 0); - i = ml_replace((linenr_T)1, (char_u *)"", TRUE); + i = ml_replace((linenr_T)1, (char_u *)"", true); buf->b_ml.ml_flags |= ML_EMPTY; return i; @@ -3146,7 +3150,9 @@ attention_message ( msg_outtrans(buf->b_fname); MSG_PUTS("\"\n"); FileInfo file_info; - if (os_fileinfo((char *)buf->b_fname, &file_info)) { + if (!os_fileinfo((char *)buf->b_fname, &file_info)) { + MSG_PUTS(_(" CANNOT BE FOUND")); + } else { MSG_PUTS(_(" dated: ")); x = file_info.stat.st_mtim.tv_sec; p = ctime(&x); // includes '\n' @@ -3343,7 +3349,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, int choice = 0; #ifdef UNIX - process_still_running = FALSE; + process_still_running = false; #endif /* * If there is a SwapExists autocommand and we can handle @@ -3355,12 +3361,16 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname, choice = do_swapexists(buf, (char_u *) fname); if (choice == 0) { - /* Show info about the existing swap file. */ - attention_message(buf, (char_u *) fname); + // Show info about the existing swap file. + attention_message(buf, (char_u *)fname); + + // We don't want a 'q' typed at the more-prompt + // interrupt loading a file. + got_int = false; - /* We don't want a 'q' typed at the more-prompt - * interrupt loading a file. */ - got_int = FALSE; + // If vimrc has "simalt ~x" we don't want it to + // interfere with the prompt here. + flush_buffers(FLUSH_TYPEAHEAD); } if (swap_exists_action != SEA_NONE && choice == 0) { @@ -3524,17 +3534,16 @@ static int b0_magic_wrong(ZERO_BL *b0p) * == 0 == 0 OK FAIL TRUE * * current file doesn't exist, inode for swap unknown, both file names not - * available -> probably same file - * == 0 == 0 FAIL FAIL FALSE + * available -> compare file names + * == 0 == 0 FAIL FAIL fname_c != fname_s * * Only the last 32 bits of the inode will be used. This can't be changed * without making the block 0 incompatible with 32 bit versions. */ -static int -fnamecmp_ino ( - char_u *fname_c, /* current file name */ - char_u *fname_s, /* file name from swap file */ +static bool fnamecmp_ino( + char_u *fname_c, // current file name + char_u *fname_s, // file name from swap file long ino_block0 ) { @@ -3575,11 +3584,13 @@ fnamecmp_ino ( /* * Can't compare inodes or file names, guess that the files are different, - * unless both appear not to exist at all. + * unless both appear not to exist at all, then compare with the file name + * in the swap file. */ - if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL) - return FALSE; - return TRUE; + if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL) { + return STRCMP(fname_c, fname_s) != 0; + } + return true; } /* @@ -3698,9 +3709,9 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) curix++) { curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; } - } else if (line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines - && curix < buf->b_ml.ml_usedchunks - 1) { - /* Adjust cached curix & curline */ + } else if (curix < buf->b_ml.ml_usedchunks - 1 + && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines) { + // Adjust cached curix & curline curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines; curix++; } @@ -3839,13 +3850,17 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype) ml_upd_lastcurix = curix; } -/* - * Find offset for line or line with offset. - * Find line with offset if "lnum" is 0; return remaining offset in offp - * Find offset of line if "lnum" > 0 - * return -1 if information is not available - */ -long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp) +/// Find offset for line or line with offset. +/// +/// @param buf buffer to use +/// @param lnum if > 0, find offset of lnum, store offset in offp +/// if == 0, return line with offset *offp +/// @param offp Location where offset of line is stored, or to read offset to +/// use to find line. In the later case, store remaining offset. +/// @param no_ff ignore 'fileformat' option, always use one byte for NL. +/// +/// @return -1 if information is not available +long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff) { linenr_T curline; int curix; @@ -3858,7 +3873,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp) int text_end; long offset; int len; - int ffdos = (get_fileformat(buf) == EOL_DOS); + int ffdos = !no_ff && (get_fileformat(buf) == EOL_DOS); int extra = 0; /* take care of cached line first */ @@ -3953,7 +3968,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp) /* Don't count the last line break if 'noeol' and ('bin' or * 'nofixeol'). */ if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol - && buf->b_ml.ml_line_count == lnum) { + && lnum > buf->b_ml.ml_line_count) { size -= ffdos + 1; } } @@ -3972,7 +3987,7 @@ void goto_byte(long cnt) if (boff) { boff--; } - lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff); + lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff, false); if (lnum < 1) { // past the end curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; curwin->w_curswant = MAXCOL; @@ -3998,18 +4013,15 @@ void goto_byte(long cnt) /// Return 0 otherwise. int inc(pos_T *lp) { - char_u *p = ml_get_pos(lp); - - if (*p != NUL) { // still within line, move to next char (may be NUL) - if (has_mbyte) { - int l = (*mb_ptr2len)(p); + // when searching position may be set to end of a line + if (lp->col != MAXCOL) { + const char_u *const p = ml_get_pos(lp); + if (*p != NUL) { // still within line, move to next char (may be NUL) + const int l = utfc_ptr2len(p); lp->col += l; - return (p[l] != NUL) ? 0 : 2; + return ((p[l] != NUL) ? 0 : 2); } - lp->col++; - lp->coladd = 0; - return (p[1] != NUL) ? 0 : 2; } if (lp->lnum != curbuf->b_ml.ml_line_count) { // there is a next line lp->col = 0; @@ -4033,27 +4045,33 @@ int incl(pos_T *lp) int dec(pos_T *lp) { - char_u *p; - lp->coladd = 0; - if (lp->col > 0) { // still within line + if (lp->col == MAXCOL) { + // past end of line + char_u *p = ml_get(lp->lnum); + lp->col = (colnr_T)STRLEN(p); + lp->col -= utf_head_off(p, p + lp->col); + return 0; + } + + if (lp->col > 0) { + // still within line lp->col--; - if (has_mbyte) { - p = ml_get(lp->lnum); - lp->col -= (*mb_head_off)(p, p + lp->col); - } + char_u *p = ml_get(lp->lnum); + lp->col -= utf_head_off(p, p + lp->col); return 0; } - if (lp->lnum > 1) { // there is a prior line + if (lp->lnum > 1) { + // there is a prior line lp->lnum--; - p = ml_get(lp->lnum); + char_u *p = ml_get(lp->lnum); lp->col = (colnr_T)STRLEN(p); - if (has_mbyte) { - lp->col -= (*mb_head_off)(p, p + lp->col); - } + lp->col -= utf_head_off(p, p + lp->col); return 1; } - return -1; // at start of file + + // at start of file + return -1; } /// Same as dec(), but skip NUL at the end of non-empty lines. diff --git a/src/nvim/memory.c b/src/nvim/memory.c index b2aef13946..8789075c44 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -10,6 +10,7 @@ #include "nvim/vim.h" #include "nvim/eval.h" +#include "nvim/highlight.h" #include "nvim/memfile.h" #include "nvim/memory.h" #include "nvim/message.h" @@ -618,7 +619,6 @@ void free_all_mem(void) /* Obviously named calls. */ free_all_autocmds(); - free_all_options(); free_all_marks(); alist_clear(&global_alist); free_homedir(); @@ -656,6 +656,9 @@ void free_all_mem(void) /* Destroy all windows. Must come before freeing buffers. */ win_free_all(); + // Free all option values. Must come after closing windows. + free_all_options(); + free_cmdline_buf(); /* Clear registers. */ @@ -696,7 +699,7 @@ void free_all_mem(void) /* screenlines (can't display anything now!) */ free_screenlines(); - clear_hl_tables(); + clear_hl_tables(false); list_free_log(); } diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 968962c894..1c54db10eb 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -63,8 +63,8 @@ ex_menu(exarg_T *eap) char_u *p; int i; long pri_tab[MENUDEPTH + 1]; - int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu - * disable */ + TriState enable = kNone; // kTrue for "menu enable", + // kFalse for "menu disable vimmenu_T menuarg; modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu); @@ -133,10 +133,10 @@ ex_menu(exarg_T *eap) * Check for "disable" or "enable" argument. */ if (STRNCMP(arg, "enable", 6) == 0 && ascii_iswhite(arg[6])) { - enable = TRUE; + enable = kTrue; arg = skipwhite(arg + 6); } else if (STRNCMP(arg, "disable", 7) == 0 && ascii_iswhite(arg[7])) { - enable = FALSE; + enable = kFalse; arg = skipwhite(arg + 7); } @@ -160,22 +160,21 @@ ex_menu(exarg_T *eap) /* * If there is only a menu name, display menus with that name. */ - if (*map_to == NUL && !unmenu && enable == MAYBE) { + if (*map_to == NUL && !unmenu && enable == kNone) { show_menus(menu_path, modes); goto theend; - } else if (*map_to != NUL && (unmenu || enable != MAYBE)) { + } else if (*map_to != NUL && (unmenu || enable != kNone)) { EMSG(_(e_trailing)); goto theend; } - if (enable != MAYBE) { - /* - * Change sensitivity of the menu. - * For the PopUp menu, remove a menu for each mode separately. - * Careful: menu_nable_recurse() changes menu_path. - */ - if (STRCMP(menu_path, "*") == 0) /* meaning: do all menus */ + if (enable != kNone) { + // Change sensitivity of the menu. + // For the PopUp menu, remove a menu for each mode separately. + // Careful: menu_nable_recurse() changes menu_path. + if (STRCMP(menu_path, "*") == 0) { // meaning: do all menus menu_path = (char_u *)""; + } if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) @@ -1187,7 +1186,7 @@ get_menu_cmd_modes( modes = MENU_NORMAL_MODE; break; } - /* FALLTHROUGH */ + FALLTHROUGH; default: cmd--; if (forceit) { diff --git a/src/nvim/message.c b/src/nvim/message.c index 9d4d421941..10f4905fb2 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -331,6 +331,7 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen) */ int smsg(char *s, ...) + FUNC_ATTR_PRINTF(1, 2) { va_list arglist; @@ -341,6 +342,7 @@ int smsg(char *s, ...) } int smsg_attr(int attr, char *s, ...) + FUNC_ATTR_PRINTF(2, 3) { va_list arglist; @@ -541,7 +543,7 @@ int emsg(const char_u *s_) // Reset msg_silent, an error causes messages to be switched back on. msg_silent = 0; - cmd_silent = FALSE; + cmd_silent = false; if (global_busy) { // break :global command global_busy++; @@ -550,7 +552,7 @@ int emsg(const char_u *s_) if (p_eb) { beep_flush(); // also includes flush_buffers() } else { - flush_buffers(false); // flush internal buffers + flush_buffers(FLUSH_MINIMAL); // flush internal buffers } did_emsg = true; // flag for DoOneCmd() } @@ -581,6 +583,7 @@ void emsg_invreg(int name) /// Print an error message with unknown number of arguments bool emsgf(const char *const fmt, ...) + FUNC_ATTR_PRINTF(1, 2) { bool ret; @@ -610,7 +613,7 @@ static bool emsgfv(const char *fmt, va_list ap) /// detected when fuzzing vim. void iemsg(const char *s) { - msg((char_u *)s); + emsg((char_u *)s); #ifdef ABORT_ON_INTERNAL_ERROR abort(); #endif @@ -644,6 +647,7 @@ static void msg_emsgf_event(void **argv) } void msg_schedule_emsgf(const char *const fmt, ...) + FUNC_ATTR_PRINTF(1, 2) { va_list ap; va_start(ap, fmt); @@ -699,8 +703,8 @@ char_u *msg_may_trunc(int force, char_u *s) return s; for (n = 0; size >= room; ) { - size -= (*mb_ptr2cells)(s + n); - n += (*mb_ptr2len)(s + n); + size -= utf_ptr2cells(s + n); + n += utfc_ptr2len(s + n); } --n; } @@ -828,12 +832,11 @@ void msg_end_prompt(void) lines_left = -1; } -/* - * wait for the user to hit a key (normally a return) - * if 'redraw' is TRUE, clear and redraw the screen - * if 'redraw' is FALSE, just redraw the screen - * if 'redraw' is -1, don't redraw at all - */ +/// wait for the user to hit a key (normally a return) +/// +/// if 'redraw' is true, redraw the entire screen NOT_VALID +/// if 'redraw' is false, do a normal redraw +/// if 'redraw' is -1, don't redraw at all void wait_return(int redraw) { int c; @@ -843,8 +846,9 @@ void wait_return(int redraw) int save_Recording; FILE *save_scriptout; - if (redraw == TRUE) - must_redraw = CLEAR; + if (redraw == true) { + redraw_all_later(NOT_VALID); + } /* If using ":silent cmd", don't wait for a return. Also don't set * need_wait_return to do it later. */ @@ -1121,7 +1125,7 @@ void msg_putchar_attr(int c, int attr) buf[2] = (char)K_THIRD(c); buf[3] = NUL; } else { - buf[(*mb_char2bytes)(c, (char_u *)buf)] = NUL; + buf[utf_char2bytes(c, (char_u *)buf)] = NUL; } msg_puts_attr(buf, attr); } @@ -1219,10 +1223,10 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr) // Don't include composing chars after the end. mb_l = utfc_ptr2len_len((char_u *)str, len + 1); if (mb_l > 1) { - c = (*mb_ptr2char)((char_u *)str); + c = utf_ptr2char((char_u *)str); if (vim_isprintc(c)) { // Printable multi-byte char: count the cells. - retval += (*mb_ptr2cells)((char_u *)str); + retval += utf_ptr2cells((char_u *)str); } else { // Unprintable multi-byte char: print the printable chars so // far and the translation of the unprintable char. @@ -1471,18 +1475,20 @@ void msg_prt_line(char_u *s, int list) while (!got_int) { if (n_extra > 0) { - --n_extra; - if (c_extra) + n_extra--; + if (c_extra) { c = c_extra; - else + } else { + assert(p_extra != NULL); c = *p_extra++; - } else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1) { - col += (*mb_ptr2cells)(s); + } + } else if ((l = utfc_ptr2len(s)) > 1) { + col += utf_ptr2cells(s); char buf[MB_MAXBYTES + 1]; if (lcs_nbsp != NUL && list - && (mb_ptr2char(s) == 160 || mb_ptr2char(s) == 0x202f)) { - mb_char2bytes(lcs_nbsp, (char_u *)buf); - buf[(*mb_ptr2len)((char_u *)buf)] = NUL; + && (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) { + utf_char2bytes(lcs_nbsp, (char_u *)buf); + buf[utfc_ptr2len((char_u *)buf)] = NUL; } else { memmove(buf, s, (size_t)l); buf[l] = NUL; @@ -1549,7 +1555,7 @@ static char_u *screen_puts_mbyte(char_u *s, int l, int attr) int cw; msg_didout = true; // remember that line is not empty - cw = (*mb_ptr2cells)(s); + cw = utf_ptr2cells(s); if (cw > 1 && (cmdmsg_rl ? msg_col <= 1 : msg_col == Columns - 1)) { // Doesn't fit, print a highlighted '>' to fill it up. @@ -1672,7 +1678,7 @@ void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr) /// @param[in] attr Highlight attributes. /// @param[in] fmt Format string. void msg_printf_attr(const int attr, const char *const fmt, ...) - FUNC_ATTR_NONNULL_ARG(2) + FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PRINTF(2, 3) { static char msgbuf[IOSIZE]; @@ -1711,14 +1717,12 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, && (*s == '\n' || (cmdmsg_rl ? (msg_col <= 1 || (*s == TAB && msg_col <= 7) - || (has_mbyte - && (*mb_ptr2cells)(s) > 1 + || (utf_ptr2cells(s) > 1 && msg_col <= 2)) : (msg_col + t_col >= Columns - 1 || (*s == TAB && msg_col + t_col >= ((Columns - 1) & ~7)) - || (has_mbyte - && (*mb_ptr2cells)(s) > 1 + || (utf_ptr2cells(s) > 1 && msg_col + t_col >= Columns - 2))))) { // The screen is scrolled up when at the last row (some terminals // scroll automatically, some don't. To avoid problems we scroll @@ -1787,7 +1791,7 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, wrap = *s == '\n' || msg_col + t_col >= Columns - || (has_mbyte && (*mb_ptr2cells)(s) > 1 + || (utf_ptr2cells(s) > 1 && msg_col + t_col >= Columns - 1) ; if (t_col > 0 && (wrap || *s == '\r' || *s == '\b' @@ -1821,7 +1825,7 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, } else if (*s == BELL) { // beep (from ":sh") vim_beep(BO_SH); } else if (*s >= 0x20) { // printable char - cw = mb_ptr2cells(s); + cw = utf_ptr2cells(s); if (maxlen >= 0) { // avoid including composing chars after the end l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); @@ -1888,12 +1892,13 @@ static void msg_scroll_up(void) fill_msgsep, fill_msgsep, HL_ATTR(HLF_MSGSEP)); } int nscroll = MIN(msg_scrollsize()+1, Rows); - ui_call_set_scroll_region(Rows-nscroll, Rows-1, 0, Columns-1); - screen_del_lines(Rows-nscroll, 0, 1, nscroll, NULL); - ui_reset_scroll_region(); + screen_del_lines(Rows-nscroll, 1, Rows, 0, Columns); } else { - screen_del_lines(0, 0, 1, (int)Rows, NULL); + screen_del_lines(0, 1, (int)Rows, 0, Columns); } + // TODO(bfredl): when msgsep display is properly batched, this fill should be + // eliminated. + screen_fill(Rows-1, Rows, 0, (int)Columns, ' ', ' ', 0); } /* @@ -2259,8 +2264,8 @@ static int do_more_prompt(int typed_char) skip_redraw = TRUE; /* skip redraw once */ need_wait_return = FALSE; /* don't wait in main() */ } - /*FALLTHROUGH*/ - case 'q': /* quit */ + FALLTHROUGH; + case 'q': // quit case Ctrl_C: case ESC: if (confirm_msg_used) { @@ -2307,9 +2312,10 @@ static int do_more_prompt(int typed_char) mp_last = msg_sb_start(mp_last->sb_prev); } - if (toscroll == -1 && screen_ins_lines(0, 0, 1, - (int)Rows, NULL) == OK) { - /* display line at top */ + if (toscroll == -1 + && screen_ins_lines(0, 1, (int)Rows, 0, (int)Columns) == OK) { + screen_fill(0, 1, 0, (int)Columns, ' ', ' ', 0); + // display line at top (void)disp_sb_line(0, mp); } else { /* redisplay all lines */ @@ -2868,14 +2874,12 @@ do_dialog ( // Make the character lowercase, as chars in "hotkeys" are. c = mb_tolower(c); retval = 1; - for (i = 0; hotkeys[i]; ++i) { - if (has_mbyte) { - if ((*mb_ptr2char)(hotkeys + i) == c) - break; - i += (*mb_ptr2len)(hotkeys + i) - 1; - } else if (hotkeys[i] == c) + for (i = 0; hotkeys[i]; i++) { + if (utf_ptr2char(hotkeys + i) == c) { break; - ++retval; + } + i += utfc_ptr2len(hotkeys + i) - 1; + retval++; } if (hotkeys[i]) break; @@ -2907,25 +2911,13 @@ copy_char ( int lowercase /* make character lower case */ ) { - int len; - int c; - - if (has_mbyte) { - if (lowercase) { - c = mb_tolower((*mb_ptr2char)(from)); - return (*mb_char2bytes)(c, to); - } else { - len = (*mb_ptr2len)(from); - memmove(to, from, (size_t)len); - return len; - } - } else { - if (lowercase) - *to = (char_u)TOLOWER_LOC(*from); - else - *to = *from; - return 1; + if (lowercase) { + int c = mb_tolower(utf_ptr2char(from)); + return utf_char2bytes(c, to); } + int len = utfc_ptr2len(from); + memmove(to, from, (size_t)len); + return len; } #define HAS_HOTKEY_LEN 30 diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 3d7399f151..4032210213 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -98,7 +98,7 @@ open_line ( colnr_T newcol = 0; // new cursor column int newindent = 0; // auto-indent of the new line bool trunc_line = false; // truncate current line afterwards - bool retval = false; // return value, default is false + bool retval = false; // return value int extra_len = 0; // length of p_extra string int lead_len; // length of comment leader char_u *lead_flags; // position in 'comments' for comment leader @@ -165,8 +165,8 @@ open_line ( *p_extra = NUL; } - u_clearline(); /* cannot do "U" command when adding lines */ - did_si = FALSE; + u_clearline(); // cannot do "U" command when adding lines + did_si = false; ai_col = 0; /* @@ -286,8 +286,8 @@ open_line ( * checking for "if" and the like. */ if (last_char == '{') { - did_si = TRUE; /* do indent */ - no_si = TRUE; /* don't delete it when '{' typed */ + did_si = true; // do indent + no_si = true; // don't delete it when '{' typed } /* * Look for "if" and the like, use 'cinwords'. @@ -296,7 +296,7 @@ open_line ( */ else if (last_char != ';' && last_char != '}' && cin_is_cinword(ptr)) - did_si = TRUE; + did_si = true; } } else { // dir == BACKWARD // Skip preprocessor directives, unless they are @@ -320,17 +320,19 @@ open_line ( } } p = skipwhite(ptr); - if (*p == '}') /* if line starts with '}': do indent */ - did_si = TRUE; - else /* can delete indent when '{' typed */ - can_si_back = TRUE; + if (*p == '}') { // if line starts with '}': do indent + did_si = true; + } else { // can delete indent when '{' typed + can_si_back = true; + } } curwin->w_cursor = old_cursor; } - if (do_si) - can_si = TRUE; + if (do_si) { + can_si = true; + } - did_ai = TRUE; + did_ai = true; } /* @@ -546,7 +548,7 @@ open_line ( /* blank-out any other chars from the old leader. */ while (--p >= leader) { - int l = mb_head_off(leader, p); + int l = utf_head_off(leader, p); if (l > 1) { p -= l; @@ -665,7 +667,7 @@ open_line ( } } - did_si = can_si = FALSE; + did_si = can_si = false; } else if (comment_end != NULL) { // We have finished a comment, so we don't use the leader. // If this was a C-comment and 'ai' or 'si' is set do a normal @@ -699,17 +701,17 @@ open_line ( replace_push(NUL); /* end of extra blanks */ if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES)) { while ((*p_extra == ' ' || *p_extra == '\t') - && (!enc_utf8 - || !utf_iscomposing(utf_ptr2char(p_extra + 1))) - ) { - if (REPLACE_NORMAL(State)) + && !utf_iscomposing(utf_ptr2char(p_extra + 1))) { + if (REPLACE_NORMAL(State)) { replace_push(*p_extra); - ++p_extra; - ++less_cols_off; + } + p_extra++; + less_cols_off++; } } - if (*p_extra != NUL) - did_ai = FALSE; /* append some text, don't truncate now */ + if (*p_extra != NUL) { + did_ai = false; // append some text, don't truncate now + } /* columns for marks adjusted for removed columns */ less_cols = (int)(p_extra - saved_line); @@ -736,7 +738,7 @@ open_line ( } STRCAT(leader, p_extra); p_extra = leader; - did_ai = TRUE; /* So truncating blanks works with comments */ + did_ai = true; // So truncating blanks works with comments less_cols -= lead_len; } else end_comment_pending = NUL; /* turns out there was no leader */ @@ -769,7 +771,7 @@ open_line ( (void)u_save_cursor(); /* errors are ignored! */ vr_lines_changed++; } - ml_replace(curwin->w_cursor.lnum, p_extra, TRUE); + ml_replace(curwin->w_cursor.lnum, p_extra, true); changed_bytes(curwin->w_cursor.lnum, 0); curwin->w_cursor.lnum--; did_append = FALSE; @@ -812,8 +814,9 @@ open_line ( } } newcol += curwin->w_cursor.col; - if (no_si) - did_si = FALSE; + if (no_si) { + did_si = false; + } } /* @@ -828,12 +831,13 @@ open_line ( if (dir == FORWARD) { if (trunc_line || (State & INSERT)) { - /* truncate current line at cursor */ + // truncate current line at cursor saved_line[curwin->w_cursor.col] = NUL; - /* Remove trailing white space, unless OPENLINE_KEEPTRAIL used. */ - if (trunc_line && !(flags & OPENLINE_KEEPTRAIL)) + // Remove trailing white space, unless OPENLINE_KEEPTRAIL used. + if (trunc_line && !(flags & OPENLINE_KEEPTRAIL)) { truncate_spaces(saved_line); - ml_replace(curwin->w_cursor.lnum, saved_line, FALSE); + } + ml_replace(curwin->w_cursor.lnum, saved_line, false); saved_line = NULL; if (did_append) { changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col, @@ -880,8 +884,7 @@ open_line ( && curbuf->b_p_lisp && curbuf->b_p_ai) { fixthisline(get_lisp_indent); - p = get_cursor_line_ptr(); - ai_col = (colnr_T)(skipwhite(p) - p); + ai_col = (colnr_T)getwhitecols_curline(); } /* * May do indenting after opening a new line. @@ -894,8 +897,7 @@ open_line ( ? KEY_OPEN_FORW : KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) { do_c_expr_indent(); - p = get_cursor_line_ptr(); - ai_col = (colnr_T)(skipwhite(p) - p); + ai_col = (colnr_T)getwhitecols_curline(); } if (vreplace_mode != 0) State = vreplace_mode; @@ -909,8 +911,8 @@ open_line ( /* Put new line in p_extra */ p_extra = vim_strsave(get_cursor_line_ptr()); - /* Put back original line */ - ml_replace(curwin->w_cursor.lnum, next_line, FALSE); + // Put back original line + ml_replace(curwin->w_cursor.lnum, next_line, false); /* Insert new stuff into line again */ curwin->w_cursor.col = 0; @@ -920,7 +922,7 @@ open_line ( next_line = NULL; } - retval = TRUE; /* success! */ + retval = true; // success! theend: curbuf->b_p_pi = saved_pi; xfree(saved_line); @@ -1203,16 +1205,15 @@ int get_last_leader_offset(char_u *line, char_u **flags) /* * Return the number of window lines occupied by buffer line "lnum". */ -int plines(linenr_T lnum) +int plines(const linenr_T lnum) { - return plines_win(curwin, lnum, TRUE); + return plines_win(curwin, lnum, true); } -int -plines_win ( - win_T *wp, - linenr_T lnum, - int winheight /* when TRUE limit to window height */ +int plines_win( + win_T *const wp, + const linenr_T lnum, + const bool winheight // when true limit to window height ) { /* Check for filler lines above this buffer line. When folded the result @@ -1220,34 +1221,34 @@ plines_win ( return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum); } -int plines_nofill(linenr_T lnum) +int plines_nofill(const linenr_T lnum) { - return plines_win_nofill(curwin, lnum, TRUE); + return plines_win_nofill(curwin, lnum, true); } -int -plines_win_nofill ( - win_T *wp, - linenr_T lnum, - int winheight /* when TRUE limit to window height */ +int plines_win_nofill( + win_T *const wp, + const linenr_T lnum, + const bool winheight // when true limit to window height ) { - int lines; - - if (!wp->w_p_wrap) + if (!wp->w_p_wrap) { return 1; + } - if (wp->w_width == 0) + if (wp->w_width == 0) { return 1; + } - /* A folded lines is handled just like an empty line. */ - /* NOTE: Caller must handle lines that are MAYBE folded. */ - if (lineFolded(wp, lnum) == TRUE) + // A folded lines is handled just like an empty line. + if (lineFolded(wp, lnum)) { return 1; + } - lines = plines_win_nofold(wp, lnum); - if (winheight > 0 && lines > wp->w_height) + const int lines = plines_win_nofold(wp, lnum); + if (winheight && lines > wp->w_height) { return wp->w_height; + } return lines; } @@ -1347,11 +1348,12 @@ int plines_m_win(win_T *wp, linenr_T first, linenr_T last) ++count; /* count 1 for "+-- folded" line */ first += x; } else { - if (first == wp->w_topline) - count += plines_win_nofill(wp, first, TRUE) + wp->w_topfill; - else - count += plines_win(wp, first, TRUE); - ++first; + if (first == wp->w_topline) { + count += plines_win_nofill(wp, first, true) + wp->w_topfill; + } else { + count += plines_win(wp, first, true); + } + first++; } } return count; @@ -1396,7 +1398,7 @@ void ins_bytes_len(char_u *p, size_t len) void ins_char(int c) { char_u buf[MB_MAXBYTES + 1]; - size_t n = (size_t)(*mb_char2bytes)(c, buf); + size_t n = (size_t)utf_char2bytes(c, buf); // When "c" is 0x100, 0x200, etc. we don't want to insert a NUL byte. // Happens for CTRL-Vu9900. @@ -1494,8 +1496,8 @@ void ins_char_bytes(char_u *buf, size_t charlen) p[i] = ' '; } - /* Replace the line in the buffer. */ - ml_replace(lnum, newp, FALSE); + // Replace the line in the buffer. + ml_replace(lnum, newp, false); // mark the buffer as changed and prepare for displaying changed_bytes(lnum, (colnr_T)col); @@ -1508,7 +1510,7 @@ void ins_char_bytes(char_u *buf, size_t charlen) && msg_silent == 0 && !ins_compl_active() ) { - showmatch(mb_ptr2char(buf)); + showmatch(utf_ptr2char(buf)); } if (!p_ri || (State & REPLACE_FLAG)) { @@ -1545,19 +1547,17 @@ void ins_str(char_u *s) memmove(newp, oldp, (size_t)col); memmove(newp + col, s, (size_t)newlen); memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1)); - ml_replace(lnum, newp, FALSE); + ml_replace(lnum, newp, false); changed_bytes(lnum, col); curwin->w_cursor.col += newlen; } -/* - * Delete one character under the cursor. - * If "fixpos" is TRUE, don't leave the cursor on the NUL after the line. - * Caller must have prepared for undo. - * - * return FAIL for failure, OK otherwise - */ -int del_char(int fixpos) +// Delete one character under the cursor. +// If "fixpos" is true, don't leave the cursor on the NUL after the line. +// Caller must have prepared for undo. +// +// return FAIL for failure, OK otherwise +int del_char(bool fixpos) { if (has_mbyte) { /* Make sure the cursor is at the start of a character. */ @@ -1605,11 +1605,19 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine) char_u *oldp = ml_get(lnum); colnr_T oldlen = (colnr_T)STRLEN(oldp); - /* - * Can't do anything when the cursor is on the NUL after the line. - */ - if (col >= oldlen) + // Can't do anything when the cursor is on the NUL after the line. + if (col >= oldlen) { + return FAIL; + } + // If "count" is zero there is nothing to do. + if (count == 0) { + return OK; + } + // If "count" is negative the caller must be doing something wrong. + if (count < 1) { + IEMSGN("E950: Invalid count for del_bytes(): %ld", count); return FAIL; + } /* If 'delcombine' is set and deleting (less than) one character, only * delete the last combining character. */ @@ -1644,9 +1652,7 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine) ) { --curwin->w_cursor.col; curwin->w_cursor.coladd = 0; - if (has_mbyte) - curwin->w_cursor.col -= - (*mb_head_off)(oldp, oldp + curwin->w_cursor.col); + curwin->w_cursor.col -= utf_head_off(oldp, oldp + curwin->w_cursor.col); } count = oldlen - col; movelen = 1; @@ -1663,8 +1669,9 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine) memmove(newp, oldp, (size_t)col); } memmove(newp + col, oldp + col + count, (size_t)movelen); - if (!was_alloced) - ml_replace(lnum, newp, FALSE); + if (!was_alloced) { + ml_replace(lnum, newp, false); + } /* mark the buffer as changed and prepare for displaying */ changed_bytes(lnum, curwin->w_cursor.col); @@ -1745,11 +1752,11 @@ del_lines ( int gchar_pos(pos_T *pos) { - char_u *ptr = ml_get_pos(pos); - - if (has_mbyte) - return (*mb_ptr2char)(ptr); - return (int)*ptr; + // When searching columns is sometimes put at the end of a line. + if (pos->col == MAXCOL) { + return NUL; + } + return utf_ptr2char(ml_get_pos(pos)); } /* @@ -2385,16 +2392,12 @@ int get_keystroke(void) } break; } - if (has_mbyte) { - if (MB_BYTE2LEN(n) > len) - continue; /* more bytes to get */ - buf[len >= buflen ? buflen - 1 : len] = NUL; - n = (*mb_ptr2char)(buf); + if (MB_BYTE2LEN(n) > len) { + // more bytes to get. + continue; } -#ifdef UNIX - if (n == intr_char) - n = ESC; -#endif + buf[len >= buflen ? buflen - 1 : len] = NUL; + n = utf_ptr2char(buf); break; } xfree(buf); @@ -2479,7 +2482,7 @@ int prompt_for_number(int *mouse_used) save_cmdline_row = cmdline_row; cmdline_row = 0; save_State = State; - State = CMDLINE; + State = ASKMORE; // prevents a screen update when using a timer i = get_number(TRUE, mouse_used); if (KeyTyped) { @@ -2545,7 +2548,7 @@ void msgmore(long n) void beep_flush(void) { if (emsg_silent == 0) { - flush_buffers(false); + flush_buffers(FLUSH_MINIMAL); vim_beep(BO_ERROR); } } @@ -2704,8 +2707,10 @@ void fast_breakcheck(void) } } -// os_call_shell wrapper. Handles 'verbose', :profile, and v:shell_error. -// Invalidates cached tags. +/// os_call_shell() wrapper. Handles 'verbose', :profile, and v:shell_error. +/// Invalidates cached tags. +/// +/// @return shell command exit code int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg) { int retval; @@ -2713,8 +2718,8 @@ int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg) if (p_verbose > 3) { verbose_enter(); - smsg(_("Calling shell to execute: \"%s\""), cmd == NULL ? p_sh : cmd); - ui_linefeed(); + smsg(_("Executing command: \"%s\""), cmd == NULL ? p_sh : cmd); + msg_putchar('\n'); verbose_leave(); } @@ -2836,4 +2841,3 @@ int goto_im(void) { return p_im && stuff_empty() && typebuf_typed(); } - diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 8c615f52e7..3c792326a4 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -125,6 +125,9 @@ retnomove: // find the window where the row is in wp = mouse_find_win(&row, &col); + if (wp == NULL) { + return IN_UNKNOWN; + } dragwin = NULL; // winpos and height may change in win_enter()! if (row >= wp->w_height) { // In (or below) status line @@ -427,6 +430,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump) // Find the window at screen position "*rowp" and "*colp". The positions are // updated to become relative to the top-left of the window. +// Returns NULL when something is wrong. win_T *mouse_find_win(int *rowp, int *colp) { frame_T *fp; @@ -450,7 +454,14 @@ win_T *mouse_find_win(int *rowp, int *colp) } } } - return fp->fr_win; + // When using a timer that closes a window the window might not actually + // exist. + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp == fp->fr_win) { + return wp; + } + } + return NULL; } /* diff --git a/src/nvim/move.c b/src/nvim/move.c index 41859a489f..3a29851ee6 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -16,7 +16,6 @@ #include <inttypes.h> #include <stdbool.h> -#include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/move.h" #include "nvim/charset.h" @@ -97,16 +96,34 @@ static void comp_botline(win_T *wp) set_empty_rows(wp, done); } -/* -* Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is -* set. -*/ +void reset_cursorline(void) +{ + curwin->w_last_cursorline = 0; +} + +// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set. static void redraw_for_cursorline(win_T *wp) { if ((wp->w_p_rnu || wp->w_p_cul) && (wp->w_valid & VALID_CROW) == 0 && !pum_visible()) { - redraw_win_later(wp, SOME_VALID); + if (wp->w_p_rnu) { + // win_line() will redraw the number column only. + redraw_win_later(wp, VALID); + } + if (wp->w_p_cul) { + if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0) { + // "w_last_cursorline" may be outdated, worst case we redraw + // too much. This is optimized for moving the cursor around in + // the current window. + redrawWinline(wp, wp->w_last_cursorline, false); + redrawWinline(wp, wp->w_cursor.lnum, false); + redraw_win_later(wp, VALID); + } else { + redraw_win_later(wp, SOME_VALID); + } + wp->w_last_cursorline = wp->w_cursor.lnum; + } } } @@ -901,9 +918,9 @@ void curs_columns( extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width; if (extra > 0) { - win_ins_lines(curwin, 0, extra, false, false); + win_ins_lines(curwin, 0, extra); } else if (extra < 0) { - win_del_lines(curwin, 0, -extra, false, false); + win_del_lines(curwin, 0, -extra); } } else { curwin->w_skipcol = 0; @@ -1726,7 +1743,7 @@ void cursor_correct(void) * * return FAIL for failure, OK otherwise */ -int onepage(int dir, long count) +int onepage(Direction dir, long count) { long n; int retval = OK; @@ -1884,16 +1901,18 @@ int onepage(int dir, long count) } curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL); - /* - * Avoid the screen jumping up and down when 'scrolloff' is non-zero. - * But make sure we scroll at least one line (happens with mix of long - * wrapping lines and non-wrapping line). - */ - if (retval == OK && dir == FORWARD && check_top_offset()) { - scroll_cursor_top(1, false); - if (curwin->w_topline <= old_topline - && old_topline < curbuf->b_ml.ml_line_count) { - curwin->w_topline = old_topline + 1; + if (retval == OK && dir == FORWARD) { + // Avoid the screen jumping up and down when 'scrolloff' is non-zero. + // But make sure we scroll at least one line (happens with mix of long + // wrapping lines and non-wrapping line). + if (check_top_offset()) { + scroll_cursor_top(1, false); + if (curwin->w_topline <= old_topline + && old_topline < curbuf->b_ml.ml_line_count) { + curwin->w_topline = old_topline + 1; + (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); + } + } else if (curwin->w_botline > curbuf->b_ml.ml_line_count) { (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL); } } @@ -2166,9 +2185,7 @@ void do_check_cursorbind(void) restart_edit = restart_edit_save; } // Correct cursor for multi-byte character. - if (has_mbyte) { - mb_adjust_cursor(); - } + mb_adjust_cursor(); redraw_later(VALID); // Only scroll when 'scrollbind' hasn't done this. diff --git a/src/nvim/move.h b/src/nvim/move.h index 00fbcc580f..3670dc9086 100644 --- a/src/nvim/move.h +++ b/src/nvim/move.h @@ -2,8 +2,7 @@ #define NVIM_MOVE_H #include <stdbool.h> -#include "nvim/buffer_defs.h" -#include "nvim/pos.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "move.h.generated.h" diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c index 3244d83a93..3356cdc61e 100644 --- a/src/nvim/msgpack_rpc/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -350,6 +350,7 @@ static void handle_request(Channel *channel, msgpack_object *request) } } else { multiqueue_put(channel->events, on_request_event, 1, evdata); + DLOG("RPC: scheduled %.*s", method->via.bin.size, method->via.bin.ptr); } } @@ -505,6 +506,11 @@ end: static void unsubscribe(Channel *channel, char *event) { char *event_string = pmap_get(cstr_t)(event_strings, event); + if (!event_string) { + WLOG("RPC: ch %" PRIu64 ": tried to unsubscribe unknown event '%s'", + channel->id, event); + return; + } pmap_del(cstr_t)(channel->rpc.subscribed_events, event_string); map_foreach_value(channels, channel, { @@ -738,4 +744,3 @@ static void log_msg_close(FILE *f, msgpack_object msg) log_unlock(); } #endif - diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 570368991a..f87de52a82 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1269,7 +1269,8 @@ static void normal_redraw(NormalState *s) xfree(p); } - if (need_fileinfo) { // show file info after redraw + // show fileinfo after redraw + if (need_fileinfo && !shortmess(SHM_FILEINFO)) { fileinfo(false, true, false); need_fileinfo = false; } @@ -1867,7 +1868,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) } else { bangredo = true; // do_bang() will put cmd in redo buffer. } - // fallthrough + FALLTHROUGH; case OP_INDENT: case OP_COLON: @@ -2015,7 +2016,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) default: clearopbeep(oap); } - virtual_op = MAYBE; + virtual_op = kNone; if (!gui_yank) { /* * if 'sol' not set, go back to old column for some commands @@ -2090,7 +2091,7 @@ static void op_colon(oparg_T *oap) */ static void op_function(oparg_T *oap) { - int save_virtual_op = virtual_op; + const TriState save_virtual_op = virtual_op; if (*p_opfunc == NUL) EMSG(_("E774: 'operatorfunc' is empty")); @@ -2113,7 +2114,7 @@ static void op_function(oparg_T *oap) // Reset virtual_op so that 'virtualedit' can be changed in the // function. - virtual_op = MAYBE; + virtual_op = kNone; (void)call_func_retnr(p_opfunc, 1, argv, false); @@ -2858,9 +2859,10 @@ static void find_start_of_word(pos_T *pos) while (pos->col > 0) { col = pos->col - 1; - col -= (*mb_head_off)(line, line + col); - if (get_mouse_class(line + col) != cclass) + col -= utf_head_off(line, line + col); + if (get_mouse_class(line + col) != cclass) { break; + } pos->col = col; } } @@ -2877,8 +2879,8 @@ static void find_end_of_word(pos_T *pos) line = ml_get(pos->lnum); if (*p_sel == 'e' && pos->col > 0) { - --pos->col; - pos->col -= (*mb_head_off)(line, line + pos->col); + pos->col--; + pos->col -= utf_head_off(line, line + pos->col); } cclass = get_mouse_class(line + pos->col); while (line[pos->col] != NUL) { @@ -2990,6 +2992,43 @@ void reset_VIsual(void) } } +// Check for a balloon-eval special item to include when searching for an +// identifier. When "dir" is BACKWARD "ptr[-1]" must be valid! +// Returns true if the character at "*ptr" should be included. +// "dir" is FORWARD or BACKWARD, the direction of searching. +// "*colp" is in/decremented if "ptr[-dir]" should also be included. +// "bnp" points to a counter for square brackets. +static bool find_is_eval_item( + const char_u *const ptr, + int *const colp, + int *const bnp, + const int dir) +{ + // Accept everything inside []. + if ((*ptr == ']' && dir == BACKWARD) || (*ptr == '[' && dir == FORWARD)) { + *bnp += 1; + } + if (*bnp > 0) { + if ((*ptr == '[' && dir == BACKWARD) || (*ptr == ']' && dir == FORWARD)) { + *bnp -= 1; + } + return true; + } + + // skip over "s.var" + if (*ptr == '.') { + return true; + } + + // two-character item: s->var + if (ptr[dir == BACKWARD ? 0 : 1] == '>' + && ptr[dir == BACKWARD ? -1 : 0] == '-') { + *colp += dir; + return true; + } + return false; +} + /* * Find the identifier under or to the right of the cursor. * "find_type" can have one of three values: @@ -3030,6 +3069,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, int this_class = 0; int prev_class; int prevcol; + int bn = 0; // bracket nesting /* * if i == 0: try to find an identifier @@ -3041,71 +3081,62 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, * 1. skip to start of identifier/string */ col = startcol; - if (has_mbyte) { - while (ptr[col] != NUL) { - this_class = mb_get_class(ptr + col); - if (this_class != 0 && (i == 1 || this_class != 1)) - break; - col += (*mb_ptr2len)(ptr + col); + while (ptr[col] != NUL) { + // Stop at a ']' to evaluate "a[x]". + if ((find_type & FIND_EVAL) && ptr[col] == ']') { + break; } - } else - while (ptr[col] != NUL - && (i == 0 ? !vim_iswordc(ptr[col]) : ascii_iswhite(ptr[col])) - ) - ++col; - - - /* - * 2. Back up to start of identifier/string. - */ - if (has_mbyte) { - /* Remember class of character under cursor. */ this_class = mb_get_class(ptr + col); - while (col > 0 && this_class != 0) { - prevcol = col - 1 - (*mb_head_off)(ptr, ptr + col - 1); - prev_class = mb_get_class(ptr + prevcol); - if (this_class != prev_class - && (i == 0 - || prev_class == 0 - || (find_type & FIND_IDENT)) - ) - break; - col = prevcol; + if (this_class != 0 && (i == 1 || this_class != 1)) { + break; } + col += utfc_ptr2len(ptr + col); + } - /* If we don't want just any old string, or we've found an - * identifier, stop searching. */ - if (this_class > 2) - this_class = 2; - if (!(find_type & FIND_STRING) || this_class == 2) - break; - } else { - while (col > 0 - && ((i == 0 - ? vim_iswordc(ptr[col - 1]) - : (!ascii_iswhite(ptr[col - 1]) - && (!(find_type & FIND_IDENT) - || !vim_iswordc(ptr[col - 1])))) - )) - --col; + // When starting on a ']' count it, so that we include the '['. + bn = ptr[col] == ']'; - /* If we don't want just any old string, or we've found an - * identifier, stop searching. */ - if (!(find_type & FIND_STRING) || vim_iswordc(ptr[col])) + // + // 2. Back up to start of identifier/string. + // + // Remember class of character under cursor. + if ((find_type & FIND_EVAL) && ptr[col] == ']') { + this_class = mb_get_class((char_u *)"a"); + } else { + this_class = mb_get_class(ptr + col); + } + while (col > 0 && this_class != 0) { + prevcol = col - 1 - utf_head_off(ptr, ptr + col - 1); + prev_class = mb_get_class(ptr + prevcol); + if (this_class != prev_class + && (i == 0 + || prev_class == 0 + || (find_type & FIND_IDENT)) + && (!(find_type & FIND_EVAL) + || prevcol == 0 + || !find_is_eval_item(ptr + prevcol, &prevcol, &bn, BACKWARD))) { break; + } + col = prevcol; + } + + // If we don't want just any old string, or we've found an + // identifier, stop searching. + if (this_class > 2) { + this_class = 2; + } + if (!(find_type & FIND_STRING) || this_class == 2) { + break; } } - if (ptr[col] == NUL || (i == 0 && ( - has_mbyte ? this_class != 2 : - !vim_iswordc(ptr[col])))) { - /* - * didn't find an identifier or string - */ - if (find_type & FIND_STRING) + if (ptr[col] == NUL || (i == 0 && this_class != 2)) { + // Didn't find an identifier or string. + if (find_type & FIND_STRING) { EMSG(_("E348: No string under cursor")); - else + } else { EMSG(_(e_noident)); + } return 0; } ptr += col; @@ -3114,21 +3145,20 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, /* * 3. Find the end if the identifier/string. */ + bn = 0; + startcol -= col; col = 0; - if (has_mbyte) { - /* Search for point of changing multibyte character class. */ - this_class = mb_get_class(ptr); - while (ptr[col] != NUL - && ((i == 0 ? mb_get_class(ptr + col) == this_class - : mb_get_class(ptr + col) != 0) - )) - col += (*mb_ptr2len)(ptr + col); - } else - while ((i == 0 ? vim_iswordc(ptr[col]) - : (ptr[col] != NUL && !ascii_iswhite(ptr[col]))) - ) { - ++col; - } + // Search for point of changing multibyte character class. + this_class = mb_get_class(ptr); + while (ptr[col] != NUL + && ((i == 0 + ? mb_get_class(ptr + col) == this_class + : mb_get_class(ptr + col) != 0) + || ((find_type & FIND_EVAL) + && col <= (int)startcol + && find_is_eval_item(ptr + col, &col, &bn, FORWARD)))) { + col += utfc_ptr2len(ptr + col); + } assert(col >= 0); return (size_t)col; @@ -3994,8 +4024,12 @@ static void nv_mousescroll(cmdarg_T *cap) row = mouse_row; col = mouse_col; - /* find the window at the pointer coordinates */ - curwin = mouse_find_win(&row, &col); + // find the window at the pointer coordinates + win_T *const wp = mouse_find_win(&row, &col); + if (wp == NULL) { + return; + } + curwin = wp; curbuf = curwin->w_buffer; } @@ -4169,12 +4203,12 @@ dozet: else curwin->w_cursor.lnum = curwin->w_botline; } - /* FALLTHROUGH */ + FALLTHROUGH; case NL: case CAR: case K_KENTER: beginline(BL_WHITE | BL_FIX); - /* FALLTHROUGH */ + FALLTHROUGH; case 't': scroll_cursor_top(0, true); redraw_later(VALID); @@ -4183,7 +4217,7 @@ dozet: /* "z." and "zz": put cursor in middle of screen */ case '.': beginline(BL_WHITE | BL_FIX); - /* FALLTHROUGH */ + FALLTHROUGH; case 'z': scroll_cursor_halfway(true); redraw_later(VALID); @@ -4201,10 +4235,10 @@ dozet: curwin->w_cursor.lnum = 1; else curwin->w_cursor.lnum = curwin->w_topline - 1; - /* FALLTHROUGH */ + FALLTHROUGH; case '-': beginline(BL_WHITE | BL_FIX); - /* FALLTHROUGH */ + FALLTHROUGH; case 'b': scroll_cursor_bot(0, true); redraw_later(VALID); @@ -4214,7 +4248,7 @@ dozet: /* "zH" - scroll screen right half-page */ case 'H': cap->count1 *= curwin->w_width / 2; - /* FALLTHROUGH */ + FALLTHROUGH; /* "zh" - scroll screen to the right */ case 'h': @@ -4230,7 +4264,7 @@ dozet: /* "zL" - scroll screen left half-page */ case 'L': cap->count1 *= curwin->w_width / 2; - /* FALLTHROUGH */ + FALLTHROUGH; /* "zl" - scroll screen to the left */ case 'l': @@ -4447,7 +4481,7 @@ dozet: break; } undo = true; - /*FALLTHROUGH*/ + FALLTHROUGH; case 'g': /* "zg": add good word to word list */ case 'w': /* "zw": add wrong word to word list */ @@ -4738,6 +4772,10 @@ static void nv_ident(cmdarg_T *cap) assert(*kp != NUL); // option.c:do_set() should default to ":help" if empty. bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command bool kp_help = (STRCMP(kp, ":he") == 0 || STRCMP(kp, ":help") == 0); + if (kp_help && *skipwhite(ptr) == NUL) { + EMSG(_(e_noident)); // found white space only + return; + } size_t buf_size = n * 2 + 30 + STRLEN(kp); char *buf = xmalloc(buf_size); buf[0] = NUL; @@ -5005,7 +5043,10 @@ static void nv_scroll(cmdarg_T *cap) curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; } - cursor_correct(); /* correct for 'so' */ + // Correct for 'so', except when an operator is pending. + if (cap->oap->op_type == OP_NOP) { + cursor_correct(); + } beginline(BL_SOL | BL_FIX); } @@ -6257,7 +6298,7 @@ static void nv_gomark(cmdarg_T *cap) pos_T *pos; int c; pos_T old_cursor = curwin->w_cursor; - int old_KeyTyped = KeyTyped; /* getting file may reset it */ + const bool old_KeyTyped = KeyTyped; // getting file may reset it if (cap->cmdchar == 'g') c = cap->extra_char; @@ -6294,7 +6335,7 @@ static void nv_pcmark(cmdarg_T *cap) { pos_T *pos; linenr_T lnum = curwin->w_cursor.lnum; - int old_KeyTyped = KeyTyped; /* getting file may reset it */ + const bool old_KeyTyped = KeyTyped; // getting file may reset it if (!checkclearopq(cap->oap)) { if (cap->cmdchar == 'g') @@ -6459,8 +6500,8 @@ void may_start_select(int c) */ static void n_start_visual_mode(int c) { - /* Check for redraw before changing the state. */ - conceal_check_cursur_line(); + // Check for redraw before changing the state. + conceal_check_cursor_line(); VIsual_mode = c; VIsual_active = true; @@ -6477,8 +6518,8 @@ static void n_start_visual_mode(int c) foldAdjustVisual(); setmouse(); - /* Check for redraw after changing the state. */ - conceal_check_cursur_line(); + // Check for redraw after changing the state. + conceal_check_cursor_line(); if (p_smd && msg_silent == 0) redraw_cmdline = true; /* show visual mode later */ @@ -6623,7 +6664,7 @@ static void nv_g_cmd(cmdarg_T *cap) */ case K_BS: cap->nchar = Ctrl_H; - /* FALLTHROUGH */ + FALLTHROUGH; case 'h': case 'H': case Ctrl_H: @@ -6689,7 +6730,7 @@ static void nv_g_cmd(cmdarg_T *cap) */ case '^': flag = true; - /* FALLTHROUGH */ + FALLTHROUGH; case '0': case 'm': @@ -6867,7 +6908,7 @@ static void nv_g_cmd(cmdarg_T *cap) /* "g'm" and "g`m": jump to mark without setting pcmark */ case '\'': cap->arg = true; - /*FALLTHROUGH*/ + FALLTHROUGH; case '`': nv_gomark(cap); break; @@ -6925,7 +6966,7 @@ static void nv_g_cmd(cmdarg_T *cap) case 'q': case 'w': oap->cursor_start = curwin->w_cursor; - /*FALLTHROUGH*/ + FALLTHROUGH; case '~': case 'u': case 'U': diff --git a/src/nvim/ops.c b/src/nvim/ops.c index c95345f9b2..5a6e56299d 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -310,30 +310,32 @@ void shift_line( */ static void shift_block(oparg_T *oap, int amount) { - int left = (oap->op_type == OP_LSHIFT); - int oldstate = State; - int total; - char_u *newp, *oldp; - int oldcol = curwin->w_cursor.col; - int p_sw = get_sw_value(curbuf); - int p_ts = (int)curbuf->b_p_ts; + const bool left = (oap->op_type == OP_LSHIFT); + const int oldstate = State; + char_u *newp; + const int oldcol = curwin->w_cursor.col; + const int p_sw = get_sw_value(curbuf); + const int p_ts = (int)curbuf->b_p_ts; struct block_def bd; int incr; - colnr_T ws_vcol; int i = 0, j = 0; - int len; - int old_p_ri = p_ri; + const int old_p_ri = p_ri; p_ri = 0; /* don't want revins in indent */ - State = INSERT; /* don't want REPLACE for State */ - block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE); - if (bd.is_short) + State = INSERT; // don't want REPLACE for State + block_prep(oap, &bd, curwin->w_cursor.lnum, true); + if (bd.is_short) { return; + } + + // total is number of screen columns to be inserted/removed + int total = (int)((unsigned)amount * (unsigned)p_sw); + if ((total / p_sw) != amount) { + return; // multiplication overflow + } - /* total is number of screen columns to be inserted/removed */ - total = amount * p_sw; - oldp = get_cursor_line_ptr(); + char_u *const oldp = get_cursor_line_ptr(); if (!left) { /* @@ -342,8 +344,8 @@ static void shift_block(oparg_T *oap, int amount) * 3. Divvy into TABs & spp * 4. Construct new string */ - total += bd.pre_whitesp; /* all virtual WS up to & incl a split TAB */ - ws_vcol = bd.start_vcol - bd.pre_whitesp; + total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB + colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp; if (bd.startspaces) { if (has_mbyte) { if ((*mb_ptr2len)(bd.textstart) == 1) { @@ -372,8 +374,8 @@ static void shift_block(oparg_T *oap, int amount) j = total; /* if we're splitting a TAB, allow for it */ bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0); - len = (int)STRLEN(bd.textstart) + 1; - newp = (char_u *) xmalloc((size_t)(bd.textcol + i + j + len)); + const int len = (int)STRLEN(bd.textstart) + 1; + newp = (char_u *)xmalloc((size_t)(bd.textcol + i + j + len)); memset(newp, NUL, (size_t)(bd.textcol + i + j + len)); memmove(newp, oldp, (size_t)bd.textcol); memset(newp + bd.textcol, TAB, (size_t)i); @@ -390,10 +392,7 @@ static void shift_block(oparg_T *oap, int amount) size_t fill; // nr of spaces that replace a TAB size_t new_line_len; // the length of the line after the // block shift - colnr_T block_space_width; - colnr_T shift_amount; char_u *non_white = bd.textstart; - colnr_T non_white_col; /* * Firstly, let's find the first non-whitespace character that is @@ -410,19 +409,20 @@ static void shift_block(oparg_T *oap, int amount) MB_PTR_ADV(non_white); } - /* The character's column is in "bd.start_vcol". */ - non_white_col = bd.start_vcol; + // The character's column is in "bd.start_vcol". + colnr_T non_white_col = bd.start_vcol; while (ascii_iswhite(*non_white)) { incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col); non_white_col += incr; } - block_space_width = non_white_col - oap->start_vcol; - /* We will shift by "total" or "block_space_width", whichever is less. - */ - shift_amount = (block_space_width < total ? block_space_width : total); + const colnr_T block_space_width = non_white_col - oap->start_vcol; + // We will shift by "total" or "block_space_width", whichever is less. + const colnr_T shift_amount = block_space_width < total + ? block_space_width + : total; // The column to which we will shift the text. destination_col = non_white_col - shift_amount; @@ -454,7 +454,7 @@ static void shift_block(oparg_T *oap, int amount) fill = (size_t)(destination_col - verbatim_copy_width); assert(verbatim_copy_end - oldp >= 0); - size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp); + const size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp); // The replacement line will consist of: // - the beginning of the original line up to "verbatim_copy_end", // - "fill" number of spaces, @@ -466,8 +466,8 @@ static void shift_block(oparg_T *oap, int amount) memset(newp + verbatim_diff, ' ', fill); STRMOVE(newp + verbatim_diff + fill, non_white); } - /* replace the line */ - ml_replace(curwin->w_cursor.lnum, newp, FALSE); + // replace the line + ml_replace(curwin->w_cursor.lnum, newp, false); changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol); State = oldstate; curwin->w_cursor.col = oldcol; @@ -520,12 +520,12 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def } } - if (has_mbyte && spaces > 0) { + if (spaces > 0) { int off; // Avoid starting halfway through a multi-byte character. if (b_insert) { - off = (*mb_head_off)(oldp, oldp + offset + spaces); + off = utf_head_off(oldp, oldp + offset + spaces); } else { off = (*mb_off_next)(oldp, oldp + offset); offset += off; @@ -561,7 +561,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def offset += count; STRMOVE(newp + offset, oldp); - ml_replace(lnum, newp, FALSE); + ml_replace(lnum, newp, false); if (lnum == oap->end.lnum) { /* Set "']" mark to the end of the block instead of the end of @@ -1110,7 +1110,7 @@ int insert_reg( ) { int retval = OK; - int allocated; + bool allocated; /* * It is possible to get into an endless loop by having CTRL-R a in @@ -1187,82 +1187,92 @@ static void stuffescaped(const char *arg, int literally) } } -/* - * If "regname" is a special register, return TRUE and store a pointer to its - * value in "argp". - */ -int get_spec_reg( +// If "regname" is a special register, return true and store a pointer to its +// value in "argp". +bool get_spec_reg( int regname, char_u **argp, - int *allocated, /* return: TRUE when value was allocated */ - int errmsg /* give error message when failing */ + bool *allocated, // return: true when value was allocated + bool errmsg // give error message when failing ) { size_t cnt; *argp = NULL; - *allocated = FALSE; + *allocated = false; switch (regname) { case '%': /* file name */ if (errmsg) check_fname(); /* will give emsg if not set */ *argp = curbuf->b_fname; - return TRUE; + return true; - case '#': /* alternate file name */ - *argp = getaltfname(errmsg); /* may give emsg if not set */ - return TRUE; + case '#': // alternate file name + *argp = getaltfname(errmsg); // may give emsg if not set + return true; case '=': /* result of expression */ *argp = get_expr_line(); - *allocated = TRUE; - return TRUE; + *allocated = true; + return true; case ':': /* last command line */ if (last_cmdline == NULL && errmsg) EMSG(_(e_nolastcmd)); *argp = last_cmdline; - return TRUE; + return true; case '/': /* last search-pattern */ if (last_search_pat() == NULL && errmsg) EMSG(_(e_noprevre)); *argp = last_search_pat(); - return TRUE; + return true; case '.': /* last inserted text */ *argp = get_last_insert_save(); - *allocated = TRUE; - if (*argp == NULL && errmsg) + *allocated = true; + if (*argp == NULL && errmsg) { EMSG(_(e_noinstext)); - return TRUE; + } + return true; - case Ctrl_F: /* Filename under cursor */ - case Ctrl_P: /* Path under cursor, expand via "path" */ - if (!errmsg) - return FALSE; - *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP - | (regname == Ctrl_P ? FNAME_EXP : 0), 1L, NULL); - *allocated = TRUE; - return TRUE; + case Ctrl_F: // Filename under cursor + case Ctrl_P: // Path under cursor, expand via "path" + if (!errmsg) { + return false; + } + *argp = file_name_at_cursor( + FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0), + 1L, NULL); + *allocated = true; + return true; - case Ctrl_W: /* word under cursor */ - case Ctrl_A: /* WORD (mnemonic All) under cursor */ - if (!errmsg) - return FALSE; + case Ctrl_W: // word under cursor + case Ctrl_A: // WORD (mnemonic All) under cursor + if (!errmsg) { + return false; + } cnt = find_ident_under_cursor(argp, (regname == Ctrl_W ? (FIND_IDENT|FIND_STRING) : FIND_STRING)); *argp = cnt ? vim_strnsave(*argp, cnt) : NULL; - *allocated = TRUE; - return TRUE; + *allocated = true; + return true; + + case Ctrl_L: // Line under cursor + if (!errmsg) { + return false; + } + + *argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false); + return true; case '_': /* black hole: always empty */ *argp = (char_u *)""; - return TRUE; + return true; } - return FALSE; + return false; } /// Paste a yank register into the command line. @@ -1427,10 +1437,11 @@ int op_delete(oparg_T *oap) return FAIL; } - for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum) { - block_prep(oap, &bd, lnum, TRUE); - if (bd.textlen == 0) /* nothing to delete */ + for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) { + block_prep(oap, &bd, lnum, true); + if (bd.textlen == 0) { // nothing to delete continue; + } /* Adjust cursor position for tab replaced by spaces and 'lbr'. */ if (lnum == curwin->w_cursor.lnum) { @@ -1473,9 +1484,9 @@ int op_delete(oparg_T *oap) } if (u_save_cursor() == FAIL) return FAIL; - if (curbuf->b_p_ai) { /* don't delete indent */ - beginline(BL_WHITE); /* cursor on first non-white */ - did_ai = TRUE; /* delete the indent when ESC hit */ + if (curbuf->b_p_ai) { // don't delete indent + beginline(BL_WHITE); // cursor on first non-white + did_ai = true; // delete the indent when ESC hit ai_col = curwin->w_cursor.col; } else beginline(0); /* cursor in column 0 */ @@ -1656,11 +1667,12 @@ int op_replace(oparg_T *oap, int c) */ if (oap->motion_type == kMTBlockWise) { bd.is_MAX = (curwin->w_curswant == MAXCOL); - for (; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) { - curwin->w_cursor.col = 0; /* make sure cursor position is valid */ - block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE); - if (bd.textlen == 0 && (!virtual_op || bd.is_MAX)) - continue; /* nothing to replace */ + for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) { + curwin->w_cursor.col = 0; // make sure cursor position is valid + block_prep(oap, &bd, curwin->w_cursor.lnum, true); + if (bd.textlen == 0 && (!virtual_op || bd.is_MAX)) { + continue; // nothing to replace + } /* n == number of extra chars required * If we split a TAB, it may be replaced by several characters. @@ -1725,13 +1737,8 @@ int op_replace(oparg_T *oap, int c) if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { // strlen(newp) at this point int newp_len = bd.textcol + bd.startspaces; - if (has_mbyte) { - while (--num_chars >= 0) { - newp_len += (*mb_char2bytes)(c, newp + newp_len); - } - } else { - memset(newp + newp_len, c, (size_t)numc); - newp_len += numc; + while (--num_chars >= 0) { + newp_len += utf_char2bytes(c, newp + newp_len); } if (!bd.is_short) { // insert post-spaces @@ -1747,8 +1754,8 @@ int op_replace(oparg_T *oap, int c) after_p = (char_u *)xmalloc(after_p_len); memmove(after_p, oldp, after_p_len); } - /* replace the line */ - ml_replace(curwin->w_cursor.lnum, newp, FALSE); + // replace the line + ml_replace(curwin->w_cursor.lnum, newp, false); if (after_p != NULL) { ml_append(curwin->w_cursor.lnum++, after_p, (int)after_p_len, false); appended_lines_mark(curwin->w_cursor.lnum, 1L); @@ -1852,7 +1859,7 @@ void op_tilde(oparg_T *oap) for (; pos.lnum <= oap->end.lnum; pos.lnum++) { int one_change; - block_prep(oap, &bd, pos.lnum, FALSE); + block_prep(oap, &bd, pos.lnum, false); pos.col = bd.textcol; one_change = swapchars(oap->op_type, &pos, bd.textlen); did_change |= one_change; @@ -1956,7 +1963,7 @@ int swapchar(int op_type, pos_T *pos) /* Special handling of German sharp s: change to "SS". */ curwin->w_cursor = *pos; - del_char(FALSE); + del_char(false); ins_char('S'); ins_char('S'); curwin->w_cursor = sp; @@ -2002,6 +2009,7 @@ void op_insert(oparg_T *oap, long count1) { long ins_len, pre_textlen = 0; char_u *firstline, *ins_text; + colnr_T ind_pre = 0; struct block_def bd; int i; pos_T t1; @@ -2030,11 +2038,15 @@ void op_insert(oparg_T *oap, long count1) --curwin->w_cursor.col; ve_flags = old_ve_flags; } - /* Get the info about the block before entering the text */ - block_prep(oap, &bd, oap->start.lnum, TRUE); + // Get the info about the block before entering the text + block_prep(oap, &bd, oap->start.lnum, true); + // Get indent information + ind_pre = (colnr_T)getwhitecols_curline(); firstline = ml_get(oap->start.lnum) + bd.textcol; - if (oap->op_type == OP_APPEND) + + if (oap->op_type == OP_APPEND) { firstline += bd.textlen; + } pre_textlen = (long)STRLEN(firstline); } @@ -2087,10 +2099,23 @@ void op_insert(oparg_T *oap, long count1) if (oap->motion_type == kMTBlockWise) { struct block_def bd2; - - /* The user may have moved the cursor before inserting something, try - * to adjust the block for that. */ - if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX) { + bool did_indent = false; + + // if indent kicked in, the firstline might have changed + // but only do that, if the indent actually increased + const colnr_T ind_post = (colnr_T)getwhitecols_curline(); + if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre) { + bd.textcol += ind_post - ind_pre; + bd.start_vcol += ind_post - ind_pre; + did_indent = true; + } + + // The user may have moved the cursor before inserting something, try + // to adjust the block for that. But only do it, if the difference + // does not come from indent kicking in. + if (oap->start.lnum == curbuf->b_op_start_orig.lnum + && !bd.is_MAX + && !did_indent) { if (oap->op_type == OP_INSERT && oap->start.col + oap->start.coladd != curbuf->b_op_start_orig.col + curbuf->b_op_start_orig.coladd) { @@ -2119,7 +2144,7 @@ void op_insert(oparg_T *oap, long count1) * tabs. Get the starting column again and correct the length. * Don't do this when "$" used, end-of-line will have changed. */ - block_prep(oap, &bd2, oap->start.lnum, TRUE); + block_prep(oap, &bd2, oap->start.lnum, true); if (!bd.is_MAX || bd2.textlen < bd.textlen) { if (oap->op_type == OP_APPEND) { pre_textlen += bd2.textlen - bd.textlen; @@ -2134,9 +2159,17 @@ void op_insert(oparg_T *oap, long count1) * Subsequent calls to ml_get() flush the firstline data - take a * copy of the required string. */ - firstline = ml_get(oap->start.lnum) + bd.textcol; - if (oap->op_type == OP_APPEND) - firstline += bd.textlen; + firstline = ml_get(oap->start.lnum); + const size_t len = STRLEN(firstline); + colnr_T add = bd.textcol; + if (oap->op_type == OP_APPEND) { + add += bd.textlen; + } + if ((size_t)add > len) { + firstline += len; // short line, point to the NUL + } else { + firstline += add; + } ins_len = (long)STRLEN(firstline) - pre_textlen; if (pre_textlen >= 0 && ins_len > 0) { ins_text = vim_strnsave(firstline, (size_t)ins_len); @@ -2178,7 +2211,7 @@ int op_change(oparg_T *oap) if (!p_paste && curbuf->b_p_si && !curbuf->b_p_cin ) - can_si = TRUE; /* It's like opening a new line, do si */ + can_si = true; // It's like opening a new line, do si } /* First delete the text in the region. In an empty buffer only need to @@ -2204,7 +2237,7 @@ int op_change(oparg_T *oap) } firstline = ml_get(oap->start.lnum); pre_textlen = (long)STRLEN(firstline); - pre_indent = (long)(skipwhite(firstline) - firstline); + pre_indent = (long)getwhitecols(firstline); bd.textcol = curwin->w_cursor.col; } @@ -2225,7 +2258,7 @@ int op_change(oparg_T *oap) // the indent, exclude that indent change from the inserted text. firstline = ml_get(oap->start.lnum); if (bd.textcol > (colnr_T)pre_indent) { - long new_indent = (long)(skipwhite(firstline) - firstline); + long new_indent = (long)getwhitecols(firstline); pre_textlen += new_indent - pre_indent; bd.textcol += (colnr_T)(new_indent - pre_indent); @@ -2239,7 +2272,7 @@ int op_change(oparg_T *oap) STRLCPY(ins_text, firstline + bd.textcol, ins_len + 1); for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; linenr++) { - block_prep(oap, &bd, linenr, TRUE); + block_prep(oap, &bd, linenr, true); if (!bd.is_short || virtual_op) { pos_T vpos; @@ -2263,7 +2296,7 @@ int op_change(oparg_T *oap) offset += ins_len; oldp += bd.textcol; STRMOVE(newp + offset, oldp); - ml_replace(linenr, newp, FALSE); + ml_replace(linenr, newp, false); } } check_cursor(); @@ -2430,11 +2463,10 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) if (virtual_op) { getvcol(curwin, &oap->end, &cs, NULL, &ce); if (p[endcol] == NUL || (cs + oap->end.coladd < ce - /* Don't add space for double-wide - * char; endcol will be on last byte - * of multi-byte char. */ - && (*mb_head_off)(p, p + endcol) == 0 - )) { + // Don't add space for double-wide + // char; endcol will be on last byte + // of multi-byte char. + && utf_head_off(p, p + endcol) == 0)) { if (oap->start.lnum == oap->end.lnum && oap->start.col == oap->end.col) { /* Special case: inside a single char */ @@ -2509,19 +2541,27 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append) } // Some versions of Vi use ">=" here, some don't... if (yanklines > (size_t)p_report) { + char namebuf[100]; + + if (oap->regname == NUL) { + *namebuf = NUL; + } else { + vim_snprintf(namebuf, sizeof(namebuf), _(" into \"%c"), oap->regname); + } + // redisplay now, so message is not deleted update_topline_redraw(); if (yanklines == 1) { if (yank_type == kMTBlockWise) { - MSG(_("block of 1 line yanked")); + smsg(_("block of 1 line yanked%s"), namebuf); } else { - MSG(_("1 line yanked")); + smsg(_("1 line yanked%s"), namebuf); } } else if (yank_type == kMTBlockWise) { - smsg(_("block of %" PRId64 " lines yanked"), - (int64_t)yanklines); + smsg(_("block of %" PRId64 " lines yanked%s"), + (int64_t)yanklines, namebuf); } else { - smsg(_("%" PRId64 " lines yanked"), (int64_t)yanklines); + smsg(_("%" PRId64 " lines yanked%s"), (int64_t)yanklines, namebuf); } } } @@ -2642,7 +2682,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) int lendiff = 0; pos_T old_pos; char_u *insert_string = NULL; - int allocated = FALSE; + bool allocated = false; long cnt; if (flags & PUT_FIXINDENT) @@ -2738,9 +2778,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) * For special registers '%' (file name), '#' (alternate file name) and * ':' (last command line), etc. we have to create a fake yank register. */ - if (get_spec_reg(regname, &insert_string, &allocated, TRUE)) { - if (insert_string == NULL) + if (get_spec_reg(regname, &insert_string, &allocated, true)) { + if (insert_string == NULL) { return; + } } if (!curbuf->terminal) { @@ -2982,7 +3023,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) bd.startspaces = incr - bd.endspaces; --bd.textcol; delcount = 1; - bd.textcol -= (*mb_head_off)(oldp, oldp + bd.textcol); + bd.textcol -= utf_head_off(oldp, oldp + bd.textcol); if (oldp[bd.textcol] != TAB) { /* Only a Tab can be split into spaces. Other * characters will have to be moved to after the @@ -3109,10 +3150,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) ptr += yanklen; } STRMOVE(ptr, oldp + col); - ml_replace(lnum, newp, FALSE); - /* Place cursor on last putted char. */ + ml_replace(lnum, newp, false); + // Place cursor on last putted char. if (lnum == curwin->w_cursor.lnum) { - /* make sure curwin->w_virtcol is updated */ + // make sure curwin->w_virtcol is updated changed_cline_bef_curs(); curwin->w_cursor.col += (colnr_T)(totlen - 1); } @@ -3156,7 +3197,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) memmove(newp, oldp, (size_t)col); /* append to first line */ memmove(newp + col, y_array[0], (size_t)(yanklen + 1)); - ml_replace(lnum, newp, FALSE); + ml_replace(lnum, newp, false); curwin->w_cursor.lnum = lnum; i = 1; @@ -3612,9 +3653,9 @@ int do_join(size_t count, curr = skipwhite(curr); if (*curr != ')' && currsize != 0 && endcurr1 != TAB && (!has_format_option(FO_MBYTE_JOIN) - || (mb_ptr2char(curr) < 0x100 && endcurr1 < 0x100)) + || (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100)) && (!has_format_option(FO_MBYTE_JOIN2) - || mb_ptr2char(curr) < 0x100 || endcurr1 < 0x100) + || utf_ptr2char(curr) < 0x100 || endcurr1 < 0x100) ) { /* don't add a space if the line is ending in a space */ if (endcurr1 == ' ') @@ -3631,18 +3672,12 @@ int do_join(size_t count, sumsize += currsize + spaces[t]; endcurr1 = endcurr2 = NUL; if (insert_space && currsize > 0) { - if (has_mbyte) { - cend = curr + currsize; + cend = curr + currsize; + MB_PTR_BACK(curr, cend); + endcurr1 = utf_ptr2char(cend); + if (cend > curr) { MB_PTR_BACK(curr, cend); - endcurr1 = (*mb_ptr2char)(cend); - if (cend > curr) { - MB_PTR_BACK(curr, cend); - endcurr2 = (*mb_ptr2char)(cend); - } - } else { - endcurr1 = *(curr + currsize - 1); - if (currsize > 1) - endcurr2 = *(curr + currsize - 2); + endcurr2 = utf_ptr2char(cend); } } line_breakcheck(); @@ -3685,7 +3720,7 @@ int do_join(size_t count, curr = skipwhite(curr); currsize = (int)STRLEN(curr); } - ml_replace(curwin->w_cursor.lnum, newp, FALSE); + ml_replace(curwin->w_cursor.lnum, newp, false); if (setmark) { // Set the '] mark. @@ -4105,10 +4140,9 @@ format_lines ( if (next_leader_len > 0) { (void)del_bytes(next_leader_len, false, false); mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L, - (long)-next_leader_len); - } else if (second_indent > 0) { /* the "leader" for FO_Q_SECOND */ - char_u *p = get_cursor_line_ptr(); - int indent = (int)(skipwhite(p) - p); + (long)-next_leader_len); + } else if (second_indent > 0) { // the "leader" for FO_Q_SECOND + int indent = (int)getwhitecols_curline(); if (indent > 0) { (void)del_bytes(indent, FALSE, FALSE); @@ -4237,7 +4271,8 @@ int paragraph_start(linenr_T lnum) * - start/endspaces is the number of columns of the first/last yanked char * that are to be yanked. */ -static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, int is_del) +static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, + bool is_del) { int incr = 0; char_u *pend; @@ -4391,7 +4426,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) length = (colnr_T)STRLEN(ml_get(pos.lnum)); } else { // oap->motion_type == kMTCharWise - if (!oap->inclusive) { + if (pos.lnum == oap->start.lnum && !oap->inclusive) { dec(&(oap->end)); } length = (colnr_T)STRLEN(ml_get(pos.lnum)); @@ -4902,10 +4937,11 @@ void *get_reg_contents(int regname, int flags) return NULL; char_u *retval; - int allocated; - if (get_spec_reg(regname, &retval, &allocated, FALSE)) { - if (retval == NULL) + bool allocated; + if (get_spec_reg(regname, &retval, &allocated, false)) { + if (retval == NULL) { return NULL; + } if (allocated) { return get_reg_wrap_one_line(retval, flags); } @@ -5374,8 +5410,8 @@ void cursor_pos_info(dict_T *dict) switch (l_VIsual_mode) { case Ctrl_V: virtual_op = virtual_active(); - block_prep(&oparg, &bd, lnum, 0); - virtual_op = MAYBE; + block_prep(&oparg, &bd, lnum, false); + virtual_op = kNone; s = bd.textstart; len = (long)bd.textlen; break; diff --git a/src/nvim/option.c b/src/nvim/option.c index 50c172b580..11f3df7cfa 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1068,6 +1068,10 @@ void set_helplang_default(const char *lang) if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) { p_hlg[0] = (char_u)TOLOWER_ASC(p_hlg[3]); p_hlg[1] = (char_u)TOLOWER_ASC(p_hlg[4]); + } else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C') { + // any C like setting, such as C.UTF-8, becomes "en" + p_hlg[0] = 'e'; + p_hlg[1] = 'n'; } p_hlg[2] = NUL; options[idx].flags |= P_ALLOCED; @@ -1434,7 +1438,7 @@ do_set ( || (long *)varp == &p_wcm) && (*arg == '<' || *arg == '^' - || ((!arg[1] || ascii_iswhite(arg[1])) + || (*arg != NUL && (!arg[1] || ascii_iswhite(arg[1])) && !ascii_isdigit(*arg)))) { value = string_to_key(arg); if (value == 0 && (long *)varp != &p_wcm) { @@ -1769,14 +1773,13 @@ do_set ( // Set the new value. *(char_u **)(varp) = newval; - if (!starting && origval != NULL && newval != NULL) { - // origval may be freed by - // did_set_string_option(), make a copy. - saved_origval = xstrdup((char *)origval); - // newval (and varp) may become invalid if the - // buffer is closed by autocommands. - saved_newval = xstrdup((char *)newval); - } + // origval may be freed by + // did_set_string_option(), make a copy. + saved_origval = (origval != NULL) ? xstrdup((char *)origval) : 0; + + // newval (and varp) may become invalid if the + // buffer is closed by autocommands. + saved_newval = (newval != NULL) ? xstrdup((char *)newval) : 0; // Handle side effects, and set the global value for // ":set" on local options. Note: when setting 'syntax' @@ -1786,8 +1789,14 @@ do_set ( new_value_alloced, oldval, errbuf, opt_flags); if (errmsg == NULL) { - trigger_optionsset_string(opt_idx, opt_flags, saved_origval, - saved_newval); + if (!starting) { + trigger_optionsset_string(opt_idx, opt_flags, saved_origval, + saved_newval); + } + if (options[opt_idx].flags & P_UI_OPTION) { + ui_call_option_set(cstr_as_string(options[opt_idx].fullname), + STRING_OBJ(cstr_as_string(saved_newval))); + } } xfree(saved_origval); xfree(saved_newval); @@ -2378,8 +2387,8 @@ static char *set_string_option(const int opt_idx, const char *const value, char *const oldval = *varp; *varp = s; - char *const saved_oldval = (starting ? NULL : xstrdup(oldval)); - char *const saved_newval = (starting ? NULL : xstrdup(s)); + char *const saved_oldval = xstrdup(oldval); + char *const saved_newval = xstrdup(s); char *const r = (char *)did_set_string_option( opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, NULL, opt_flags); @@ -2389,8 +2398,13 @@ static char *set_string_option(const int opt_idx, const char *const value, // call autocommand after handling side effects if (r == NULL) { - trigger_optionsset_string(opt_idx, opt_flags, - saved_oldval, saved_newval); + if (!starting) { + trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_newval); + } + if (options[opt_idx].flags & P_UI_OPTION) { + ui_call_option_set(cstr_as_string(options[opt_idx].fullname), + STRING_OBJ(cstr_as_string(saved_newval))); + } } xfree(saved_oldval); xfree(saved_newval); @@ -2434,7 +2448,7 @@ did_set_string_option ( int did_chartab = FALSE; char_u **gvarp; bool free_oldval = (options[opt_idx].flags & P_ALLOCED); - int ft_changed = false; + bool value_changed = false; /* Get the global option to compare with, otherwise we would have to check * two values for all local options. */ @@ -2703,7 +2717,7 @@ did_set_string_option ( if (*p != NUL) x2 = *p++; if (*p != NUL) { - x3 = mb_ptr2char(p); + x3 = utf_ptr2char(p); p += mb_ptr2len(p); } if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ',')) { @@ -3155,11 +3169,13 @@ did_set_string_option ( if (!valid_filetype(*varp)) { errmsg = e_invarg; } else { - ft_changed = STRCMP(oldval, *varp) != 0; + value_changed = STRCMP(oldval, *varp) != 0; } } else if (gvarp == &p_syn) { if (!valid_filetype(*varp)) { errmsg = e_invarg; + } else { + value_changed = STRCMP(oldval, *varp) != 0; } } else if (varp == &curwin->w_p_winhl) { if (!parse_winhl_opt(curwin)) { @@ -3235,14 +3251,28 @@ did_set_string_option ( */ /* When 'syntax' is set, load the syntax of that name */ if (varp == &(curbuf->b_p_syn)) { - apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, - curbuf->b_fname, TRUE, curbuf); + static int syn_recursive = 0; + + syn_recursive++; + // Only pass true for "force" when the value changed or not used + // recursively, to avoid endless recurrence. + apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, curbuf->b_fname, + value_changed || syn_recursive == 1, curbuf); + syn_recursive--; } else if (varp == &(curbuf->b_p_ft)) { // 'filetype' is set, trigger the FileType autocommand - if (!(opt_flags & OPT_MODELINE) || ft_changed) { + // Skip this when called from a modeline and the filetype was + // already set to this value. + if (!(opt_flags & OPT_MODELINE) || value_changed) { + static int ft_recursive = 0; + + ft_recursive++; did_filetype = true; - apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, - curbuf->b_fname, true, curbuf); + // Only pass true for "force" when the value changed or not + // used recursively, to avoid endless recurrence. + apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname, + value_changed || ft_recursive == 1, curbuf); + ft_recursive--; // Just in case the old "curbuf" is now invalid if (varp != &(curbuf->b_p_ft)) { varp = NULL; @@ -3705,6 +3735,9 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, } else if ((int *)varp == &p_lnr) { // 'langnoremap' -> !'langremap' p_lrm = !p_lnr; + } else if ((int *)varp == &curwin->w_p_cul && !value && old_value) { + // 'cursorline' + reset_cursorline(); // 'undofile' } else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) { // Only take action when the option was set. When reset we do not @@ -3961,8 +3994,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, /* Enable Arabic shaping (major part of what Arabic requires) */ if (!p_arshape) { - p_arshape = TRUE; - redraw_later_clear(); + p_arshape = true; + redraw_all_later(NOT_VALID); } } @@ -4019,7 +4052,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, options[opt_idx].flags |= P_WAS_SET; - if (!starting) { + // Don't do this while starting up or recursively. + if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL) { char buf_old[2]; char buf_new[2]; char buf_type[7]; @@ -4036,10 +4070,11 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, (char_u *) options[opt_idx].fullname, NULL, false, NULL); reset_v_option_vars(); - if (options[opt_idx].flags & P_UI_OPTION) { - ui_call_option_set(cstr_as_string(options[opt_idx].fullname), - BOOLEAN_OBJ(value)); - } + } + + if (options[opt_idx].flags & P_UI_OPTION) { + ui_call_option_set(cstr_as_string(options[opt_idx].fullname), + BOOLEAN_OBJ(value)); } comp_col(); /* in case 'ruler' or 'showcmd' changed */ @@ -4393,7 +4428,8 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, options[opt_idx].flags |= P_WAS_SET; - if (!starting && errmsg == NULL) { + // Don't do this while starting up, failure or recursively. + if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL) { char buf_old[NUMBUFLEN]; char buf_new[NUMBUFLEN]; char buf_type[7]; @@ -4408,10 +4444,11 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, (char_u *) options[opt_idx].fullname, NULL, false, NULL); reset_v_option_vars(); - if (options[opt_idx].flags & P_UI_OPTION) { - ui_call_option_set(cstr_as_string(options[opt_idx].fullname), - INTEGER_OBJ(value)); - } + } + + if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) { + ui_call_option_set(cstr_as_string(options[opt_idx].fullname), + INTEGER_OBJ(value)); } comp_col(); /* in case 'columns' or 'ls' changed */ @@ -4426,7 +4463,10 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, static void trigger_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *newval) { - if (oldval != NULL && newval != NULL) { + // Don't do this recursively. + if (oldval != NULL + && newval != NULL + && *get_vim_var_str(VV_OPTION_TYPE) == NUL) { char buf_type[7]; vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s", @@ -4437,10 +4477,6 @@ static void trigger_optionsset_string(int opt_idx, int opt_flags, apply_autocmds(EVENT_OPTIONSET, (char_u *)options[opt_idx].fullname, NULL, false, NULL); reset_v_option_vars(); - if (options[opt_idx].flags & P_UI_OPTION) { - ui_call_option_set(cstr_as_string(options[opt_idx].fullname), - STRING_OBJ(cstr_as_string(newval))); - } } } @@ -6406,22 +6442,25 @@ static void langmap_set(void) ++p; break; } - if (p[0] == '\\' && p[1] != NUL) - ++p; - from = (*mb_ptr2char)(p); + if (p[0] == '\\' && p[1] != NUL) { + p++; + } + from = utf_ptr2char(p); to = NUL; if (p2 == NULL) { MB_PTR_ADV(p); if (p[0] != ',') { - if (p[0] == '\\') - ++p; - to = (*mb_ptr2char)(p); + if (p[0] == '\\') { + p++; + } + to = utf_ptr2char(p); } } else { if (p2[0] != ',') { - if (p2[0] == '\\') - ++p2; - to = (*mb_ptr2char)(p2); + if (p2[0] == '\\') { + p2++; + } + to = utf_ptr2char(p2); } } if (to == NUL) { @@ -6846,66 +6885,37 @@ int get_sts_value(void) */ void find_mps_values(int *initc, int *findc, int *backwards, int switchit) { - char_u *ptr; + char_u *ptr = curbuf->b_p_mps; - ptr = curbuf->b_p_mps; while (*ptr != NUL) { - if (has_mbyte) { - char_u *prev; - - if (mb_ptr2char(ptr) == *initc) { - if (switchit) { - *findc = *initc; - *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1); - *backwards = TRUE; - } else { - *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1); - *backwards = FALSE; - } - return; - } - prev = ptr; - ptr += mb_ptr2len(ptr) + 1; - if (mb_ptr2char(ptr) == *initc) { - if (switchit) { - *findc = *initc; - *initc = mb_ptr2char(prev); - *backwards = FALSE; - } else { - *findc = mb_ptr2char(prev); - *backwards = TRUE; - } - return; - } - ptr += mb_ptr2len(ptr); - } else { - if (*ptr == *initc) { - if (switchit) { - *backwards = TRUE; - *findc = *initc; - *initc = ptr[2]; - } else { - *backwards = FALSE; - *findc = ptr[2]; - } - return; + if (utf_ptr2char(ptr) == *initc) { + if (switchit) { + *findc = *initc; + *initc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1); + *backwards = true; + } else { + *findc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1); + *backwards = false; } - ptr += 2; - if (*ptr == *initc) { - if (switchit) { - *backwards = FALSE; - *findc = *initc; - *initc = ptr[-2]; - } else { - *backwards = TRUE; - *findc = ptr[-2]; - } - return; + return; + } + char_u *prev = ptr; + ptr += utfc_ptr2len(ptr) + 1; + if (utf_ptr2char(ptr) == *initc) { + if (switchit) { + *findc = *initc; + *initc = utf_ptr2char(prev); + *backwards = false; + } else { + *findc = utf_ptr2char(prev); + *backwards = true; } - ++ptr; + return; + } + ptr += utfc_ptr2len(ptr); + if (*ptr == ',') { + ptr++; } - if (*ptr == ',') - ++ptr; } } diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 5ae306e00e..bc7f1a2b0a 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -68,7 +68,7 @@ return { type='bool', scope={'global'}, vi_def=true, vim=true, - redraw={'everything', 'ui_option'}, + redraw={'all_windows', 'ui_option'}, varname='p_arshape', defaults={if_true={vi=true}} @@ -92,7 +92,7 @@ return { full_name='ambiwidth', abbreviation='ambw', type='string', scope={'global'}, vi_def=true, - redraw={'everything', 'ui_option'}, + redraw={'all_windows', 'ui_option'}, varname='p_ambw', defaults={if_true={vi="single"}} }, @@ -133,7 +133,7 @@ return { full_name='background', abbreviation='bg', type='string', scope={'global'}, vi_def=true, - redraw={'everything'}, + redraw={'all_windows'}, varname='p_bg', defaults={if_true={vi="light"}} }, @@ -662,7 +662,7 @@ return { full_name='emoji', abbreviation='emo', type='bool', scope={'global'}, vi_def=true, - redraw={'everything', 'ui_option'}, + redraw={'all_windows', 'ui_option'}, varname='p_emoji', defaults={if_true={vi=true}} }, @@ -671,7 +671,6 @@ return { type='string', scope={'global'}, deny_in_modelines=true, vi_def=true, - redraw={'everything'}, varname='p_enc', defaults={if_true={vi=macros('ENC_DFLT')}} }, @@ -1023,7 +1022,7 @@ return { deny_duplicates=true, vi_def=true, varname='p_guifont', - redraw={'everything', 'ui_option'}, + redraw={'ui_option'}, defaults={if_true={vi=""}} }, { @@ -1031,7 +1030,7 @@ return { type='string', list='onecomma', scope={'global'}, vi_def=true, varname='p_guifontset', - redraw={'everything', 'ui_option'}, + redraw={'ui_option'}, defaults={if_true={vi=""}} }, { @@ -1039,7 +1038,7 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, vi_def=true, - redraw={'everything', 'ui_option'}, + redraw={'ui_option'}, varname='p_guifontwide', defaults={if_true={vi=""}} }, @@ -1099,7 +1098,6 @@ return { type='string', list='onecomma', scope={'global'}, deny_duplicates=true, vi_def=true, - redraw={'everything'}, varname='p_hl', defaults={if_true={vi=macros('HIGHLIGHT_INIT')}} }, @@ -1195,7 +1193,7 @@ return { full_name='inccommand', abbreviation='icm', type='string', scope={'global'}, vi_def=true, - redraw={'everything'}, + redraw={'all_windows'}, varname='p_icm', defaults={if_true={vi=""}} }, @@ -1399,7 +1397,7 @@ return { full_name='linespace', abbreviation='lsp', type='number', scope={'global'}, vi_def=true, - redraw={'everything', 'ui_option'}, + redraw={'ui_option'}, varname='p_linespace', defaults={if_true={vi=0}} }, @@ -1771,10 +1769,9 @@ return { { full_name='printheader', abbreviation='pheader', type='string', scope={'global'}, - gettext=true, vi_def=true, varname='p_header', - defaults={if_true={vi=N_("%<%f%h%m%=Page %N")}} + defaults={if_true={vi="%<%f%h%m%=Page %N"}} }, { full_name='printmbcharset', abbreviation='pmbcs', @@ -2044,9 +2041,9 @@ return { vi_def=true, varname='p_sp', defaults={ - condition='UNIX', - if_true={vi="| tee"}, - if_false={vi=">"}, + condition='WIN32', + if_true={vi=">%s 2>&1"}, + if_false={vi="| tee"}, } }, { @@ -2429,7 +2426,6 @@ return { full_name='termencoding', abbreviation='tenc', type='string', scope={'global'}, vi_def=true, - redraw={'everything'}, defaults={if_true={vi=""}} }, { diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 0df857352b..2f90d0bc9e 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -196,16 +196,19 @@ void init_homedir(void) const char *homedrive = os_getenv("HOMEDRIVE"); const char *homepath = os_getenv("HOMEPATH"); if (homepath == NULL) { - homepath = "\\"; + homepath = "\\"; } - if (homedrive != NULL && strlen(homedrive) + strlen(homepath) < MAXPATHL) { + if (homedrive != NULL + && strlen(homedrive) + strlen(homepath) < MAXPATHL) { snprintf(os_buf, MAXPATHL, "%s%s", homedrive, homepath); if (os_buf[0] != NUL) { var = os_buf; - vim_setenv("HOME", os_buf); } } } + if (var == NULL) { + var = os_getenv("USERPROFILE"); + } #endif if (var != NULL) { @@ -454,12 +457,15 @@ void expand_env_esc(char_u *restrict srcp, } else if ((src[0] == ' ' || src[0] == ',') && !one) { at_start = true; } - *dst++ = *src++; - --dstlen; + if (dstlen > 0) { + *dst++ = *src++; + dstlen--; - if (prefix != NULL && src - prefix_len >= srcp - && STRNCMP(src - prefix_len, prefix, prefix_len) == 0) { - at_start = true; + if (prefix != NULL + && src - prefix_len >= srcp + && STRNCMP(src - prefix_len, prefix, prefix_len) == 0) { + at_start = true; + } } } } @@ -608,6 +614,12 @@ char *vim_getenv(const char *name) return xstrdup(kos_env_path); } +#ifdef WIN32 + if (strcmp(name, "HOME") == 0) { + return xstrdup(homedir); + } +#endif + bool vimruntime = (strcmp(name, "VIMRUNTIME") == 0); if (!vimruntime && strcmp(name, "VIM") != 0) { return NULL; @@ -758,7 +770,12 @@ size_t home_replace(const buf_T *const buf, const char_u *src, dirlen = strlen(homedir); } - const char *const homedir_env = os_getenv("HOME"); + const char *homedir_env = os_getenv("HOME"); +#ifdef WIN32 + if (homedir_env == NULL) { + homedir_env = os_getenv("USERPROFILE"); + } +#endif char *homedir_env_mod = (char *)homedir_env; bool must_free = false; diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index cf00fd4f82..9a4391a0ae 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -110,7 +110,7 @@ bool os_isrealdir(const char *name) /// Check if the given path is a directory or not. /// -/// @return `true` if `fname` is a directory. +/// @return `true` if `name` is a directory. bool os_isdir(const char_u *name) FUNC_ATTR_NONNULL_ALL { @@ -126,6 +126,25 @@ bool os_isdir(const char_u *name) return true; } +/// Check if the given path is a directory and is executable. +/// Gives the same results as `os_isdir()` on Windows. +/// +/// @return `true` if `name` is a directory and executable. +bool os_isdir_executable(const char *name) + FUNC_ATTR_NONNULL_ALL +{ + int32_t mode = os_getperm((const char *)name); + if (mode < 0) { + return false; + } + +#ifdef WIN32 + return (S_ISDIR(mode)); +#else + return (S_ISDIR(mode) && (S_IXUSR & mode)); +#endif +} + /// Check what `name` is: /// @return NODE_NORMAL: file or directory (or doesn't exist) /// NODE_WRITABLE: writable device, socket, fifo, etc. diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 599487c345..f62253cbce 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -351,6 +351,8 @@ static bool input_poll(int ms) blocking = true; multiqueue_process_events(ch_before_blocking_events); } + DLOG("blocking... events_enabled=%d events_pending=%d", events_enabled, + !multiqueue_empty(main_loop.events)); LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof); blocking = false; diff --git a/src/nvim/os/lang.c b/src/nvim/os/lang.c index 47c278ee97..6b2a54ddbe 100644 --- a/src/nvim/os/lang.c +++ b/src/nvim/os/lang.c @@ -31,7 +31,7 @@ void lang_init(void) char buf[20] = { 0 }; if (CFStringGetCString(cf_lang_region, buf, 20, kCFStringEncodingUTF8)) { - os_setenv("LANG", lang_region, true); + os_setenv("LANG", buf, true); } } CFRelease(cf_lang_region); diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 04f59d7522..19d199f4d5 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -80,27 +80,61 @@ char **shell_build_argv(const char *cmd, const char *extra_args) void shell_free_argv(char **argv) { char **p = argv; - if (p == NULL) { // Nothing was allocated, return return; } - while (*p != NULL) { // Free each argument xfree(*p); p++; } - xfree(argv); } +/// Joins shell arguments from `argv` into a new string. +/// If the result is too long it is truncated with ellipsis ("..."). +/// +/// @returns[allocated] `argv` joined to a string. +char *shell_argv_to_str(char **const argv) + FUNC_ATTR_NONNULL_ALL +{ + size_t n = 0; + char **p = argv; + char *rv = xcalloc(256, sizeof(*rv)); + const size_t maxsize = (256 * sizeof(*rv)); + if (*p == NULL) { + return rv; + } + while (*p != NULL) { + xstrlcat(rv, "'", maxsize); + xstrlcat(rv, *p, maxsize); + n = xstrlcat(rv, "' ", maxsize); + if (n >= maxsize) { + break; + } + p++; + } + if (n < maxsize) { + rv[n - 1] = '\0'; + } else { + // Command too long, show ellipsis: "/bin/bash 'foo' 'bar'..." + rv[maxsize - 4] = '.'; + rv[maxsize - 3] = '.'; + rv[maxsize - 2] = '.'; + rv[maxsize - 1] = '\0'; + } + return rv; +} + /// Calls the user-configured 'shell' (p_sh) for running a command or wildcard /// expansion. /// /// @param cmd The command to execute, or NULL to run an interactive shell. /// @param opts Options that control how the shell will work. /// @param extra_args Extra arguments to the shell, or NULL. +/// +/// @return shell command exit code int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args) { DynamicBuffer input = DYNAMIC_BUFFER_INIT; @@ -450,8 +484,8 @@ static void out_data_ring(char *output, size_t size) /// @param output Data to append to screen lines. /// @param remaining Size of data. /// @param new_line If true, next data output will be on a new line. -static void out_data_append_to_screen(char *output, size_t *count, - bool eof) +static void out_data_append_to_screen(char *output, size_t *count, bool eof) + FUNC_ATTR_NONNULL_ALL { char *p = output, *end = output + *count; while (p < end) { @@ -466,7 +500,7 @@ static void out_data_append_to_screen(char *output, size_t *count, // incomplete UTF-8 sequence that could be composing with the last // complete sequence. // This will be corrected when we switch to vterm based implementation - int i = *p ? mb_ptr2len_len((char_u *)p, (int)(end-p)) : 1; + int i = *p ? utfc_ptr2len_len((char_u *)p, (int)(end-p)) : 1; if (!eof && i == 1 && utf8len_tab_zero[*(uint8_t *)p] > (end-p)) { *count = (size_t)(p - output); goto end; @@ -491,7 +525,7 @@ static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, && out_data_decide_throttle(cnt)) { // Skip output above a threshold. // Save the skipped output. If it is the final chunk, we display it later. out_data_ring(ptr, cnt); - } else { + } else if (ptr != NULL) { out_data_append_to_screen(ptr, &cnt, eof); } diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 290d421acc..31ef1a0cd6 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -114,12 +114,12 @@ struct tm *os_localtime_r(const time_t *restrict clock, #endif } -/// Obtains the current Unix timestamp and adjusts it to local time. +/// Gets the current Unix timestamp and adjusts it to local time. /// /// @param result Pointer to a 'struct tm' where the result should be placed /// @return A pointer to a 'struct tm' in the current time zone (the 'result' /// argument) or NULL in case of error -struct tm *os_get_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL +struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL { time_t rawtime = time(NULL); return os_localtime_r(&rawtime, result); diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index a27fee4e90..09ba718302 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -138,8 +138,8 @@ void mch_exit(int r) { exiting = true; - ui_builtin_stop(); ui_flush(); + ui_builtin_stop(); ml_close_all(true); // remove all memfiles if (!event_teardown() && r == 0) { @@ -149,6 +149,8 @@ void mch_exit(int r) stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) } + ILOG("Nvim exit: %d", r); + #ifdef EXITFREE free_all_mem(); #endif @@ -419,7 +421,6 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file, xfree(tempname); // With interactive completion, the error message is not printed. if (!(flags & EW_SILENT)) { - redraw_later_clear(); // probably messed up screen msg_putchar('\n'); // clear bottom line quickly #if SIZEOF_LONG > SIZEOF_INT assert(Rows <= (long)INT_MAX + 1); diff --git a/src/nvim/path.c b/src/nvim/path.c index d5c636ff08..eeb374cf44 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -52,7 +52,8 @@ /// @param s2 Second file name. /// @param checkname When both files don't exist, only compare their names. /// @return Enum of type FileComparison. @see FileComparison. -FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname) +FileComparison path_full_compare(char_u *const s1, char_u *const s2, + const bool checkname) { assert(s1 && s2); char_u exp1[MAXPATHL]; @@ -1769,7 +1770,7 @@ void path_fix_case(char_u *name) } // Open the directory where the file is located. - char_u *slash = vim_strrchr(name, '/'); + char_u *slash = STRRCHR(name, '/'); char_u *tail; Directory dir; bool ok; @@ -1818,7 +1819,7 @@ void path_fix_case(char_u *name) int after_pathsep(const char *b, const char *p) { return p > b && vim_ispathsep(p[-1]) - && (!has_mbyte || (*mb_head_off)((char_u *)b, (char_u *)p - 1) == 0); + && utf_head_off((char_u *)b, (char_u *)p - 1) == 0; } /* @@ -2212,10 +2213,10 @@ static int path_to_absolute(const char_u *fname, char_u *buf, size_t len, // expand it if forced or not an absolute path if (force || !path_is_absolute(fname)) { - p = vim_strrchr(fname, '/'); + p = STRRCHR(fname, '/'); #ifdef WIN32 if (p == NULL) { - p = vim_strrchr(fname, '\\'); + p = STRRCHR(fname, '\\'); } #endif if (p != NULL) { diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt index 6811f99add..3a70264dd1 100644 --- a/src/nvim/po/CMakeLists.txt +++ b/src/nvim/po/CMakeLists.txt @@ -8,6 +8,7 @@ if(NOT LANGUAGES) af ca cs + da de en_GB eo diff --git a/src/nvim/po/af.po b/src/nvim/po/af.po index f42ad04409..61ad72d7e0 100644 --- a/src/nvim/po/af.po +++ b/src/nvim/po/af.po @@ -2362,7 +2362,7 @@ msgstr "E216: Geen sodanige groep of gebeurtenis nie: %s" #. Highlight title msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Outobevele ---" @@ -2381,7 +2381,7 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: outobevele te diep genes" #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s outobevele vir \"%s\"" #, c-format @@ -4353,7 +4353,7 @@ msgstr "E55: Onpaar %s)" msgid "E66: \\z( not allowed here" msgstr "E66: \\z( nie hier toegelaat nie" -msgid "E67: \\z1 et al. not allowed here" +msgid "E67: \\z1 - \\z9 not allowed here" msgstr "E67: \\z1 e.a. nie hier toegelaat nie" #, c-format diff --git a/src/nvim/po/ca.po b/src/nvim/po/ca.po index b485b61491..7e83cb08ed 100644 --- a/src/nvim/po/ca.po +++ b/src/nvim/po/ca.po @@ -3409,7 +3409,7 @@ msgstr "-q [ftxerrors] edita el fitxer on hi ha el primer error" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5349,8 +5349,8 @@ msgstr "Atenció: la regió %s no està suportada" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Llegint el fitxer d'afixos %s ..." +msgid "Reading affix file %s..." +msgstr "Llegint el fitxer d'afixos %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5548,8 +5548,8 @@ msgstr "%d paraula/es ignorada/es amb caràcters no-ASCII a %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Llegint el fitxer de paraules %s ..." +msgid "Reading word file %s..." +msgstr "Llegint el fitxer de paraules %s..." #: ../spell.c:6155 #, c-format @@ -5619,8 +5619,8 @@ msgstr "Nombre total de paraules: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Escrivint el fitxer de suggeriments %s ..." +msgid "Writing suggestion file %s..." +msgstr "Escrivint el fitxer de suggeriments %s..." #: ../spell.c:7707 ../spell.c:7927 #, c-format @@ -5646,8 +5646,8 @@ msgstr "Atenció: s'ha especificat composició i NOBREAK alhora" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Escrivint el fitxer d'ortografia %s ..." +msgid "Writing spell file %s..." +msgstr "Escrivint el fitxer d'ortografia %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/check.vim b/src/nvim/po/check.vim index b323174550..eae27ef74d 100644 --- a/src/nvim/po/check.vim +++ b/src/nvim/po/check.vim @@ -38,6 +38,7 @@ let s:save_wrapscan = &wrapscan set nowrapscan " Start at the first "msgid" line. +let wsv = winsaveview() 1 /^msgid\> @@ -113,9 +114,96 @@ if search('msgid "\("\n"\)\?\([EW][0-9]\+:\).*\nmsgstr "\("\n"\)\?[^"]\@=\2\@!') endif endif +func! CountNl(first, last) + let nl = 0 + for lnum in range(a:first, a:last) + let nl += count(getline(lnum), "\n") + endfor + return nl +endfunc + +" Check that the \n at the end of the msgid line is also present in the msgstr +" line. Skip over the header. +1 +/^"MIME-Version: +while 1 + let lnum = search('^msgid\>') + if lnum <= 0 + break + endif + let strlnum = search('^msgstr\>') + let end = search('^$') + if end <= 0 + let end = line('$') + 1 + endif + let origcount = CountNl(lnum, strlnum - 1) + let transcount = CountNl(strlnum, end - 1) + " Allow for a few more or less line breaks when there are 2 or more + if origcount != transcount && (origcount <= 2 || transcount <= 2) + echomsg 'Mismatching "\n" in line ' . line('.') + if error == 0 + let error = lnum + endif + endif +endwhile + +" Check that the file is well formed according to msgfmts understanding +if executable("msgfmt") + let filename = expand("%") + let a = system("msgfmt --statistics OLD_PO_FILE_INPUT=yes " . filename) + if v:shell_error != 0 + let error = matchstr(a, filename.':\zs\d\+\ze:')+0 + for line in split(a, '\n') | echomsg line | endfor + endif +endif + +" Check that the plural form is properly initialized +1 +let plural = search('^msgid_plural ', 'n') +if (plural && search('^"Plural-Forms: ', 'n') == 0) || (plural && search('^msgstr\[0\] ".\+"', 'n') != plural + 1) + if search('^"Plural-Forms: ', 'n') == 0 + echomsg "Missing Plural header" + if error == 0 + let error = search('\(^"[A-Za-z-_]\+: .*\\n"\n\)\+\zs', 'n') - 1 + endif + elseif error == 0 + let error = plural + endif +elseif !plural && search('^"Plural-Forms: ', 'n') + " We allow for a stray plural header, msginit adds one. +endif + +" Check that 8bit encoding is used instead of 8-bit +let cte = search('^"Content-Transfer-Encoding:\s\+8-bit', 'n') +let ctc = search('^"Content-Type:.*;\s\+\<charset=[iI][sS][oO]_', 'n') +let ctu = search('^"Content-Type:.*;\s\+\<charset=utf-8', 'n') +if cte + echomsg "Content-Transfer-Encoding should be 8bit instead of 8-bit" + " TODO: make this an error + " if error == 0 + " let error = cte + " endif +elseif ctc + echomsg "Content-Type charset should be 'ISO-...' instead of 'ISO_...'" + " TODO: make this an error + " if error == 0 + " let error = ct + " endif +elseif ctu + echomsg "Content-Type charset should be 'UTF-8' instead of 'utf-8'" + " TODO: make this an error + " if error == 0 + " let error = ct + " endif +endif + + if error == 0 + " If all was OK restore the view. + call winrestview(wsv) echomsg "OK" else + " Put the cursor on the line with the error. exe error endif diff --git a/src/nvim/po/cleanup.vim b/src/nvim/po/cleanup.vim index 24ae74ed38..b27d88092f 100644 --- a/src/nvim/po/cleanup.vim +++ b/src/nvim/po/cleanup.vim @@ -8,12 +8,18 @@ let s:was_diff = &diff setl nodiff -silent g/^#: /d +" untranslated message preceded by c-format or comment +silent g/^#, c-format\n#/.d +silent g/^#\..*\n#/.d + +silent g/^#[:~] /d silent g/^#, fuzzy\(, .*\)\=\nmsgid ""\@!/.+1,/^$/-1s/^/#\~ / silent g/^msgstr"/s//msgstr "/ silent g/^msgid"/s//msgid "/ silent g/^msgstr ""\(\n"\)\@!/?^msgid?,.s/^/#\~ / +silent g/^\n\n\n/.d + if s:was_diff setl diff endif diff --git a/src/nvim/po/cs.cp1250.po b/src/nvim/po/cs.cp1250.po index 112e949815..26bdbe8c45 100644 --- a/src/nvim/po/cs.cp1250.po +++ b/src/nvim/po/cs.cp1250.po @@ -2535,7 +2535,7 @@ msgstr "E216: Událost %s neexistuje" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Automatické pøíkazy ---" @@ -2559,7 +2559,7 @@ msgstr "E218: vnoøení automatického pøíkazu pøíliš hluboká" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s automatické pøíkazy pro \"%s\"" #: ../fileio.c:7149 @@ -3486,7 +3486,7 @@ msgstr "-q [chybový soubor] editovat soubor na místì výskytu první chyby" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/po/cs.po b/src/nvim/po/cs.po index 3839230df2..986d6753a8 100644 --- a/src/nvim/po/cs.po +++ b/src/nvim/po/cs.po @@ -2535,7 +2535,7 @@ msgstr "E216: Událost %s neexistuje" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Automatické pøíkazy ---" @@ -2559,7 +2559,7 @@ msgstr "E218: vnoøení automatického pøíkazu pøíli¹ hluboká" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s automatické pøíkazy pro \"%s\"" #: ../fileio.c:7149 @@ -3486,7 +3486,7 @@ msgstr "-q [chybový soubor] editovat soubor na místì výskytu první chyby" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/po/da.po b/src/nvim/po/da.po new file mode 100644 index 0000000000..58cd19210b --- /dev/null +++ b/src/nvim/po/da.po @@ -0,0 +1,7088 @@ +# Danish translation for Vim +# Copyright (C) 2018 The Vim authors +# This file is distributed under the same license as the vim package. +# scootergrisen, 2018. +msgid "" +msgstr "" +"Project-Id-Version: Vim 8.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-06-08 22:09+0200\n" +"PO-Revision-Date: 2018-06-23 23:30+0200\n" +"Last-Translator: scootergrisen\n" +"Language-Team: Danish\n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "E831: bf_key_init() called with empty password" +msgstr "E831: bf_key_init() kaldt med tom adgangskode" + +msgid "E820: sizeof(uint32_t) != 4" +msgstr "E820: sizeof(uint32_t) != 4" + +msgid "E817: Blowfish big/little endian use wrong" +msgstr "E817: Forkert brug af stor/lille byterækkefølge for blowfish" + +msgid "E818: sha256 test failed" +msgstr "E818: sha256-test mislykkede" + +msgid "E819: Blowfish test failed" +msgstr "E819: Blowfish-test mislykkede" + +msgid "[Location List]" +msgstr "[Placeringsliste]" + +msgid "[Quickfix List]" +msgstr "[Quickfix-liste]" + +msgid "E855: Autocommands caused command to abort" +msgstr "E855: Autokommandoer forÃ¥rsagede afbrydelse af kommando" + +msgid "E82: Cannot allocate any buffer, exiting..." +msgstr "E82: Kan ikke allokere buffer, afslutter..." + +msgid "E83: Cannot allocate buffer, using other one..." +msgstr "E83: Kan ikke allokere buffer, bruger en anden..." + +msgid "E931: Buffer cannot be registered" +msgstr "E931: Buffer kan ikke registreres" + +msgid "E937: Attempt to delete a buffer that is in use" +msgstr "E937: Forsøg pÃ¥ at slette en buffer som er i brug" + +msgid "E515: No buffers were unloaded" +msgstr "E515: Ingen buffere blev udlæst" + +msgid "E516: No buffers were deleted" +msgstr "E516: Ingen brugere blev slettet" + +msgid "E517: No buffers were wiped out" +msgstr "E517: Ingen buffere blev ryddet" + +msgid "1 buffer unloaded" +msgstr "1 buffer udlæst" + +#, c-format +msgid "%d buffers unloaded" +msgstr "%d buffere udlæst" + +msgid "1 buffer deleted" +msgstr "1 buffer slettet" + +#, c-format +msgid "%d buffers deleted" +msgstr "%d buffere slettet" + +msgid "1 buffer wiped out" +msgstr "1 buffer ryddet" + +#, c-format +msgid "%d buffers wiped out" +msgstr "%d buffere ryddet" + +msgid "E90: Cannot unload last buffer" +msgstr "E90: Kan ikke udlæse sidste buffer" + +msgid "E84: No modified buffer found" +msgstr "E84: Fandt ingen ændret buffer" + +msgid "E85: There is no listed buffer" +msgstr "E85: Der er ingen oplistet buffer" + +msgid "E87: Cannot go beyond last buffer" +msgstr "E87: Kan ikke gÃ¥ over sidste buffer" + +msgid "E88: Cannot go before first buffer" +msgstr "E88: Kan ikke gÃ¥ før første buffer" + +#, c-format +msgid "E89: No write since last change for buffer %ld (add ! to override)" +msgstr "" +"E89: Ingen skrivning siden sidste ændring for bufferen %ld (tilføj ! for at " +"tilsidesætte)" + +msgid "E948: Job still running (add ! to end the job)" +msgstr "E948: Job kører stadig (tilføj ! for at afslutte jobbet)" + +msgid "E37: No write since last change (add ! to override)" +msgstr "" +"E37: Ingen skrivning siden sidste ændring (tilføj ! for at tilsidesætte)" + +msgid "E948: Job still running" +msgstr "E948: Job kører stadig" + +msgid "E37: No write since last change" +msgstr "E37: Ingen skrivning siden sidste ændring" + +msgid "W14: Warning: List of file names overflow" +msgstr "W14: Advarsel: Overløb i liste over filnavne" + +#, c-format +msgid "E92: Buffer %ld not found" +msgstr "E92: Bufferen %ld blev ikke fundet" + +#, c-format +msgid "E93: More than one match for %s" +msgstr "E93: Flere end ét match for %s" + +#, c-format +msgid "E94: No matching buffer for %s" +msgstr "E94: Ingen matchende buffer for %s" + +#, c-format +msgid "line %ld" +msgstr "linje %ld" + +msgid "E95: Buffer with this name already exists" +msgstr "E95: Buffer med dette navn findes allerede" + +msgid " [Modified]" +msgstr " [Ændret]" + +msgid "[Not edited]" +msgstr "[Ikke redigeret]" + +msgid "[New file]" +msgstr "[Ny fil]" + +msgid "[Read errors]" +msgstr "[Læsefejl]" + +msgid "[RO]" +msgstr "[SB]" + +msgid "[readonly]" +msgstr "[skrivebeskyttet]" + +#, c-format +msgid "1 line --%d%%--" +msgstr "1 linje --%d%%--" + +#, c-format +msgid "%ld lines --%d%%--" +msgstr "%ld linjer --%d%%--" + +#, c-format +msgid "line %ld of %ld --%d%%-- col " +msgstr "linje %ld af %ld --%d%%-- kol " + +msgid "[No Name]" +msgstr "[Intet navn]" + +msgid "help" +msgstr "hjælp" + +msgid "[Help]" +msgstr "[Hjælp]" + +msgid "[Preview]" +msgstr "[ForhÃ¥ndsvisning]" + +msgid "All" +msgstr "Alt" + +msgid "Bot" +msgstr "Ned" + +msgid "Top" +msgstr "Øve" + +msgid "" +"\n" +"# Buffer list:\n" +msgstr "" +"\n" +"# Bufferliste:\n" + +msgid "E382: Cannot write, 'buftype' option is set" +msgstr "E382: Kan ikke skrive, 'buftype'-tilvalget er sat" + +msgid "[Prompt]" +msgstr "[Prompt]" + +msgid "[Scratch]" +msgstr "[Kladdeblok]" + +msgid "" +"\n" +"--- Signs ---" +msgstr "" +"\n" +"--- Signs ---" + +#, c-format +msgid "Signs for %s:" +msgstr "Signs for %s:" + +#, c-format +msgid " line=%ld id=%d name=%s" +msgstr " linje=%ld id=%d navn=%s" + +msgid "E902: Cannot connect to port" +msgstr "E902: Kan ikke oprette forbindelse til port" + +msgid "E901: gethostbyname() in channel_open()" +msgstr "E901: gethostbyname() i channel_open()" + +msgid "E898: socket() in channel_open()" +msgstr "E898: socket() i channel_open()" + +msgid "E903: received command with non-string argument" +msgstr "E903: modtog kommando med argument som ikke er en streng" + +msgid "E904: last argument for expr/call must be a number" +msgstr "E904: sidste argument for udtryk/kald skal være et nummer" + +msgid "E904: third argument for call must be a list" +msgstr "E904: tredje argument for kald skal være en liste" + +#, c-format +msgid "E905: received unknown command: %s" +msgstr "E905: modtog ukendt kommando: %s" + +#, c-format +msgid "E630: %s(): write while not connected" +msgstr "E630: %s(): skrivning mens der ikke er forbindelse" + +#, c-format +msgid "E631: %s(): write failed" +msgstr "E631: %s(): skrivning mislykkedes" + +#, c-format +msgid "E917: Cannot use a callback with %s()" +msgstr "E917: Kan ikke bruge et callback med %s()" + +msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" +msgstr "" +"E912: kan ikke bruge ch_evalexpr()/ch_sendexpr() med en rÃ¥- eller nl-kanal" + +msgid "E906: not an open channel" +msgstr "E906: ikke en Ã¥ben kanal" + +msgid "E920: _io file requires _name to be set" +msgstr "E920: _io-fil kræver at _name er sat" + +msgid "E915: in_io buffer requires in_buf or in_name to be set" +msgstr "E915: in_io-buffer kræver at in_buf eller in_name er sat" + +#, c-format +msgid "E918: buffer must be loaded: %s" +msgstr "E918: buffer skal være indlæst: %s" + +msgid "E821: File is encrypted with unknown method" +msgstr "E821: Filen er krypteret med ukendt metode" + +msgid "Warning: Using a weak encryption method; see :help 'cm'" +msgstr "Advarsel: Bruger en svag krypteringsmetode; se :help 'cm'" + +msgid "Enter encryption key: " +msgstr "Indtast krypteringsnøgle: " + +msgid "Enter same key again: " +msgstr "Indtast samme nøgle igen: " + +msgid "Keys don't match!" +msgstr "Nøglerne er ikke ens!" + +msgid "[crypted]" +msgstr "[crypted]" + +#, c-format +msgid "E720: Missing colon in Dictionary: %s" +msgstr "E720: Manglende kolon i ordbog: %s" + +#, c-format +msgid "E721: Duplicate key in Dictionary: \"%s\"" +msgstr "E721: Duplikeret nøgle i ordbog: \"%s\"" + +#, c-format +msgid "E722: Missing comma in Dictionary: %s" +msgstr "E722: Manglende komma i ordbog: %s" + +#, c-format +msgid "E723: Missing end of Dictionary '}': %s" +msgstr "E723: Manglende slutning pÃ¥ ordbog '}': %s" + +msgid "extend() argument" +msgstr "extend()-argument" + +#, c-format +msgid "E737: Key already exists: %s" +msgstr "E737: Nøgle findes allerede: %s" + +#, c-format +msgid "E96: Cannot diff more than %ld buffers" +msgstr "E96: Kan ikke diff'e flere end %ld buffere" + +msgid "E810: Cannot read or write temp files" +msgstr "E810: Kan ikke læse eller skrive midlertidige filer" + +msgid "E97: Cannot create diffs" +msgstr "E97: Kan ikke oprette diff'er" + +msgid "Patch file" +msgstr "Patch-fil" + +msgid "E816: Cannot read patch output" +msgstr "E816: Kan ikke læse patch-output" + +msgid "E98: Cannot read diff output" +msgstr "E98: Kan ikke læse diff-output" + +msgid "E99: Current buffer is not in diff mode" +msgstr "E99: Nuværende buffer er ikke i diff-tilstand" + +msgid "E793: No other buffer in diff mode is modifiable" +msgstr "E793: Ingen anden buffer i diff-tilstand kan ændres" + +msgid "E100: No other buffer in diff mode" +msgstr "E100: Ingen anden buffer i diff-tilstand" + +msgid "E101: More than two buffers in diff mode, don't know which one to use" +msgstr "" +"E101: Mere end to buffere i diff-tilstand, ved ikke hvilke der skal bruges" + +#, c-format +msgid "E102: Can't find buffer \"%s\"" +msgstr "E102: Kan ikke finde bufferen \"%s\"" + +#, c-format +msgid "E103: Buffer \"%s\" is not in diff mode" +msgstr "E103: Bufferen \"%s\" er ikke i diff-tilstand" + +msgid "E787: Buffer changed unexpectedly" +msgstr "E787: Buffer ændret uventet" + +msgid "E104: Escape not allowed in digraph" +msgstr "E104: Escape ikke tilladt i digraf" + +msgid "E544: Keymap file not found" +msgstr "E544: Keymap-fil ikke fundet" + +msgid "E105: Using :loadkeymap not in a sourced file" +msgstr "E105: Bruger :loadkeymap ikke i en sourced fil" + +msgid "E791: Empty keymap entry" +msgstr "E791: Tom keymap-post" + +msgid " Keyword completion (^N^P)" +msgstr " Fuldførelse af nøgleord (^N^P)" + +msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" +msgstr " ^X tilstand (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" + +msgid " Whole line completion (^L^N^P)" +msgstr " Fuldførelse af hel linje (^L^N^P)" + +msgid " File name completion (^F^N^P)" +msgstr " Fuldførelse af filnavn (^F^N^P)" + +msgid " Tag completion (^]^N^P)" +msgstr " Fuldførelse af tag (^]^N^P)" + +msgid " Path pattern completion (^N^P)" +msgstr " Fuldførelse af sti (^N^P)" + +msgid " Definition completion (^D^N^P)" +msgstr " Fuldførelse af definition (^D^N^P)" + +msgid " Dictionary completion (^K^N^P)" +msgstr " Fuldførelse af ordbog (^K^N^P)" + +msgid " Thesaurus completion (^T^N^P)" +msgstr " Fuldførelse af tesaurus (^T^N^P)" + +msgid " Command-line completion (^V^N^P)" +msgstr " Fuldførelse af kommandolinje (^V^N^P)" + +msgid " User defined completion (^U^N^P)" +msgstr " Fuldførelse af brugerdefineret (^U^N^P)" + +msgid " Omni completion (^O^N^P)" +msgstr " Fuldførelse af omni (^O^N^P)" + +msgid " Spelling suggestion (s^N^P)" +msgstr " Staveforslag (s^N^P)" + +msgid " Keyword Local completion (^N^P)" +msgstr " Fuldførelse af nøgleord local (^N^P)" + +msgid "Hit end of paragraph" +msgstr "Stødte pÃ¥ slutningen af afsnit" + +msgid "E839: Completion function changed window" +msgstr "E839: Fuldførelse-funktion ændrede vindue" + +msgid "E840: Completion function deleted text" +msgstr "E840: Fuldførelse-funktion slettede tekst" + +msgid "'dictionary' option is empty" +msgstr "'dictionary'-tilvalget er tomt" + +msgid "'thesaurus' option is empty" +msgstr "'thesaurus'-tilvalget er tomt" + +#, c-format +msgid "Scanning dictionary: %s" +msgstr "Skanner ordbog: %s" + +msgid " (insert) Scroll (^E/^Y)" +msgstr " (indsæt) Rul (^E/^Y)" + +msgid " (replace) Scroll (^E/^Y)" +msgstr " (erstat) Rul (^E/^Y)" + +#, c-format +msgid "Scanning: %s" +msgstr "Skanner: %s" + +msgid "Scanning tags." +msgstr "Skanner tags." + +msgid "match in file" +msgstr "match i fil" + +msgid " Adding" +msgstr " Tilføjer" + +msgid "-- Searching..." +msgstr "-- Søger..." + +msgid "Back at original" +msgstr "Tilbage ved original" + +msgid "Word from other line" +msgstr "Ord fra anden linje" + +msgid "The only match" +msgstr "Det eneste match" + +#, c-format +msgid "match %d of %d" +msgstr "match %d af %d" + +#, c-format +msgid "match %d" +msgstr "match %d" + +msgid "E18: Unexpected characters in :let" +msgstr "E18: Uventede tegn i :let" + +#, c-format +msgid "E121: Undefined variable: %s" +msgstr "E121: Udefineret variabel: %s" + +msgid "E111: Missing ']'" +msgstr "E111: Manglende ']'" + +msgid "E719: Cannot use [:] with a Dictionary" +msgstr "E719: Kan ikke bruge [:] med en ordbog" + +#, c-format +msgid "E734: Wrong variable type for %s=" +msgstr "E734: Forkert variabeltype for %s=" + +#, c-format +msgid "E461: Illegal variable name: %s" +msgstr "E461: Ulovligt variabelnavn: %s" + +msgid "E806: using Float as a String" +msgstr "E806: bruger flydende kommatal som en streng" + +msgid "E687: Less targets than List items" +msgstr "E687: Færre mÃ¥l end listepunkter" + +msgid "E688: More targets than List items" +msgstr "E688: Flere mÃ¥l end listepunkter" + +msgid "Double ; in list of variables" +msgstr "Dobbelt ; i liste over variabler" + +#, c-format +msgid "E738: Can't list variables for %s" +msgstr "E738: Kan ikke opliste variabler for %s" + +msgid "E689: Can only index a List or Dictionary" +msgstr "E689: Kan kun indeksere en liste eller ordbog" + +msgid "E708: [:] must come last" +msgstr "E708: [:] skal være sidst" + +msgid "E709: [:] requires a List value" +msgstr "E709: [:] kræver en listeværdi" + +msgid "E710: List value has more items than target" +msgstr "E710: Listeværdi har flere punkter end mÃ¥l" + +msgid "E711: List value has not enough items" +msgstr "E711: Listeværdi har ikke nok punkter" + +msgid "E690: Missing \"in\" after :for" +msgstr "E690: Manglende \"in\" efter :for" + +#, c-format +msgid "E108: No such variable: \"%s\"" +msgstr "E108: Ingen sÃ¥dan variabel: \"%s\"" + +#, c-format +msgid "E940: Cannot lock or unlock variable %s" +msgstr "E940: Kan ikke lÃ¥se eller lÃ¥se op for variablen %s" + +msgid "E743: variable nested too deep for (un)lock" +msgstr "E743: variabel indlejret for dybt til at blive lÃ¥st/lÃ¥st op" + +msgid "E109: Missing ':' after '?'" +msgstr "E109: Manglende ':' efter '?'" + +msgid "E804: Cannot use '%' with Float" +msgstr "E804: Kan ikke bruge '%' med flydende kommatal" + +msgid "E110: Missing ')'" +msgstr "E110: Manglende ')'" + +msgid "E695: Cannot index a Funcref" +msgstr "E695: Kan ikke indeksere en funcref" + +msgid "E909: Cannot index a special variable" +msgstr "E909: Kan ikke indeksere en speciel variabel" + +#, c-format +msgid "E112: Option name missing: %s" +msgstr "E112: Tilvalgsnavn mangler: %s" + +#, c-format +msgid "E113: Unknown option: %s" +msgstr "E113: Ukendt tilvalg: %s" + +#, c-format +msgid "E114: Missing quote: %s" +msgstr "E114: Manglende citationstegn: %s" + +#, c-format +msgid "E115: Missing quote: %s" +msgstr "E115: Manglende citationstegn: %s" + +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "Ikke nok hukommelse til at sætte referencer, affaldsindsamling afbrudt!" + +msgid "E724: variable nested too deep for displaying" +msgstr "E724: variabel indlejret for dybt til at blive vist" + +msgid "E805: Using a Float as a Number" +msgstr "E805: Bruger et flydende kommatal som et nummer" + +msgid "E703: Using a Funcref as a Number" +msgstr "E703: Bruger en funcref som et nummer" + +msgid "E745: Using a List as a Number" +msgstr "E745: Bruger en liste som et nummer" + +msgid "E728: Using a Dictionary as a Number" +msgstr "E728: Bruger en ordbog som et nummer" + +msgid "E910: Using a Job as a Number" +msgstr "E910: Bruger et job som et nummer" + +msgid "E913: Using a Channel as a Number" +msgstr "E913: Bruger en kanal som et nummer" + +msgid "E891: Using a Funcref as a Float" +msgstr "E891: Bruger en funcref som et fyldende kommatal" + +msgid "E892: Using a String as a Float" +msgstr "E892: Bruger en streng som et flydende kommatal" + +msgid "E893: Using a List as a Float" +msgstr "E893: Bruger en liste som et flydende kommatal" + +msgid "E894: Using a Dictionary as a Float" +msgstr "E894: Bruger en ordbog som et flydende kommatal" + +msgid "E907: Using a special value as a Float" +msgstr "E907: Bruger en speciel værdi som et flydende kommatal" + +msgid "E911: Using a Job as a Float" +msgstr "E911: Bruger et job som et flydende kommatal" + +msgid "E914: Using a Channel as a Float" +msgstr "E914: Bruger en kanal som et flydende kommatal" + +msgid "E729: using Funcref as a String" +msgstr "E729: bruger funcref som en streng" + +msgid "E730: using List as a String" +msgstr "E730: bruger liste som en streng" + +msgid "E731: using Dictionary as a String" +msgstr "E731: bruger ordbog som en streng" + +msgid "E908: using an invalid value as a String" +msgstr "E908: bruger en ugyldig værdi som en streng" + +#, c-format +msgid "E795: Cannot delete variable %s" +msgstr "E795: Kan ikke slette variablen %s" + +#, c-format +msgid "E704: Funcref variable name must start with a capital: %s" +msgstr "E704: Funcref-variabelnavn skal begynde med et stort bogstav: %s" + +#, c-format +msgid "E705: Variable name conflicts with existing function: %s" +msgstr "E705: Variabelnavn er i konflikt med eksisterende funktion: %s" + +#, c-format +msgid "E741: Value is locked: %s" +msgstr "E741: Værdien er lÃ¥st: %s" + +msgid "Unknown" +msgstr "Ukendt" + +#, c-format +msgid "E742: Cannot change value of %s" +msgstr "E742: Kan ikke ændre værdien af %s" + +msgid "E698: variable nested too deep for making a copy" +msgstr "E698: variabel indlejret for dybt til at lave en kopi" + +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# globale variabler:\n" + +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\tSidst sat fra " + +msgid "E691: Can only compare List with List" +msgstr "E691: Kan kun sammenligne liste med liste" + +msgid "E692: Invalid operation for List" +msgstr "E692: Ugyldig handling for liste" + +msgid "E735: Can only compare Dictionary with Dictionary" +msgstr "E735: Kan kun sammenligne ordbog med ordbog" + +msgid "E736: Invalid operation for Dictionary" +msgstr "E736: Ugyldig handling for ordbog" + +msgid "E694: Invalid operation for Funcrefs" +msgstr "E694: Ugyldig handling for funcref'er" + +msgid "map() argument" +msgstr "map()-argument" + +msgid "filter() argument" +msgstr "filter()-argument" + +#, c-format +msgid "E686: Argument of %s must be a List" +msgstr "E686: Argument af %s skal være en liste" + +msgid "E928: String required" +msgstr "E928: Streng kræves" + +msgid "E808: Number or Float required" +msgstr "E808: Nummer eller flydende kommatal kræves" + +msgid "add() argument" +msgstr "add()-argument" + +msgid "E785: complete() can only be used in Insert mode" +msgstr "E785: complete() kan kun bruges i indsæt-tilstand" + +msgid "&Ok" +msgstr "&Ok" + +#, c-format +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld linje: " +msgstr[1] "+-%s%3ld linjer: " + +#, c-format +msgid "E700: Unknown function: %s" +msgstr "E700: Ukendt funktion: %s" + +msgid "E922: expected a dict" +msgstr "E922: ventede en ordbog" + +msgid "E923: Second argument of function() must be a list or a dict" +msgstr "E923: Andet argument af function() skal være en liste eller en ordbog" + +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"&OK\n" +"&Annuller" + +msgid "called inputrestore() more often than inputsave()" +msgstr "kaldte inputrestore() flere gange end inputsave()" + +msgid "insert() argument" +msgstr "insert()-argument" + +msgid "E786: Range not allowed" +msgstr "E786: OmrÃ¥de ikke tilladt" + +msgid "E916: not a valid job" +msgstr "E916: ikke et gyldigt job" + +msgid "E701: Invalid type for len()" +msgstr "E701: Ugyldig type for len()" + +#, c-format +msgid "E798: ID is reserved for \":match\": %ld" +msgstr "E798: ID er reserveret til \":match\": %ld" + +msgid "E726: Stride is zero" +msgstr "E726: Stride er nul" + +msgid "E727: Start past end" +msgstr "E727: Start efter slutningen" + +msgid "<empty>" +msgstr "<tom>" + +msgid "E240: No connection to the X server" +msgstr "E240: Ingen forbindelse til X-serveren" + +#, c-format +msgid "E241: Unable to send to %s" +msgstr "E241: Kan ikke sende til %s" + +msgid "E277: Unable to read a server reply" +msgstr "E277: Kan ikke læse et serversvar" + +msgid "E941: already started a server" +msgstr "E941: allerede startet en server" + +msgid "E942: +clientserver feature not available" +msgstr "E942: +clientserver-funktionalitet ikke tilgængelig" + +msgid "remove() argument" +msgstr "remove()-argument" + +msgid "E655: Too many symbolic links (cycle?)" +msgstr "E655: For mange symbolske links (cyklus?)" + +msgid "reverse() argument" +msgstr "reverse()-argument" + +msgid "E258: Unable to send to client" +msgstr "E258: Kan ikke sende til klient" + +#, c-format +msgid "E927: Invalid action: '%s'" +msgstr "E927: Ugyldig handling: '%s'" + +msgid "sort() argument" +msgstr "sort()-argument" + +msgid "uniq() argument" +msgstr "uniq()-argument" + +msgid "E702: Sort compare function failed" +msgstr "E702: Sort-sammenligningsfunktion mislykkedes" + +msgid "E882: Uniq compare function failed" +msgstr "E882: Uniq-sammenligningsfunktion mislykkedes" + +msgid "(Invalid)" +msgstr "(Ugyldig)" + +#, c-format +msgid "E935: invalid submatch number: %d" +msgstr "E935: ugyldigt undermatch-nummer: %d" + +msgid "E677: Error writing temp file" +msgstr "E677: Fejl ved skrivning af midlertidig fil" + +msgid "E921: Invalid callback argument" +msgstr "E921: Ugyldigt callback-argument" + +#, c-format +msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s" +msgstr "<%s>%s%s %d, hex %02x, oct %03o, digr %s" + +#, c-format +msgid "<%s>%s%s %d, Hex %02x, Octal %03o" +msgstr "<%s>%s%s %d, hex %02x, octal %03o" + +#, c-format +msgid "> %d, Hex %04x, Oct %o, Digr %s" +msgstr "> %d, hex %04x, oct %o, digr %s" + +#, c-format +msgid "> %d, Hex %08x, Oct %o, Digr %s" +msgstr "> %d, hex %08x, oct %o, digr %s" + +#, c-format +msgid "> %d, Hex %04x, Octal %o" +msgstr "> %d, hex %04x, octal %o" + +#, c-format +msgid "> %d, Hex %08x, Octal %o" +msgstr "> %d, hex %08x, octal %o" + +msgid "E134: Move lines into themselves" +msgstr "E134: flyt linjer ind i dem selv" + +msgid "1 line moved" +msgstr "1 linje flyttet" + +#, c-format +msgid "%ld lines moved" +msgstr "%ld linjer flyttet" + +#, c-format +msgid "%ld lines filtered" +msgstr "%ld linjer filtreret" + +msgid "E135: *Filter* Autocommands must not change current buffer" +msgstr "E135: *Filter*-autokommandoer mÃ¥ ikke ændre nuværende buffer" + +msgid "[No write since last change]\n" +msgstr "[Ingen skrivning siden sidste ændring]\n" + +#, c-format +msgid "%sviminfo: %s in line: " +msgstr "%sviminfo: %s pÃ¥ linje: " + +msgid "E136: viminfo: Too many errors, skipping rest of file" +msgstr "E136: viminfo: For mange fejl, springer resten af filen over" + +#, c-format +msgid "Reading viminfo file \"%s\"%s%s%s" +msgstr "Læser viminfo-filen \"%s\"%s%s%s" + +msgid " info" +msgstr " info" + +msgid " marks" +msgstr " mærker" + +msgid " oldfiles" +msgstr " gamle filer" + +msgid " FAILED" +msgstr " MISLYKKEDES" + +#, c-format +msgid "E137: Viminfo file is not writable: %s" +msgstr "E137: Viminfo-filen er skrivebeskyttet: %s" + +#, c-format +msgid "E929: Too many viminfo temp files, like %s!" +msgstr "E929: For mange midlertidige filer for viminfo, sÃ¥som %s!" + +#, c-format +msgid "E138: Can't write viminfo file %s!" +msgstr "E138: Kan ikke skrive viminfo-filen %s!" + +#, c-format +msgid "Writing viminfo file \"%s\"" +msgstr "Skriver viminfo-filen \"%s\"" + +#, c-format +msgid "E886: Can't rename viminfo file to %s!" +msgstr "E886: Kan ikke omdøbe viminfo-fil til %s!" + +#, c-format +msgid "# This viminfo file was generated by Vim %s.\n" +msgstr "# Denne viminfo-fil blev genereret af Vim %s.\n" + +msgid "" +"# You may edit it if you're careful!\n" +"\n" +msgstr "" +"# Du kan redigere den, hvis du er forsigtig!\n" +"\n" + +msgid "# Value of 'encoding' when this file was written\n" +msgstr "# Værdien af 'encoding' da filen blev skrevet\n" + +msgid "Illegal starting char" +msgstr "Ulovligt tegn i begyndelsen" + +msgid "" +"\n" +"# Bar lines, copied verbatim:\n" +msgstr "" +"\n" +"#-bjælkelinjer, kopieret ordret:\n" + +msgid "Save As" +msgstr "Gem som" + +msgid "Write partial file?" +msgstr "Skriv ufuldstændig fil?" + +msgid "E140: Use ! to write partial buffer" +msgstr "E140: Brug ! til at skrive ufuldstændig buffer" + +#, c-format +msgid "Overwrite existing file \"%s\"?" +msgstr "Overskriv eksisterende fil \"%s\"?" + +#, c-format +msgid "Swap file \"%s\" exists, overwrite anyway?" +msgstr "Swap-filen \"%s\" findes, overskriv alligevel?" + +#, c-format +msgid "E768: Swap file exists: %s (:silent! overrides)" +msgstr "E768: Swap-filen findes: %s (:silent! tilsidesætter)" + +#, c-format +msgid "E141: No file name for buffer %ld" +msgstr "E141: Intet filnavn for buffer %ld" + +msgid "E142: File not written: Writing is disabled by 'write' option" +msgstr "E142: Fil ikke skrevet: Skrivning er deaktiveret af 'write'-tilvalget" + +#, c-format +msgid "" +"'readonly' option is set for \"%s\".\n" +"Do you wish to write anyway?" +msgstr "" +"'readonly'-tilvalget er sat for \"%s\".\n" +"Vil du skrive alligevel?" + +#, c-format +msgid "" +"File permissions of \"%s\" are read-only.\n" +"It may still be possible to write it.\n" +"Do you wish to try?" +msgstr "" +"Filtilladelserne for \"%s\" er skrivebeskyttede.\n" +"Der kan stadig være mulighed for at skrive den.\n" +"Vil du prøve?" + +#, c-format +msgid "E505: \"%s\" is read-only (add ! to override)" +msgstr "E505: \"%s\" er skrivebeskyttet (tilføj ! for at tilsidesætte)" + +msgid "Edit File" +msgstr "Rediger fil" + +#, c-format +msgid "E143: Autocommands unexpectedly deleted new buffer %s" +msgstr "E143: Autokommandoer slettede uventede ny buffer %s" + +msgid "E144: non-numeric argument to :z" +msgstr "E144: ikke-numerisk argument til :z" + +msgid "E145: Shell commands not allowed in rvim" +msgstr "E145: Skalkommandoer er ikke tilladt i rvim" + +msgid "E146: Regular expressions can't be delimited by letters" +msgstr "E146: Regulære udtryk kan ikke afgrænses af bogstaver" + +#, c-format +msgid "replace with %s (y/n/a/q/l/^E/^Y)?" +msgstr "erstat med %s (y/n/a/q/l/^E/^Y)?" + +msgid "(Interrupted) " +msgstr "(Afbrudt) " + +msgid "1 match" +msgstr "1 match" + +msgid "1 substitution" +msgstr "1 erstatning" + +#, c-format +msgid "%ld matches" +msgstr "%ld match" + +#, c-format +msgid "%ld substitutions" +msgstr "%ld erstatninger" + +msgid " on 1 line" +msgstr " pÃ¥ 1 linje" + +#, c-format +msgid " on %ld lines" +msgstr " pÃ¥ %ld linjer" + +msgid "E147: Cannot do :global recursive with a range" +msgstr "E147: Kan ikke foretage :global rekursivt med et omrÃ¥de" + +msgid "E148: Regular expression missing from global" +msgstr "E148: Regulære udtryk mangler fra global" + +#, c-format +msgid "Pattern found in every line: %s" +msgstr "Mønster fundet pÃ¥ hver linje: %s" + +#, c-format +msgid "Pattern not found: %s" +msgstr "Mønster ikke fundet: %s" + +msgid "" +"\n" +"# Last Substitute String:\n" +"$" +msgstr "" +"\n" +"# Sidste erstatningsstreng:\n" +"$" + +msgid "E478: Don't panic!" +msgstr "E478: Tag det bare helt roligt!" + +#, c-format +msgid "E661: Sorry, no '%s' help for %s" +msgstr "E661: Beklager, ingen '%s' hjælp til %s" + +#, c-format +msgid "E149: Sorry, no help for %s" +msgstr "E149: Beklager, ingen hjælp til %s" + +#, c-format +msgid "Sorry, help file \"%s\" not found" +msgstr "Beklager, hjælpfilen \"%s\" ikke fundet" + +#, c-format +msgid "E151: No match: %s" +msgstr "E151: Intet match: %s" + +#, c-format +msgid "E152: Cannot open %s for writing" +msgstr "E152: Kan ikke Ã¥bne %s til skrivning" + +#, c-format +msgid "E153: Unable to open %s for reading" +msgstr "E153: Kan ikke Ã¥bne %s til læsning" + +#, c-format +msgid "E670: Mix of help file encodings within a language: %s" +msgstr "E670: Blanding af kodninger for hjælpfiler i samme sprog: %s" + +#, c-format +msgid "E154: Duplicate tag \"%s\" in file %s/%s" +msgstr "E154: Duplikeret tag \"%s\" i fil %s/%s" + +#, c-format +msgid "E150: Not a directory: %s" +msgstr "E150: Ikke en mappe: %s" + +#, c-format +msgid "E160: Unknown sign command: %s" +msgstr "E160: Ukendt sign-kommando: %s" + +msgid "E156: Missing sign name" +msgstr "E156: Manglende sign-navn" + +msgid "E612: Too many signs defined" +msgstr "E612: For mange signs defineret" + +#, c-format +msgid "E239: Invalid sign text: %s" +msgstr "E239: Ugyldig sign-tekst: %s" + +#, c-format +msgid "E155: Unknown sign: %s" +msgstr "E155: Ukendt sign: %s" + +msgid "E159: Missing sign number" +msgstr "E159: Manglende sign-nummer" + +#, c-format +msgid "E158: Invalid buffer name: %s" +msgstr "E158: Ugyldigt buffernavn: %s" + +msgid "E934: Cannot jump to a buffer that does not have a name" +msgstr "E934: Kan ikke hoppe til en buffer som ikke har et navn" + +#, c-format +msgid "E157: Invalid sign ID: %ld" +msgstr "E157: Ugyldigt sign-ID: %ld" + +#, c-format +msgid "E885: Not possible to change sign %s" +msgstr "E885: Det er ikke muligt at ændre sign %s" + +msgid " (NOT FOUND)" +msgstr " (IKKE FUNDET)" + +msgid " (not supported)" +msgstr " (understøttes ikke)" + +msgid "[Deleted]" +msgstr "[Slettet]" + +msgid "No old files" +msgstr "Ingen gamle filer" + +msgid "Entering Debug mode. Type \"cont\" to continue." +msgstr "GÃ¥r i fejlretningstilstand. Skriv \"cont\" for at fortsætte." + +#, c-format +msgid "Oldval = \"%s\"" +msgstr "Oldval = \"%s\"" + +#, c-format +msgid "Newval = \"%s\"" +msgstr "Newval = \"%s\"" + +#, c-format +msgid "line %ld: %s" +msgstr "linje %ld: %s" + +#, c-format +msgid "cmd: %s" +msgstr "cmd: %s" + +msgid "frame is zero" +msgstr "ramme er nul" + +#, c-format +msgid "frame at highest level: %d" +msgstr "ramme pÃ¥ højeste niveau: %d" + +#, c-format +msgid "Breakpoint in \"%s%s\" line %ld" +msgstr "Breakpoint i \"%s%s\" linje %ld" + +#, c-format +msgid "E161: Breakpoint not found: %s" +msgstr "E161: Breakpoint ikke fundet: %s" + +msgid "No breakpoints defined" +msgstr "Ingen breakpoints defineret" + +#, c-format +msgid "%3d %s %s line %ld" +msgstr "%3d %s %s linje %ld" + +#, c-format +msgid "%3d expr %s" +msgstr "%3d udtryk %s" + +msgid "E750: First use \":profile start {fname}\"" +msgstr "E750: Brug først \":profile start {fname}\"" + +#, c-format +msgid "Save changes to \"%s\"?" +msgstr "Gem ændringer til \"%s\"?" + +#, c-format +msgid "E947: Job still running in buffer \"%s\"" +msgstr "E947: Job kører stadig i bufferen \"%s\"" + +#, c-format +msgid "E162: No write since last change for buffer \"%s\"" +msgstr "E162: Ingen skrivning siden sidste ændring for bufferen \"%s\"" + +msgid "Warning: Entered other buffer unexpectedly (check autocommands)" +msgstr "Advarsel: Indtastede anden buffer uventede (tjek autokommandoer)" + +msgid "E163: There is only one file to edit" +msgstr "E163: Der er kun én fil at redigere" + +msgid "E164: Cannot go before first file" +msgstr "E164: Kan ikke gÃ¥ før første fil" + +msgid "E165: Cannot go beyond last file" +msgstr "E165: Kan ikke gÃ¥ over sidste fil" + +#, c-format +msgid "E666: compiler not supported: %s" +msgstr "E666: kompiler understøttes ikke: %s" + +#, c-format +msgid "Searching for \"%s\" in \"%s\"" +msgstr "Søger efter \"%s\" i \"%s\"" + +#, c-format +msgid "Searching for \"%s\"" +msgstr "Søger efter \"%s\"" + +#, c-format +msgid "not found in '%s': \"%s\"" +msgstr "ikke fundet i '%s': \"%s\"" + +#, c-format +msgid "W20: Required python version 2.x not supported, ignoring file: %s" +msgstr "W20: Krævede python-version 2.x understøttes ikke, ignorerer fil: %s" + +#, c-format +msgid "W21: Required python version 3.x not supported, ignoring file: %s" +msgstr "W21: Krævede python-version 3.x understøttes ikke, ignorerer fil: %s" + +msgid "Source Vim script" +msgstr "Source Vim-script" + +#, c-format +msgid "Cannot source a directory: \"%s\"" +msgstr "Kan ikke source en mappe: \"%s\"" + +#, c-format +msgid "could not source \"%s\"" +msgstr "kunne ikke source \"%s\"" + +#, c-format +msgid "line %ld: could not source \"%s\"" +msgstr "linje %ld: kunne ikke source \"%s\"" + +#, c-format +msgid "sourcing \"%s\"" +msgstr "sourcing \"%s\"" + +#, c-format +msgid "line %ld: sourcing \"%s\"" +msgstr "linje %ld: sourcing \"%s\"" + +#, c-format +msgid "finished sourcing %s" +msgstr "færdig med sourcing af %s" + +#, c-format +msgid "continuing in %s" +msgstr "fortsætter i %s" + +msgid "modeline" +msgstr "tilstandslinje" + +msgid "--cmd argument" +msgstr "--cmd-argument" + +msgid "-c argument" +msgstr "-c-argument" + +msgid "environment variable" +msgstr "miljøvariabel" + +msgid "error handler" +msgstr "fejlhÃ¥ndtering" + +msgid "W15: Warning: Wrong line separator, ^M may be missing" +msgstr "W15: Advarsel: Forkert linjeseparator, ^M mangler muligvis" + +msgid "E167: :scriptencoding used outside of a sourced file" +msgstr "E167: :scriptencoding brugt udenfor en sourced fil" + +msgid "E168: :finish used outside of a sourced file" +msgstr "E168: :finish udenfor en sourced fil" + +#, c-format +msgid "Current %slanguage: \"%s\"" +msgstr "Nuværende %ssprog: \"%s\"" + +#, c-format +msgid "E197: Cannot set language to \"%s\"" +msgstr "E197: Kan ikke sætte sprog til \"%s\"" + +msgid "Entering Ex mode. Type \"visual\" to go to Normal mode." +msgstr "GÃ¥r i Ex-tilstand. Skriv \"visual\" for at gÃ¥ til normal tilstand." + +msgid "E501: At end-of-file" +msgstr "E501: Ved filens slutning" + +msgid "E169: Command too recursive" +msgstr "E169: Kommando for rekursiv" + +#, c-format +msgid "E605: Exception not caught: %s" +msgstr "E605: Undtagelse ikke fanget: %s" + +msgid "End of sourced file" +msgstr "Slut pÃ¥ sourced fil" + +msgid "End of function" +msgstr "Slutning af funktion" + +msgid "E464: Ambiguous use of user-defined command" +msgstr "E464: Flertydig brug af brugerdefineret kommando" + +msgid "E492: Not an editor command" +msgstr "E492: Ikke en editor-kommando" + +msgid "E493: Backwards range given" +msgstr "E493: Baglæns omrÃ¥de givet" + +msgid "Backwards range given, OK to swap" +msgstr "Baglæns omrÃ¥de givet, OK at bytte om" + +msgid "E494: Use w or w>>" +msgstr "E494: Brug w eller w>>" + +msgid "E943: Command table needs to be updated, run 'make cmdidxs'" +msgstr "E943: Kommandotabel skal opdateres, kør 'make cmdidxs'" + +msgid "E319: Sorry, the command is not available in this version" +msgstr "E319: Beklager, kommandoen er ikke tilgængelig i denne version" + +msgid "1 more file to edit. Quit anyway?" +msgstr "1 fil mere at redigere. Afslut alligevel?" + +#, c-format +msgid "%d more files to edit. Quit anyway?" +msgstr "%d filer mere at redigere. Afslut alligevel?" + +msgid "E173: 1 more file to edit" +msgstr "E173: 1 fil mere at redigere" + +#, c-format +msgid "E173: %ld more files to edit" +msgstr "E173: %ld filer mere at redigere" + +msgid "E174: Command already exists: add ! to replace it" +msgstr "E174: Kommandoen findes allerede: tilføj ! for at erstatte den" + +msgid "" +"\n" +" Name Args Address Complete Definition" +msgstr "" +"\n" +" Navn Argumenter Adresse Fuldført Definition" + +msgid "No user-defined commands found" +msgstr "Fandt ingen brugerdefinerede kommandoer" + +msgid "E175: No attribute specified" +msgstr "E175: Ingen attribut angivet" + +msgid "E176: Invalid number of arguments" +msgstr "E176: Ugyldigt antal argumenter" + +msgid "E177: Count cannot be specified twice" +msgstr "E177: Tælling mÃ¥ ikke angives to gange" + +msgid "E178: Invalid default value for count" +msgstr "E178: Ugyldig standardværdi for tælling" + +msgid "E179: argument required for -complete" +msgstr "E179: argument kræves til -complete" + +msgid "E179: argument required for -addr" +msgstr "E179: argument kræves til -addr" + +#, c-format +msgid "E181: Invalid attribute: %s" +msgstr "E181: Ugyldig attribut: %s" + +msgid "E182: Invalid command name" +msgstr "E182: Ugyldigt kommandonavn" + +msgid "E183: User defined commands must start with an uppercase letter" +msgstr "E183: Brugerdefinerede kommandoer skal begynde med et stort bogstav" + +msgid "E841: Reserved name, cannot be used for user defined command" +msgstr "E841: Reserveret navn, kan ikke bruges til brugerdefineret kommando" + +#, c-format +msgid "E184: No such user-defined command: %s" +msgstr "E184: Ingen sÃ¥dan brugerdefineret kommando: %s" + +#, c-format +msgid "E180: Invalid address type value: %s" +msgstr "E180: Ugyldig værdi for adressetype: %s" + +#, c-format +msgid "E180: Invalid complete value: %s" +msgstr "E180: Ugyldig complete-værdi: %s" + +msgid "E468: Completion argument only allowed for custom completion" +msgstr "E468: Fuldførelse-argument kun tilladt for tilpasset fuldførelse" + +msgid "E467: Custom completion requires a function argument" +msgstr "E467: Tilpasset fuldførelse kræver et funktion-argument" + +msgid "unknown" +msgstr "ukendt" + +#, c-format +msgid "E185: Cannot find color scheme '%s'" +msgstr "E185: Kan ikke finde farveskemaet '%s'" + +msgid "Greetings, Vim user!" +msgstr "Hejsa, Vim-bruger!" + +msgid "E784: Cannot close last tab page" +msgstr "E784: Kan ikke lukke sidste fanebladsside" + +msgid "Already only one tab page" +msgstr "Allerede kun én fanebladsside" + +msgid "Edit File in new window" +msgstr "Rediger fil i nyt vindue" + +#, c-format +msgid "Tab page %d" +msgstr "Fanebladsside %d" + +msgid "No swap file" +msgstr "Ingen swap-fil" + +msgid "Append File" +msgstr "Tilføj fil til slutningen" + +msgid "E747: Cannot change directory, buffer is modified (add ! to override)" +msgstr "" +"E747: Kan ikke skifte mappe, buffer er ændret (tilføj ! for at tilsidesætte)" + +msgid "E186: No previous directory" +msgstr "E186: Ingen tidligere ordbog" + +msgid "E187: Unknown" +msgstr "E187: Ukendt" + +msgid "E465: :winsize requires two number arguments" +msgstr "E465: :winsize kræver to nummer-argumenter" + +#, c-format +msgid "Window position: X %d, Y %d" +msgstr "Vinduesplacering: X %d, Y %d" + +msgid "E188: Obtaining window position not implemented for this platform" +msgstr "" +"E188: Indhentelse af vinduesplacering ikke implementeret pÃ¥ denne platform" + +msgid "E466: :winpos requires two number arguments" +msgstr "E466: :winpos kræver to nummer-argumenter" + +msgid "E930: Cannot use :redir inside execute()" +msgstr "E930: Kan ikke bruge :redir i execute()" + +msgid "Save Redirection" +msgstr "Gem omdirigering" + +msgid "Save View" +msgstr "Gem visning" + +msgid "Save Session" +msgstr "Gem session" + +msgid "Save Setup" +msgstr "Gem opsætning" + +#, c-format +msgid "E739: Cannot create directory: %s" +msgstr "E739: Kan ikke oprette mappe: %s" + +#, c-format +msgid "E189: \"%s\" exists (add ! to override)" +msgstr "E189: \"%s\" findes (tilføj ! for at tilsidesætte)" + +#, c-format +msgid "E190: Cannot open \"%s\" for writing" +msgstr "E190: Kan ikke Ã¥bne \"%s\" til skrivning" + +msgid "E191: Argument must be a letter or forward/backward quote" +msgstr "" +"E191: Argument skal være et bogstav eller retvendt/omvendt citationstegn" + +msgid "E192: Recursive use of :normal too deep" +msgstr "E192: Rekursiv brug af :normal for dyb" + +msgid "E809: #< is not available without the +eval feature" +msgstr "E809: #< er ikke tilgængelig uden +eval-funktionaliteten" + +msgid "E194: No alternate file name to substitute for '#'" +msgstr "E194: Intet alternate-filnavn til erstatning for '#'" + +msgid "E495: no autocommand file name to substitute for \"<afile>\"" +msgstr "E495: intet autokommando-filnavn til erstatning for \"<afile>\"" + +msgid "E496: no autocommand buffer number to substitute for \"<abuf>\"" +msgstr "E496: intet autokommando-buffernummer til erstatning for \"<abuf>\"" + +msgid "E497: no autocommand match name to substitute for \"<amatch>\"" +msgstr "E497: intet autokommando-matchnavn til erstatning for \"<amatch>\"" + +msgid "E498: no :source file name to substitute for \"<sfile>\"" +msgstr "E498: intet :source-filnavn til erstatning for \"<sfile>\"" + +msgid "E842: no line number to use for \"<slnum>\"" +msgstr "E842: intet linjenummer til brug for \"<slnum>\"" + +#, no-c-format +msgid "E499: Empty file name for '%' or '#', only works with \":p:h\"" +msgstr "E499: Tomt filnavn for '%' eller '#', virker kun med \":p:h\"" + +msgid "E500: Evaluates to an empty string" +msgstr "E500: Evaluerer til en tom streng" + +msgid "E195: Cannot open viminfo file for reading" +msgstr "E195: Kan ikke Ã¥bne viminfo-fil til læsning" + +msgid "Untitled" +msgstr "Unavngivet" + +msgid "E196: No digraphs in this version" +msgstr "E196: Ingen digraffer i denne version" + +msgid "E608: Cannot :throw exceptions with 'Vim' prefix" +msgstr "E608: Kan ikke :throw-undtagelser med 'Vim'-præfiks" + +#, c-format +msgid "Exception thrown: %s" +msgstr "Undtagelse kastet: %s" + +#, c-format +msgid "Exception finished: %s" +msgstr "Undtagelse færdig: %s" + +#, c-format +msgid "Exception discarded: %s" +msgstr "Undtagelse forkastet: %s" + +#, c-format +msgid "%s, line %ld" +msgstr "%s, linje %ld" + +#, c-format +msgid "Exception caught: %s" +msgstr "Undtagelse fanget: %s" + +#, c-format +msgid "%s made pending" +msgstr "%s gjort afventende" + +#, c-format +msgid "%s resumed" +msgstr "%s genoptaget" + +#, c-format +msgid "%s discarded" +msgstr "%s forkastet" + +msgid "Exception" +msgstr "Undtagelse" + +msgid "Error and interrupt" +msgstr "Fejl og afbryd" + +msgid "Error" +msgstr "Fejl" + +msgid "Interrupt" +msgstr "Afbryd" + +msgid "E579: :if nesting too deep" +msgstr "E579: :if-indlejring for dyb" + +msgid "E580: :endif without :if" +msgstr "E580: :endif uden :if" + +msgid "E581: :else without :if" +msgstr "E581: :else uden :if" + +msgid "E582: :elseif without :if" +msgstr "E582: :elseif uden :if" + +msgid "E583: multiple :else" +msgstr "E583: flere :else" + +msgid "E584: :elseif after :else" +msgstr "E584: :elseif efter :else" + +msgid "E585: :while/:for nesting too deep" +msgstr "E585: :while/:for-indlejring for dyb" + +msgid "E586: :continue without :while or :for" +msgstr "E586: :continue uden :while eller :for" + +msgid "E587: :break without :while or :for" +msgstr "E587: :break uden :while eller :for" + +msgid "E732: Using :endfor with :while" +msgstr "E732: Bruger :endfor med :while" + +msgid "E733: Using :endwhile with :for" +msgstr "E733: Bruger :endwhile med :for" + +msgid "E601: :try nesting too deep" +msgstr "E601: :try-indlejring for dyb" + +msgid "E603: :catch without :try" +msgstr "E603: :catch uden :try" + +msgid "E604: :catch after :finally" +msgstr "E604: :catch efter :finally" + +msgid "E606: :finally without :try" +msgstr "E606: :finally uden :try" + +msgid "E607: multiple :finally" +msgstr "E607: flere :finally" + +msgid "E602: :endtry without :try" +msgstr "E602: :endtry uden :try" + +msgid "E193: :endfunction not inside a function" +msgstr "E193: :endfunction ikke i en funktion" + +msgid "E788: Not allowed to edit another buffer now" +msgstr "E788: Ikke tilladt at redigere anden buffer nu" + +msgid "E811: Not allowed to change buffer information now" +msgstr "E811: Ikke tilladt at ændre bufferinformation nu" + +msgid "tagname" +msgstr "tagnavn" + +msgid " kind file\n" +msgstr " kind-fil\n" + +msgid "'history' option is zero" +msgstr "'history'-tilvalget er nul" + +#, c-format +msgid "" +"\n" +"# %s History (newest to oldest):\n" +msgstr "" +"\n" +"# %s Historik (nyeste til ældste):\n" + +msgid "Command Line" +msgstr "Kommandolinje" + +msgid "Search String" +msgstr "Søgestreng" + +msgid "Expression" +msgstr "Udtryk" + +msgid "Input Line" +msgstr "Inputlinje" + +msgid "Debug Line" +msgstr "Fejlretningslinje" + +msgid "E198: cmd_pchar beyond the command length" +msgstr "E198: cmd_pchar efter kommandolængden" + +msgid "E199: Active window or buffer deleted" +msgstr "E199: Aktivt vindue eller buffer slettet" + +msgid "E812: Autocommands changed buffer or buffer name" +msgstr "E812: Autokommandoer ændrede buffer eller buffernavn" + +msgid "Illegal file name" +msgstr "Ulovlig filnavn" + +msgid "is a directory" +msgstr "er en mappe" + +msgid "is not a file" +msgstr "er ikke en fil" + +msgid "is a device (disabled with 'opendevice' option)" +msgstr "er en enhed (deaktiveret med 'opendevice'-tilvalget)" + +msgid "[New File]" +msgstr "[Ny fil]" + +msgid "[New DIRECTORY]" +msgstr "[Ny MAPPE]" + +msgid "[File too big]" +msgstr "[Filen er for stor]" + +msgid "[Permission Denied]" +msgstr "[Tilladelse nægtet]" + +msgid "E200: *ReadPre autocommands made the file unreadable" +msgstr "E200: *ReadPre-autokommandoer gjorde filen ulæselig" + +msgid "E201: *ReadPre autocommands must not change current buffer" +msgstr "E201: *ReadPre-autokommandoer mÃ¥ ikke ændre nuværende buffer" + +msgid "Vim: Reading from stdin...\n" +msgstr "Vim: Læser fra stdin...\n" + +msgid "Reading from stdin..." +msgstr "Læser fra stdin..." + +msgid "E202: Conversion made file unreadable!" +msgstr "E202: Konvertering gjorde filen ulæselig!" + +msgid "[fifo/socket]" +msgstr "[fifo/sokkel]" + +msgid "[fifo]" +msgstr "[fifo]" + +msgid "[socket]" +msgstr "[sokkel]" + +msgid "[character special]" +msgstr "[character special]" + +msgid "[CR missing]" +msgstr "[CR mangler]" + +msgid "[long lines split]" +msgstr "[opdeling af lange linjer]" + +msgid "[NOT converted]" +msgstr "[IKKE konverteret]" + +msgid "[converted]" +msgstr "[konverteret]" + +#, c-format +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[KONVERTERINGSFEJL pÃ¥ linje %ld]" + +#, c-format +msgid "[ILLEGAL BYTE in line %ld]" +msgstr "[ULOVLIG BYTE pÃ¥ linje %ld]" + +msgid "[READ ERRORS]" +msgstr "[LÆSEFEJL]" + +msgid "Can't find temp file for conversion" +msgstr "Kan ikke finde midlertidig fil til konvertering" + +msgid "Conversion with 'charconvert' failed" +msgstr "Konvertering med 'charconvert' mislykkedes" + +msgid "can't read output of 'charconvert'" +msgstr "kan ikke læse output af 'charconvert'" + +msgid "E676: No matching autocommands for acwrite buffer" +msgstr "E676: Ingen matchende autokommandoer for acwrite-buffer" + +msgid "E203: Autocommands deleted or unloaded buffer to be written" +msgstr "E203: Autokommandoer slettet eller udlæste buffer som skal skrives" + +msgid "E204: Autocommand changed number of lines in unexpected way" +msgstr "E204: Autokommando ændrede antal linjer pÃ¥ en uventede mÃ¥de" + +msgid "NetBeans disallows writes of unmodified buffers" +msgstr "NetBeans tillader ikke skrivninger af uændrede buffere" + +msgid "Partial writes disallowed for NetBeans buffers" +msgstr "Ufuldstændige skrivninger er ikke tilladt for NetBeans-buffere" + +msgid "is not a file or writable device" +msgstr "er ikke en fil eller enhed som der kan skrives til" + +msgid "writing to device disabled with 'opendevice' option" +msgstr "skrivning til enhed er deaktiveret med 'opendevice'-tilvalget" + +msgid "is read-only (add ! to override)" +msgstr "er skrivebeskyttet (tilføj ! for at tilsidesætte)" + +msgid "E506: Can't write to backup file (add ! to override)" +msgstr "" +"E506: Kan ikke skrive til sikkerhedskopieret fil (tilføj ! for at " +"tilsidesætte)" + +msgid "E507: Close error for backup file (add ! to override)" +msgstr "" +"E507: Fejl ved lukning af sikkerhedskopieret fil (tilføj ! for at " +"tilsidesætte)" + +msgid "E508: Can't read file for backup (add ! to override)" +msgstr "" +"E508: Kan ikke læse fil til sikkerhedskopiering (tilføj ! for at " +"tilsidesætte)" + +msgid "E509: Cannot create backup file (add ! to override)" +msgstr "" +"E509: Kan ikke oprette (create) sikkerhedskopieret fil (tilføj ! for at " +"tilsidesætte)" + +msgid "E510: Can't make backup file (add ! to override)" +msgstr "" +"E510: Kan ikke oprette (make) sikkerhedskopieret fil (tilføj ! for at " +"tilsidesætte)" + +msgid "E214: Can't find temp file for writing" +msgstr "E214: Kan ikke finde midlertidig fil til skrivning" + +msgid "E213: Cannot convert (add ! to write without conversion)" +msgstr "E213: Kan ikke konvertere (tilføj ! for at skrive uden konvertering)" + +msgid "E166: Can't open linked file for writing" +msgstr "E166: Kan ikke Ã¥bne linket fil til skrivning" + +msgid "E212: Can't open file for writing" +msgstr "E212: Kan ikke Ã¥bne filen til skrivning" + +msgid "E949: File changed while writing" +msgstr "E949: Filen blev ændret ved skrivning" + +msgid "E512: Close failed" +msgstr "E512: Lukning mislykkedes" + +msgid "E513: write error, conversion failed (make 'fenc' empty to override)" +msgstr "" +"E513: fejl ved skrivning, konvertering mislykkedes (gør 'fenc' tom for at " +"tilsidesætte)" + +#, c-format +msgid "" +"E513: write error, conversion failed in line %ld (make 'fenc' empty to " +"override)" +msgstr "" +"E513: fejl ved skrivning, konvertering mislykkedes pÃ¥ linje %ld (gør 'fenc' " +"tom for at tilsidesætte)" + +msgid "E514: write error (file system full?)" +msgstr "E514: skrivefejl (er filsystemet fuldt?)" + +msgid " CONVERSION ERROR" +msgstr " KONVERTERINGSFEJL" + +#, c-format +msgid " in line %ld;" +msgstr " pÃ¥ linje %ld;" + +msgid "[Device]" +msgstr "[Enhed]" + +msgid "[New]" +msgstr "[Ny]" + +msgid " [a]" +msgstr " [a]" + +msgid " appended" +msgstr " tilføjet i slutningen" + +msgid " [w]" +msgstr " [s]" + +msgid " written" +msgstr " skrevet" + +msgid "E205: Patchmode: can't save original file" +msgstr "E205: Patchmode: kan ikke gemme original fil" + +msgid "E206: patchmode: can't touch empty original file" +msgstr "E206: patchmode: kan ikke touch tom original fil" + +msgid "E207: Can't delete backup file" +msgstr "E207: Kan ikke slette sikkerhedskopieret fil" + +msgid "" +"\n" +"WARNING: Original file may be lost or damaged\n" +msgstr "" +"\n" +"ADVARSEL: Den originale fil kan man mistet eller beskadiget\n" + +msgid "don't quit the editor until the file is successfully written!" +msgstr "afslut ikke editoren inden filen er blevet skrevet!" + +msgid "[dos]" +msgstr "[dos]" + +msgid "[dos format]" +msgstr "[dos-format]" + +msgid "[mac]" +msgstr "[mac]" + +msgid "[mac format]" +msgstr "[mac-format]" + +msgid "[unix]" +msgstr "[unix]" + +msgid "[unix format]" +msgstr "[unix-format]" + +msgid "1 line, " +msgstr "1 linje, " + +#, c-format +msgid "%ld lines, " +msgstr "%ld linjer, " + +msgid "1 character" +msgstr "1 tegn" + +#, c-format +msgid "%lld characters" +msgstr "%lld tegn" + +msgid "[noeol]" +msgstr "[ingen eol]" + +msgid "[Incomplete last line]" +msgstr "[Ufuldstændig sidste linje]" + +msgid "WARNING: The file has been changed since reading it!!!" +msgstr "ADVARSEL: Filen er blevet ændret siden den blev læst!!!" + +msgid "Do you really want to write to it" +msgstr "Vil du virkelig skrive den" + +#, c-format +msgid "E208: Error writing to \"%s\"" +msgstr "E208: Fejl ved skrivning til \"%s\"" + +#, c-format +msgid "E209: Error closing \"%s\"" +msgstr "E209: Fejl ved lukning af \"%s\"" + +#, c-format +msgid "E210: Error reading \"%s\"" +msgstr "E210: Fejl ved læsning af \"%s\"" + +msgid "E246: FileChangedShell autocommand deleted buffer" +msgstr "E246: FileChangedShell-autokommando slettede buffer" + +#, c-format +msgid "E211: File \"%s\" no longer available" +msgstr "E211: Filen \"%s\" er ikke længere tilgængelig" + +#, c-format +msgid "" +"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as " +"well" +msgstr "" +"W12: Advarsel: Filen \"%s\" er blevet ændret og bufferen blev ogsÃ¥ ændret i " +"Vim" + +msgid "See \":help W12\" for more info." +msgstr "Se \":help W12\" for mere info." + +#, c-format +msgid "W11: Warning: File \"%s\" has changed since editing started" +msgstr "W11: Advarsel: Filen \"%s\" er blevet ændret siden redigeringen startede" + +msgid "See \":help W11\" for more info." +msgstr "Se \":help W11\" for mere info." + +#, c-format +msgid "W16: Warning: Mode of file \"%s\" has changed since editing started" +msgstr "" +"W16: Advarsel: Tilstanden af filen \"%s\" er blevet ændret siden redigeringen " +"startede" + +msgid "See \":help W16\" for more info." +msgstr "Se \":help W16\" for mere info." + +#, c-format +msgid "W13: Warning: File \"%s\" has been created after editing started" +msgstr "" +"W13: Advarsel: Filen \"%s\" er blevet oprettet efter redigeringen startede" + +msgid "Warning" +msgstr "Advarsel" + +msgid "" +"&OK\n" +"&Load File" +msgstr "" +"&OK\n" +"&Indlæs fil" + +#, c-format +msgid "E462: Could not prepare for reloading \"%s\"" +msgstr "E462: Kunne ikke forbedre til genindlæsning af \"%s\"" + +#, c-format +msgid "E321: Could not reload \"%s\"" +msgstr "E321: Kunne ikke genindlæse \"%s\"" + +msgid "--Deleted--" +msgstr "--Slettet--" + +#, c-format +msgid "auto-removing autocommand: %s <buffer=%d>" +msgstr "auto-removing-autokommando: %s <buffer=%d>" + +#, c-format +msgid "E367: No such group: \"%s\"" +msgstr "E367: Ingen sÃ¥dan gruppe: \"%s\"" + +msgid "E936: Cannot delete the current group" +msgstr "E936: Kan ikke slette den nuværende gruppe" + +msgid "W19: Deleting augroup that is still in use" +msgstr "W19: Sletter augroup som stadig er i brug" + +#, c-format +msgid "E215: Illegal character after *: %s" +msgstr "E215: Ulovligt tegn efter *: %s" + +#, c-format +msgid "E216: No such event: %s" +msgstr "E216: Ingen sÃ¥dan hændelse: %s" + +#, c-format +msgid "E216: No such group or event: %s" +msgstr "E216: Ingen sÃ¥dan gruppe eller hændelse: %s" + +msgid "" +"\n" +"--- Auto-Commands ---" +msgstr "" +"\n" +"--- Auto-kommandoer ---" + +#, c-format +msgid "E680: <buffer=%d>: invalid buffer number " +msgstr "E680: <buffer=%d>: ugyldigt buffernummer " + +msgid "E217: Can't execute autocommands for ALL events" +msgstr "E217: Kan ikke udføre autokommandoer for ALLE hændelser" + +msgid "No matching autocommands" +msgstr "Ingen matchende autokommandoer" + +msgid "E218: autocommand nesting too deep" +msgstr "E218: autokommando indlejret for dyb" + +#, c-format +msgid "%s Auto commands for \"%s\"" +msgstr "%s Auto-kommandoer for \"%s\"" + +#, c-format +msgid "Executing %s" +msgstr "Udfører %s" + +#, c-format +msgid "autocommand %s" +msgstr "autokommando %s" + +msgid "E219: Missing {." +msgstr "E219: Manglende {." + +msgid "E220: Missing }." +msgstr "E220: Manglende }." + +msgid "E490: No fold found" +msgstr "E490: Ingen sammenfoldning fundet" + +msgid "E350: Cannot create fold with current 'foldmethod'" +msgstr "E350: Kan ikke oprette sammenfoldning med nuværende 'foldmethod'" + +msgid "E351: Cannot delete fold with current 'foldmethod'" +msgstr "E351: Kan ikke slette sammenfoldning med nuværende 'foldmethod'" + +#, c-format +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld linje sammenfoldet " +msgstr[1] "+--%3ld linjer sammenfoldet " + +msgid "E222: Add to read buffer" +msgstr "E222: Tilføj til læsebuffer" + +msgid "E223: recursive mapping" +msgstr "E223: rekursiv mapping" + +#, c-format +msgid "E224: global abbreviation already exists for %s" +msgstr "E224: global forkortelse findes allerede for %s" + +#, c-format +msgid "E225: global mapping already exists for %s" +msgstr "E225: global mapping findes allerede for %s" + +#, c-format +msgid "E226: abbreviation already exists for %s" +msgstr "E226: forkortelse findes allerede for %s" + +#, c-format +msgid "E227: mapping already exists for %s" +msgstr "E227: mapping findes allerede for %s" + +msgid "No abbreviation found" +msgstr "Ingen forkortelse fundet" + +msgid "No mapping found" +msgstr "Ingen mapping fundet" + +msgid "E228: makemap: Illegal mode" +msgstr "E228: makemap: Ulovlig tilstand" + +msgid "E851: Failed to create a new process for the GUI" +msgstr "E851: Kunne ikke oprette en ny proces for GUI'en" + +msgid "E852: The child process failed to start the GUI" +msgstr "E852: Barneprocessen kunne ikke starte GUI'en" + +msgid "E229: Cannot start the GUI" +msgstr "E229: Kan ikke starte GUI'en" + +#, c-format +msgid "E230: Cannot read from \"%s\"" +msgstr "E230: Kan ikke læse fra \"%s\"" + +msgid "E665: Cannot start GUI, no valid font found" +msgstr "E665: Kan ikke starte GUI, ingen gyldig skrifttype fundet" + +msgid "E231: 'guifontwide' invalid" +msgstr "E231: 'guifontwide' ugyldig" + +msgid "E599: Value of 'imactivatekey' is invalid" +msgstr "E599: Værdien af 'imactivatekey' er ugyldig" + +#, c-format +msgid "E254: Cannot allocate color %s" +msgstr "E254: Kan ikke allokere farven %s" + +msgid "No match at cursor, finding next" +msgstr "Intet match ved markør, finder næste" + +msgid "<cannot open> " +msgstr "<kan ikke Ã¥bne> " + +#, c-format +msgid "E616: vim_SelFile: can't get font %s" +msgstr "E616: vim_SelFile: kan ikke hente skrifttypen %s" + +msgid "E614: vim_SelFile: can't return to current directory" +msgstr "E614: vim_SelFile: kan ikke vende tilbage til nuværende mappe" + +msgid "Pathname:" +msgstr "Stinavn:" + +msgid "E615: vim_SelFile: can't get current directory" +msgstr "E615: vim_SelFile: kan ikke hente nuværende mappe" + +msgid "OK" +msgstr "OK" + +msgid "Cancel" +msgstr "Annuller" + +msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." +msgstr "" +"Rullebjælke-widget: Kunne ikke hente geometri eller pixelkort til miniature." + +msgid "Vim dialog" +msgstr "Vim-dialog" + +msgid "E232: Cannot create BalloonEval with both message and callback" +msgstr "E232: Kan ikke oprette BalloonEval med bÃ¥de meddelelse og callback" + +msgid "_Cancel" +msgstr "_Annuller" + +msgid "_Save" +msgstr "_Gem" + +msgid "_Open" +msgstr "_Ã…bn" + +msgid "_OK" +msgstr "_OK" + +msgid "" +"&Yes\n" +"&No\n" +"&Cancel" +msgstr "" +"&Ja\n" +"&Nej\n" +"&Annuller" + +msgid "Yes" +msgstr "Ja" + +msgid "No" +msgstr "Nej" + +msgid "Input _Methods" +msgstr "Input_metoder" + +msgid "VIM - Search and Replace..." +msgstr "VIM - Søg og erstat..." + +msgid "VIM - Search..." +msgstr "VIM - Søg..." + +msgid "Find what:" +msgstr "Find hvad:" + +msgid "Replace with:" +msgstr "Erstat med:" + +msgid "Match whole word only" +msgstr "Match kun hele ord" + +msgid "Match case" +msgstr "Der skelnes ikke mellem store og smÃ¥ bogstaver" + +msgid "Direction" +msgstr "Retning" + +msgid "Up" +msgstr "Op" + +msgid "Down" +msgstr "Ned" + +msgid "Find Next" +msgstr "Find næste" + +msgid "Replace" +msgstr "Erstat" + +msgid "Replace All" +msgstr "Erstat alle" + +msgid "_Close" +msgstr "_Luk" + +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim: Modtog \"die\"-anmodning fra sessionshÃ¥ndtering\n" + +msgid "Close tab" +msgstr "Luk faneblad" + +msgid "New tab" +msgstr "Nyt faneblad" + +msgid "Open Tab..." +msgstr "Ã…bn faneblad..." + +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim: Hovedvindue uventet ødelagt\n" + +msgid "&Filter" +msgstr "&Filter" + +msgid "&Cancel" +msgstr "&Annuller" + +msgid "Directories" +msgstr "Mapper" + +msgid "Filter" +msgstr "Filter" + +msgid "&Help" +msgstr "&Hjælp" + +msgid "Files" +msgstr "Filer" + +msgid "&OK" +msgstr "&OK" + +msgid "Selection" +msgstr "Markering" + +msgid "Find &Next" +msgstr "Find &næste" + +msgid "&Replace" +msgstr "&Erstat" + +msgid "Replace &All" +msgstr "Erstat &alle" + +msgid "&Undo" +msgstr "&Fortryd" + +msgid "Open tab..." +msgstr "Ã…bn faneblad..." + +msgid "Find string (use '\\\\' to find a '\\')" +msgstr "Find streng (brug '\\\\' til at finde et '\\')" + +msgid "Find & Replace (use '\\\\' to find a '\\')" +msgstr "Find og erstat (brug '\\\\' til at finde et '\\')" + +msgid "Not Used" +msgstr "Ikke brugt" + +msgid "Directory\t*.nothing\n" +msgstr "Mappe\t\t*.nothing\n" + +#, c-format +msgid "E671: Cannot find window title \"%s\"" +msgstr "E671: Kan ikke finde vinduestitlen \"%s\"" + +#, c-format +msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." +msgstr "E243: Argumentet understøttes ikke: \"-%s\"; Brug OLE-versionen." + +msgid "E672: Unable to open window inside MDI application" +msgstr "E672: Kan ikke Ã¥bne vindue i MDI-program" + +msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" +msgstr "" +"Vim E458: Kan ikke allokere colormap-post, nogle farver kan være forkerte" + +#, c-format +msgid "E250: Fonts for the following charsets are missing in fontset %s:" +msgstr "E250: Skrifttyper for følgende tegnsæt mangler i skrifttypesættet %s:" + +#, c-format +msgid "E252: Fontset name: %s" +msgstr "E252: Skrifttypesætnavn: %s" + +#, c-format +msgid "Font '%s' is not fixed-width" +msgstr "Skrifttypen '%s' er ikke med fast bredde" + +#, c-format +msgid "E253: Fontset name: %s" +msgstr "E253: Skrifttypesætnavn: %s" + +#, c-format +msgid "Font0: %s" +msgstr "Skrifttype0: %s" + +#, c-format +msgid "Font1: %s" +msgstr "Skrifttype1: %s" + +#, c-format +msgid "Font%ld width is not twice that of font0" +msgstr "Bredden pÃ¥ skrifttype%ld er ikke det dobbelte af skrifttype0" + +#, c-format +msgid "Font0 width: %ld" +msgstr "Bredden pÃ¥ skrifttype0: %ld" + +#, c-format +msgid "Font1 width: %ld" +msgstr "Bredden pÃ¥ skrifttype1: %ld" + +msgid "Invalid font specification" +msgstr "Ugyldig skrifttypespecifikation" + +msgid "&Dismiss" +msgstr "&Luk" + +msgid "no specific match" +msgstr "intet specifikt match" + +msgid "Vim - Font Selector" +msgstr "Vim - Skrifttypevælger" + +msgid "Name:" +msgstr "Navn:" + +msgid "Show size in Points" +msgstr "Vis størrelse i punkter" + +msgid "Encoding:" +msgstr "Kodning:" + +msgid "Font:" +msgstr "Skrifttype:" + +msgid "Style:" +msgstr "Stil:" + +msgid "Size:" +msgstr "Størrelse:" + +msgid "E256: Hangul automata ERROR" +msgstr "E256: FEJL ved Hangul automata" + +msgid "E550: Missing colon" +msgstr "E550: Manglende kolon" + +msgid "E551: Illegal component" +msgstr "E551: Ulovlig komponent" + +msgid "E552: digit expected" +msgstr "E552: ciffer ventet" + +#, c-format +msgid "Page %d" +msgstr "Side %d" + +msgid "No text to be printed" +msgstr "Ingen tekst at udskrive" + +#, c-format +msgid "Printing page %d (%d%%)" +msgstr "Udskriver side %d (%d%%)" + +#, c-format +msgid " Copy %d of %d" +msgstr " Kopi %d af %d" + +#, c-format +msgid "Printed: %s" +msgstr "Udskrev: %s" + +msgid "Printing aborted" +msgstr "Udskrivning afbrudt" + +msgid "E455: Error writing to PostScript output file" +msgstr "E455: Fejl ved skrivning til PostScript-output-fil" + +#, c-format +msgid "E624: Can't open file \"%s\"" +msgstr "E624: Kan ikke Ã¥bne filen \"%s\"" + +#, c-format +msgid "E457: Can't read PostScript resource file \"%s\"" +msgstr "E457: Kan ikke læse PostScript-ressourcefilen \"%s\"" + +#, c-format +msgid "E618: file \"%s\" is not a PostScript resource file" +msgstr "E618: filen \"%s\" er ikke en PostScript-ressourcefil" + +#, c-format +msgid "E619: file \"%s\" is not a supported PostScript resource file" +msgstr "E619: filen \"%s\" er ikke en understøttet PostScript-ressourcefil" + +#, c-format +msgid "E621: \"%s\" resource file has wrong version" +msgstr "E621: \"%s\"-ressourcefilen har forkert version" + +msgid "E673: Incompatible multi-byte encoding and character set." +msgstr "E673: Inkompatibel multibyte-kodning og -tegnsæt." + +msgid "E674: printmbcharset cannot be empty with multi-byte encoding." +msgstr "E674: printmbcharset mÃ¥ ikke være tom med multibyte-kodning." + +msgid "E675: No default font specified for multi-byte printing." +msgstr "E675: Ingen standardskrifttype angivet for multibyte-udskrivning." + +msgid "E324: Can't open PostScript output file" +msgstr "E324: Kan ikke Ã¥bne PostScript-output-fil" + +#, c-format +msgid "E456: Can't open file \"%s\"" +msgstr "E456: Kan ikke Ã¥bne filen \"%s\"" + +msgid "E456: Can't find PostScript resource file \"prolog.ps\"" +msgstr "E456: Kan ikke finde PostScript-ressourcefilen \"prolog.ps\"" + +msgid "E456: Can't find PostScript resource file \"cidfont.ps\"" +msgstr "E456: Kan ikke finde PostScript-ressourcefilen \"cidfont.ps\"" + +#, c-format +msgid "E456: Can't find PostScript resource file \"%s.ps\"" +msgstr "E456: Kan ikke finde PostScript-ressourcefilen \"%s.ps\"" + +#, c-format +msgid "E620: Unable to convert to print encoding \"%s\"" +msgstr "E620: Kan ikke konvertere til udskrivningskodningen \"%s\"" + +msgid "Sending to printer..." +msgstr "Sender til printer..." + +msgid "E365: Failed to print PostScript file" +msgstr "E365: Kunne ikke udskrive PostScript-fil" + +msgid "Print job sent." +msgstr "Udskrivningsjob sendt." + +msgid "Add a new database" +msgstr "Tilføj en ny database" + +msgid "Query for a pattern" +msgstr "Forespørgsel til et mønster" + +msgid "Show this message" +msgstr "Vis denne meddelelse" + +msgid "Kill a connection" +msgstr "Dræb en forbindelse" + +msgid "Reinit all connections" +msgstr "Geninitialisere alle forbindelser" + +msgid "Show connections" +msgstr "Vis forbindelser" + +#, c-format +msgid "E560: Usage: cs[cope] %s" +msgstr "E560: Anvendelse: cs[cope] %s" + +msgid "This cscope command does not support splitting the window.\n" +msgstr "Denne cscope-kommando understøtter ikke opdeling af vinduet.\n" + +msgid "E562: Usage: cstag <ident>" +msgstr "E562: Anvendelse: cstag <ident>" + +msgid "E257: cstag: tag not found" +msgstr "E257: cstag: tag ikke fundet" + +#, c-format +msgid "E563: stat(%s) error: %d" +msgstr "E563: fejl ved stat(%s): %d" + +msgid "E563: stat error" +msgstr "E563: fejl ved stat" + +#, c-format +msgid "E564: %s is not a directory or a valid cscope database" +msgstr "E564: %s er ikke en mappe eller en gyldig cscope-database" + +#, c-format +msgid "Added cscope database %s" +msgstr "Tilføjede cscope-databasen %s" + +#, c-format +msgid "E262: error reading cscope connection %ld" +msgstr "E262: fejl ved læsning af cscope-forbindelse %ld" + +msgid "E561: unknown cscope search type" +msgstr "E561: ukendt cscope-søgetype" + +msgid "E566: Could not create cscope pipes" +msgstr "E566: Kunne ikke oprette cscope-pipes" + +msgid "E622: Could not fork for cscope" +msgstr "E622: Kunne ikke fork for cscope" + +msgid "cs_create_connection setpgid failed" +msgstr "cs_create_connection setpgid mislykkedes" + +msgid "cs_create_connection exec failed" +msgstr "cs_create_connection exec mislykkedes" + +msgid "cs_create_connection: fdopen for to_fp failed" +msgstr "cs_create_connection: fdopen for to_fp mislykkedes" + +msgid "cs_create_connection: fdopen for fr_fp failed" +msgstr "cs_create_connection: fdopen for fr_fp mislykkedes" + +msgid "E623: Could not spawn cscope process" +msgstr "E623: Kunne ikke spawn cscope-proces" + +msgid "E567: no cscope connections" +msgstr "E567: ingen cscope-forbindelser" + +#, c-format +msgid "E469: invalid cscopequickfix flag %c for %c" +msgstr "E469: ugyldigt cscopequickfix-flag %c for %c" + +#, c-format +msgid "E259: no matches found for cscope query %s of %s" +msgstr "E259: ingen match fundet for cscope-forespørgsel %s af %s" + +msgid "cscope commands:\n" +msgstr "cscope-kommandoer:\n" + +#, c-format +msgid "%-5s: %s%*s (Usage: %s)" +msgstr "%-5s: %s%*s (Anvendelse: %s)" + +msgid "" +"\n" +" a: Find assignments to this symbol\n" +" c: Find functions calling this function\n" +" d: Find functions called by this function\n" +" e: Find this egrep pattern\n" +" f: Find this file\n" +" g: Find this definition\n" +" i: Find files #including this file\n" +" s: Find this C symbol\n" +" t: Find this text string\n" +msgstr "" +"\n" +" a: Find tildelinger til symbolet\n" +" c: Find funktioner som kalder funktionen\n" +" d: Find funktioner som kaldes af funktionen\n" +" e: Find dette egrep-mønster\n" +" f: Find filen\n" +" g: Find definitionen\n" +" i: Find filer som #inkludere filen\n" +" s: Find C-symbolet\n" +" t: Find tekststrengen\n" + +#, c-format +msgid "E625: cannot open cscope database: %s" +msgstr "E625: kan ikke Ã¥bne cscope-database: %s" + +msgid "E626: cannot get cscope database information" +msgstr "E626: kan ikke hente information for cscope-database" + +msgid "E568: duplicate cscope database not added" +msgstr "E568: duplikeret cscope-database ikke tilføjet" + +#, c-format +msgid "E261: cscope connection %s not found" +msgstr "E261: cscope-forbindelsen %s ikke fundet" + +#, c-format +msgid "cscope connection %s closed" +msgstr "cscope-forbindelsen %s lukket" + +msgid "E570: fatal error in cs_manage_matches" +msgstr "E570: fatal fejl i cs_manage_matches" + +#, c-format +msgid "Cscope tag: %s" +msgstr "Cscope-tag: %s" + +msgid "" +"\n" +" # line" +msgstr "" +"\n" +" # linje" + +msgid "filename / context / line\n" +msgstr "filnavn/kontekst/linje\n" + +#, c-format +msgid "E609: Cscope error: %s" +msgstr "E609: Fejl ved cscope: %s" + +msgid "All cscope databases reset" +msgstr "Alle cscope-databaser nulstillet" + +msgid "no cscope connections\n" +msgstr "ingen cscope-forbindelser\n" + +msgid " # pid database name prepend path\n" +msgstr " # pid databasenavn prepend-sti\n" + +msgid "Lua library cannot be loaded." +msgstr "Lua-bibliotek kan ikke indlæses." + +msgid "cannot save undo information" +msgstr "kan ikke gemme fortrydinformation" + +msgid "" +"E815: Sorry, this command is disabled, the MzScheme libraries could not be " +"loaded." +msgstr "" +"E815: Beklager, kommandoen er deaktiveret, MzScheme-bibliotekerne kunne ikke " +"indlæses." + +msgid "" +"E895: Sorry, this command is disabled, the MzScheme's racket/base module " +"could not be loaded." +msgstr "" +"E895: Beklager, kommandoen er deaktiveret, MzScheme's racket-/base-modul " +"kunne ikke indlæses." + +msgid "invalid expression" +msgstr "ugyldigt udtryk" + +msgid "expressions disabled at compile time" +msgstr "udtryk deaktiveret ved kompileringstid" + +msgid "hidden option" +msgstr "skjult tilvalg" + +msgid "unknown option" +msgstr "ukendt tilvalg" + +msgid "window index is out of range" +msgstr "vinduesindeks udenfor omrÃ¥de" + +msgid "couldn't open buffer" +msgstr "kan ikke Ã¥bne buffer" + +msgid "cannot delete line" +msgstr "kan ikke slette linje" + +msgid "cannot replace line" +msgstr "kan ikke erstatte linje" + +msgid "cannot insert line" +msgstr "kan ikke indsætte linje" + +msgid "string cannot contain newlines" +msgstr "streng mÃ¥ ikke indeholde linjeskift" + +msgid "error converting Scheme values to Vim" +msgstr "fejl ved konvertering af Scheme-værdier til Vim" + +msgid "Vim error: ~a" +msgstr "Fejl ved Vim: ~a" + +msgid "Vim error" +msgstr "Fejl ved Vim" + +msgid "buffer is invalid" +msgstr "buffer er ugyldig" + +msgid "window is invalid" +msgstr "vindue er ugyldigt" + +msgid "linenr out of range" +msgstr "linjenummer udenfor omrÃ¥de" + +msgid "not allowed in the Vim sandbox" +msgstr "ikke tilladt i Vim-sandboksen" + +msgid "E836: This Vim cannot execute :python after using :py3" +msgstr "E836: Denne Vim kan ikke udføre :python efter brug af :py3" + +msgid "" +"E263: Sorry, this command is disabled, the Python library could not be " +"loaded." +msgstr "" +"E263: Beklager, kommandoen er deaktiveret, Python-biblioteket kunne ikke " +"indlæses." + +msgid "" +"E887: Sorry, this command is disabled, the Python's site module could not be " +"loaded." +msgstr "" +"E887: Beklager, kommandoen er deaktiveret, Python's site-modul kunne ikke " +"indlæses." + +msgid "E659: Cannot invoke Python recursively" +msgstr "E659: Kan ikke starte Python rekursivt" + +msgid "E837: This Vim cannot execute :py3 after using :python" +msgstr "E837: Denne Vim kan ikke udføre :py3 efter brug af :python" + +msgid "E265: $_ must be an instance of String" +msgstr "E265: $_ skal være en instans af streng" + +msgid "" +"E266: Sorry, this command is disabled, the Ruby library could not be loaded." +msgstr "" +"E266: Beklager, kommandoen er deaktiveret, Ruby-biblioteket kunne ikke " +"indlæses." + +msgid "E267: unexpected return" +msgstr "E267: uventet return" + +msgid "E268: unexpected next" +msgstr "E268: uventet next" + +msgid "E269: unexpected break" +msgstr "E269: uventet break" + +msgid "E270: unexpected redo" +msgstr "E270: uventet redo" + +msgid "E271: retry outside of rescue clause" +msgstr "E271: prøv igen udenfor rescue clause" + +msgid "E272: unhandled exception" +msgstr "E272: uhÃ¥ndteret undtagelse" + +#, c-format +msgid "E273: unknown longjmp status %d" +msgstr "E273: ukendt longjmp-status %d" + +msgid "invalid buffer number" +msgstr "ugyldigt buffernummer" + +msgid "not implemented yet" +msgstr "endnu ikke implementeret" + +msgid "cannot set line(s)" +msgstr "kan ikke sætte linje(r)" + +msgid "invalid mark name" +msgstr "ugyldigt mærkenavn" + +msgid "mark not set" +msgstr "mærke ikke sat" + +#, c-format +msgid "row %d column %d" +msgstr "række %d kolonne %d" + +msgid "cannot insert/append line" +msgstr "kan ikke indsætte/tilføje linje" + +msgid "line number out of range" +msgstr "linjenummer udenfor omrÃ¥de" + +msgid "unknown flag: " +msgstr "ukendt flag: " + +msgid "unknown vimOption" +msgstr "ukendt vimOption" + +msgid "keyboard interrupt" +msgstr "tastaturafbryd" + +msgid "vim error" +msgstr "fejl ved vim" + +msgid "cannot create buffer/window command: object is being deleted" +msgstr "kan ikke oprette buffer-/vindue-kommando: objekt slettes" + +msgid "" +"cannot register callback command: buffer/window is already being deleted" +msgstr "" +"kan ikke registrere callback-kommando: buffer/vindue er allerede ved at " +"blive slettet" + +msgid "" +"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim." +"org" +msgstr "" +"E280: FATAL FEJL VED TCL: reflist korrupt!? Rapportér det venligst til vim-" +"dev@vim.org" + +msgid "cannot register callback command: buffer/window reference not found" +msgstr "" +"kan ikke registrere callback-kommando: buffer-/vindue-reference ikke fundet" + +msgid "" +"E571: Sorry, this command is disabled: the Tcl library could not be loaded." +msgstr "" +"E571: Beklager, kommandoen er deaktiveret: Tcl-biblioteket kunne ikke " +"indlæses." + +#, c-format +msgid "E572: exit code %d" +msgstr "E572: afslutningskode %d" + +msgid "cannot get line" +msgstr "kan ikke hente linje" + +msgid "Unable to register a command server name" +msgstr "Kan ikke registrere et kommandoservernavn" + +msgid "E248: Failed to send command to the destination program" +msgstr "E248: Kunne ikke sende kommando til destinationsprogrammet" + +#, c-format +msgid "E573: Invalid server id used: %s" +msgstr "E573: Ugyldigt server-id brugt: %s" + +msgid "E251: VIM instance registry property is badly formed. Deleted!" +msgstr "" +"E251: Registreringsegenskab for VIM-instans er dÃ¥rligt udformet. Slettet!" + +#, c-format +msgid "E938: Duplicate key in JSON: \"%s\"" +msgstr "E938: Duplikeret nøgle i JSON: \"%s\"" + +#, c-format +msgid "E696: Missing comma in List: %s" +msgstr "E696: Manglende komma i liste: %s" + +#, c-format +msgid "E697: Missing end of List ']': %s" +msgstr "E697: Manglende slutning pÃ¥ List ']': %s" + +msgid "Unknown option argument" +msgstr "Ukendt tilvalgsargument" + +msgid "Too many edit arguments" +msgstr "For mange redigeringsargumenter" + +msgid "Argument missing after" +msgstr "Argument mangler efter" + +msgid "Garbage after option argument" +msgstr "Affald efter tilvalgsargument" + +msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" +msgstr "" +"For mange \"+kommando\"-, \"-c kommando\"- eller \"--cmd kommando\"-argumenter" + +msgid "Invalid argument for" +msgstr "Ugyldigt argument for" + +#, c-format +msgid "%d files to edit\n" +msgstr "%d filer at redigere\n" + +msgid "netbeans is not supported with this GUI\n" +msgstr "netbeans understøttes ikke med denne GUI\n" + +msgid "'-nb' cannot be used: not enabled at compile time\n" +msgstr "'-nb' kan ikke bruges: ikke aktiveret ved kompileringstid\n" + +msgid "This Vim was not compiled with the diff feature." +msgstr "Denne Vim blev ikke kompileret med diff-funktionaliteten." + +msgid "Attempt to open script file again: \"" +msgstr "Forsøg pÃ¥ at Ã¥bne scriptfil igen: \"" + +msgid "Cannot open for reading: \"" +msgstr "Kan ikke Ã¥bne til læsning: \"" + +msgid "Cannot open for script output: \"" +msgstr "Kan ikke Ã¥bne for script-output: \"" + +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim: Fejl: Kunne ikke starte gvim fra NetBeans\n" + +msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n" +msgstr "Vim: Fejl: Denne version af Vim kører ikke i en Cygwin-terminal\n" + +msgid "Vim: Warning: Output is not to a terminal\n" +msgstr "Vim: Advarsel: Output er ikke til en terminal\n" + +msgid "Vim: Warning: Input is not from a terminal\n" +msgstr "Vim: Advarsel: Input er ikke fra en terminal\n" + +msgid "pre-vimrc command line" +msgstr "pre-vimrc-kommandolinje" + +#, c-format +msgid "E282: Cannot read from \"%s\"" +msgstr "E282: Kan ikke læse fra \"%s\"" + +msgid "" +"\n" +"More info with: \"vim -h\"\n" +msgstr "" +"\n" +"Mere info med: \"vim -h\"\n" + +msgid "[file ..] edit specified file(s)" +msgstr "[fil ..] rediger angivne fil(er)" + +msgid "- read text from stdin" +msgstr "- læs tekst fra stdin" + +msgid "-t tag edit file where tag is defined" +msgstr "-t tag rediger fil hvor tag er defineret" + +msgid "-q [errorfile] edit file with first error" +msgstr "-q [fejlfil] rediger fil med første fejl" + +msgid "" +"\n" +"\n" +"usage:" +msgstr "" +"\n" +"\n" +"anvendelse:" + +msgid " vim [arguments] " +msgstr " vim [argumenter] " + +msgid "" +"\n" +" or:" +msgstr "" +"\n" +" eller:" + +msgid "" +"\n" +"Where case is ignored prepend / to make flag upper case" +msgstr "" +"\n" +"NÃ¥r der ikke skelnes mellem store og smÃ¥ bogstaver, sÃ¥ tilføj / i " +"begyndelsen for at gøre flag til store bogstaver" + +msgid "" +"\n" +"\n" +"Arguments:\n" +msgstr "" +"\n" +"\n" +"Argumenter:\n" + +msgid "--\t\t\tOnly file names after this" +msgstr "--\t\t\tKun filnavne herefter" + +msgid "--literal\t\tDon't expand wildcards" +msgstr "--literal\t\tUdvid ikke jokertegn" + +msgid "-register\t\tRegister this gvim for OLE" +msgstr "-register\t\tRegistrer denne gvim til OLE" + +msgid "-unregister\t\tUnregister gvim for OLE" +msgstr "-unregister\t\tAfregistrer gvim for OLE" + +msgid "-g\t\t\tRun using GUI (like \"gvim\")" +msgstr "-g\t\t\tKør med GUI (ligesom \"gvim\")" + +msgid "-f or --nofork\tForeground: Don't fork when starting GUI" +msgstr "-f eller --nofork\tForgrund: Fork ikke nÃ¥r GUI startes" + +msgid "-v\t\t\tVi mode (like \"vi\")" +msgstr "-v\t\t\tVi-tilstand (ligesom \"vi\")" + +msgid "-e\t\t\tEx mode (like \"ex\")" +msgstr "-e\t\t\tEx-tilstand (ligesom \"ex\")" + +msgid "-E\t\t\tImproved Ex mode" +msgstr "-E\t\t\tForbedret Ex-tilstand" + +msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")" +msgstr "-s\t\t\tStille (batch) tilstand (kun til \"ex\")" + +msgid "-d\t\t\tDiff mode (like \"vimdiff\")" +msgstr "-d\t\t\tDiff-tilstand (ligesom \"vimdiff\")" + +msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" +msgstr "-y\t\t\tEasy-tilstand (ligesom \"evim\", tilstandsløs)" + +msgid "-R\t\t\tReadonly mode (like \"view\")" +msgstr "-R\t\t\tSkrivebeskyttet tilstand (ligesom \"view\")" + +msgid "-Z\t\t\tRestricted mode (like \"rvim\")" +msgstr "-Z\t\t\tRestriktiv tilstand (ligesom \"rvim\")" + +msgid "-m\t\t\tModifications (writing files) not allowed" +msgstr "-m\t\t\tÆndringer (skrivning af filer) ikke tilladt" + +msgid "-M\t\t\tModifications in text not allowed" +msgstr "-M\t\t\tÆndringer i tekst ikke tilladt" + +msgid "-b\t\t\tBinary mode" +msgstr "-b\t\t\tBinær tilstand" + +msgid "-l\t\t\tLisp mode" +msgstr "-l\t\t\tLisp-tilstand" + +msgid "-C\t\t\tCompatible with Vi: 'compatible'" +msgstr "-C\t\t\tKompatibel med Vi: 'compatible'" + +msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'" +msgstr "-N\t\t\tIkke fuldt ud Vi-kompatibel: 'nocompatible'" + +msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]" +msgstr "-V[N][fnavn]\t\tVær uddybende [niveau N] [log meddelelser til fnavn]" + +msgid "-D\t\t\tDebugging mode" +msgstr "-D\t\t\tFejlretningstilstand" + +msgid "-n\t\t\tNo swap file, use memory only" +msgstr "-n\t\t\tIngen swap-fil, brug kun hukommelse" + +msgid "-r\t\t\tList swap files and exit" +msgstr "-r\t\t\tOplist swap-filer og afslut" + +msgid "-r (with file name)\tRecover crashed session" +msgstr "-r (med filnavn)\tGendan session som holdt op med at virke" + +msgid "-L\t\t\tSame as -r" +msgstr "-L\t\t\tSamme som -r" + +msgid "-f\t\t\tDon't use newcli to open window" +msgstr "-f\t\t\tBrug ikke newcli til at Ã¥bne vindue" + +msgid "-dev <device>\t\tUse <device> for I/O" +msgstr "-dev <enhed>\t\tBrug <enhed> til I/O" + +msgid "-A\t\t\tstart in Arabic mode" +msgstr "-A\t\t\tstart i arabisk tilstand" + +msgid "-H\t\t\tStart in Hebrew mode" +msgstr "-H\t\t\tStart i hebraisk tilstand" + +msgid "-F\t\t\tStart in Farsi mode" +msgstr "-F\t\t\tStart i persisk tilstand" + +msgid "-T <terminal>\tSet terminal type to <terminal>" +msgstr "-T <terminal>\tSæt terminaltype til <terminal>" + +msgid "--not-a-term\t\tSkip warning for input/output not being a terminal" +msgstr "" +"--not-a-term\t\tSpring advarsel over for input/output som ikke er en terminal" + +msgid "--ttyfail\t\tExit if input or output is not a terminal" +msgstr "--ttyfail\t\tAfslut hvis input eller output ikke er en terminal" + +msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc" +msgstr "-u <vimrc>\t\tBrug <vimrc> i stedet for nogen .vimrc" + +msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc" +msgstr "-U <gvimrc>\t\tBrug <gvimrc> i stedet for nogen .gvimrc" + +msgid "--noplugin\t\tDon't load plugin scripts" +msgstr "--noplugin\t\tIndlæs ikke plugin-scripts" + +msgid "-p[N]\t\tOpen N tab pages (default: one for each file)" +msgstr "-p[N]\t\tÃ…bn N fanebladssider (standard: én pr. fil)" + +msgid "-o[N]\t\tOpen N windows (default: one for each file)" +msgstr "-o[N]\t\tÃ…bn N vinduer (standard: én pr. fil)" + +msgid "-O[N]\t\tLike -o but split vertically" +msgstr "-O[N]\t\tLigesom -o men opdel lodret" + +msgid "+\t\t\tStart at end of file" +msgstr "+\t\t\tBegynd ved slutningen af filen" + +msgid "+<lnum>\t\tStart at line <lnum>" +msgstr "+<lnum>\t\tBegynd ved linje <lnum>" + +msgid "--cmd <command>\tExecute <command> before loading any vimrc file" +msgstr "--cmd <kommando>\tUdfør <kommando> inden indlæsning af vimrc-filer" + +msgid "-c <command>\t\tExecute <command> after loading the first file" +msgstr "-c <kommando>\tUdfør <kommando> efter indlæsning af den første fil" + +msgid "-S <session>\t\tSource file <session> after loading the first file" +msgstr "-S <session>\t\tSource filen <session> efter indlæsning af den første fil" + +msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>" +msgstr "-s <scriptind>\tLæs normal tilstand-kommandoer fra filen <scriptind>" + +msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>" +msgstr "" +"-w <scriptud>\tTilføj alle indtastede kommandoer til slutningen af filen " +"<scriptud>" + +msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>" +msgstr "-W <scriptud>\tSkriv alle indtastede kommandoer til filen <scriptud>" + +msgid "-x\t\t\tEdit encrypted files" +msgstr "-x\t\t\tRediger krypterede filer" + +msgid "-display <display>\tConnect vim to this particular X-server" +msgstr "-display <display>\tForbind vim til denne X-server" + +msgid "-X\t\t\tDo not connect to X server" +msgstr "-X\t\t\tOpret ikke forbindelse til X-server" + +msgid "--remote <files>\tEdit <files> in a Vim server if possible" +msgstr "--remote <filer>\tRediger <filer> i en Vim-server, hvis det er muligt" + +msgid "--remote-silent <files> Same, don't complain if there is no server" +msgstr "" +"--remote-silent <filer> Samme, men vær tavs hvis der ikke er nogen server" + +msgid "" +"--remote-wait <files> As --remote but wait for files to have been edited" +msgstr "" +"--remote-wait <filer> Som --remote men vent pÃ¥ filer som skal redigeres" + +msgid "" +"--remote-wait-silent <files> Same, don't complain if there is no server" +msgstr "" +"--remote-wait-silent <filer> Samme, men vær tavs hvis der ikke er nogen " +"server" + +msgid "" +"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file" +msgstr "" +"--remote-tab[-wait][-silent] <filer> Som --remote men brug fanebladsside " +"pr. fil" + +msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit" +msgstr "--remote-send <nøgler>\tSend <nøgler> til en Vim-server og afslut" + +msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result" +msgstr "" +"--remote-expr <udtryk>\tEvaluér <udtryk> i en Vim-server og udskriv " +"resultatet" + +msgid "--serverlist\t\tList available Vim server names and exit" +msgstr "--serverlist\t\tOplist tilgængelige Vim-servernavne og afslut" + +msgid "--servername <name>\tSend to/become the Vim server <name>" +msgstr "--servername <navn>\tSend til/bliv Vim-serveren <navn>" + +msgid "--startuptime <file>\tWrite startup timing messages to <file>" +msgstr "--startuptime <fil>\tSkriv meddelelser om opstartstiming til <fil>" + +msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo" +msgstr "-i <viminfo>\t\tBrug <viminfo> i stedet for .viminfo" + +msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo" +msgstr "--clean\t\t'nocompatible', Vim-standarder, ingen plugins, ingen viminfo" + +msgid "-h or --help\tPrint Help (this message) and exit" +msgstr "-h eller --help\tUdskriv hjælp (denne meddelelse) og afslut" + +msgid "--version\t\tPrint version information and exit" +msgstr "--version\t\tUdskriv versionsinformation og afslut" + +msgid "" +"\n" +"Arguments recognised by gvim (Motif version):\n" +msgstr "" +"\n" +"Argumenter som genkendes af gvim (Motif-version):\n" + +msgid "" +"\n" +"Arguments recognised by gvim (neXtaw version):\n" +msgstr "" +"\n" +"Argumenter som genkendes af gvim (neXtaw-version):\n" + +msgid "" +"\n" +"Arguments recognised by gvim (Athena version):\n" +msgstr "" +"\n" +"Argumenter som genkendes af gvim (Athena-version):\n" + +msgid "-display <display>\tRun vim on <display>" +msgstr "-display <display>\tKør vim pÃ¥ <display>" + +msgid "-iconic\t\tStart vim iconified" +msgstr "-iconic\t\tStart vim som ikon" + +msgid "-background <color>\tUse <color> for the background (also: -bg)" +msgstr "-background <farve>\tBrug <farve> til baggrunden (ogsÃ¥: -bg)" + +msgid "-foreground <color>\tUse <color> for normal text (also: -fg)" +msgstr "-foreground <farve>\tBrug <farve> til normal tekst (ogsÃ¥: -fg)" + +msgid "-font <font>\t\tUse <font> for normal text (also: -fn)" +msgstr "-font <skrifttype>\tBrug <skrifttype> til normal tekst (ogsÃ¥: -fn)" + +msgid "-boldfont <font>\tUse <font> for bold text" +msgstr "-boldfont <skrifttype>\tBrug <skrifttype> til fed tekst" + +msgid "-italicfont <font>\tUse <font> for italic text" +msgstr "-italicfont <skriftt.>\tBrug <skrifttype> til kursiv tekst" + +msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)" +msgstr "-geometry <geom>\tBrug <geom> for indledende geometri (ogsÃ¥: -geom)" + +msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)" +msgstr "-borderwidth <bredde>\tBrug en kantbredde pÃ¥ <bredde> (ogsÃ¥: -bw)" + +msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)" +msgstr "" +"-scrollbarwidth <bredde> Brug en rullebjælkebredde pÃ¥ <bredde> (ogsÃ¥: -sw)" + +msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)" +msgstr "-menuheight <højde>\tBrug en menulinjehøjde pÃ¥ <højde> (ogsÃ¥: -mh)" + +msgid "-reverse\t\tUse reverse video (also: -rv)" +msgstr "-reverse\t\tBrug omvendt grafik (ogsÃ¥: -rv)" + +msgid "+reverse\t\tDon't use reverse video (also: +rv)" +msgstr "+reverse\t\tBrug ikke omvendt grafik (ogsÃ¥: +rv)" + +msgid "-xrm <resource>\tSet the specified resource" +msgstr "-xrm <ressource>\tSæt den angivne ressource" + +msgid "" +"\n" +"Arguments recognised by gvim (GTK+ version):\n" +msgstr "" +"\n" +"Argumenter genkendt af gvim (GTK+-version):\n" + +msgid "-display <display>\tRun vim on <display> (also: --display)" +msgstr "-display <display>\tKør vim pÃ¥ <display> (ogsÃ¥: --display)" + +msgid "--role <role>\tSet a unique role to identify the main window" +msgstr "--role <rolle>\tSæt en unik rolle til at identificere hovedvinduet" + +msgid "--socketid <xid>\tOpen Vim inside another GTK widget" +msgstr "--socketid <xid>\tÃ…bn Vim i en anden GTK-widget" + +msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" +msgstr "--echo-wid\t\tFÃ¥ gvim til at skrive vinduets ID til stdout" + +msgid "-P <parent title>\tOpen Vim inside parent application" +msgstr "-P <forældertitel>\tÃ…bn Vim i forælderprogram" + +msgid "--windowid <HWND>\tOpen Vim inside another win32 widget" +msgstr "--windowid <HWND>\tÃ…bn Vim i en anden win32-widget" + +msgid "No display" +msgstr "Intet display" + +msgid ": Send failed.\n" +msgstr ": Sending mislykkedes.\n" + +msgid ": Send failed. Trying to execute locally\n" +msgstr ": Sending mislykkedes. Prøver at udføre lokalt\n" + +#, c-format +msgid "%d of %d edited" +msgstr "%d af %d redigeret" + +msgid "No display: Send expression failed.\n" +msgstr "Intet display: Send-udtryk mislykkedes.\n" + +msgid ": Send expression failed.\n" +msgstr ": Send-udtryk mislykkedes.\n" + +msgid "No marks set" +msgstr "Ingen mærker sat" + +#, c-format +msgid "E283: No marks matching \"%s\"" +msgstr "E283: Ingen mærker matcher \"%s\"" + +msgid "" +"\n" +"mark line col file/text" +msgstr "" +"\n" +"mærke linje kol fil/tekst" + +msgid "" +"\n" +" jump line col file/text" +msgstr "" +"\n" +" hop linje kol fil/tekst" + +msgid "" +"\n" +"change line col text" +msgstr "" +"\n" +"skift linje kol tekst" + +msgid "" +"\n" +"# File marks:\n" +msgstr "" +"\n" +"# Filmærker:\n" + +msgid "" +"\n" +"# Jumplist (newest first):\n" +msgstr "" +"\n" +"# Hopliste (nyeste først):\n" + +msgid "" +"\n" +"# History of marks within files (newest to oldest):\n" +msgstr "" +"\n" +"# Historik over mærker i filer (nyeste til ældste):\n" + +msgid "Missing '>'" +msgstr "Manglende '>'" + +msgid "E543: Not a valid codepage" +msgstr "E543: Ikke en gyldig tegnkodningstabel" + +msgid "E284: Cannot set IC values" +msgstr "E284: Kan ikke sætte IC-værdier" + +msgid "E285: Failed to create input context" +msgstr "E285: Kunne ikke oprette inputkontekst" + +msgid "E286: Failed to open input method" +msgstr "E286: Kunne ikke Ã¥bne inputmetode" + +msgid "E287: Warning: Could not set destroy callback to IM" +msgstr "E287: Advarsel: Kunne ikke sætte destroy callback til IM" + +msgid "E288: input method doesn't support any style" +msgstr "E288: inputmetode understøtter ikke nogen stil" + +msgid "E289: input method doesn't support my preedit type" +msgstr "E289: inputmetode understøtter ikke min preedit-type" + +msgid "E293: block was not locked" +msgstr "E293: blok blev ikke lÃ¥st" + +msgid "E294: Seek error in swap file read" +msgstr "E294: Søgefejl ved læsning af swap-fil" + +msgid "E295: Read error in swap file" +msgstr "E295: Læsefejl i swap-fil" + +msgid "E296: Seek error in swap file write" +msgstr "E296: Søgefejl ved skrivning af swap-fil" + +msgid "E297: Write error in swap file" +msgstr "E297: Skrivefejl i swap-fil" + +msgid "E300: Swap file already exists (symlink attack?)" +msgstr "E300: Swap-filen findes allerede (symlink angreb?)" + +msgid "E298: Didn't get block nr 0?" +msgstr "E298: Blev blok nr. 0 ikke hentet?" + +msgid "E298: Didn't get block nr 1?" +msgstr "E298: Blev blok nr. 1 ikke hentet?" + +msgid "E298: Didn't get block nr 2?" +msgstr "E298: Blev blok nr. 2 ikke hentet?" + +msgid "E843: Error while updating swap file crypt" +msgstr "E843: Fejl ved opdatering af crypt for swap-fil" + +msgid "E301: Oops, lost the swap file!!!" +msgstr "E301: Ups, mistede swap-filen!!!" + +msgid "E302: Could not rename swap file" +msgstr "E302: Kunne ikke omdøbe swap-fil" + +#, c-format +msgid "E303: Unable to open swap file for \"%s\", recovery impossible" +msgstr "E303: Kan ikke Ã¥bne swap-filen for \"%s\", gendannelse er ikke muligt" + +msgid "E304: ml_upd_block0(): Didn't get block 0??" +msgstr "E304: ml_upd_block0(): Blev blok 0 ikke hentet??" + +#, c-format +msgid "E305: No swap file found for %s" +msgstr "E305: Fandt ingen swap-fil for %s" + +msgid "Enter number of swap file to use (0 to quit): " +msgstr "Indtast antal swap-filer som der skal bruges (0 for at afslutte): " + +#, c-format +msgid "E306: Cannot open %s" +msgstr "E306: Kan ikke Ã¥bne %s" + +msgid "Unable to read block 0 from " +msgstr "Kan ikke læse blok 0 fra " + +msgid "" +"\n" +"Maybe no changes were made or Vim did not update the swap file." +msgstr "" +"\n" +"MÃ¥ske er der ikke foretaget nogen ændringer eller Vim opdaterede ikke swap-" +"filen." + +msgid " cannot be used with this version of Vim.\n" +msgstr " kan ikke bruges med denne version af Vim.\n" + +msgid "Use Vim version 3.0.\n" +msgstr "Brug Vim version 3.0.\n" + +#, c-format +msgid "E307: %s does not look like a Vim swap file" +msgstr "E307: %s ligner ikke en Vim swap-fil" + +msgid " cannot be used on this computer.\n" +msgstr " kan ikke bruges pÃ¥ denne computer.\n" + +msgid "The file was created on " +msgstr "Filen blev oprettet pÃ¥ " + +msgid "" +",\n" +"or the file has been damaged." +msgstr "" +",\n" +"eller filen er beskadiget." + +#, c-format +msgid "" +"E833: %s is encrypted and this version of Vim does not support encryption" +msgstr "" +"E833: %s er krypteret og denne version af Vim understøtter ikke kryptering" + +msgid " has been damaged (page size is smaller than minimum value).\n" +msgstr " er beskadiget (sidestørrelsen er mindre end minimumsværdien).\n" + +#, c-format +msgid "Using swap file \"%s\"" +msgstr "Bruger swap-filen \"%s\"" + +#, c-format +msgid "Original file \"%s\"" +msgstr "Den originale fil \"%s\"" + +msgid "E308: Warning: Original file may have been changed" +msgstr "E308: Advarsel: Den originale fil kan være ændret" + +#, c-format +msgid "Swap file is encrypted: \"%s\"" +msgstr "Swap-filen er krypteret: \"%s\"" + +msgid "" +"\n" +"If you entered a new crypt key but did not write the text file," +msgstr "" +"\n" +"Hvis du indtastede en ny crypt-nøgle men ikke skrev tekstfilen," + +msgid "" +"\n" +"enter the new crypt key." +msgstr "" +"\n" +"sÃ¥ indtast den nye crypt-nøgle." + +msgid "" +"\n" +"If you wrote the text file after changing the crypt key press enter" +msgstr "" +"\n" +"Hvis du skrev tekstfilen efter crypt-nøglen blev ændret, sÃ¥ tryk pÃ¥ enter" + +msgid "" +"\n" +"to use the same key for text file and swap file" +msgstr "" +"\n" +"for at bruge den samme nøgle til tekstfilen og swap-filen" + +#, c-format +msgid "E309: Unable to read block 1 from %s" +msgstr "E309: Kan ikke læse blok 1 fra %s" + +msgid "???MANY LINES MISSING" +msgstr "???MANGE LINJER MANGLER" + +msgid "???LINE COUNT WRONG" +msgstr "???LINJEANTAL FORKERT" + +msgid "???EMPTY BLOCK" +msgstr "???TOM BLOK" + +msgid "???LINES MISSING" +msgstr "???LINJER MANGLER" + +#, c-format +msgid "E310: Block 1 ID wrong (%s not a .swp file?)" +msgstr "E310: Forkert ID for blok 1 (%s ikke en .swp-fil?)" + +msgid "???BLOCK MISSING" +msgstr "???BLOK MANGLER" + +msgid "??? from here until ???END lines may be messed up" +msgstr "??? herfra indtil ???SLUT kan linjer være rodet" + +msgid "??? from here until ???END lines may have been inserted/deleted" +msgstr "??? herfra indtil ???SLUT kan linjer være indsat/slettet" + +msgid "???END" +msgstr "???SLUT" + +msgid "E311: Recovery Interrupted" +msgstr "E311: Gendannelse afbrudt" + +msgid "" +"E312: Errors detected while recovering; look for lines starting with ???" +msgstr "" +"E312: Fejl registreret ved gendannelse; kig efter linjer som begynder med " +"???" + +msgid "See \":help E312\" for more information." +msgstr "Se \":help E312\" for mere information." + +msgid "Recovery completed. You should check if everything is OK." +msgstr "Gendannelse gennemført. Du bør tjekke om alt er OK." + +msgid "" +"\n" +"(You might want to write out this file under another name\n" +msgstr "" +"\n" +"(Det kan være du vil skrive filen under et andet navn\n" + +msgid "and run diff with the original file to check for changes)" +msgstr "og kør diff men den originale fil for at tjekke for ændringer)" + +msgid "Recovery completed. Buffer contents equals file contents." +msgstr "" +"Gendannelse gennemført. Bufferens indhold er det samme som filens indhold." + +msgid "" +"\n" +"You may want to delete the .swp file now.\n" +"\n" +msgstr "" +"\n" +"Det kan være du vil slette .swp-filen nu.\n" +"\n" + +msgid "Using crypt key from swap file for the text file.\n" +msgstr "Bruger crypt-nøglen fra swap-filen til tekstfilen.\n" + +msgid "Swap files found:" +msgstr "Swap-filer fundet:" + +msgid " In current directory:\n" +msgstr " I nuværende mappe:\n" + +msgid " Using specified name:\n" +msgstr " Bruger angivne navn:\n" + +msgid " In directory " +msgstr " I mappe " + +msgid " -- none --\n" +msgstr " -- ingen --\n" + +msgid " owned by: " +msgstr " ejet af: " + +msgid " dated: " +msgstr " dateret: " + +msgid " dated: " +msgstr " dateret: " + +msgid " [from Vim version 3.0]" +msgstr " [fra Vim version 3.0]" + +msgid " [does not look like a Vim swap file]" +msgstr " [ligner ikke en Vim swap-fil]" + +msgid " file name: " +msgstr " filnavn: " + +msgid "" +"\n" +" modified: " +msgstr "" +"\n" +" ændret: " + +msgid "YES" +msgstr "JA" + +msgid "no" +msgstr "nej" + +msgid "" +"\n" +" user name: " +msgstr "" +"\n" +" brugernavn: " + +msgid " host name: " +msgstr " værtsnavn: " + +msgid "" +"\n" +" host name: " +msgstr "" +"\n" +" værtsnavn: " + +msgid "" +"\n" +" process ID: " +msgstr "" +"\n" +" proces-ID: " + +msgid " (still running)" +msgstr " (kører stadig)" + +msgid "" +"\n" +" [not usable with this version of Vim]" +msgstr "" +"\n" +" [ikke anvendelig med denne version af Vim]" + +msgid "" +"\n" +" [not usable on this computer]" +msgstr "" +"\n" +" [ikke anvendelig pÃ¥ denne computer]" + +msgid " [cannot be read]" +msgstr " [kan ikke læses]" + +msgid " [cannot be opened]" +msgstr " [kan ikke Ã¥bnes]" + +msgid "E313: Cannot preserve, there is no swap file" +msgstr "E313: Kan ikke bevares, der er ikke nogen swap-fil" + +msgid "File preserved" +msgstr "Fil bevaret" + +msgid "E314: Preserve failed" +msgstr "E314: Bevaring mislykkedes" + +#, c-format +msgid "E315: ml_get: invalid lnum: %ld" +msgstr "E315: ml_get: ugyldig lnum: %ld" + +#, c-format +msgid "E316: ml_get: cannot find line %ld" +msgstr "E316: ml_get: kan ikke finde linje %ld" + +msgid "E317: pointer block id wrong 3" +msgstr "E317: forkert blok-id for pointer 3" + +msgid "stack_idx should be 0" +msgstr "stack_idx skal være 0" + +msgid "E318: Updated too many blocks?" +msgstr "E318: Opdaterede for mange blokke?" + +msgid "E317: pointer block id wrong 4" +msgstr "E317: forkert blok-id for pointer 4" + +msgid "deleted block 1?" +msgstr "slettede blok 1?" + +#, c-format +msgid "E320: Cannot find line %ld" +msgstr "E320: Kan ikke finde linje %ld" + +msgid "E317: pointer block id wrong" +msgstr "E317: forkert blok-id for pointer" + +msgid "pe_line_count is zero" +msgstr "pe_line_count er nul" + +#, c-format +msgid "E322: line number out of range: %ld past the end" +msgstr "E322: linjenummer udenfor omrÃ¥de: %ld efter slutningen" + +#, c-format +msgid "E323: line count wrong in block %ld" +msgstr "E323: linje antal forkert i blok %ld" + +msgid "Stack size increases" +msgstr "Stakstørrelse øges" + +msgid "E317: pointer block id wrong 2" +msgstr "E317: forkert blok-id for pointer 2" + +#, c-format +msgid "E773: Symlink loop for \"%s\"" +msgstr "E773: Symlink-løkke for \"%s\"" + +msgid "E325: ATTENTION" +msgstr "E325: OBS" + +msgid "" +"\n" +"Found a swap file by the name \"" +msgstr "" +"\n" +"Fandt en swap-fil ved navn \"" + +msgid "While opening file \"" +msgstr "Ved Ã¥bning af filen \"" + +msgid " NEWER than swap file!\n" +msgstr " NYERE end swap-fil!\n" + +msgid "" +"\n" +"(1) Another program may be editing the same file. If this is the case,\n" +" be careful not to end up with two different instances of the same\n" +" file when making changes. Quit, or continue with caution.\n" +msgstr "" +"\n" +"(1) Et andet program redigere muligvis den samme fil. Hvis det er tilfældet,\n" +" sÃ¥ pas pÃ¥ ikke at ende med to forskellige instanser af den samme\n" +" fil nÃ¥r der foretages ændringer. Afslut, eller fortsæt med forsigtighed.\n" + +msgid "(2) An edit session for this file crashed.\n" +msgstr "(2) En redigeringssession for filen holdt op med at virke.\n" + +msgid " If this is the case, use \":recover\" or \"vim -r " +msgstr " Hvis det er tilfældet, sÃ¥ brug \":recover\" eller \"vim -r " + +msgid "" +"\"\n" +" to recover the changes (see \":help recovery\").\n" +msgstr "" +"\"\n" +" for at gendanne ændringerne (se \":help recovery\").\n" + +msgid " If you did this already, delete the swap file \"" +msgstr " Hvis du allerede har gjort det, sÃ¥ slet swap-filen \"" + +msgid "" +"\"\n" +" to avoid this message.\n" +msgstr "" +"\"\n" +" for at undgÃ¥ denne meddelelse.\n" + +msgid "Swap file \"" +msgstr "Swap-filen \"" + +msgid "\" already exists!" +msgstr "\" findes allerede!" + +msgid "VIM - ATTENTION" +msgstr "VIM - OBS" + +msgid "Swap file already exists!" +msgstr "Swap-filen findes allerede!" + +msgid "" +"&Open Read-Only\n" +"&Edit anyway\n" +"&Recover\n" +"&Quit\n" +"&Abort" +msgstr "" +"&Ã…bn skrivebeskyttet\n" +"&Rediger alligevel\n" +"&Gendan\n" +"&Afslut\n" +"&Afbryd" + +msgid "" +"&Open Read-Only\n" +"&Edit anyway\n" +"&Recover\n" +"&Delete it\n" +"&Quit\n" +"&Abort" +msgstr "" +"&Ã…bn skrivebeskyttet\n" +"&Rediger alligevel\n" +"&Gendan\n" +"&Slet den\n" +"&Afslut\n" +"&Afbryd" + +msgid "E326: Too many swap files found" +msgstr "E326: For mange swap-filer fundet" + +msgid "E327: Part of menu-item path is not sub-menu" +msgstr "E327: Del af sti til menupunkt er ikke undermenu" + +msgid "E328: Menu only exists in another mode" +msgstr "E328: Menuen findes kun i en anden tilstand" + +#, c-format +msgid "E329: No menu \"%s\"" +msgstr "E329: Ingen menu \"%s\"" + +msgid "E792: Empty menu name" +msgstr "E792: Tomt menunavn" + +msgid "E330: Menu path must not lead to a sub-menu" +msgstr "E330: Menusti mÃ¥ ikke lede til en undermenu" + +msgid "E331: Must not add menu items directly to menu bar" +msgstr "E331: MÃ¥ ikke tilføje menupunkter direkte til menulinje" + +msgid "E332: Separator cannot be part of a menu path" +msgstr "E332: Separator mÃ¥ ikke være del af en menusti" + +msgid "" +"\n" +"--- Menus ---" +msgstr "" +"\n" +"--- Menuer ---" + +msgid "Tear off this menu" +msgstr "Løsriv menuen" + +#, c-format +msgid "E335: Menu not defined for %s mode" +msgstr "E335: Menu ikke defineret for %s-tilstand" + +msgid "E333: Menu path must lead to a menu item" +msgstr "E333: Menusti skal lede til et menupunkt" + +#, c-format +msgid "E334: Menu not found: %s" +msgstr "E334: Menu ikke fundet: %s" + +msgid "E336: Menu path must lead to a sub-menu" +msgstr "E336: Menusti skal lede til en undermenu" + +msgid "E337: Menu not found - check menu names" +msgstr "E337: Menu ikke fundet - tjek menunavne" + +#, c-format +msgid "Error detected while processing %s:" +msgstr "Fejl registreret ved behandling af %s:" + +#, c-format +msgid "line %4ld:" +msgstr "linje %4ld:" + +#, c-format +msgid "E354: Invalid register name: '%s'" +msgstr "E354: Ugyldigt registernavn: '%s'" + +msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>" +msgstr "Oversætter: scootergrisen" + +msgid "Interrupt: " +msgstr "Afbryd: " + +msgid "Press ENTER or type command to continue" +msgstr "Tryk pÃ¥ ENTER eller skriv kommando for at fortsætte" + +#, c-format +msgid "%s line %ld" +msgstr "%s linje %ld" + +msgid "-- More --" +msgstr "-- Mere --" + +msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit " +msgstr " MELLEMRUM/d/j: skærm/side/linje ned, b/u/k: op, q: afslut " + +msgid "Question" +msgstr "SpørgsmÃ¥l" + +msgid "" +"&Yes\n" +"&No" +msgstr "" +"&Ja\n" +"&Nej" + +msgid "" +"&Yes\n" +"&No\n" +"Save &All\n" +"&Discard All\n" +"&Cancel" +msgstr "" +"&Ja\n" +"&Nej\n" +"Gem &alle\n" +"&Forkast alle\n" +"&Annuller" + +msgid "Select Directory dialog" +msgstr "Vælg mappe-dialog" + +msgid "Save File dialog" +msgstr "Gem fil-dialog" + +msgid "Open File dialog" +msgstr "Ã…bn fil-dialog" + +msgid "E338: Sorry, no file browser in console mode" +msgstr "E338: Beklager, ingen filbrowser i konsol-tilstand" + +msgid "E766: Insufficient arguments for printf()" +msgstr "E766: Ikke nok argumenter for printf()" + +msgid "E807: Expected Float argument for printf()" +msgstr "E807: Ventede flydende kommatal-argument for printf()" + +msgid "E767: Too many arguments to printf()" +msgstr "E767: For mange argumenter til printf()" + +msgid "W10: Warning: Changing a readonly file" +msgstr "W10: Advarsel: Ændre en skrivebeskyttet fil" + +msgid "Type number and <Enter> or click with mouse (empty cancels): " +msgstr "Skriv nummer og <Enter> eller klik med musen (tom annullerer): " + +msgid "Type number and <Enter> (empty cancels): " +msgstr "Skriv nummer og <Enter> (tom annullerer): " + +msgid "1 more line" +msgstr "1 linje mere" + +msgid "1 line less" +msgstr "1 linje mindre" + +#, c-format +msgid "%ld more lines" +msgstr "%ld linjer mere" + +#, c-format +msgid "%ld fewer lines" +msgstr "%ld linjere mindre" + +msgid " (Interrupted)" +msgstr " (Afbrudt)" + +msgid "Beep!" +msgstr "Bip!" + +msgid "ERROR: " +msgstr "FEJL: " + +#, c-format +msgid "" +"\n" +"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n" +msgstr "" +"\n" +"[byte] samlet allok-frigivet %lu-%lu, i brug %lu, spidspunktsbrug %lu\n" + +#, c-format +msgid "" +"[calls] total re/malloc()'s %lu, total free()'s %lu\n" +"\n" +msgstr "" +"[kald] samlet re/malloc()'er %lu, samlet free()'er %lu\n" +"\n" + +msgid "E340: Line is becoming too long" +msgstr "E340: Linje er ved at blive for lang" + +#, c-format +msgid "E341: Internal error: lalloc(%ld, )" +msgstr "E341: Intern fejl: lalloc(%ld, )" + +#, c-format +msgid "E342: Out of memory! (allocating %lu bytes)" +msgstr "E342: Ikke mere ledig hukommelse! (allokerer %lu byte)" + +#, c-format +msgid "Calling shell to execute: \"%s\"" +msgstr "Kalder skal til udførelse af: \"%s\"" + +msgid "E545: Missing colon" +msgstr "E545: Manglende kolon" + +msgid "E546: Illegal mode" +msgstr "E546: Ulovlig tilstand" + +msgid "E547: Illegal mouseshape" +msgstr "E547: Ulovlig museform" + +msgid "E548: digit expected" +msgstr "E548: ciffer ventet" + +msgid "E549: Illegal percentage" +msgstr "E549: Ulovlig procent" + +msgid "E854: path too long for completion" +msgstr "E854: sti for lang til fuldførelse" + +#, c-format +msgid "" +"E343: Invalid path: '**[number]' must be at the end of the path or be " +"followed by '%s'." +msgstr "" +"E343: Ugyldig sti: '**[nummer]' skal være i slutningen af stien eller " +"efterfølges af '%s'." + +#, c-format +msgid "E344: Can't find directory \"%s\" in cdpath" +msgstr "E344: Kan ikke finde mappen \"%s\" i cdpath" + +#, c-format +msgid "E345: Can't find file \"%s\" in path" +msgstr "E345: Kan ikke finde filen \"%s\" i path" + +#, c-format +msgid "E346: No more directory \"%s\" found in cdpath" +msgstr "E346: Ikke flere mappe \"%s\" fundet i cdpath" + +#, c-format +msgid "E347: No more file \"%s\" found in path" +msgstr "E347: Ikke flere fil \"%s\" fundet i path" + +#, c-format +msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" +msgstr "E668: Forkert adgangstilstand for NetBeans-forbindelsens info-fil: \"%s\"" + +#, c-format +msgid "E658: NetBeans connection lost for buffer %ld" +msgstr "E658: NetBeans-forbindelse mistet for buffer %ld" + +msgid "E838: netbeans is not supported with this GUI" +msgstr "E838: netbeans understøttes ikke med denne GUI" + +msgid "E511: netbeans already connected" +msgstr "E511: netbeans allerede forbundet" + +#, c-format +msgid "E505: %s is read-only (add ! to override)" +msgstr "E505: %s er skrivebeskyttet (tilføj ! for at tilsidesætte)" + +msgid "E349: No identifier under cursor" +msgstr "E349: Ingen identifikator under markør" + +msgid "E774: 'operatorfunc' is empty" +msgstr "E774: 'operatorfunc' er tom" + +msgid "E775: Eval feature not available" +msgstr "E775: Eval-funktionalitet ikke tilgængelig" + +msgid "Warning: terminal cannot highlight" +msgstr "Advarsel: terminal kan ikke fremhæve" + +msgid "E348: No string under cursor" +msgstr "E348: Ingen streng under markør" + +msgid "E352: Cannot erase folds with current 'foldmethod'" +msgstr "E352: Kan ikke slette sammenfoldninger med nuværende 'foldmethod'" + +msgid "E664: changelist is empty" +msgstr "E664: ændringsliste er tom" + +msgid "E662: At start of changelist" +msgstr "E662: Ved begyndelsen af ændringsliste" + +msgid "E663: At end of changelist" +msgstr "E663: Ved slutningen af ændringsliste" + +msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim" +msgstr "" +"Skriv :qa! og tryk pÃ¥ <Enter> for at droppe alle ændringer og afslut Vim" + +#, c-format +msgid "1 line %sed 1 time" +msgstr "1 linje %sed 1 gang" + +#, c-format +msgid "1 line %sed %d times" +msgstr "1 linje %sed %d gange" + +#, c-format +msgid "%ld lines %sed 1 time" +msgstr "%ld linjer %sed 1 gang" + +#, c-format +msgid "%ld lines %sed %d times" +msgstr "%ld linjer %sed %d gange" + +#, c-format +msgid "%ld lines to indent... " +msgstr "%ld linjer at indrykke... " + +msgid "1 line indented " +msgstr "1 linje indrykket " + +#, c-format +msgid "%ld lines indented " +msgstr "%ld linjer indrykket " + +msgid "E748: No previously used register" +msgstr "E748: Intet tidligere brugt register" + +msgid "cannot yank; delete anyway" +msgstr "kan ikke rykke; slet alligevel" + +msgid "1 line changed" +msgstr "1 linje ændret" + +#, c-format +msgid "%ld lines changed" +msgstr "%ld linjer ændret" + +#, c-format +msgid "freeing %ld lines" +msgstr "frigør %ld linjer" + +#, c-format +msgid " into \"%c" +msgstr " i \"%c" + +#, c-format +msgid "block of 1 line yanked%s" +msgstr "blok pÃ¥ 1 linje rykket%s" + +#, c-format +msgid "1 line yanked%s" +msgstr "1 linje rykket%s" + +#, c-format +msgid "block of %ld lines yanked%s" +msgstr "blok pÃ¥ %ld linjer rykket%s" + +#, c-format +msgid "%ld lines yanked%s" +msgstr "%ld linjer rykket%s" + +#, c-format +msgid "E353: Nothing in register %s" +msgstr "E353: Intet i register %s" + +msgid "" +"\n" +"--- Registers ---" +msgstr "" +"\n" +"--- Registre ---" + +msgid "Illegal register name" +msgstr "Ulovligt registernavn" + +msgid "" +"\n" +"# Registers:\n" +msgstr "" +"\n" +"# Registre:\n" + +#, c-format +msgid "E574: Unknown register type %d" +msgstr "E574: Ukendt registertype %d" + +msgid "" +"E883: search pattern and expression register may not contain two or more " +"lines" +msgstr "" +"E883: søgemønster og udtryksregister mÃ¥ ikke indeholde to eller flere linjer" + +#, c-format +msgid "%ld Cols; " +msgstr "%ld kolonner; " + +#, c-format +msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes" +msgstr "Markerede %s%ld af %ld linje; %lld af %lld ord; %lld af %lld byte" + +#, c-format +msgid "" +"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of " +"%lld Bytes" +msgstr "" +"Markerede %s%ld af %ld linje; %lld af %lld ord; %lld af %lld tegn; %lld af %" +"lld byte" + +#, c-format +msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld" +msgstr "Kol %s af %s; Linje %ld af %ld; Ord %lld af %lld; Byte %lld af %lld" + +#, c-format +msgid "" +"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte " +"%lld of %lld" +msgstr "" +"Kol %s af %s; Linje %ld af %ld; Ord %lld af %lld; Tegn %lld af %lld; Byte %" +"lld af %lld" + +#, c-format +msgid "(+%lld for BOM)" +msgstr "(+%lld for BOM)" + +msgid "Thanks for flying Vim" +msgstr "Tak fordi du fløj med Vim" + +msgid "E518: Unknown option" +msgstr "E518: Ukendt tilvalg" + +msgid "E519: Option not supported" +msgstr "E519: Tilvalg understøttes ikke" + +msgid "E520: Not allowed in a modeline" +msgstr "E520: Ikke tilladt pÃ¥ en tilstandslinje" + +msgid "E846: Key code not set" +msgstr "E846: Tastekode ikke sat" + +msgid "E521: Number required after =" +msgstr "E521: Nummer kræves efter =" + +msgid "E522: Not found in termcap" +msgstr "E522: Ikke fundet i termcap" + +#, c-format +msgid "E539: Illegal character <%s>" +msgstr "E539: Ulovligt tegn <%s>" + +#, c-format +msgid "For option %s" +msgstr "For tilvalget %s" + +msgid "E529: Cannot set 'term' to empty string" +msgstr "E529: Kan ikke sætte 'term' til tom streng" + +msgid "E530: Cannot change term in GUI" +msgstr "E530: Kan ikke skifte term i GUI" + +msgid "E531: Use \":gui\" to start the GUI" +msgstr "E531: Brug \":gui\" til at starte GUI'en" + +msgid "E589: 'backupext' and 'patchmode' are equal" +msgstr "E589: 'backupext' og 'patchmode' er ens" + +msgid "E834: Conflicts with value of 'listchars'" +msgstr "E834: Er i konflikt med værdien af 'listchars'" + +msgid "E835: Conflicts with value of 'fillchars'" +msgstr "E835: Er i konflikt med værdien af 'fillchars'" + +msgid "E617: Cannot be changed in the GTK+ 2 GUI" +msgstr "E617: Kan ikke ændres i GTK+ 2 GUI'en" + +#, c-format +msgid "E950: Cannot convert between %s and %s" +msgstr "E950: Kan ikke konvertere mellem %s og %s" + +msgid "E524: Missing colon" +msgstr "E524: Manglende kolon" + +msgid "E525: Zero length string" +msgstr "E525: Streng uden længde" + +#, c-format +msgid "E526: Missing number after <%s>" +msgstr "E526: Manglende nummer efter <%s>" + +msgid "E527: Missing comma" +msgstr "E527: Manglende komma" + +msgid "E528: Must specify a ' value" +msgstr "E528: Skal angive en '-værdi" + +msgid "E595: contains unprintable or wide character" +msgstr "E595: indeholder tegn som ikke kan udskrives eller er bredt" + +msgid "E596: Invalid font(s)" +msgstr "E596: Ugyldig skrifttype(r)" + +msgid "E597: can't select fontset" +msgstr "E597: kan ikke vælge skrifttypesæt" + +msgid "E598: Invalid fontset" +msgstr "E598: Ugyldigt skrifttypesæt" + +msgid "E533: can't select wide font" +msgstr "E533: kan ikke vælge bred skrifttype" + +msgid "E534: Invalid wide font" +msgstr "E534: Ugyldig bred skrifttype" + +#, c-format +msgid "E535: Illegal character after <%c>" +msgstr "E535: Ulovligt tegn efter <%c>" + +msgid "E536: comma required" +msgstr "E536: komma kræves" + +#, c-format +msgid "E537: 'commentstring' must be empty or contain %s" +msgstr "E537: 'commentstring' skal være tom eller indeholde %s" + +msgid "E538: No mouse support" +msgstr "E538: Ingen understøttelse af mus" + +msgid "E540: Unclosed expression sequence" +msgstr "E540: Ulukket udtryk-sekvens" + +msgid "E541: too many items" +msgstr "E541: for mange punkter" + +msgid "E542: unbalanced groups" +msgstr "E542: ubalancerede grupper" + +msgid "E946: Cannot make a terminal with running job modifiable" +msgstr "E946: Kan ikke gøre en terminal med kørende job ændringsbar" + +msgid "E590: A preview window already exists" +msgstr "E590: Der findes allerede et forhÃ¥ndsvisningsvindue" + +msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'" +msgstr "W17: Arabisk kræver UTF-8, brug ':set encoding=utf-8'" + +msgid "E954: 24-bit colors are not supported on this environment" +msgstr "E954: 24-bit farver understøttes ikke i dette miljø" + +#, c-format +msgid "E593: Need at least %d lines" +msgstr "E593: Skal være mindst %d linjer" + +#, c-format +msgid "E594: Need at least %d columns" +msgstr "E594: Skal være mindst %d kolonner" + +#, c-format +msgid "E355: Unknown option: %s" +msgstr "E355: Ukendt tilvalg: %s" + +#, c-format +msgid "E521: Number required: &%s = '%s'" +msgstr "E521: Nummer kræves: &%s = '%s'" + +msgid "" +"\n" +"--- Terminal codes ---" +msgstr "" +"\n" +"--- Terminal-koder ---" + +msgid "" +"\n" +"--- Global option values ---" +msgstr "" +"\n" +"--- Værdier for globale tilvalg ---" + +msgid "" +"\n" +"--- Local option values ---" +msgstr "" +"\n" +"--- Værdier for lokale tilvalg ---" + +msgid "" +"\n" +"--- Options ---" +msgstr "" +"\n" +"--- Tilvalg ---" + +msgid "E356: get_varp ERROR" +msgstr "E356: Fejl ved get_varp" + +#, c-format +msgid "E357: 'langmap': Matching character missing for %s" +msgstr "E357: 'langmap': Matchende tegn mangler for %s" + +#, c-format +msgid "E358: 'langmap': Extra characters after semicolon: %s" +msgstr "E358: 'langmap': Ekstra tegn efter semikolon: %s" + +msgid "cannot open " +msgstr "kan ikke Ã¥bne " + +msgid "VIM: Can't open window!\n" +msgstr "VIM: Kan ikke Ã¥bne vindue!\n" + +msgid "Need Amigados version 2.04 or later\n" +msgstr "Behøver Amigados version 2.04 eller senere\n" + +#, c-format +msgid "Need %s version %ld\n" +msgstr "Behøver %s version %ld\n" + +msgid "Cannot open NIL:\n" +msgstr "Kan ikke Ã¥bne NIL:\n" + +msgid "Cannot create " +msgstr "Kan ikke oprette " + +#, c-format +msgid "Vim exiting with %d\n" +msgstr "Vim afsluttede med %d\n" + +msgid "cannot change console mode ?!\n" +msgstr "kan ikke skifte konsoltilstand ?!\n" + +msgid "mch_get_shellsize: not a console??\n" +msgstr "mch_get_shellsize: ikke en konsol??\n" + +msgid "E360: Cannot execute shell with -f option" +msgstr "E360: Kan ikke udføre skal med -f-tilvalget" + +msgid "Cannot execute " +msgstr "Kan ikke udføre " + +msgid "shell " +msgstr "skal " + +msgid " returned\n" +msgstr " returnerede\n" + +msgid "ANCHOR_BUF_SIZE too small." +msgstr "ANCHOR_BUF_SIZE for lille." + +msgid "I/O ERROR" +msgstr "FEJL VED I/O" + +msgid "Message" +msgstr "Meddelelse" + +msgid "E237: Printer selection failed" +msgstr "E237: Valg af printer mislykkedes" + +#, c-format +msgid "to %s on %s" +msgstr "til %s pÃ¥ %s" + +#, c-format +msgid "E613: Unknown printer font: %s" +msgstr "E613: Ukendt skrifttype til printer: %s" + +#, c-format +msgid "E238: Print error: %s" +msgstr "E238: Fejl ved udskrivning: %s" + +#, c-format +msgid "Printing '%s'" +msgstr "Udskriver '%s'" + +#, c-format +msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" +msgstr "E244: Ulovligt tegnsætnavn \"%s\" i skrifttypenavnet \"%s\"" + +#, c-format +msgid "E244: Illegal quality name \"%s\" in font name \"%s\"" +msgstr "E244: Ulovligt kvalitetsnavn \"%s\" i skrifttypenavnet \"%s\"" + +#, c-format +msgid "E245: Illegal char '%c' in font name \"%s\"" +msgstr "E245: Ulovligt tegn '%c' i skrifttypenavnet \"%s\"" + +#, c-format +msgid "Opening the X display took %ld msec" +msgstr "Ã…bningen af X-displayet tog %ld ms" + +msgid "" +"\n" +"Vim: Got X error\n" +msgstr "" +"\n" +"Vim: Fik fejl ved X\n" + +msgid "Testing the X display failed" +msgstr "Test af X-displayet mislykkedes" + +msgid "Opening the X display timed out" +msgstr "Ã…bningen af X-displayet fik timeout" + +msgid "" +"\n" +"Could not get security context for " +msgstr "" +"\n" +"Kunne ikke hente sikkerhedskontekst for " + +msgid "" +"\n" +"Could not set security context for " +msgstr "" +"\n" +"Kunne ikke sætte sikkerhedskontekst for " + +#, c-format +msgid "Could not set security context %s for %s" +msgstr "Kunne ikke sætte sikkerhedskonteksten %s for %s" + +#, c-format +msgid "Could not get security context %s for %s. Removing it!" +msgstr "Kunne ikke hente sikkerhedskonteksten %s for %s. Fjerner den!" + +msgid "" +"\n" +"Cannot execute shell sh\n" +msgstr "" +"\n" +"Kan ikke udføre skallen sh\n" + +msgid "" +"\n" +"shell returned " +msgstr "" +"\n" +"skal returnerede " + +msgid "" +"\n" +"Cannot create pipes\n" +msgstr "" +"\n" +"Kan ikke oprette pipes\n" + +msgid "" +"\n" +"Cannot fork\n" +msgstr "" +"\n" +"Kan ikke fork\n" + +msgid "" +"\n" +"Cannot execute shell " +msgstr "" +"\n" +"Kan ikke udføre skallen " + +msgid "" +"\n" +"Command terminated\n" +msgstr "" +"\n" +"Kommando termineret\n" + +msgid "XSMP lost ICE connection" +msgstr "XSMP mistede ICE-forbindelse" + +#, c-format +msgid "dlerror = \"%s\"" +msgstr "dlerror = \"%s\"" + +msgid "Opening the X display failed" +msgstr "Ã…bningen af X-displayet mislykkedes" + +msgid "XSMP handling save-yourself request" +msgstr "XSMP-hÃ¥ndtering save-yourself-anmodning" + +msgid "XSMP opening connection" +msgstr "XSMP Ã¥bner forbindelse" + +msgid "XSMP ICE connection watch failed" +msgstr "XSMP ICE-forbindelse watch mislykkedes" + +#, c-format +msgid "XSMP SmcOpenConnection failed: %s" +msgstr "XSMP SmcOpenConnection mislykkedes: %s" + +msgid "At line" +msgstr "PÃ¥ linje" + +msgid "Could not load vim32.dll!" +msgstr "Kunne ikke indlæse vim32.dll!" + +msgid "VIM Error" +msgstr "Fejl ved VIM" + +msgid "Could not fix up function pointers to the DLL!" +msgstr "Kunne ikke rette op pÃ¥ funktion-pointere til DLL'en!" + +#, c-format +msgid "Vim: Caught %s event\n" +msgstr "Vim: Fangede %s-hændelse\n" + +msgid "close" +msgstr "luk" + +msgid "logoff" +msgstr "log ud" + +msgid "shutdown" +msgstr "luk ned" + +msgid "E371: Command not found" +msgstr "E371: Kommando ikke fundet" + +msgid "" +"VIMRUN.EXE not found in your $PATH.\n" +"External commands will not pause after completion.\n" +"See :help win32-vimrun for more information." +msgstr "" +"VIMRUN.EXE ikke fundet i din $PATH.\n" +"Eksterne kommandoer sættes ikke pÃ¥ pause efter fuldførelse.\n" +"Se :help win32-vimrun for mere information." + +msgid "Vim Warning" +msgstr "Advarsel ved Vim" + +#, c-format +msgid "shell returned %d" +msgstr "skal returnerede %d" + +msgid "E926: Current location list was changed" +msgstr "E926: Nuværende placeringsliste blev ændret" + +#, c-format +msgid "E372: Too many %%%c in format string" +msgstr "E372: For mange %%%c i formatet streng" + +#, c-format +msgid "E373: Unexpected %%%c in format string" +msgstr "E373: Uventet %%%c i formatet streng" + +msgid "E374: Missing ] in format string" +msgstr "E374: Manglende ] i formatet streng" + +#, c-format +msgid "E375: Unsupported %%%c in format string" +msgstr "E375: Ikke-understøttet %%%c i formatet streng" + +#, c-format +msgid "E376: Invalid %%%c in format string prefix" +msgstr "E376: Ugyldig %%%c i præfiks for formatet streng" + +#, c-format +msgid "E377: Invalid %%%c in format string" +msgstr "E377: Ugyldig %%%c i formatet streng" + +msgid "E378: 'errorformat' contains no pattern" +msgstr "E378: 'errorformat' indeholder ikke noget mønter" + +msgid "E379: Missing or empty directory name" +msgstr "E379: Manglende eller tomt mappenavn" + +msgid "E553: No more items" +msgstr "E553: Ikke flere punkter" + +msgid "E924: Current window was closed" +msgstr "E924: Nuværende vindue blev lukket" + +msgid "E925: Current quickfix was changed" +msgstr "E925: Nuværende quickfix blev ændret" + +#, c-format +msgid "(%d of %d)%s%s: " +msgstr "(%d af %d)%s%s: " + +msgid " (line deleted)" +msgstr " (linje slettet)" + +#, c-format +msgid "%serror list %d of %d; %d errors " +msgstr "%sfejlliste %d af %d; %d fejl " + +msgid "E380: At bottom of quickfix stack" +msgstr "E380: Nederst i quickfix-stakken" + +msgid "E381: At top of quickfix stack" +msgstr "E381: Øverst i quickfix-stakken" + +msgid "No entries" +msgstr "Ingen poster" + +msgid "Error file" +msgstr "Fejlfil" + +msgid "E683: File name missing or invalid pattern" +msgstr "E683: Filnavn mangler eller ugyldigt mønster" + +#, c-format +msgid "Cannot open file \"%s\"" +msgstr "Kan ikke Ã¥bne filen \"%s\"" + +msgid "E681: Buffer is not loaded" +msgstr "E681: Buffer er ikke indlæst" + +msgid "E777: String or List expected" +msgstr "E777: Streng eller liste ventet" + +#, c-format +msgid "E369: invalid item in %s%%[]" +msgstr "E369: ugyldigt punkt i %s%%[]" + +#, c-format +msgid "E769: Missing ] after %s[" +msgstr "E769: Manglende ] efter %s[" + +msgid "E944: Reverse range in character class" +msgstr "E944: Baglæns omrÃ¥de i tegnklasse" + +msgid "E945: Range too large in character class" +msgstr "E945: OmrÃ¥de for stort i tegnklasse" + +#, c-format +msgid "E53: Unmatched %s%%(" +msgstr "E53: Ikke-matchet %s%%(" + +#, c-format +msgid "E54: Unmatched %s(" +msgstr "E54: Ikke-matchet %s(" + +#, c-format +msgid "E55: Unmatched %s)" +msgstr "E55: Ikke-matchet %s)" + +msgid "E66: \\z( not allowed here" +msgstr "E66: \\z( ikke tilladt her" + +msgid "E67: \\z1 et al. not allowed here" +msgstr "E67: \\z1 og andre ikke tilladt her" + +#, c-format +msgid "E69: Missing ] after %s%%[" +msgstr "E69: Manglende ] efter %s%%[" + +#, c-format +msgid "E70: Empty %s%%[]" +msgstr "E70: Tom %s%%[]" + +msgid "E65: Illegal back reference" +msgstr "E65: Ulovlig tilbage-reference" + +msgid "E339: Pattern too long" +msgstr "E339: Mønster for langt" + +msgid "E50: Too many \\z(" +msgstr "E50: For mange \\z(" + +#, c-format +msgid "E51: Too many %s(" +msgstr "E51: For mange %s(" + +msgid "E52: Unmatched \\z(" +msgstr "E52: Ikke-matchet \\z(" + +#, c-format +msgid "E59: invalid character after %s@" +msgstr "E59: ugyldigt tegn efter %s@" + +#, c-format +msgid "E60: Too many complex %s{...}s" +msgstr "E60: For mange komplekse %s{...}s" + +#, c-format +msgid "E61: Nested %s*" +msgstr "E61: Indlejret %s*" + +#, c-format +msgid "E62: Nested %s%c" +msgstr "E62: Indlejret %s%c" + +msgid "E63: invalid use of \\_" +msgstr "E63: ugyldig brug af \\_" + +#, c-format +msgid "E64: %s%c follows nothing" +msgstr "E64: %s%c efterfølger intet" + +msgid "E68: Invalid character after \\z" +msgstr "E68: Ugyldigt tegn efter \\z" + +#, c-format +msgid "E678: Invalid character after %s%%[dxouU]" +msgstr "E678: Ugyldigt tegn efter %s%%[dxouU]" + +#, c-format +msgid "E71: Invalid character after %s%%" +msgstr "E71: Ugyldigt tegn efter %s%%" + +#, c-format +msgid "E554: Syntax error in %s{...}" +msgstr "E554: Fejl ved syntaks i %s{...}" + +msgid "External submatches:\n" +msgstr "Eksterne undermatch:\n" + +#, c-format +msgid "E888: (NFA regexp) cannot repeat %s" +msgstr "E888: (NFA regexp) kan ikke gentage %s" + +msgid "" +"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be " +"used " +msgstr "" +"E864: \\%#= mÃ¥ kun efterfølges af 0, 1 eller 2. Bruger den automatiske motor " + +msgid "Switching to backtracking RE engine for pattern: " +msgstr "Skifter til backtracking RE-motor for mønster: " + +msgid "E865: (NFA) Regexp end encountered prematurely" +msgstr "E865: (NFA) Mødte slutningen pÃ¥ regulært udtryk for tidligt" + +#, c-format +msgid "E866: (NFA regexp) Misplaced %c" +msgstr "E866: (NFA regexp) Forkert placeret %c" + +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %ld" +msgstr "E877: (NFA regexp) Ugyldig tegnklasse: %ld" + +#, c-format +msgid "E867: (NFA) Unknown operator '\\z%c'" +msgstr "E867: (NFA) Ukendt operator '\\z%c'" + +msgid "E951: \\% value too large" +msgstr "E951: \\%-værdi for stor" + +#, c-format +msgid "E867: (NFA) Unknown operator '\\%%%c'" +msgstr "E867: (NFA) Ukendt operator '\\%%%c'" + +msgid "E868: Error building NFA with equivalence class!" +msgstr "E868: Fejl ved bygning af NFA med ligestillet klasse!" + +#, c-format +msgid "E869: (NFA) Unknown operator '\\@%c'" +msgstr "E869: (NFA) Ukendt operator '\\@%c'" + +msgid "E870: (NFA regexp) Error reading repetition limits" +msgstr "E870: (NFA regexp) Fejl ved læsning af gentagelsesgrænser" + +msgid "E871: (NFA regexp) Can't have a multi follow a multi !" +msgstr "E871: (NFA regexp) En multi mÃ¥ ikke efterfølges af en multi !" + +msgid "E872: (NFA regexp) Too many '('" +msgstr "E872: (NFA regexp) For mange '('" + +msgid "E879: (NFA regexp) Too many \\z(" +msgstr "E879: (NFA regexp) For mange \\z(" + +msgid "E873: (NFA regexp) proper termination error" +msgstr "E873: (NFA regexp) fejl ved korrekt terminering" + +msgid "E874: (NFA) Could not pop the stack !" +msgstr "E874: (NFA) Kunne ikke pop'e stakken !" + +msgid "" +"E875: (NFA regexp) (While converting from postfix to NFA), too many states " +"left on stack" +msgstr "" +"E875: (NFA regexp) (Ved konvertering fra postfix til NFA), for mange " +"tilstande tilbage pÃ¥ stak" + +msgid "E876: (NFA regexp) Not enough space to store the whole NFA " +msgstr "E876: (NFA regexp) Ikke nok plads til at lagre hele NFA'en " + +msgid "E878: (NFA) Could not allocate memory for branch traversal!" +msgstr "E878: (NFA) Kunne ikke allokere hukommelse til gennemgang af gren!" + +msgid "" +"Could not open temporary log file for writing, displaying on stderr ... " +msgstr "Kunne ikke Ã¥bne midlertidig logfil til skrivning, viser pÃ¥ stderr ... " + +#, c-format +msgid "(NFA) COULD NOT OPEN %s !" +msgstr "(NFA) KUNNE IKKE Ã…BNE %s !" + +msgid "Could not open temporary log file for writing " +msgstr "Kunne ikke Ã¥bne midlertidig logfil til skrivning " + +msgid " VREPLACE" +msgstr " VERSTAT" + +msgid " REPLACE" +msgstr " ERSTAT" + +msgid " REVERSE" +msgstr " BAGLÆNS" + +msgid " INSERT" +msgstr " INDSÆT" + +msgid " (insert)" +msgstr " (indsæt)" + +msgid " (replace)" +msgstr " (erstat)" + +msgid " (vreplace)" +msgstr " (verstat)" + +msgid " Hebrew" +msgstr " Hebraisk" + +msgid " Arabic" +msgstr " Arabisk" + +msgid " (paste)" +msgstr " (indsæt)" + +msgid " VISUAL" +msgstr " VISUEL" + +msgid " VISUAL LINE" +msgstr " VISUEL LINJE" + +msgid " VISUAL BLOCK" +msgstr " VISUEL BLOK" + +msgid " SELECT" +msgstr " VÆLG" + +msgid " SELECT LINE" +msgstr " VÆLG LINJE" + +msgid " SELECT BLOCK" +msgstr " VÆLG BLOK" + +msgid "recording" +msgstr "optager" + +#, c-format +msgid "E383: Invalid search string: %s" +msgstr "E383: Ugyldig søgestreng: %s" + +#, c-format +msgid "E384: search hit TOP without match for: %s" +msgstr "E384: søgning ramte ØVERST uden match for: %s" + +#, c-format +msgid "E385: search hit BOTTOM without match for: %s" +msgstr "E385: søgning ramte NEDERST uden match for: %s" + +msgid "E386: Expected '?' or '/' after ';'" +msgstr "E386: Ventede '?' eller '/' efter ';'" + +msgid " (includes previously listed match)" +msgstr " (inkluderer tidligere oplistet match)" + +msgid "--- Included files " +msgstr "--- Inkluderede filer " + +msgid "not found " +msgstr "ikke fundet " + +msgid "in path ---\n" +msgstr "i sti ---\n" + +msgid " (Already listed)" +msgstr " (Allerede oplistet)" + +msgid " NOT FOUND" +msgstr " IKKE FUNDET" + +#, c-format +msgid "Scanning included file: %s" +msgstr "Skanner inkluderede filer: %s" + +#, c-format +msgid "Searching included file %s" +msgstr "Søger efter inkluderede fil %s" + +msgid "E387: Match is on current line" +msgstr "E387: Match er pÃ¥ nuværende linje" + +msgid "All included files were found" +msgstr "Alle inkluderede filer blev fundet" + +msgid "No included files" +msgstr "Ingen inkluderede filer" + +msgid "E388: Couldn't find definition" +msgstr "E388: Kunne ikke finde definition" + +msgid "E389: Couldn't find pattern" +msgstr "E389: Kunne ikke finde mønster" + +msgid "Substitute " +msgstr "Erstatning " + +#, c-format +msgid "" +"\n" +"# Last %sSearch Pattern:\n" +"~" +msgstr "" +"\n" +"# Sidste %sSøgemønster:\n" +"~" + +msgid "E756: Spell checking is not enabled" +msgstr "E756: Stavekontrol er ikke aktiveret" + +#, c-format +msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\"" +msgstr "Advarsel: Kan ikke finde ordlisten \"%s_%s.spl\" eller \"%s_ascii.spl\"" + +#, c-format +msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\"" +msgstr "Advarsel: Kan ikke finde ordlisten \"%s.%s.spl\" eller \"%s.ascii.spl\"" + +msgid "E797: SpellFileMissing autocommand deleted buffer" +msgstr "E797: SpellFileMissing-autokommando slettede buffer" + +#, c-format +msgid "Warning: region %s not supported" +msgstr "Advarsel: regionen %s understøttes ikke" + +msgid "Sorry, no suggestions" +msgstr "Beklager, ingen forslag" + +#, c-format +msgid "Sorry, only %ld suggestions" +msgstr "Beklager, kun %ld forslag" + +#, c-format +msgid "Change \"%.*s\" to:" +msgstr "Ændr \"%.*s\" til:" + +#, c-format +msgid " < \"%.*s\"" +msgstr " < \"%.*s\"" + +msgid "E752: No previous spell replacement" +msgstr "E752: Ingen tidligere staveerstatning" + +#, c-format +msgid "E753: Not found: %s" +msgstr "E753: Ikke fundet: %s" + +msgid "E758: Truncated spell file" +msgstr "E758: Afkortet spell-fil" + +#, c-format +msgid "Trailing text in %s line %d: %s" +msgstr "Efterstillede tekst i %s linje %d: %s" + +#, c-format +msgid "Affix name too long in %s line %d: %s" +msgstr "Affix-navn for langt i %s linje %d: %s" + +msgid "E761: Format error in affix file FOL, LOW or UPP" +msgstr "E761: Fejl i format i affix-filens FOL, LOW eller UPP" + +msgid "E762: Character in FOL, LOW or UPP is out of range" +msgstr "E762: Tegn i FOL, LOW eller UPP er udenfor omrÃ¥de" + +msgid "Compressing word tree..." +msgstr "Komprimerer ordtræ..." + +#, c-format +msgid "Reading spell file \"%s\"" +msgstr "Læser spell-filen \"%s\"" + +msgid "E757: This does not look like a spell file" +msgstr "E757: Det ligner ikke en spell-fil" + +msgid "E771: Old spell file, needs to be updated" +msgstr "E771: Gammel spell-fil, som skal opdateres" + +msgid "E772: Spell file is for newer version of Vim" +msgstr "E772: Spell-filen er til en nyere version af Vim" + +msgid "E770: Unsupported section in spell file" +msgstr "E770: Ikke-understøttet sektion i spell-fil" + +#, c-format +msgid "E778: This does not look like a .sug file: %s" +msgstr "E778: ligner ikke en .sug-fil: %s" + +#, c-format +msgid "E779: Old .sug file, needs to be updated: %s" +msgstr "E779: Gammel .sug-fil, som skal opdateres: %s" + +#, c-format +msgid "E780: .sug file is for newer version of Vim: %s" +msgstr "E780: .sug-filen er til en nyere version af Vim: %s" + +#, c-format +msgid "E781: .sug file doesn't match .spl file: %s" +msgstr "E781: .sug-filen matcher ikke .spl-filen: %s" + +#, c-format +msgid "E782: error while reading .sug file: %s" +msgstr "E782: fejl ved læsning af .sug-fil: %s" + +#, c-format +msgid "Reading affix file %s ..." +msgstr "Læser affix-filen %s ..." + +#, c-format +msgid "Conversion failure for word in %s line %d: %s" +msgstr "Mislykkede konvertering for ordet %s linje %d: %s" + +#, c-format +msgid "Conversion in %s not supported: from %s to %s" +msgstr "Konvertering i %s understøttes ikke: fra %s til %s" + +#, c-format +msgid "Conversion in %s not supported" +msgstr "Konvertering i %s understøttes ikke" + +#, c-format +msgid "Invalid value for FLAG in %s line %d: %s" +msgstr "Ugyldig værdi for FLAG i %s linje %d: %s" + +#, c-format +msgid "FLAG after using flags in %s line %d: %s" +msgstr "FLAG efter brug af flag i %s linje %d: %s" + +#, c-format +msgid "" +"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line " +"%d" +msgstr "" +"Definering af COMPOUNDFORBIDFLAG efter PFX-punkt kan give forkerte " +"resultater i %s linje %d" + +#, c-format +msgid "" +"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line " +"%d" +msgstr "" +"Definering af COMPOUNDPERMITFLAG efter PFX-punkt kan give forkerte " +"resultater i %s linje %d" + +#, c-format +msgid "Wrong COMPOUNDRULES value in %s line %d: %s" +msgstr "Forkert COMPOUNDRULES-værdi i %s linje %d: %s" + +#, c-format +msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s" +msgstr "Forkert COMPOUNDWORDMAX-værdi i %s linje %d: %s" + +#, c-format +msgid "Wrong COMPOUNDMIN value in %s line %d: %s" +msgstr "Forkert COMPOUNDMIN-værdi i %s linje %d: %s" + +#, c-format +msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s" +msgstr "Forkert COMPOUNDSYLMAX-værdi i %s linje %d: %s" + +#, c-format +msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s" +msgstr "Forkert CHECKCOMPOUNDPATTERN-værdi i %s linje %d: %s" + +#, c-format +msgid "Different combining flag in continued affix block in %s line %d: %s" +msgstr "Forskellige kombineringsflag i fortsat affix-blok i %s linje %d: %s" + +#, c-format +msgid "Duplicate affix in %s line %d: %s" +msgstr "Duplikeret affix i %s linje %d: %s" + +#, c-format +msgid "" +"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s " +"line %d: %s" +msgstr "" +"Affix ogsÃ¥ brugt for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST i %s " +"linje %d: %s" + +#, c-format +msgid "Expected Y or N in %s line %d: %s" +msgstr "Ventede Y eller N i %s linje %d: %s" + +#, c-format +msgid "Broken condition in %s line %d: %s" +msgstr "Ødelagt betingelse i %s linje %d: %s" + +#, c-format +msgid "Expected REP(SAL) count in %s line %d" +msgstr "Ventede REP(SAL)-tælling i %s linje %d" + +#, c-format +msgid "Expected MAP count in %s line %d" +msgstr "Ventede MAP-tælling i %s linje %d" + +#, c-format +msgid "Duplicate character in MAP in %s line %d" +msgstr "Duplikeret tegn i MAP i %s linje %d" + +#, c-format +msgid "Unrecognized or duplicate item in %s line %d: %s" +msgstr "Ikke-genkendt eller duplikeret punkt i %s linje %d: %s" + +#, c-format +msgid "Missing FOL/LOW/UPP line in %s" +msgstr "Manglende FOL-/LOW-/UPP-linje i %s" + +msgid "COMPOUNDSYLMAX used without SYLLABLE" +msgstr "COMPOUNDSYLMAX brugt uden SYLLABLE" + +msgid "Too many postponed prefixes" +msgstr "For mange udskudte præfikser" + +msgid "Too many compound flags" +msgstr "For mange compound-flag" + +msgid "Too many postponed prefixes and/or compound flags" +msgstr "For mange udskudte præfikser og/eller compound-flag" + +#, c-format +msgid "Missing SOFO%s line in %s" +msgstr "Manglende SOFO%s-linje i %s" + +#, c-format +msgid "Both SAL and SOFO lines in %s" +msgstr "BÃ¥de SAL- og SOFO-linjer i %s" + +#, c-format +msgid "Flag is not a number in %s line %d: %s" +msgstr "Flag er ikke et nummer i %s linje %d: %s" + +#, c-format +msgid "Illegal flag in %s line %d: %s" +msgstr "Ulovligt flag i %s linje %d: %s" + +#, c-format +msgid "%s value differs from what is used in another .aff file" +msgstr "%s-værdi er ikke den samme som bruges i en anden .aff-fil" + +#, c-format +msgid "Reading dictionary file %s ..." +msgstr "Læser ordbogsfilen %s ..." + +#, c-format +msgid "E760: No word count in %s" +msgstr "E760: Ingen ordtælling i %s" + +#, c-format +msgid "line %6d, word %6ld - %s" +msgstr "linje %6d, ord %6ld - %s" + +#, c-format +msgid "Duplicate word in %s line %d: %s" +msgstr "Duplikeret ord i %s linje %d: %s" + +#, c-format +msgid "First duplicate word in %s line %d: %s" +msgstr "Første duplikeret ord i %s linje %d: %s" + +#, c-format +msgid "%d duplicate word(s) in %s" +msgstr "%d duplikeret ord i %s" + +#, c-format +msgid "Ignored %d word(s) with non-ASCII characters in %s" +msgstr "Ignorerede %d ord med ikke-ASCII-tegn i %s" + +#, c-format +msgid "Reading word file %s ..." +msgstr "Læser ordfilen %s ..." + +#, c-format +msgid "Duplicate /encoding= line ignored in %s line %d: %s" +msgstr "Duplikeret /encoding=-linje ignoreret i %s linje %d: %s" + +#, c-format +msgid "/encoding= line after word ignored in %s line %d: %s" +msgstr "/encoding=-linje efter ord ignoreret i %s linje %d: %s" + +#, c-format +msgid "Duplicate /regions= line ignored in %s line %d: %s" +msgstr "Duplikerede /regions=-linjer ignoreret i %s linje %d: %s" + +#, c-format +msgid "Too many regions in %s line %d: %s" +msgstr "For mange regioner i %s linje %d: %s" + +#, c-format +msgid "/ line ignored in %s line %d: %s" +msgstr "/-linje ignoreret i %s linje %d: %s" + +#, c-format +msgid "Invalid region nr in %s line %d: %s" +msgstr "Ugyldigt regisionsnummer i %s linje %d: %s" + +#, c-format +msgid "Unrecognized flags in %s line %d: %s" +msgstr "Ugenkendte flag i %s linje %d: %s" + +#, c-format +msgid "Ignored %d words with non-ASCII characters" +msgstr "Ignorerer %d ord med ikke-ASCII-tegn" + +msgid "E845: Insufficient memory, word list will be incomplete" +msgstr "E845: Ikke nok hukommelse, ordlisten vil være ufuldstændig" + +#, c-format +msgid "Compressed %d of %d nodes; %d (%d%%) remaining" +msgstr "Komprimerede %d af %d punkter; %d (%d%%) tilbage" + +msgid "Reading back spell file..." +msgstr "Læser spell-fil tilbage..." + +msgid "Performing soundfolding..." +msgstr "Udfører lydsammenfoldning..." + +#, c-format +msgid "Number of words after soundfolding: %ld" +msgstr "Antal ord efter lydsammenfoldning: %ld" + +#, c-format +msgid "Total number of words: %d" +msgstr "Samlet antal ord: %d" + +#, c-format +msgid "Writing suggestion file %s ..." +msgstr "Skriver forslagsfilen %s ..." + +#, c-format +msgid "Estimated runtime memory use: %d bytes" +msgstr "AnslÃ¥et brug af afviklingshukommelse: %d byte" + +msgid "E751: Output file name must not have region name" +msgstr "E751: Outputfilnavn mÃ¥ ikke have regionsnavn" + +#, c-format +msgid "E754: Only up to %ld regions supported" +msgstr "E754: Kun op til %ld regioner understøttes" + +#, c-format +msgid "E755: Invalid region in %s" +msgstr "E755: Ugyldig region i %s" + +msgid "Warning: both compounding and NOBREAK specified" +msgstr "Advarsel: bÃ¥de compounding og NOBREAK angivet" + +#, c-format +msgid "Writing spell file %s ..." +msgstr "Skriver spell-filen %s ..." + +msgid "Done!" +msgstr "Færdig!" + +#, c-format +msgid "E765: 'spellfile' does not have %ld entries" +msgstr "E765: 'spellfile' har ingen %ld-poster" + +#, c-format +msgid "Word '%.*s' removed from %s" +msgstr "Ordet '%.*s' fjernet fra %s" + +#, c-format +msgid "Word '%.*s' added to %s" +msgstr "Ordet '%.*s' tilføjet til %s" + +msgid "E763: Word characters differ between spell files" +msgstr "E763: Ordtegn er ikke ens i spell-filer" + +msgid "E783: duplicate char in MAP entry" +msgstr "E783: duplikeret tegn i MAP-post" + +msgid "No Syntax items defined for this buffer" +msgstr "Ingen syntakspunkter defineret for denne buffer" + +msgid "syntax conceal on" +msgstr "syntax conceal on" + +msgid "syntax conceal off" +msgstr "syntax conceal off" + +#, c-format +msgid "E390: Illegal argument: %s" +msgstr "E390: Ulovligt argument: %s" + +msgid "syntax case ignore" +msgstr "syntax case ignore" + +msgid "syntax case match" +msgstr "syntax case match" + +msgid "syntax spell toplevel" +msgstr "syntax spell toplevel" + +msgid "syntax spell notoplevel" +msgstr "syntax spell notoplevel" + +msgid "syntax spell default" +msgstr "syntax spell default" + +msgid "syntax iskeyword " +msgstr "syntax iskeyword " + +#, c-format +msgid "E391: No such syntax cluster: %s" +msgstr "E391: Ingen sÃ¥dan syntaks-cluster: %s" + +msgid "syncing on C-style comments" +msgstr "synkronisering pÃ¥ C-style-kommentarer" + +msgid "no syncing" +msgstr "ingen synkronisering" + +msgid "syncing starts " +msgstr "synkronisering starter " + +msgid " lines before top line" +msgstr " linjer inden øverste linje" + +msgid "" +"\n" +"--- Syntax sync items ---" +msgstr "" +"\n" +"--- Syntaks-synkroniseringspunkter ---" + +msgid "" +"\n" +"syncing on items" +msgstr "" +"\n" +"synkroniserer pÃ¥ punkter" + +msgid "" +"\n" +"--- Syntax items ---" +msgstr "" +"\n" +"--- Syntakspunkter ---" + +#, c-format +msgid "E392: No such syntax cluster: %s" +msgstr "E392: Ingen sÃ¥dan syntaks-cluster: %s" + +msgid "minimal " +msgstr "minimal " + +msgid "maximal " +msgstr "maksimal " + +msgid "; match " +msgstr "; match " + +msgid " line breaks" +msgstr " linjeombrydninger" + +msgid "E395: contains argument not accepted here" +msgstr "E395: indeholder argument som ikke accepteres her" + +msgid "E844: invalid cchar value" +msgstr "E844: ugyldig cchar-værdi" + +msgid "E393: group[t]here not accepted here" +msgstr "E393: group[t]here accepteres ikke her" + +#, c-format +msgid "E394: Didn't find region item for %s" +msgstr "E394: Find ikke regionspunkter for %s" + +msgid "E397: Filename required" +msgstr "E397: Filnavn kræves" + +msgid "E847: Too many syntax includes" +msgstr "E847: For mange syntaks inkluderinger" + +#, c-format +msgid "E789: Missing ']': %s" +msgstr "E789: Manglende ']': %s" + +#, c-format +msgid "E890: trailing char after ']': %s]%s" +msgstr "E890: efterstillede tegn efter ']': %s]%s" + +#, c-format +msgid "E398: Missing '=': %s" +msgstr "E398: Manglende '=': %s" + +#, c-format +msgid "E399: Not enough arguments: syntax region %s" +msgstr "E399: For mange argumenter: syntaks region %s" + +msgid "E848: Too many syntax clusters" +msgstr "E848: For mange syntaks-clusters" + +msgid "E400: No cluster specified" +msgstr "E400: Ingen cluster angivet" + +#, c-format +msgid "E401: Pattern delimiter not found: %s" +msgstr "E401: Mønsterafgrænser ikke fundet: %s" + +#, c-format +msgid "E402: Garbage after pattern: %s" +msgstr "E402: Affald efter mønster: %s" + +msgid "E403: syntax sync: line continuations pattern specified twice" +msgstr "" +"E403: syntaks synkronisering: linjefortsættelsesmønster angivet to gange" + +#, c-format +msgid "E404: Illegal arguments: %s" +msgstr "E404: Ulovlige argumenter: %s" + +#, c-format +msgid "E405: Missing equal sign: %s" +msgstr "E405: Manglende lighedstegn: %s" + +#, c-format +msgid "E406: Empty argument: %s" +msgstr "E406: Tomt argument: %s" + +#, c-format +msgid "E407: %s not allowed here" +msgstr "E407: %s ikke tilladt her" + +#, c-format +msgid "E408: %s must be first in contains list" +msgstr "E408: %s skal være først i contains-liste" + +#, c-format +msgid "E409: Unknown group name: %s" +msgstr "E409: Ukendt gruppenavn: %s" + +#, c-format +msgid "E410: Invalid :syntax subcommand: %s" +msgstr "E410: Ugyldig :syntax-underkommando: %s" + +msgid "" +" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN" +msgstr "" +" SAMLET ANTAL MATCH LANGSOMST GENNEMS. NAVN MØNSTER" + +msgid "E679: recursive loop loading syncolor.vim" +msgstr "E679: rekursiv løkke ved indlæsning af syncolor.vim" + +#, c-format +msgid "E411: highlight group not found: %s" +msgstr "E411: fremhævningsgruppe ikke fundet: %s" + +#, c-format +msgid "E412: Not enough arguments: \":highlight link %s\"" +msgstr "E412: Ikke nok argumenter: \":highlight link %s\"" + +#, c-format +msgid "E413: Too many arguments: \":highlight link %s\"" +msgstr "E413: For mange argumenter: \":highlight link %s\"" + +msgid "E414: group has settings, highlight link ignored" +msgstr "E414: gruppe har indstillinger, highlight link ignoreret" + +#, c-format +msgid "E415: unexpected equal sign: %s" +msgstr "E415: uventet lighedstegn: %s" + +#, c-format +msgid "E416: missing equal sign: %s" +msgstr "E416: manglende lighedstegn: %s" + +#, c-format +msgid "E417: missing argument: %s" +msgstr "E417: manglende argument: %s" + +#, c-format +msgid "E418: Illegal value: %s" +msgstr "E418: Ulovlig værdi: %s" + +msgid "E419: FG color unknown" +msgstr "E419: Forgrundsfarve ukendt" + +msgid "E420: BG color unknown" +msgstr "E420: Baggrundsfarve ukendt" + +#, c-format +msgid "E421: Color name or number not recognized: %s" +msgstr "E421: Farvenavn eller -nummer ikke genkendt: %s" + +#, c-format +msgid "E422: terminal code too long: %s" +msgstr "E422: terminalkode for lang: %s" + +#, c-format +msgid "E423: Illegal argument: %s" +msgstr "E423: Ulovligt argument: %s" + +msgid "E424: Too many different highlighting attributes in use" +msgstr "E424: For mange forskellige fremhævningsattributter i brug" + +msgid "E669: Unprintable character in group name" +msgstr "E669: Tegn som ikke kan udskrives i gruppenavn" + +msgid "W18: Invalid character in group name" +msgstr "W18: Ugyldige tegn i gruppenavn" + +msgid "E849: Too many highlight and syntax groups" +msgstr "E849: For mange fremhævnings- og syntaksgrupper" + +msgid "E555: at bottom of tag stack" +msgstr "E555: nederst i tag-stak" + +msgid "E556: at top of tag stack" +msgstr "E556: øverst i tag-stak" + +msgid "E425: Cannot go before first matching tag" +msgstr "E425: Kan ikke gÃ¥ efter første matchende tag" + +#, c-format +msgid "E426: tag not found: %s" +msgstr "E426: tag ikke fundet: %s" + +msgid " # pri kind tag" +msgstr " # pri kind tag" + +msgid "file\n" +msgstr "fil\n" + +msgid "E427: There is only one matching tag" +msgstr "E427: Der er kun ét matchende tag" + +msgid "E428: Cannot go beyond last matching tag" +msgstr "E428: Kan ikke gÃ¥ efter sidste matchende tag" + +#, c-format +msgid "File \"%s\" does not exist" +msgstr "Filen \"%s\" findes ikke" + +#, c-format +msgid "tag %d of %d%s" +msgstr "tag %d af %d%s" + +msgid " or more" +msgstr " eller flere" + +msgid " Using tag with different case!" +msgstr " Bruger tag med anden versaltype!" + +#, c-format +msgid "E429: File \"%s\" does not exist" +msgstr "E429: Filen \"%s\" findes ikke" + +msgid "" +"\n" +" # TO tag FROM line in file/text" +msgstr "" +"\n" +" # TIL tag FRA linje i fil/tekst" + +#, c-format +msgid "Searching tags file %s" +msgstr "Søger i tags-filen %s" + +#, c-format +msgid "E430: Tag file path truncated for %s\n" +msgstr "E430: Tag-filens sti afkortet for %s\n" + +msgid "Ignoring long line in tags file" +msgstr "Ignorerer lang linje i tags-fil" + +#, c-format +msgid "E431: Format error in tags file \"%s\"" +msgstr "E431: Fejl ved format i tags-filen \"%s\"" + +#, c-format +msgid "Before byte %ld" +msgstr "Inden byte %ld" + +#, c-format +msgid "E432: Tags file not sorted: %s" +msgstr "E432: Tags-fil ikke sorteret: %s" + +msgid "E433: No tags file" +msgstr "E433: Ingen tags-fil" + +msgid "E434: Can't find tag pattern" +msgstr "E434: Kan ikke finde tag-mønster" + +msgid "E435: Couldn't find tag, just guessing!" +msgstr "E435: Kunne ikke finde tag, gætter bare!" + +#, c-format +msgid "Duplicate field name: %s" +msgstr "Duplikeret feltnavn: %s" + +msgid "' not known. Available builtin terminals are:" +msgstr "' ikke kendt. Tilgængelige indbyggede terminaler:" + +msgid "defaulting to '" +msgstr "bruger standarden '" + +msgid "E557: Cannot open termcap file" +msgstr "E557: Kan ikke Ã¥bne termcap-fil" + +msgid "E558: Terminal entry not found in terminfo" +msgstr "E558: Terminal-post ikke fundet i terminfo" + +msgid "E559: Terminal entry not found in termcap" +msgstr "E559: Terminal-post ikke fundet i termcap" + +#, c-format +msgid "E436: No \"%s\" entry in termcap" +msgstr "E436: Ingen \"%s\"-post i termcap" + +msgid "E437: terminal capability \"cm\" required" +msgstr "E437: terminal-formÃ¥enheden \"cm\" kræves" + +msgid "" +"\n" +"--- Terminal keys ---" +msgstr "" +"\n" +"--- Terminal-taster ---" + +msgid "Cannot open $VIMRUNTIME/rgb.txt" +msgstr "Kan ikke Ã¥bne $VIMRUNTIME/rgb.txt" + +#, c-format +msgid "Kill job in \"%s\"?" +msgstr "Dræb job i \"%s\"?" + +msgid "Terminal" +msgstr "Terminal" + +msgid "Terminal-finished" +msgstr "Terminal-færdig" + +msgid "active" +msgstr "aktiv" + +msgid "running" +msgstr "køre" + +msgid "finished" +msgstr "færdig" + +#, c-format +msgid "E953: File exists: %s" +msgstr "E953: Filen findes: %s" + +msgid "E955: Not a terminal buffer" +msgstr "E955: Ikke en terminal-buffer" + +msgid "new shell started\n" +msgstr "ny skal startet\n" + +msgid "Vim: Error reading input, exiting...\n" +msgstr "Vim: Fejl ved læsning af input, afslutter...\n" + +msgid "Used CUT_BUFFER0 instead of empty selection" +msgstr "Brugte CUT_BUFFER0 i stedet for tom markering" + +msgid "E881: Line count changed unexpectedly" +msgstr "E881: Linjeantal ændret uventet" + +msgid "No undo possible; continue anyway" +msgstr "Ingen fortryd mulig; fortsætter alligevel" + +#, c-format +msgid "E828: Cannot open undo file for writing: %s" +msgstr "E828: Kan ikke Ã¥bne fortrydelsesfil til skrivning: %s" + +#, c-format +msgid "E825: Corrupted undo file (%s): %s" +msgstr "E825: Korrupt fortrydelsesfil (%s): %s" + +msgid "Cannot write undo file in any directory in 'undodir'" +msgstr "Kan ikke skrive fortrydelsesfil i nogen mappe i 'undodir'" + +#, c-format +msgid "Will not overwrite with undo file, cannot read: %s" +msgstr "Overskriver ikke med fortrydelsesfil, kan ikke læse: %s" + +#, c-format +msgid "Will not overwrite, this is not an undo file: %s" +msgstr "Overskriver ikke, det er ikke en fortrydelsesfil: %s" + +msgid "Skipping undo file write, nothing to undo" +msgstr "Springer skrivning af fortrydelsesfil over, intet at fortryde" + +#, c-format +msgid "Writing undo file: %s" +msgstr "Skriver fortrydelsesfil: %s" + +#, c-format +msgid "E829: write error in undo file: %s" +msgstr "E829: fejl ved skrivning i fortrydelsesfil: %s" + +#, c-format +msgid "Not reading undo file, owner differs: %s" +msgstr "Læser ikke fortrydelsesfil, ejer er ikke den samme: %s" + +#, c-format +msgid "Reading undo file: %s" +msgstr "Læser fortrydelsesfil: %s" + +#, c-format +msgid "E822: Cannot open undo file for reading: %s" +msgstr "E822: Kan ikke Ã¥bne fortrydelsesfil til læsning: %s" + +#, c-format +msgid "E823: Not an undo file: %s" +msgstr "E823: Ikke en fortrydelsesfil: %s" + +#, c-format +msgid "E832: Non-encrypted file has encrypted undo file: %s" +msgstr "E832: Ikke-krypteret fil har krypteret fortrydelsesfil: %s" + +#, c-format +msgid "E826: Undo file decryption failed: %s" +msgstr "E826: Dekryptering af fortrydelsesfil mislykkedes: %s" + +#, c-format +msgid "E827: Undo file is encrypted: %s" +msgstr "E827: Fortrydelsesfilen er krypteret: %s" + +#, c-format +msgid "E824: Incompatible undo file: %s" +msgstr "E824: Inkompatibel fortrydelsesfil: %s" + +msgid "File contents changed, cannot use undo info" +msgstr "Filindholdet ændret, kan ikke bruge fortrydelsesinfo" + +#, c-format +msgid "Finished reading undo file %s" +msgstr "Færdig med at læse fortrydelsesfilen %s" + +msgid "Already at oldest change" +msgstr "Allerede ved ældste ændring" + +msgid "Already at newest change" +msgstr "Allerede ved nyeste ændring" + +#, c-format +msgid "E830: Undo number %ld not found" +msgstr "E830: Fortrydelsesnummer %ld ikke fundet" + +msgid "E438: u_undo: line numbers wrong" +msgstr "E438: u_undo: linjenumre forkerte" + +msgid "more line" +msgstr "linje mere" + +msgid "more lines" +msgstr "linjer mere" + +msgid "line less" +msgstr "linje mindre" + +msgid "fewer lines" +msgstr "linjere mindre" + +msgid "change" +msgstr "ændring" + +msgid "changes" +msgstr "ændringer" + +#, c-format +msgid "%ld %s; %s #%ld %s" +msgstr "%ld %s; %s #%ld %s" + +msgid "before" +msgstr "inden" + +msgid "after" +msgstr "efter" + +msgid "Nothing to undo" +msgstr "Intet at fortryde" + +msgid "number changes when saved" +msgstr "nummer ændrin. hvornÃ¥r gemt" + +#, c-format +msgid "%ld seconds ago" +msgstr "%ld sekunder siden" + +msgid "E790: undojoin is not allowed after undo" +msgstr "E790: undojoin ikke tilladt efter undo" + +msgid "E439: undo list corrupt" +msgstr "E439: fortrydelsesliste korrupt" + +msgid "E440: undo line missing" +msgstr "E440: fortrydelseslinje mangler" + +#, c-format +msgid "E122: Function %s already exists, add ! to replace it" +msgstr "E122: Funktionen %s findes allerede, tilføj ! for at erstatte den" + +msgid "E717: Dictionary entry already exists" +msgstr "E717: Ordbog-post findes allerede" + +msgid "E718: Funcref required" +msgstr "E718: Funcref kræves" + +#, c-format +msgid "E130: Unknown function: %s" +msgstr "E130: Ukendt funktion: %s" + +#, c-format +msgid "E125: Illegal argument: %s" +msgstr "E125: Ulovligt argument: %s" + +#, c-format +msgid "E853: Duplicate argument name: %s" +msgstr "E853: Duplikeret argumentnavn: %s" + +#, c-format +msgid "E740: Too many arguments for function %s" +msgstr "E740: For mange argumenter til funktionen %s" + +#, c-format +msgid "E116: Invalid arguments for function %s" +msgstr "E116: Ugyldige argumenter til funktionen %s" + +msgid "E132: Function call depth is higher than 'maxfuncdepth'" +msgstr "E132: Dybden af funktionskald er større end 'maxfuncdepth'" + +#, c-format +msgid "calling %s" +msgstr "kalder %s" + +#, c-format +msgid "%s aborted" +msgstr "%s afbrudt" + +#, c-format +msgid "%s returning #%ld" +msgstr "%s returnerer #%ld" + +#, c-format +msgid "%s returning %s" +msgstr "%s returnerer %s" + +msgid "E699: Too many arguments" +msgstr "E699: For mange argumenter" + +#, c-format +msgid "E117: Unknown function: %s" +msgstr "E117: Ukendt funktion: %s" + +#, c-format +msgid "E933: Function was deleted: %s" +msgstr "E933: Funktion blev slettet: %s" + +#, c-format +msgid "E119: Not enough arguments for function: %s" +msgstr "E119: Ikke nok argumenter til funktionen: %s" + +#, c-format +msgid "E120: Using <SID> not in a script context: %s" +msgstr "E120: Bruger <SID> ikke i et script kontekst: %s" + +#, c-format +msgid "E725: Calling dict function without Dictionary: %s" +msgstr "E725: Kalder dict-funktion uden ordbog: %s" + +msgid "E129: Function name required" +msgstr "E129: Funktionsnavn kræves" + +#, c-format +msgid "E128: Function name must start with a capital or \"s:\": %s" +msgstr "E128: Funktionsnavnet skal begynde med et stort bogstav eller \"s:\": %s" + +#, c-format +msgid "E884: Function name cannot contain a colon: %s" +msgstr "E884: Funktionsnavnet mÃ¥ ikke indeholdet et kolon: %s" + +#, c-format +msgid "E123: Undefined function: %s" +msgstr "E123: Udefineret funktion: %s" + +#, c-format +msgid "E124: Missing '(': %s" +msgstr "E124: Manglende '(': %s" + +msgid "E862: Cannot use g: here" +msgstr "E862: Kan ikke bruge g: her" + +#, c-format +msgid "E932: Closure function should not be at top level: %s" +msgstr "E932: Closure-funktion skal ikke være pÃ¥ topniveau: %s" + +msgid "E126: Missing :endfunction" +msgstr "E126: Manglende :endfunction" + +#, c-format +msgid "W22: Text found after :endfunction: %s" +msgstr "W22: Tekst fundet efter :endfunction: %s" + +#, c-format +msgid "E707: Function name conflicts with variable: %s" +msgstr "E707: Funktionsnavnet er i konflikt med variablen: %s" + +#, c-format +msgid "E127: Cannot redefine function %s: It is in use" +msgstr "E127: Kan ikke redefinere funktionen %s: Den er i brug" + +#, c-format +msgid "E746: Function name does not match script file name: %s" +msgstr "E746: Funktionsnavn matcher ikke scriptfilnavn: %s" + +#, c-format +msgid "E131: Cannot delete function %s: It is in use" +msgstr "E131: Kan ikke slette funktionen %s: Den er i brug" + +msgid "E133: :return not inside a function" +msgstr "E133: :return ikke i en funktion" + +#, c-format +msgid "E107: Missing parentheses: %s" +msgstr "E107: Manglende parenteser: %s" + +msgid "" +"\n" +"MS-Windows 64-bit GUI version" +msgstr "" +"\n" +"MS-Windows 64-bit GUI-version" + +msgid "" +"\n" +"MS-Windows 32-bit GUI version" +msgstr "" +"\n" +"MS-Windows 32-bit GUI-version" + +msgid " with OLE support" +msgstr " med understøttelse af OLE" + +msgid "" +"\n" +"MS-Windows 64-bit console version" +msgstr "" +"\n" +"MS-Windows 64-bit konsol-version" + +msgid "" +"\n" +"MS-Windows 32-bit console version" +msgstr "" +"\n" +"MS-Windows 32-bit konsol-version" + +msgid "" +"\n" +"macOS version" +msgstr "" +"\n" +"macOS-version" + +msgid "" +"\n" +"macOS version w/o darwin feat." +msgstr "" +"\n" +"macOS-version med/uden darwin-funktionalitet." + +msgid "" +"\n" +"OpenVMS version" +msgstr "" +"\n" +"OpenVMS-version" + +msgid "" +"\n" +"Included patches: " +msgstr "" +"\n" +"Rettelser som er med: " + +msgid "" +"\n" +"Extra patches: " +msgstr "" +"\n" +"Ekstra rettelser: " + +msgid "Modified by " +msgstr "Ændret af " + +msgid "" +"\n" +"Compiled " +msgstr "" +"\n" +"Kompileret " + +msgid "by " +msgstr "af " + +msgid "" +"\n" +"Huge version " +msgstr "" +"\n" +"Huge-version " + +msgid "" +"\n" +"Big version " +msgstr "" +"\n" +"Big-version " + +msgid "" +"\n" +"Normal version " +msgstr "" +"\n" +"Normal-version " + +msgid "" +"\n" +"Small version " +msgstr "" +"\n" +"Small-version " + +msgid "" +"\n" +"Tiny version " +msgstr "" +"\n" +"Tiny-version " + +msgid "without GUI." +msgstr "uden GUI." + +msgid "with GTK3 GUI." +msgstr "med GTK3-GUI." + +msgid "with GTK2-GNOME GUI." +msgstr "med GTK2-GNOME-GUI." + +msgid "with GTK2 GUI." +msgstr "med GTK2-GUI." + +msgid "with X11-Motif GUI." +msgstr "med X11-Motif-GUI." + +msgid "with X11-neXtaw GUI." +msgstr "med X11-neXtaw-GUI." + +msgid "with X11-Athena GUI." +msgstr "med X11-Athena-GUI." + +msgid "with Photon GUI." +msgstr "med Photon-GUI." + +msgid "with GUI." +msgstr "med GUI." + +msgid "with Carbon GUI." +msgstr "med Carbon-GUI." + +msgid "with Cocoa GUI." +msgstr "med Cocoa-GUI." + +msgid " Features included (+) or not (-):\n" +msgstr " Funktionaliteter som er med (+) eller ikke (-):\n" + +msgid " system vimrc file: \"" +msgstr " system vimrc-fil: \"" + +msgid " user vimrc file: \"" +msgstr " bruger vimrc-fil: \"" + +msgid " 2nd user vimrc file: \"" +msgstr " 2. bruger vimrc-fil: \"" + +msgid " 3rd user vimrc file: \"" +msgstr " 3. bruger vimrc-fil: \"" + +msgid " user exrc file: \"" +msgstr " bruger exrc-fil: \"" + +msgid " 2nd user exrc file: \"" +msgstr " 2. bruger exrc-fil: \"" + +msgid " system gvimrc file: \"" +msgstr " system gvimrc-fil: \"" + +msgid " user gvimrc file: \"" +msgstr " bruger gvimrc-fil: \"" + +msgid "2nd user gvimrc file: \"" +msgstr "2. bruger gvimrc-fil: \"" + +msgid "3rd user gvimrc file: \"" +msgstr "3. bruger gvimrc-fil: \"" + +msgid " defaults file: \"" +msgstr " defaults-fil: \"" + +msgid " system menu file: \"" +msgstr " system menu-fil: \"" + +msgid " fall-back for $VIM: \"" +msgstr " fall-back for $VIM: \"" + +msgid " f-b for $VIMRUNTIME: \"" +msgstr " f-b for $VIMRUNTIME: \"" + +msgid "Compilation: " +msgstr "Kompilering: " + +msgid "Compiler: " +msgstr "Kompiler: " + +msgid "Linking: " +msgstr "Linking: " + +msgid " DEBUG BUILD" +msgstr " FEJLRETNINGSBYG" + +msgid "VIM - Vi IMproved" +msgstr "VIM - Vi IMproved" + +msgid "version " +msgstr "version " + +msgid "by Bram Moolenaar et al." +msgstr "af Bram Moolenaar og andre" + +msgid "Vim is open source and freely distributable" +msgstr "Vim er open source og kan frit distribueres" + +msgid "Help poor children in Uganda!" +msgstr "Hjælp fattige børn i Uganda!" + +msgid "type :help iccf<Enter> for information " +msgstr "skriv :help iccf<Enter> for information " + +msgid "type :q<Enter> to exit " +msgstr "skriv :q<Enter> for at afslutte " + +msgid "type :help<Enter> or <F1> for on-line help" +msgstr "skriv :help<Enter> eller <F1> for onlinehjælp " + +msgid "type :help version8<Enter> for version info" +msgstr "skriv :help version8<Enter> for versionsinfo" + +msgid "Running in Vi compatible mode" +msgstr "Kører i Vi-kompatibel-tilstand" + +msgid "type :set nocp<Enter> for Vim defaults" +msgstr "skriv :set nocp<Enter> for Vim-standarder" + +msgid "type :help cp-default<Enter> for info on this" +msgstr "skriv :help cp-default<Enter> for info om det " + +msgid "menu Help->Orphans for information " +msgstr "menu Hjælp->Forældreløse børnfor information " + +msgid "Running modeless, typed text is inserted" +msgstr "Kører tilstandsløs, skrevet tekst indsættes" + +msgid "menu Edit->Global Settings->Toggle Insert Mode " +msgstr "menu Rediger->Globale indstillinger->Indsæt-tilstand til/fra " + +msgid " for two modes " +msgstr " for to-tilstande " + +msgid "menu Edit->Global Settings->Toggle Vi Compatible" +msgstr "menu Rediger->Globale indstillinger->Vi-kompatibel til/fra" + +msgid " for Vim defaults " +msgstr " for Vim-standarder " + +msgid "Sponsor Vim development!" +msgstr "Sponsorer udviklingen af Vim!" + +msgid "Become a registered Vim user!" +msgstr "Bliv en registreret Vim-bruger!" + +msgid "type :help sponsor<Enter> for information " +msgstr "skriv :help sponsor<Enter> for information " + +msgid "type :help register<Enter> for information " +msgstr "skriv :help register<Enter> for information " + +msgid "menu Help->Sponsor/Register for information " +msgstr "menu Hjælp->Sponsorer/registrer for information " + +msgid "Already only one window" +msgstr "Allerede kun ét vindue" + +msgid "E441: There is no preview window" +msgstr "E441: Der er ikke noget forhÃ¥ndsvisningsvindue" + +msgid "E442: Can't split topleft and botright at the same time" +msgstr "E442: Kan ikke opdele øverste venstre og nederste højre pÃ¥ samme tid" + +msgid "E443: Cannot rotate when another window is split" +msgstr "E443: Kan ikke rotere nÃ¥r et andet vindue er opdelt" + +msgid "E444: Cannot close last window" +msgstr "E444: Kan ikke lukke sidste vindue" + +msgid "E813: Cannot close autocmd window" +msgstr "E813: Kan ikke lukke autocmd-vindue" + +msgid "E814: Cannot close window, only autocmd window would remain" +msgstr "E814: Kan ikke lukke vindue, kun autocmd-vindue ville være tilbage" + +msgid "E445: Other window contains changes" +msgstr "E445: Et andet vindue indeholder ændringer" + +msgid "E446: No file name under cursor" +msgstr "E446: Intet filnavn under markør" + +#, c-format +msgid "E447: Can't find file \"%s\" in path" +msgstr "E447: Kan ikke finde filen \"%s\" i sti" + +#, c-format +msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E799: Ugyldigt ID: %ld (skal være større end eller lig med 1)" + +#, c-format +msgid "E801: ID already taken: %ld" +msgstr "E801: ID allerede taget: %ld" + +msgid "List or number required" +msgstr "Liste eller nummer kræves" + +#, c-format +msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E802: Ugyldigt ID: %ld (skal være større end eller lig med 1)" + +#, c-format +msgid "E803: ID not found: %ld" +msgstr "E803: ID ikke fundet: %ld" + +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: Kunne ikke indlæse biblioteket %s" + +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"Beklager, kommandoen er deaktiveret: Perl-biblioteket kunne ikke indlæses." + +msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +msgstr "E299: Perl-evaluering forbudt i sandbox uden Safe-modulet" + +msgid "Edit with &multiple Vims" +msgstr "Rediger med &flere Vim'er" + +msgid "Edit with single &Vim" +msgstr "Rediger med én &Vim" + +msgid "Diff with Vim" +msgstr "Diff med Vim" + +msgid "Edit with &Vim" +msgstr "Rediger med &Vim" + +msgid "Edit with existing Vim - " +msgstr "Rediger med eksisterende Vim - " + +msgid "Edits the selected file(s) with Vim" +msgstr "Redigerer den valgt fil(er) med Vim" + +msgid "Error creating process: Check if gvim is in your path!" +msgstr "Fejl ved oprettelse af proces: Tjek om gvim er i din sti!" + +msgid "gvimext.dll error" +msgstr "fejl ved gvimext.dll" + +msgid "Path length too long!" +msgstr "Stiens længde er for lang!" + +msgid "--No lines in buffer--" +msgstr "--Ingen linjer i buffer--" + +msgid "E470: Command aborted" +msgstr "E470: Kommando afbrudt" + +msgid "E471: Argument required" +msgstr "E471: Argument kræves" + +msgid "E10: \\ should be followed by /, ? or &" +msgstr "E10: \\ skal efterføles af /, ? eller &" + +msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits" +msgstr "E11: Ugyldig i kommandolinjevindue; <CR> udfører, CTRL-C afslutter" + +msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" +msgstr "" +"E12: Kommando ikke tilladt fra exrc/vimrc i nuværende mappe- eller " +"tagsøgning" + +msgid "E171: Missing :endif" +msgstr "E171: Manglende :endif" + +msgid "E600: Missing :endtry" +msgstr "E600: Manglende :endtry" + +msgid "E170: Missing :endwhile" +msgstr "E170: Manglende :endwhile" + +msgid "E170: Missing :endfor" +msgstr "E170: Manglende :endfor" + +msgid "E588: :endwhile without :while" +msgstr "E588: :endwhile uden :while" + +msgid "E588: :endfor without :for" +msgstr "E588: :endfor uden :for" + +msgid "E13: File exists (add ! to override)" +msgstr "E13: Filen findes (tilføj ! for at tilsidesætte)" + +msgid "E472: Command failed" +msgstr "E472: Kommando mislykkede" + +#, c-format +msgid "E234: Unknown fontset: %s" +msgstr "E234: Ukendt skrifttypesæt: %s" + +#, c-format +msgid "E235: Unknown font: %s" +msgstr "E235: Ukendt skrifttype: %s" + +#, c-format +msgid "E236: Font \"%s\" is not fixed-width" +msgstr "E236: Skrifttypen \"%s\" er ikke med fast bredde" + +msgid "E473: Internal error" +msgstr "E473: Intern fejl" + +#, c-format +msgid "E685: Internal error: %s" +msgstr "E685: Intern fejl: %s" + +msgid "Interrupted" +msgstr "Afbrudt" + +msgid "E14: Invalid address" +msgstr "E14: Ugyldig adresse" + +msgid "E474: Invalid argument" +msgstr "E474: Ugyldigt argument" + +#, c-format +msgid "E475: Invalid argument: %s" +msgstr "E475: Ugyldigt argument: %s" + +#, c-format +msgid "E475: Invalid value for argument %s" +msgstr "E475: Ugyldig værdi for argumentet %s" + +#, c-format +msgid "E475: Invalid value for argument %s: %s" +msgstr "E475: Ugyldig værdi for argumentet %s: %s" + +#, c-format +msgid "E15: Invalid expression: %s" +msgstr "E15: Ugyldigt udtryk: %s" + +msgid "E16: Invalid range" +msgstr "E16: Ugyldigt omrÃ¥de" + +msgid "E476: Invalid command" +msgstr "E476: Ugyldig kommando" + +#, c-format +msgid "E17: \"%s\" is a directory" +msgstr "E17: \"%s\" er en mappe" + +#, c-format +msgid "E364: Library call failed for \"%s()\"" +msgstr "E364: Kald af bibliotek mislykkedes for \"%s()\"" + +msgid "E667: Fsync failed" +msgstr "E667: Fsync mislykkedes" + +#, c-format +msgid "E448: Could not load library function %s" +msgstr "E448: Kunne ikke indlæse biblioteksfunktionen %s" + +msgid "E19: Mark has invalid line number" +msgstr "E19: Mærke har ugyldigt linjenummer" + +msgid "E20: Mark not set" +msgstr "E20: Mærke ikke sat" + +msgid "E21: Cannot make changes, 'modifiable' is off" +msgstr "E21: Kan ikke foretage ændringer, 'modifiable' er slÃ¥et fra" + +msgid "E22: Scripts nested too deep" +msgstr "E22: Scripts indlejret for dybt" + +msgid "E23: No alternate file" +msgstr "E23: Ingen alternate-fil" + +msgid "E24: No such abbreviation" +msgstr "E24: Ingen sÃ¥dan forkortelse" + +msgid "E477: No ! allowed" +msgstr "E477: Ingen ! tilladt" + +msgid "E25: GUI cannot be used: Not enabled at compile time" +msgstr "E25: GUI kan ikke bruges: Ikke aktiveret ved kompileringstid" + +msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" +msgstr "E26: Hebraisk kan ikke bruges: Ikke aktiveret ved kompileringstid\n" + +msgid "E27: Farsi cannot be used: Not enabled at compile time\n" +msgstr "" +"E27: Persisk kan ikke bruges: Ikke aktiveret ved kompileringstid\n" +"\n" + +msgid "E800: Arabic cannot be used: Not enabled at compile time\n" +msgstr "E800: Arabisk kan ikke bruges: Ikke aktiveret ved kompileringstid\n" + +#, c-format +msgid "E28: No such highlight group name: %s" +msgstr "E28: Intet sÃ¥dan fremhævningsgruppenavn: %s" + +msgid "E29: No inserted text yet" +msgstr "E29: Endnu ingen indsat tekst" + +msgid "E30: No previous command line" +msgstr "E30: Ingen tidligere kommandolinje" + +msgid "E31: No such mapping" +msgstr "E31: Ingen sÃ¥dan mapping" + +msgid "E479: No match" +msgstr "E479: Intet match" + +#, c-format +msgid "E480: No match: %s" +msgstr "E480: Intet match: %s" + +msgid "E32: No file name" +msgstr "E32: Intet filnavn" + +msgid "E33: No previous substitute regular expression" +msgstr "E33: Ingen tidligere erstatnings regulært udtryk" + +msgid "E34: No previous command" +msgstr "E34: Ingen tidligere kommando" + +msgid "E35: No previous regular expression" +msgstr "E35: Ingen tidligere regulære udtryk" + +msgid "E481: No range allowed" +msgstr "E481: Intet omrÃ¥de tilladt" + +msgid "E36: Not enough room" +msgstr "E36: Ikke plads nok" + +#, c-format +msgid "E247: no registered server named \"%s\"" +msgstr "E247: ingen registreret server ved navn \"%s\"" + +#, c-format +msgid "E482: Can't create file %s" +msgstr "E482: Kan ikke oprette filen %s" + +msgid "E483: Can't get temp file name" +msgstr "E483: Kan ikke hente midlertidigt filnavn" + +#, c-format +msgid "E484: Can't open file %s" +msgstr "E484: Kan ikke Ã¥bne filen %s" + +#, c-format +msgid "E485: Can't read file %s" +msgstr "E485: Kan ikke læse filen %s" + +msgid "E38: Null argument" +msgstr "E38: Null-argument" + +msgid "E39: Number expected" +msgstr "E39: Nummer ventet" + +#, c-format +msgid "E40: Can't open errorfile %s" +msgstr "E40: Kan ikke Ã¥bne fejlfilen %s" + +msgid "E233: cannot open display" +msgstr "E233: kan ikke Ã¥bne display" + +msgid "E41: Out of memory!" +msgstr "E41: Ikke mere ledig hukommelse!" + +msgid "Pattern not found" +msgstr "Mønster ikke fundet" + +#, c-format +msgid "E486: Pattern not found: %s" +msgstr "E486: Mønster ikke fundet: %s" + +msgid "E487: Argument must be positive" +msgstr "E487: Argument skal være positivt" + +msgid "E459: Cannot go back to previous directory" +msgstr "E459: Kan ikke gÃ¥ tilbage til tidligere mappe" + +msgid "E42: No Errors" +msgstr "E42: Ingen fejl" + +msgid "E776: No location list" +msgstr "E776: Ingen placeringsliste" + +msgid "E43: Damaged match string" +msgstr "E43: Beskadiget matchstreng" + +msgid "E44: Corrupted regexp program" +msgstr "E44: Korrupt regexp-program" + +msgid "E45: 'readonly' option is set (add ! to override)" +msgstr "E45: 'readonly'-tilvalget er sat (tilføj ! for at tilsidesætte)" + +#, c-format +msgid "E46: Cannot change read-only variable \"%s\"" +msgstr "E46: Kan ikke ændre skrivebeskyttet variabel \"%s\"" + +#, c-format +msgid "E794: Cannot set variable in the sandbox: \"%s\"" +msgstr "E794: Kan ikke sætte variabel i sandboksen: \"%s\"" + +msgid "E713: Cannot use empty key for Dictionary" +msgstr "E713: Kan ikke bruge tom nøgle til ordbog" + +msgid "E715: Dictionary required" +msgstr "E715: Ordbog kræves" + +#, c-format +msgid "E684: list index out of range: %ld" +msgstr "E684: listeindeks udenfor omrÃ¥de: %ld" + +#, c-format +msgid "E118: Too many arguments for function: %s" +msgstr "E118: For mange argumenter til funktion: %s" + +#, c-format +msgid "E716: Key not present in Dictionary: %s" +msgstr "E716: Nøgle findes ikke i ordbog: %s" + +msgid "E714: List required" +msgstr "E714: Liste kræves" + +#, c-format +msgid "E712: Argument of %s must be a List or Dictionary" +msgstr "E712: Argument af %s skal være en liste eller ordbog" + +msgid "E47: Error while reading errorfile" +msgstr "E47: Fejl ved læsning af fejlfil" + +msgid "E48: Not allowed in sandbox" +msgstr "E48: Ikke tilladt i sandboks" + +msgid "E523: Not allowed here" +msgstr "E523: Ikke tilladt her" + +msgid "E359: Screen mode setting not supported" +msgstr "E359: Skærmtilstand-indstilling understøttes ikke" + +msgid "E49: Invalid scroll size" +msgstr "E49: Ugyldig rullestørrelse" + +msgid "E91: 'shell' option is empty" +msgstr "E91: 'shell'-tilvalget er tomt" + +msgid "E255: Couldn't read in sign data!" +msgstr "E255: Kunne ikke læse i sign-data!" + +msgid "E72: Close error on swap file" +msgstr "E72: Fejl ved lukning af swap-fil" + +msgid "E73: tag stack empty" +msgstr "E73: tag-stak tom" + +msgid "E74: Command too complex" +msgstr "E74: Kommando for kompleks" + +msgid "E75: Name too long" +msgstr "E75: Navn for langt" + +msgid "E76: Too many [" +msgstr "E76: For mange [" + +msgid "E77: Too many file names" +msgstr "E77: For mange filnavne" + +msgid "E488: Trailing characters" +msgstr "E488: Efterstillede tegn" + +msgid "E78: Unknown mark" +msgstr "E78: Ukendt mærke" + +msgid "E79: Cannot expand wildcards" +msgstr "E79: Kan ikke udvide jokertegn" + +msgid "E591: 'winheight' cannot be smaller than 'winminheight'" +msgstr "E591: 'winheight' mÃ¥ ikke være mindre end 'winminheight'" + +msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'" +msgstr "E592: 'winwidth' mÃ¥ ikke være mindre end 'winminwidth'" + +msgid "E80: Error while writing" +msgstr "E80: Fejl ved skrivning" + +msgid "E939: Positive count required" +msgstr "E939: Positiv tælling kræves" + +msgid "E81: Using <SID> not in a script context" +msgstr "E81: Bruger <SID> ikke i et script kontekst" + +msgid "E449: Invalid expression received" +msgstr "E449: Ugyldigt udtryk modtaget" + +msgid "E463: Region is guarded, cannot modify" +msgstr "E463: Regionen er beskyttet, kan ikke ændre" + +msgid "E744: NetBeans does not allow changes in read-only files" +msgstr "E744: NetBeans tillader ikke ændringer i skrivebeskyttede filer" + +msgid "E363: pattern uses more memory than 'maxmempattern'" +msgstr "E363: mønster bruger mere hukommelse end 'maxmempattern'" + +msgid "E749: empty buffer" +msgstr "E749: tom buffer" + +#, c-format +msgid "E86: Buffer %ld does not exist" +msgstr "E86: Bufferen %ld findes ikke" + +msgid "E682: Invalid search pattern or delimiter" +msgstr "E682: Ugyldigt søgemønster eller -afgrænser" + +msgid "E139: File is loaded in another buffer" +msgstr "E139: Filen er indlæst i en anden buffer" + +#, c-format +msgid "E764: Option '%s' is not set" +msgstr "E764: Tilvalget '%s' er ikke sat" + +msgid "E850: Invalid register name" +msgstr "E850: Ugyldigt registernavn" + +#, c-format +msgid "E919: Directory not found in '%s': \"%s\"" +msgstr "E919: Mappe ikke fundet i '%s': \"%s\"" + +msgid "E952: Autocommand caused recursive behavior" +msgstr "E952: Autokommando forÃ¥rsagede rekursiv opførsel" + +msgid "search hit TOP, continuing at BOTTOM" +msgstr "søgning ramte ØVERST, fortsætter ved NEDERST" + +msgid "search hit BOTTOM, continuing at TOP" +msgstr "søgning ramte NEDERST, fortsætter ved ØVERST" + +#, c-format +msgid "Need encryption key for \"%s\"" +msgstr "Behøver krypteringsnøgle til \"%s\"" + +msgid "empty keys are not allowed" +msgstr "tomme nøgler er ikke tilladt" + +msgid "dictionary is locked" +msgstr "ordbog er lÃ¥st" + +msgid "list is locked" +msgstr "liste er lÃ¥st" + +#, c-format +msgid "failed to add key '%s' to dictionary" +msgstr "kunne ikke tilføje nøglen '%s' til ordbog" + +#, c-format +msgid "index must be int or slice, not %s" +msgstr "indeks skal være heltal eller slice, ikke %s" + +#, c-format +msgid "expected str() or unicode() instance, but got %s" +msgstr "ventede str()- eller unicode()-instans, men fik %s" + +#, c-format +msgid "expected bytes() or str() instance, but got %s" +msgstr "ventede bytes()- eller str()-instans, min fik %s" + +#, c-format +msgid "" +"expected int(), long() or something supporting coercing to long(), but got %s" +msgstr "" +"ventede int(), long() eller noget som understøtter coercing til long(), min " +"fik %s" + +#, c-format +msgid "expected int() or something supporting coercing to int(), but got %s" +msgstr "" +"ventede int() eller noget som understøtter coercing til int(), min fik %s" + +msgid "value is too large to fit into C int type" +msgstr "værdi er for stor til at passe i C-heltalstype" + +msgid "value is too small to fit into C int type" +msgstr "værdi er for lille til at passe i C-heltalstype" + +msgid "number must be greater than zero" +msgstr "nummer skal være større end nul" + +msgid "number must be greater or equal to zero" +msgstr "nummer skal være større end eller lig med nul" + +msgid "can't delete OutputObject attributes" +msgstr "kan ikke slette OutputObject-attributter" + +#, c-format +msgid "invalid attribute: %s" +msgstr "ugyldig attribut: %s" + +msgid "E264: Python: Error initialising I/O objects" +msgstr "E264: Python: Fejl ved initialisering af I/O-objekter" + +msgid "failed to change directory" +msgstr "kunne ikke skifte mappe" + +#, c-format +msgid "expected 3-tuple as imp.find_module() result, but got %s" +msgstr "ventede 3-tuple som imp.find_module() resultat, men fik %s" + +#, c-format +msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d" +msgstr "" +"ventede 3-tuple som imp.find_module() resultat, men fik tuple af størrelse %" +"d" + +msgid "internal error: imp.find_module returned tuple with NULL" +msgstr "intern fejl: imp.find_module returnerede tuple med NULL" + +msgid "cannot delete vim.Dictionary attributes" +msgstr "kan ikke slette vim.Dictionary-attributter" + +msgid "cannot modify fixed dictionary" +msgstr "kan ikke ændre fast ordbog" + +#, c-format +msgid "cannot set attribute %s" +msgstr "kan ikke sætte attributten %s" + +msgid "hashtab changed during iteration" +msgstr "hashtab ændret under gennemløb" + +#, c-format +msgid "expected sequence element of size 2, but got sequence of size %d" +msgstr "ventede sekvenselement af størrelse 2, men fik sekvens af størrelse %d" + +msgid "list constructor does not accept keyword arguments" +msgstr "liste-constructor accepterer ikke nøgleord-argumenter" + +msgid "list index out of range" +msgstr "listeindeks udenfor omrÃ¥de" + +#, c-format +msgid "internal error: failed to get vim list item %d" +msgstr "intern fejl: kunne ikke hente vim-listepunkt %d" + +msgid "slice step cannot be zero" +msgstr "slice-trin mÃ¥ ikke være nul" + +#, c-format +msgid "attempt to assign sequence of size greater than %d to extended slice" +msgstr "forsøg pÃ¥ at tildele sekvens som er større end %d til udvidet slice" + +#, c-format +msgid "internal error: no vim list item %d" +msgstr "intern fejl: intet vim-listepunkt %d" + +msgid "internal error: not enough list items" +msgstr "intern fejl: ikke nok listepunkter" + +msgid "internal error: failed to add item to list" +msgstr "intern fejl: kunne ikke tilføje punkt til liste" + +#, c-format +msgid "attempt to assign sequence of size %d to extended slice of size %d" +msgstr "" +"forsøg pÃ¥ at tildele sekvens af størrelsen %d til udvidet slice af " +"størrelsen %d" + +msgid "failed to add item to list" +msgstr "kunne ikke tilføje punkt til liste" + +msgid "cannot delete vim.List attributes" +msgstr "kan ikke slette vim.List-attributter" + +msgid "cannot modify fixed list" +msgstr "kan ikke ændre fast liste" + +#, c-format +msgid "unnamed function %s does not exist" +msgstr "unavngivet funktion %s findes ikke" + +#, c-format +msgid "function %s does not exist" +msgstr "funktionen %s findes ikke" + +#, c-format +msgid "failed to run function %s" +msgstr "kunne ikke køre funktionen %s" + +msgid "unable to get option value" +msgstr "kan ikke hente tilvalgsværdi" + +msgid "internal error: unknown option type" +msgstr "intern fejl: ukendt tilvalgstype" + +msgid "problem while switching windows" +msgstr "problem ved skift af vinduer" + +#, c-format +msgid "unable to unset global option %s" +msgstr "kan ikke fjerne det globale tilvalg %s" + +#, c-format +msgid "unable to unset option %s which does not have global value" +msgstr "kan ikke fjerne tilvalget %s som ikke har global værdi" + +msgid "attempt to refer to deleted tab page" +msgstr "forsøg pÃ¥ at referere til slettet fanebladsside" + +msgid "no such tab page" +msgstr "ingen sÃ¥dan fanebladsside" + +msgid "attempt to refer to deleted window" +msgstr "forsøg pÃ¥ at referere til slettet vindue" + +msgid "readonly attribute: buffer" +msgstr "skrivebeskyttet attribut: buffer" + +msgid "cursor position outside buffer" +msgstr "markørposition udenfor buffer" + +msgid "no such window" +msgstr "intet sÃ¥dan vindue" + +msgid "attempt to refer to deleted buffer" +msgstr "forsøg pÃ¥ at referere til slettet buffer" + +msgid "failed to rename buffer" +msgstr "kunne ikke omdøbe bufferen" + +msgid "mark name must be a single character" +msgstr "mærkenavn skal være ét tegn" + +#, c-format +msgid "expected vim.Buffer object, but got %s" +msgstr "ventede vim.Buffer-objekt, men fik %s" + +#, c-format +msgid "failed to switch to buffer %d" +msgstr "kunne ikke skifte til bufferen %d" + +#, c-format +msgid "expected vim.Window object, but got %s" +msgstr "ventede vim.Window-objekt, men fik %s" + +msgid "failed to find window in the current tab page" +msgstr "kunne ikke finde vindue i den nuværende fanebladsside" + +msgid "did not switch to the specified window" +msgstr "skiftede ikke til det angivne vindue" + +#, c-format +msgid "expected vim.TabPage object, but got %s" +msgstr "ventede vim.TabPage-objekt, men fik %s" + +msgid "did not switch to the specified tab page" +msgstr "skiftede ikke til den angivne fanebladsside" + +msgid "failed to run the code" +msgstr "kunne ikke køre koden" + +msgid "E858: Eval did not return a valid python object" +msgstr "E858: Eval returnerede ikke et gyldigt python-objekt" + +msgid "E859: Failed to convert returned python object to vim value" +msgstr "E859: Kunne ikke konvertere returnerede python-objekt til vim-værdi" + +#, c-format +msgid "unable to convert %s to vim dictionary" +msgstr "kan ikke konvertere %s til vim-ordbog" + +#, c-format +msgid "unable to convert %s to vim list" +msgstr "kan ikke konvertere %s til vim-liste" + +#, c-format +msgid "unable to convert %s to vim structure" +msgstr "kan ikke konvertere %s til vim-struktur" + +msgid "internal error: NULL reference passed" +msgstr "intern fejl: NULL-reference givet" + +msgid "internal error: invalid value type" +msgstr "intern fejl: ugyldig værditype" + +msgid "" +"Failed to set path hook: sys.path_hooks is not a list\n" +"You should now do the following:\n" +"- append vim.path_hook to sys.path_hooks\n" +"- append vim.VIM_SPECIAL_PATH to sys.path\n" +msgstr "" +"Kunne ikke sætte sti-hook: sys.path_hooks er ikke en liste\n" +"Du bør nu gøre følgende:\n" +"- tilføj vim.path_hook til slutningen af sys.path_hooks\n" +"- tilføj vim.VIM_SPECIAL_PATH til slutningen af sys.path\n" + +msgid "" +"Failed to set path: sys.path is not a list\n" +"You should now append vim.VIM_SPECIAL_PATH to sys.path" +msgstr "" +"Kunne ikke sætte sti: sys.path er ikke en liste\n" +"Du bør nu tilføje vim.VIM_SPECIAL_PATH til slutningen af sys.path" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*.*)\t*.*\n" +msgstr "" +"Vim-makrofiler (*.vim)\t*.vim\n" +"Alle filer (*.*)\t*.*\n" + +msgid "All Files (*.*)\t*.*\n" +msgstr "Alle filer (*.*)\t*.*\n" + +msgid "" +"All Files (*.*)\t*.*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB code (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"Alle filer (*.*)\t*.*\n" +"C-kildekode (*.c, *.h)\t*.c;*.h\n" +"C++-kildekode (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB-kode (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim-filer (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*)\t*\n" +msgstr "" +"Vim-makrofiler (*.vim)\t*.vim\n" +"Alle filer (*)\t*\n" + +msgid "All Files (*)\t*\n" +msgstr "Alle filer (*)\t*\n" + +msgid "" +"All Files (*)\t*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"Alle filer (*)\t*\n" +"C-kildekode (*.c, *.h)\t*.c;*.h\n" +"C++-kildekode (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim-filer (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" diff --git a/src/nvim/po/de.po b/src/nvim/po/de.po index 3986a796d8..a6ba8476d8 100644 --- a/src/nvim/po/de.po +++ b/src/nvim/po/de.po @@ -1918,7 +1918,7 @@ msgstr "E216: Keine solche Gruppe oder Ereignis: %s" #: ../fileio.c:5993 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autokommandos ---" @@ -1942,7 +1942,7 @@ msgstr "E218: Autokommandos zu tief verschachtelt" #: ../fileio.c:7042 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Autokommandos für \"%s\"" #: ../fileio.c:7048 @@ -1994,7 +1994,7 @@ msgstr "E223: rekursive Zuordnung" #: ../getchar.c:2835 #, c-format msgid "E224: global abbreviation already exists for %s" -msgstr "E224: Globale Abkürzung für %s existiert bereits" +msgstr "E224: Globale Kurzform für %s existiert bereits" #: ../getchar.c:2838 #, c-format @@ -2162,7 +2162,7 @@ msgstr "E23: Keine alternative Datei" #: ../globals.h:1031 msgid "E24: No such abbreviation" -msgstr "E24: Keine Abkürzung gefunden" +msgstr "E24: Diese Kurzform nicht gefunden" #: ../globals.h:1032 msgid "E477: No ! allowed" @@ -2835,7 +2835,7 @@ msgstr "-q [Fehler-Datei] öffne Datei mit erstem Fehler" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -4771,8 +4771,8 @@ msgstr "Achtung: Region %s nicht unterstützt" #: ../spell.c:4364 #, c-format -msgid "Reading affix file %s ..." -msgstr "Lese Affix-Datei %s ..." +msgid "Reading affix file %s..." +msgstr "Lese Affix-Datei %s..." #: ../spell.c:4403 ../spell.c:5449 ../spell.c:5954 #, c-format @@ -4938,8 +4938,8 @@ msgstr "" #: ../spell.c:5416 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Lese Wörterbuch-Datei %s ..." +msgid "Reading dictionary file %s..." +msgstr "Lese Wörterbuch-Datei %s..." #: ../spell.c:5425 #, c-format @@ -4973,8 +4973,8 @@ msgstr "%d Wort(e) mit Nicht-ASCII-Zeichen ignoriert in %s" #: ../spell.c:5929 #, c-format -msgid "Reading word file %s ..." -msgstr "Lese Wort-Datei %s ..." +msgid "Reading word file %s..." +msgstr "Lese Wort-Datei %s..." #: ../spell.c:5969 #, c-format @@ -5043,8 +5043,8 @@ msgstr "Gesamte Anzahl von Wörtern: %d" #: ../spell.c:7468 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Schreibe Datei %s für Vorschläge ..." +msgid "Writing suggestion file %s..." +msgstr "Schreibe Datei %s für Vorschläge..." #: ../spell.c:7520 ../spell.c:7740 #, c-format @@ -5070,8 +5070,8 @@ msgstr "Achtung: Sowohl zusammengesetzte Wörter als auch NOBREAK angegeben" #: ../spell.c:7733 #, c-format -msgid "Writing spell file %s ..." -msgstr "Schreibe Rechtschreibwörterbuch %s ..." +msgid "Writing spell file %s..." +msgstr "Schreibe Rechtschreibwörterbuch %s..." #: ../spell.c:7738 msgid "Done!" diff --git a/src/nvim/po/eo.po b/src/nvim/po/eo.po index cc0893de3a..d1ce47d97c 100644 --- a/src/nvim/po/eo.po +++ b/src/nvim/po/eo.po @@ -61,7 +61,7 @@ msgid "E931: Buffer cannot be registered" msgstr "E931: Bufro ne povas esti registrita" msgid "E937: Attempt to delete a buffer that is in use" -msgstr "E937: Provo de forviÅo de bufro, kiu estas uzanta" +msgstr "E937: Provo de forviÅo de bufro, kiu estas en uzo" msgid "E515: No buffers were unloaded" msgstr "E515: Neniu bufro estis malÅargita" @@ -72,26 +72,23 @@ msgstr "E516: Neniu bufro estis forviÅita" msgid "E517: No buffers were wiped out" msgstr "E517: Neniu bufro estis detruita" -msgid "1 buffer unloaded" -msgstr "1 bufro malÅargita" - #, c-format -msgid "%d buffers unloaded" -msgstr "%d bufroj malÅargitaj" - -msgid "1 buffer deleted" -msgstr "1 bufro forviÅita" +msgid "%d buffer unloaded" +msgid_plural "%d buffers unloaded" +msgstr[0] "%d bufro malÅargita" +msgstr[1] "%d bufroj malÅargitaj" #, c-format -msgid "%d buffers deleted" -msgstr "%d bufroj forviÅitaj" - -msgid "1 buffer wiped out" -msgstr "1 bufro detruita" +msgid "%d buffer deleted" +msgid_plural "%d buffers deleted" +msgstr[0] "%d bufro forviÅita" +msgstr[1] "%d bufroj forviÅitaj" #, c-format -msgid "%d buffers wiped out" -msgstr "%d bufroj detruitaj" +msgid "%d buffer wiped out" +msgid_plural "%d buffers wiped out" +msgstr[0] "%d bufro detruita" +msgstr[1] "%d bufroj detruitaj" msgid "E90: Cannot unload last buffer" msgstr "E90: Ne eblas malÅargi la lastan bufron" @@ -167,12 +164,10 @@ msgid "[readonly]" msgstr "[nurlegebla]" #, c-format -msgid "1 line --%d%%--" -msgstr "1 linio --%d%%--" - -#, c-format -msgid "%ld lines --%d%%--" -msgstr "%ld linioj --%d%%--" +msgid "%ld line --%d%%--" +msgid_plural "%ld lines --%d%%--" +msgstr[0] "%ld linio --%d%%--" +msgstr[1] "%ld linioj --%d%%--" #, c-format msgid "line %ld of %ld --%d%%-- col " @@ -209,6 +204,9 @@ msgstr "" msgid "E382: Cannot write, 'buftype' option is set" msgstr "E382: Ne eblas skribi, opcio 'buftype' estas Åaltita" +msgid "[Prompt]" +msgstr "[Invito]" + msgid "[Scratch]" msgstr "[Malneto]" @@ -649,7 +647,7 @@ msgstr "E795: Ne eblas forviÅi variablon %s" #, c-format msgid "E704: Funcref variable name must start with a capital: %s" -msgstr "E704: Nomo de variablo Funcref devas finiÄi per majusklo: %s" +msgstr "E704: Nomo de variablo Funcref devas eki per majusklo: %s" #, c-format msgid "E705: Variable name conflicts with existing function: %s" @@ -740,6 +738,9 @@ msgstr "E916: nevalida tasko" msgid "E701: Invalid type for len()" msgstr "E701: Nevalida datumtipo de len()" +msgid "E957: Invalid window number" +msgstr "E957: Nevalida numero de vindozo" + #, c-format msgid "E798: ID is reserved for \":match\": %ld" msgstr "E798: ID estas rezervita por \":match\": %ld" @@ -825,12 +826,11 @@ msgstr "> %d, Deksesuma %08x, Okuma %o" msgid "E134: Move lines into themselves" msgstr "E134: Movas liniojn en ilin mem" -msgid "1 line moved" -msgstr "1 linio movita" - #, c-format -msgid "%ld lines moved" -msgstr "%ld linioj movitaj" +msgid "%ld line moved" +msgid_plural "%ld lines moved" +msgstr[0] "%ld linio movita" +msgstr[1] "%ld linioj movitaj" #, c-format msgid "%ld lines filtered" @@ -982,26 +982,29 @@ msgstr "ĉu anstataÅigi per %s (y/n/a/q/l/^E/^Y)?" msgid "(Interrupted) " msgstr "(Interrompita) " -msgid "1 match" -msgstr "1 kongruo" - -msgid "1 substitution" -msgstr "1 anstataÅigo" - #, c-format -msgid "%ld matches" -msgstr "%ld kongruoj" +msgid "%ld match on %ld line" +msgid_plural "%ld matches on %ld line" +msgstr[0] "%ld kongruo en %ld linio" +msgstr[1] "%ld kongruoj en %ld linio" #, c-format -msgid "%ld substitutions" -msgstr "%ld anstataÅigoj" +msgid "%ld substitution on %ld line" +msgid_plural "%ld substitutions on %ld line" +msgstr[0] "%ld anstataÅigo en %ld linio" +msgstr[1] "%ld anstataÅigoj en %ld linio" -msgid " on 1 line" -msgstr " en 1 linio" +#, c-format +msgid "%ld match on %ld lines" +msgid_plural "%ld matches on %ld lines" +msgstr[0] "%ld kongruo en %ld linioj" +msgstr[1] "%ld kongruoj en %ld linioj" #, c-format -msgid " on %ld lines" -msgstr " en %ld linioj" +msgid "%ld substitution on %ld lines" +msgid_plural "%ld substitutions on %ld lines" +msgstr[0] "%ld anstataÅigo en %ld linioj" +msgstr[1] "%ld anstataÅigoj en %ld linioj" msgid "E147: Cannot do :global recursive with a range" msgstr "E147: Ne eblas fari \":global\" rekursie kun amplekso" @@ -1305,19 +1308,17 @@ msgstr "E319: BedaÅrinde, tiu komando ne haveblas en tiu versio" msgid "E172: Only one file name allowed" msgstr "E172: Nur unu dosiernomo permesebla" -msgid "1 more file to edit. Quit anyway?" -msgstr "1 plia redaktenda dosiero. Ĉu tamen eliri?" - #, c-format -msgid "%d more files to edit. Quit anyway?" -msgstr "%d pliaj redaktendaj dosieroj. Ĉu tamen eliri?" - -msgid "E173: 1 more file to edit" -msgstr "E173: 1 plia redaktenda dosiero" +msgid "%d more file to edit. Quit anyway?" +msgid_plural "%d more files to edit. Quit anyway?" +msgstr[0] "%d plia redaktenda dosiero. Ĉu tamen eliri?" +msgstr[1] "%d pliaj redaktendaj dosieroj. Ĉu tamen eliri?" #, c-format -msgid "E173: %ld more files to edit" -msgstr "E173: %ld pliaj redaktendaj dosieroj" +msgid "E173: %ld more file to edit" +msgid_plural "E173: %ld more files to edit" +msgstr[0] "E173: %ld plia redaktenda dosiero" +msgstr[1] "E173: %ld pliaj redaktendaj dosieroj" msgid "E174: Command already exists: add ! to replace it" msgstr "E174: La komando jam ekzistas: aldonu ! por anstataÅigi Äin" @@ -1399,6 +1400,9 @@ msgstr "E784: Ne eblas fermi lastan langeton" msgid "Already only one tab page" msgstr "Jam nur unu langeto" +msgid "Edit File in new tab page" +msgstr "Redakti Dosieron en nova langeto" + msgid "Edit File in new window" msgstr "Redakti Dosieron en nova fenestro" @@ -1698,9 +1702,6 @@ msgstr "Legado el stdin..." msgid "E202: Conversion made file unreadable!" msgstr "E202: Konverto igis la dosieron nelegebla!" -msgid "[fifo/socket]" -msgstr "[rektvica memoro/kontaktoskatolo]" - msgid "[fifo]" msgstr "[rektvica memoro]" @@ -1880,19 +1881,17 @@ msgstr "[unikso]" msgid "[unix format]" msgstr "[formato unikso]" -msgid "1 line, " -msgstr "1 linio, " - #, c-format -msgid "%ld lines, " -msgstr "%ld linioj, " - -msgid "1 character" -msgstr "1 signo" +msgid "%ld line, " +msgid_plural "%ld lines, " +msgstr[0] "%ld linio, " +msgstr[1] "%ld linioj, " #, c-format -msgid "%lld characters" -msgstr "%lld signoj" +msgid "%lld character" +msgid_plural "%lld characters" +msgstr[0] "%lld signo" +msgstr[1] "%lld signoj" msgid "[noeol]" msgstr "[sen EOL]" @@ -2002,7 +2001,7 @@ msgstr "E216: Ne ekzistas tia grupo aÅ evento: %s" msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- AÅto-Komandoj ---" @@ -2021,7 +2020,7 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: aÅtokomando tro ingita" #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s AÅtokomandoj por \"%s\"" #, c-format @@ -2264,11 +2263,11 @@ msgstr "&Malfari" msgid "Open tab..." msgstr "Malfermi langeton..." -msgid "Find string (use '\\\\' to find a '\\')" -msgstr "Trovi ĉenon (uzu '\\\\' por trovi '\\')" +msgid "Find string" +msgstr "Trovi ĉenon" -msgid "Find & Replace (use '\\\\' to find a '\\')" -msgstr "Trovi kaj anstataÅigi (uzu '\\\\' por trovi '\\')" +msgid "Find & Replace" +msgstr "Trovi & AnstataÅigi" msgid "Not Used" msgstr "Ne uzata" @@ -2560,7 +2559,7 @@ msgid "" " t: Find this text string\n" msgstr "" "\n" -" a: Trovi valirizojn al tiu simbolo\n" +" a: Trovi valorizojn al tiu simbolo\n" " c: Trovi funkciojn, kiuj alvokas tiun funkcion\n" " d: Trovi funkciojn alvokataj de tiu funkcio\n" " e: Trovi tiun egrep-Åablonon\n" @@ -2922,7 +2921,7 @@ msgstr "-q [erardosiero] redakti dosieron kun unua eraro" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -3039,7 +3038,7 @@ msgstr "-f\t\t\tNe uzi newcli por malfermi fenestrojn" msgid "-dev <device>\t\tUse <device> for I/O" msgstr "-dev <aparatdosiero>\t\tUzi <aparatdosiero>-n por eneligo" -msgid "-A\t\t\tstart in Arabic mode" +msgid "-A\t\t\tStart in Arabic mode" msgstr "-A\t\t\tKomenci en araba reÄimo" msgid "-H\t\t\tStart in Hebrew mode" @@ -3441,7 +3440,7 @@ msgstr "" #, c-format msgid "" "E833: %s is encrypted and this version of Vim does not support encryption" -msgstr "E833: %s estas ĉifrata kaj tiu versio de Vim ne subtenas ĉifradon" +msgstr "E833: %s estas ĉifrita kaj tiu versio de Vim ne subtenas ĉifradon" msgid " has been damaged (page size is smaller than minimum value).\n" msgstr " difektiÄis (paÄa grando pli malgranda ol minimuma valoro).\n" @@ -3459,7 +3458,7 @@ msgstr "E308: Averto: Originala dosiero eble ÅanÄiÄis" #, c-format msgid "Swap file is encrypted: \"%s\"" -msgstr "Perumutodosiero .swp estas ĉifrata: \"%s\"" +msgstr "Permutodosiero .swp estas ĉifrita: \"%s\"" msgid "" "\n" @@ -3488,7 +3487,7 @@ msgid "" "to use the same key for text file and swap file" msgstr "" "\n" -"por uzi la saman Ålosilon por la teksta dosiero kaj permuto dosiero .swp" +"por uzi la saman Ålosilon por la teksta dosiero kaj permutodosiero .swp" #, c-format msgid "E309: Unable to read block 1 from %s" @@ -3561,7 +3560,7 @@ msgstr "" msgid "Using crypt key from swap file for the text file.\n" msgstr "" -"Uzas Ålosilon de ĉifrado el permuto dosiero .swp por la teksta dosiero.\n" +"Uzas Ålosilon de ĉifrado el permutodosiero .swp por la teksta dosiero.\n" msgid "Swap files found:" msgstr "Permutodosiero .swp trovita:" @@ -3947,19 +3946,17 @@ msgstr "" msgid "Type number and <Enter> (empty cancels): " msgstr "Tajpu nombron kaj <Enenklavon> (malpleno rezignas): " -msgid "1 more line" -msgstr "1 plia linio" - -msgid "1 line less" -msgstr "1 malplia linio" - #, c-format -msgid "%ld more lines" -msgstr "%ld pliaj linioj" +msgid "%ld more line" +msgid_plural "%ld more lines" +msgstr[0] "%ld plia linio" +msgstr[1] "%ld pliaj linioj" #, c-format -msgid "%ld fewer lines" -msgstr "%ld malpliaj linioj" +msgid "%ld line less" +msgid_plural "%ld fewer lines" +msgstr[0] "%ld malplia linio" +msgstr[1] "%ld malpliaj linioj" msgid " (Interrupted)" msgstr " (Interrompita)" @@ -4097,31 +4094,26 @@ msgstr "" "Vim" #, c-format -msgid "1 line %sed 1 time" -msgstr "1 linio %sita 1 foje" - -#, c-format -msgid "1 line %sed %d times" -msgstr "1 linio %sita %d foje" - -#, c-format -msgid "%ld lines %sed 1 time" -msgstr "%ld linio %sita 1 foje" +msgid "%ld line %sed %d time" +msgid_plural "%ld line %sed %d times" +msgstr[0] "%ld linio %sita %d foje" +msgstr[1] "%ld linio %sita %d foje" #, c-format -msgid "%ld lines %sed %d times" -msgstr "%ld linioj %sitaj %d foje" +msgid "%ld lines %sed %d time" +msgid_plural "%ld lines %sed %d times" +msgstr[0] "%ld linioj %sitaj %d foje" +msgstr[1] "%ld linioj %sitaj %d foje" #, c-format msgid "%ld lines to indent... " msgstr "%ld krommarÄenendaj linioj... " -msgid "1 line indented " -msgstr "1 linio krommarÄenita " - #, c-format -msgid "%ld lines indented " -msgstr "%ld linioj krommarÄenitaj " +msgid "%ld line indented " +msgid_plural "%ld lines indented " +msgstr[0] "%ld linio krommarÄenita " +msgstr[1] "%ld linioj krommarÄenitaj " msgid "E748: No previously used register" msgstr "E748: Neniu reÄistro antaÅe uzata" @@ -4129,12 +4121,11 @@ msgstr "E748: Neniu reÄistro antaÅe uzata" msgid "cannot yank; delete anyway" msgstr "ne eblas kopii; tamen forviÅi" -msgid "1 line changed" -msgstr "1 linio ÅanÄita" - #, c-format -msgid "%ld lines changed" -msgstr "%ld linioj ÅanÄitaj" +msgid "%ld line changed" +msgid_plural "%ld lines changed" +msgstr[0] "%ld linio ÅanÄita" +msgstr[1] "%ld linioj ÅanÄitaj" #, c-format msgid "freeing %ld lines" @@ -4145,20 +4136,16 @@ msgid " into \"%c" msgstr " en \"%c" #, c-format -msgid "block of 1 line yanked%s" -msgstr "bloko de 1 linio kopiita%s" +msgid "block of %ld line yanked%s" +msgid_plural "block of %ld lines yanked%s" +msgstr[0] "bloko de %ld linio kopiita%s" +msgstr[1] "bloko de %ld linioj kopiitaj%s" #, c-format -msgid "1 line yanked%s" -msgstr "1 linio kopiita%s" - -#, c-format -msgid "block of %ld lines yanked%s" -msgstr "bloko de %ld linioj kopiita%s" - -#, c-format -msgid "%ld lines yanked%s" -msgstr "%ld linioj kopiitaj%s" +msgid "%ld line yanked%s" +msgid_plural "%ld lines yanked%s" +msgstr[0] "%ld linio kopiita%s" +msgstr[1] "%ld linioj kopiitaj%s" #, c-format msgid "E353: Nothing in register %s" @@ -4514,7 +4501,7 @@ msgstr "Ne povis Åalti kuntekston de sekureco %s por %s" #, c-format msgid "Could not get security context %s for %s. Removing it!" msgstr "" -"Ne povis akiri kuntekston de sekureco %s por %s. Gi nun estas forigata!" +"Ne povis akiri kuntekston de sekureco %s por %s. Äœi nun estas forigata!" msgid "" "\n" @@ -4733,7 +4720,7 @@ msgid "E66: \\z( not allowed here" msgstr "E66: \\z( estas nepermesebla tie" # DP: vidu http://www.thefreedictionary.com/et+al. -msgid "E67: \\z1 et al. not allowed here" +msgid "E67: \\z1 - \\z9 not allowed here" msgstr "E67: \\z1 kaj aliaj estas nepermeseblaj tie" #, c-format @@ -4744,6 +4731,9 @@ msgstr "E69: Mankas ] malantaÅ %s%%[" msgid "E70: Empty %s%%[]" msgstr "E70: Malplena %s%%[]" +msgid "E956: Cannot use pattern recursively" +msgstr "E956: Ne eblas uzi Åablonon rekursie" + msgid "E65: Illegal back reference" msgstr "E65: Nevalida retro-referenco" @@ -4813,7 +4803,7 @@ msgstr "" "regulesprimo estos uzata " msgid "Switching to backtracking RE engine for pattern: " -msgstr "Åœangota al malavanca motoro de regulesprimo por Åablono: " +msgstr "ÅœanÄas al malavanca motoro de regulesprimo por Åablono: " msgid "E865: (NFA) Regexp end encountered prematurely" msgstr "E865: (NFA) Trovis finon de regulesprimo tro frue" @@ -4844,10 +4834,10 @@ msgstr "E869: (NFA) Nekonata operatoro '\\@%c'" msgid "E870: (NFA regexp) Error reading repetition limits" msgstr "E870: (NFS-regulesprimo) Eraro dum legado de limoj de ripeto" -msgid "E871: (NFA regexp) Can't have a multi follow a multi !" +msgid "E871: (NFA regexp) Can't have a multi follow a multi" msgstr "" "E871: (NFA-regulesprimo) Ne povas havi mult-selekton tuj post alia mult-" -"selekto!" +"selekto" msgid "E872: (NFA regexp) Too many '('" msgstr "E872: (NFA-regulesprimo) tro da '('" @@ -4858,7 +4848,12 @@ msgstr "E879: (NFA-regulesprimo) tro da \\z(" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (NFA-regulesprimo) propra end-eraro" -msgid "E874: (NFA) Could not pop the stack !" +msgid "Could not open temporary log file for writing, displaying on stderr... " +msgstr "" +"Ne povis malfermi provizoran protokolan dosieron por skribi, nun montras sur " +"stderr..." + +msgid "E874: (NFA) Could not pop the stack!" msgstr "E874: (NFA) Ne povis elpreni de la staplo!" msgid "" @@ -4874,19 +4869,6 @@ msgstr "E876: (NFA-regulesprimo) ne sufiĉa spaco por enmemorigi la tutan NFA " msgid "E878: (NFA) Could not allocate memory for branch traversal!" msgstr "E878: (NFA) Ne povis asigni memoron por traigi branĉojn!" -msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " -msgstr "" -"Ne povis malfermi provizoran protokolan dosieron por skribi, nun montras sur " -"stderr ..." - -#, c-format -msgid "(NFA) COULD NOT OPEN %s !" -msgstr "(NFA) NE POVIS MALFERMI %s!" - -msgid "Could not open temporary log file for writing " -msgstr "Ne povis malfermi la provizoran protokolan dosieron por skribi " - msgid " VREPLACE" msgstr " V-ANSTATAŬIGO" @@ -5104,8 +5086,8 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: eraro dum legado de dosiero .sug: %s" #, c-format -msgid "Reading affix file %s ..." -msgstr "Legado de afiksa dosiero %s ..." +msgid "Reading affix file %s..." +msgstr "Legado de afiksa dosiero %s..." #, c-format msgid "Conversion failure for word in %s line %d: %s" @@ -5240,8 +5222,8 @@ msgid "%s value differs from what is used in another .aff file" msgstr "Valoro de %s malsamas ol tiu en alia dosiero .aff" #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Legado de vortardosiero %s ..." +msgid "Reading dictionary file %s..." +msgstr "Legado de vortardosiero %s..." #, c-format msgid "E760: No word count in %s" @@ -5268,8 +5250,8 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "%d ignorita(j) vorto(j) kun neaskiaj signoj en %s" #, c-format -msgid "Reading word file %s ..." -msgstr "Legado de dosiero de vortoj %s ..." +msgid "Reading word file %s..." +msgstr "Legado de dosiero de vortoj %s..." #, c-format msgid "Duplicate /encoding= line ignored in %s line %d: %s" @@ -5325,8 +5307,8 @@ msgid "Total number of words: %d" msgstr "Totala nombro de vortoj: %d" #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Skribado de dosiero de sugesto %s ..." +msgid "Writing suggestion file %s..." +msgstr "Skribado de dosiero de sugesto %s..." #, c-format msgid "Estimated runtime memory use: %d bytes" @@ -5346,8 +5328,8 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "Averto: ambaÅ NOBREAK kaj NOBREAK specifitaj" #, c-format -msgid "Writing spell file %s ..." -msgstr "Skribado de literuma dosiero %s ..." +msgid "Writing spell file %s..." +msgstr "Skribado de literuma dosiero %s..." msgid "Done!" msgstr "Farita!" @@ -5373,6 +5355,9 @@ msgstr "E783: ripetita signo en rikordo MAP" msgid "No Syntax items defined for this buffer" msgstr "Neniu sintaksa elemento difinita por tiu bufro" +msgid "'redrawtime' exceeded, syntax highlighting disabled" +msgstr "'redrawtime' transpasita, sintaksa emfazo malÅaltita" + msgid "syntax conceal on" msgstr "sintakso de conceal Åaltata" @@ -5402,6 +5387,9 @@ msgstr "" msgid "syntax iskeyword " msgstr "sintakso iskeyword " +msgid "syntax iskeyword not set" +msgstr "sintakso iskeyword ne Åaltita" + #, c-format msgid "E391: No such syntax cluster: %s" msgstr "E391: Nenia sintaksa fasko: %s" @@ -5801,7 +5789,7 @@ msgstr "E823: Ne estas malfara dosiero: %s" #, c-format msgid "E832: Non-encrypted file has encrypted undo file: %s" -msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s" +msgstr "E832: Ne ĉifrita dosiero havas ĉifritan malfaran dosieron: %s" #, c-format msgid "E826: Undo file decryption failed: %s" @@ -5809,7 +5797,7 @@ msgstr "E826: Malĉifrado de malfara dosiero malsukcesis: %s" #, c-format msgid "E827: Undo file is encrypted: %s" -msgstr "E827: Malfara dosiero estas ĉifrata: %s" +msgstr "E827: Malfara dosiero estas ĉifrita: %s" #, c-format msgid "E824: Incompatible undo file: %s" @@ -5870,8 +5858,10 @@ msgid "number changes when saved" msgstr "numero ÅanÄoj tempo konservita" #, c-format -msgid "%ld seconds ago" -msgstr "antaÅ %ld sekundoj" +msgid "%ld second ago" +msgid_plural "%ld seconds ago" +msgstr[0] "antaÅ %ld sekundo" +msgstr[1] "antaÅ %ld sekundoj" msgid "E790: undojoin is not allowed after undo" msgstr "E790: undojoin estas nepermesebla post malfaro" @@ -6010,6 +6000,10 @@ msgstr "E133: \":return\" ekster funkcio" msgid "E107: Missing parentheses: %s" msgstr "E107: Mankas krampoj: %s" +#, c-format +msgid "%s (%s, compiled %s)" +msgstr "%s (%s, kompilita %s)" + msgid "" "\n" "MS-Windows 64-bit GUI version" diff --git a/src/nvim/po/es.po b/src/nvim/po/es.po index 10b661a5d2..f30e8780f9 100644 --- a/src/nvim/po/es.po +++ b/src/nvim/po/es.po @@ -2525,7 +2525,7 @@ msgstr "E216: No existe tal grupo o evento: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Auto-órdenes ---" @@ -2549,7 +2549,7 @@ msgstr "E218: La auto-orden se anida en exceso" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Auto-órdenes para \"%s\"" #: ../fileio.c:7149 @@ -3464,7 +3464,7 @@ msgstr "-q [fich. err.] Editar el archivo con el primer error" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5413,7 +5413,7 @@ msgstr "Advertencia: la región %s no es compatible" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "Leyendo el archivo de afijos \"%s\"..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 @@ -5578,8 +5578,8 @@ msgstr "El valor %s difiere de los que se usa en otro archivo .aff" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Leyendo el archivo de diccionario %s ..." +msgid "Reading dictionary file %s..." +msgstr "Leyendo el archivo de diccionario %s..." #: ../spell.c:5611 #, c-format @@ -5613,8 +5613,8 @@ msgstr "Ignorando %d palabra(s) con caracteres no-ASCII en %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Leyendo archivo de palabras \"%s\" ..." +msgid "Reading word file %s..." +msgstr "Leyendo archivo de palabras \"%s\"..." #: ../spell.c:6155 #, c-format @@ -5683,8 +5683,8 @@ msgstr "Número total de palabras: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Escribiendo el archivo de sugerencias %s ..." +msgid "Writing suggestion file %s..." +msgstr "Escribiendo el archivo de sugerencias %s..." #: ../spell.c:7707 ../spell.c:7927 #, c-format @@ -5711,8 +5711,8 @@ msgstr "Advertencia: Se especificó \"compounding\" y NOBREAK" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Escribiendo archivo de ortografÃa \"%s\" ..." +msgid "Writing spell file %s..." +msgstr "Escribiendo archivo de ortografÃa \"%s\"..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/fi.po b/src/nvim/po/fi.po index 8fa0cc48d4..4612988c95 100644 --- a/src/nvim/po/fi.po +++ b/src/nvim/po/fi.po @@ -2473,7 +2473,7 @@ msgstr "E216: Ryhmää tai eventtiä ei ole: %s" msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autocommandit ---" @@ -2492,7 +2492,7 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: liian monta tasoa autocommandissa" #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Autocommands kohteelle %s" #, c-format @@ -4420,7 +4420,7 @@ msgstr "E55: Pariton %s)" msgid "E66: \\z( not allowed here" msgstr "E66: \\z( ei ole sallittu tässä" -msgid "E67: \\z1 et al. not allowed here" +msgid "E67: \\z1 - \\z9 not allowed here" msgstr "E67: \\z1 jne. ei ole sallittu tässä" #, c-format @@ -4901,7 +4901,7 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: virhe luettaessa .sug-tiedostoa: %s" #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "Luetaan affiksitiedostoa %s..." #, c-format @@ -5034,7 +5034,7 @@ msgid "%s value differs from what is used in another .aff file" msgstr "%s-arvo eroaa toisessa .aff-tiedostossa olevasta" #, c-format -msgid "Reading dictionary file %s ..." +msgid "Reading dictionary file %s..." msgstr "Luetaan sanakirjatiedostoa %s" #, c-format @@ -5062,7 +5062,7 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "Ei-ASCII-merkkien takia ohitettuja sanoja %d kohteessa %s" #, c-format -msgid "Reading word file %s ..." +msgid "Reading word file %s..." msgstr "Luetaan sanatiedostoa %s..." #, c-format @@ -5118,7 +5118,7 @@ msgid "Total number of words: %d" msgstr "Sanoja yhteensä: %d" #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "Kirjoitetaan ehdotustiedostoa %s..." #, c-format @@ -5139,7 +5139,7 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "Varoitus: sekä yhdyssanamuodostus että NOBREAK käytössä" #, c-format -msgid "Writing spell file %s ..." +msgid "Writing spell file %s..." msgstr "Kirjoitetaan oikaisulukutiedostoa %s..." msgid "Done!" diff --git a/src/nvim/po/fr.po b/src/nvim/po/fr.po index 4fa4ef8f8f..5c4c154654 100644 --- a/src/nvim/po/fr.po +++ b/src/nvim/po/fr.po @@ -7,20 +7,21 @@ # FIRST AUTHOR DindinX <David.Odin@bigfoot.com> 2000. # SECOND AUTHOR Adrien Beau <version.francaise@free.fr> 2002, 2003. # THIRD AUTHOR David Blanchet <david.blanchet@free.fr> 2006, 2008. -# FOURTH AUTHOR Dominique Pellé <dominique.pelle@gmail.com> 2008, 2017. +# FOURTH AUTHOR Dominique Pellé <dominique.pelle@gmail.com> 2008, 2018. # msgid "" msgstr "" -"Project-Id-Version: Vim(Français)\n" +"Project-Id-Version: Vim 8.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-10-04 23:32+0200\n" -"PO-Revision-Date: 2017-10-04 23:44+0200\n" +"POT-Creation-Date: 2018-09-01 14:20+0200\n" +"PO-Revision-Date: 2018-09-01 17:15+0200\n" "Last-Translator: Dominique Pellé <dominique.pelle@gmail.com>\n" -"Language-Team: \n" +"Language-Team: French\n" "Language: fr\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=ISO_8859-15\n" +"Content-Type: text/plain; charset=ISO-8859-15\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" msgid "E831: bf_key_init() called with empty password" msgstr "E831: bf_key_init() appelée avec un mot de passe vide" @@ -73,26 +74,23 @@ msgstr "E516: Aucun tampon n'a été effacé" msgid "E517: No buffers were wiped out" msgstr "E517: Aucun tampon n'a été détruit" -msgid "1 buffer unloaded" -msgstr "1 tampon a été déchargé" - #, c-format -msgid "%d buffers unloaded" -msgstr "%d tampons ont été déchargés" - -msgid "1 buffer deleted" -msgstr "1 tampon a été effacé" +msgid "%d buffer unloaded" +msgid_plural "%d buffers unloaded" +msgstr[0] "%d tampon a été déchargé" +msgstr[1] "%d tampons ont été déchargés" #, c-format -msgid "%d buffers deleted" -msgstr "%d tampons ont été effacés" - -msgid "1 buffer wiped out" -msgstr "1 tampon a été détruit" +msgid "%d buffer deleted" +msgid_plural "%d buffers deleted" +msgstr[0] "%d tampon a été effacé" +msgstr[1] "%d tampons ont été effacés" #, c-format -msgid "%d buffers wiped out" -msgstr "%d tampons ont été détruits" +msgid "%d buffer wiped out" +msgid_plural "%d buffers wiped out" +msgstr[0] "%d tampon a été détruit" +msgstr[1] "%d tampons ont été détruits" msgid "E90: Cannot unload last buffer" msgstr "E90: Impossible de décharger le dernier tampon" @@ -176,12 +174,10 @@ msgid "[readonly]" msgstr "[lecture-seule]" #, c-format -msgid "1 line --%d%%--" -msgstr "1 ligne --%d%%--" - -#, c-format -msgid "%ld lines --%d%%--" -msgstr "%ld lignes --%d%%--" +msgid "%ld line --%d%%--" +msgid_plural "%ld lines --%d%%--" +msgstr[0] "%ld ligne --%d%%--" +msgstr[1] "%ld lignes --%d%%--" # AB - Faut-il remplacer "sur" par "de" ? # DB - Mon avis : oui. @@ -228,6 +224,9 @@ msgstr "" msgid "E382: Cannot write, 'buftype' option is set" msgstr "E382: Écriture impossible, l'option 'buftype' est activée" +msgid "[Prompt]" +msgstr "[Invite]" + msgid "[Scratch]" msgstr "[Brouillon]" @@ -593,7 +592,7 @@ msgstr "E108: Variable inexistante : %s" #, c-format msgid "E940: Cannot lock or unlock variable %s" -msgstr "E940: Impossible de (dé)verrouiler la variable %s" +msgstr "E940: Impossible de (dé)verrouiller la variable %s" msgid "E743: variable nested too deep for (un)lock" msgstr "E743: variable trop imbriquée pour la (dé)verrouiller" @@ -603,21 +602,6 @@ msgstr "E743: variable trop imbriquée pour la (dé)verrouiller" msgid "E109: Missing ':' after '?'" msgstr "E109: Il manque ':' après '?'" -msgid "E691: Can only compare List with List" -msgstr "E691: Une Liste ne peut être comparée qu'avec une Liste" - -msgid "E692: Invalid operation for List" -msgstr "E692: Opération invalide avec les Liste" - -msgid "E735: Can only compare Dictionary with Dictionary" -msgstr "E735: Un Dictionnaire ne peut être comparé qu'avec un Dictionnaire" - -msgid "E736: Invalid operation for Dictionary" -msgstr "E736: Opération invalide avec les Dictionnaires" - -msgid "E694: Invalid operation for Funcrefs" -msgstr "E694: Opération invalide avec les Funcrefs" - msgid "E804: Cannot use '%' with Float" msgstr "E804: Impossible d'utiliser '%' avec un Flottant" @@ -752,6 +736,21 @@ msgstr "" "\n" "\tModifié la dernière fois dans " +msgid "E691: Can only compare List with List" +msgstr "E691: Une Liste ne peut être comparée qu'avec une Liste" + +msgid "E692: Invalid operation for List" +msgstr "E692: Opération invalide avec les Liste" + +msgid "E735: Can only compare Dictionary with Dictionary" +msgstr "E735: Un Dictionnaire ne peut être comparé qu'avec un Dictionnaire" + +msgid "E736: Invalid operation for Dictionary" +msgstr "E736: Opération invalide avec les Dictionnaires" + +msgid "E694: Invalid operation for Funcrefs" +msgstr "E694: Opération invalide avec les Funcrefs" + msgid "map() argument" msgstr "argument de map()" @@ -780,6 +779,12 @@ msgid "&Ok" msgstr "&Ok" #, c-format +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld ligne : " +msgstr[1] "+-%s%3ld lignes : " + +#, c-format msgid "E700: Unknown function: %s" msgstr "E700: Fonction inconnue : %s" @@ -814,6 +819,9 @@ msgstr "E916: tâche invalide" msgid "E701: Invalid type for len()" msgstr "E701: Type invalide avec len()" +msgid "E957: Invalid window number" +msgstr "E957: numéro de fenêtre invalide" + #, c-format msgid "E798: ID is reserved for \":match\": %ld" msgstr "E798: ID est réservé pour \":match\": %ld" @@ -887,10 +895,22 @@ msgid "E921: Invalid callback argument" msgstr "E921: Argument de callback invalide" #, c-format +msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s" +msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o, Digr %s" + +#, c-format msgid "<%s>%s%s %d, Hex %02x, Octal %03o" msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o" #, c-format +msgid "> %d, Hex %04x, Oct %o, Digr %s" +msgstr "> %d, Hexa %04x, Octal %o, Digr %s" + +#, c-format +msgid "> %d, Hex %08x, Oct %o, Digr %s" +msgstr "> %d, Hexa %08x, Octal %o, Digr %s" + +#, c-format msgid "> %d, Hex %04x, Octal %o" msgstr "> %d, Hexa %04x, Octal %o" @@ -903,12 +923,11 @@ msgstr "> %d, Hexa %08x, Octal %o" msgid "E134: Move lines into themselves" msgstr "E134: La destination est dans la plage d'origine" -msgid "1 line moved" -msgstr "1 ligne déplacée" - #, c-format -msgid "%ld lines moved" -msgstr "%ld lignes déplacées" +msgid "%ld line moved" +msgid_plural "%ld lines moved" +msgstr[0] "%ld ligne déplacée" +msgstr[1] "%ld lignes déplacées" #, c-format msgid "%ld lines filtered" @@ -1116,26 +1135,29 @@ msgstr "remplacer par %s (y/n/a/q/l/^E/^Y)?" msgid "(Interrupted) " msgstr "(Interrompu) " -msgid "1 match" -msgstr "1 correspondance" - -msgid "1 substitution" -msgstr "1 substitution" - #, c-format -msgid "%ld matches" -msgstr "%ld correspondances" +msgid "%ld match on %ld line" +msgid_plural "%ld matches on %ld line" +msgstr[0] "%ld correspondance sur %ld ligne" +msgstr[1] "%ld correspondances sur %ld ligne" #, c-format -msgid "%ld substitutions" -msgstr "%ld substitutions" +msgid "%ld substitution on %ld line" +msgid_plural "%ld substitutions on %ld line" +msgstr[0] "%ld substitution sur %ld ligne" +msgstr[1] "%ld substitutions sur %ld ligne" -msgid " on 1 line" -msgstr " sur 1 ligne" +#, c-format +msgid "%ld match on %ld lines" +msgid_plural "%ld matches on %ld lines" +msgstr[0] "%ld correspondance sur %ld lignes" +msgstr[1] "%ld correspondances sur %ld lignes" #, c-format -msgid " on %ld lines" -msgstr " sur %ld lignes" +msgid "%ld substitution on %ld lines" +msgid_plural "%ld substitutions on %ld lines" +msgstr[0] "%ld substitution sur %ld lignes" +msgstr[1] "%ld substitutions sur %ld lignes" # AB - Il faut respecter l'esprit plus que la lettre. # AB - Ce message devrait contenir une référence à :vglobal. @@ -1280,6 +1302,14 @@ msgid "Entering Debug mode. Type \"cont\" to continue." msgstr "Mode débogage activé. Tapez \"cont\" pour continuer." #, c-format +msgid "Oldval = \"%s\"" +msgstr "Ancienneval = \"%s\"" + +#, c-format +msgid "Newval = \"%s\"" +msgstr "Nouvelleval = \"%s\"" + +#, c-format msgid "line %ld: %s" msgstr "ligne %ld : %s" @@ -1311,6 +1341,10 @@ msgstr "Aucun point d'arrêt n'est défini" msgid "%3d %s %s line %ld" msgstr "%3d %s %s ligne %ld" +#, c-format +msgid "%3d expr %s" +msgstr "%3d expr %s" + msgid "E750: First use \":profile start {fname}\"" msgstr "E750: Utilisez d'abord \":profile start {nomfichier}\"" @@ -1473,22 +1507,17 @@ msgstr "" msgid "E319: Sorry, the command is not available in this version" msgstr "E319: Désolé, cette commande n'est pas disponible dans cette version" -msgid "E172: Only one file name allowed" -msgstr "E172: Un seul nom de fichier autorisé" - -msgid "1 more file to edit. Quit anyway?" -msgstr "Encore 1 fichier à éditer. Quitter tout de même ?" - #, c-format -msgid "%d more files to edit. Quit anyway?" -msgstr "Encore %d fichiers à éditer. Quitter tout de même ?" - -msgid "E173: 1 more file to edit" -msgstr "E173: encore 1 fichier à éditer" +msgid "%d more file to edit. Quit anyway?" +msgid_plural "%d more files to edit. Quit anyway?" +msgstr[0] "Encore %d fichier à éditer. Quitter tout de même ?" +msgstr[1] "Encore %d fichiers à éditer. Quitter tout de même ?" #, c-format -msgid "E173: %ld more files to edit" -msgstr "E173: encore %ld fichiers à éditer" +msgid "E173: %ld more file to edit" +msgid_plural "E173: %ld more files to edit" +msgstr[0] "E173: encore %ld fichier à éditer" +msgstr[1] "E173: encore %ld fichiers à éditer" msgid "E174: Command already exists: add ! to replace it" msgstr "E174: La commande existe déjà : ajoutez ! pour la redéfinir" @@ -1569,6 +1598,9 @@ msgstr "E784: Impossible de fermer le dernier onglet" msgid "Already only one tab page" msgstr "Il ne reste déjà plus qu'un seul onglet" +msgid "Edit File in new tab page" +msgstr "Ouvrir un fichier dans un nouvel onglet" + msgid "Edit File in new window" msgstr "Ouvrir un fichier dans une nouvelle fenêtre - Vim" @@ -1876,9 +1908,6 @@ msgstr "Lecture de stdin..." msgid "E202: Conversion made file unreadable!" msgstr "E202: La conversion a rendu le fichier illisible !" -msgid "[fifo/socket]" -msgstr "[fifo/socket]" - msgid "[fifo]" msgstr "[fifo]" @@ -1965,10 +1994,6 @@ msgid "E510: Can't make backup file (add ! to override)" msgstr "" "E510: Impossible de générer la copie de secours (ajoutez ! pour passer outre)" -msgid "E460: The resource fork would be lost (add ! to override)" -msgstr "" -"E460: Les ressources partagées seraient perdues (ajoutez ! pour passer outre)" - msgid "E214: Can't find temp file for writing" msgstr "E214: Impossible de générer un fichier temporaire pour y écrire" @@ -1981,8 +2006,8 @@ msgstr "E166: Impossible d'ouvrir le lien pour y écrire" msgid "E212: Can't open file for writing" msgstr "E212: Impossible d'ouvrir le fichier pour y écrire" -msgid "E667: Fsync failed" -msgstr "E667: Fsynch a échoué" +msgid "E949: File changed while writing" +msgstr "E949: Fichier modifié après écriture" msgid "E512: Close failed" msgstr "E512: Erreur de fermeture de fichier" @@ -2067,19 +2092,17 @@ msgstr "[unix]" msgid "[unix format]" msgstr "[format unix]" -msgid "1 line, " -msgstr "1 ligne, " - #, c-format -msgid "%ld lines, " -msgstr "%ld lignes, " - -msgid "1 character" -msgstr "1 caractère" +msgid "%ld line, " +msgid_plural "%ld lines, " +msgstr[0] "%ld ligne, " +msgstr[1] "%ld lignes, " #, c-format -msgid "%lld characters" -msgstr "%lld caractères" +msgid "%lld character" +msgid_plural "%lld characters" +msgstr[0] "%lld caractère" +msgstr[1] "%lld caractères" msgid "[noeol]" msgstr "[noeol]" @@ -2192,7 +2215,7 @@ msgstr "E216: Aucun événement ou groupe %s" msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Auto-commandes ---" @@ -2212,7 +2235,7 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: autocommandes trop imbriquées" #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "Autocommandes %s pour \"%s\"" #, c-format @@ -2238,6 +2261,12 @@ msgstr "E350: Impossible de créer un repli avec la 'foldmethod'e actuelle" msgid "E351: Cannot delete fold with current 'foldmethod'" msgstr "E351: Impossible de supprimer un repli avec la 'foldmethod'e actuelle" +#, c-format +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld ligne déplacée " +msgstr[1] "+--%3ld lignes déplacées " + msgid "E222: Add to read buffer" msgstr "E222: Ajout au tampon de lecture" @@ -2459,11 +2488,11 @@ msgstr "Ann&uler" msgid "Open tab..." msgstr "Ouvrir dans un onglet..." -msgid "Find string (use '\\\\' to find a '\\')" -msgstr "Chercher une chaîne (utilisez '\\\\' pour chercher un '\\')" +msgid "Find string" +msgstr "Trouver une chaîne" -msgid "Find & Replace (use '\\\\' to find a '\\')" -msgstr "Chercher et remplacer (utilisez '\\\\' pour trouver un '\\')" +msgid "Find & Replace" +msgstr "Trouver & remplacer" # DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un # paramétrage bidon afin de sélectionner un répertoire plutôt qu'un @@ -3133,11 +3162,11 @@ msgstr "-q [fichErr] ouvrir à l'endroit de la première erreur" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" -"utilisation :" +"Utilisation :" msgid " vim [arguments] " msgstr " vim [args] " @@ -3253,7 +3282,7 @@ msgstr "-f\t\tNe pas utiliser newcli pour l'ouverture des fenêtres" msgid "-dev <device>\t\tUse <device> for I/O" msgstr "-dev <périph>\tUtiliser <périphérique> pour les E/S" -msgid "-A\t\t\tstart in Arabic mode" +msgid "-A\t\t\tStart in Arabic mode" msgstr "-A\t\tDémarrer en mode arabe" msgid "-H\t\t\tStart in Hebrew mode" @@ -3371,7 +3400,8 @@ msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo" msgstr "-i <viminfo>\t\tUtiliser <viminfo> au lieu du viminfo habituel" msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo" -msgstr "--clean\t\t'nocompatible', réglages par défaut, aucun greffon ni viminfo" +msgstr "" +"--clean\t\t'nocompatible', réglages par défaut, aucun greffon ni viminfo" msgid "-h or --help\tPrint Help (this message) and exit" msgstr "-h ou --help\t\tAfficher l'aide (ce message) puis quitter" @@ -4171,19 +4201,17 @@ msgstr "Tapez un nombre et <Entrée> ou cliquez avec la souris (rien annule) :" msgid "Type number and <Enter> (empty cancels): " msgstr "Tapez un nombre et <Entrée> (rien annule) :" -msgid "1 more line" -msgstr "1 ligne en plus" - -msgid "1 line less" -msgstr "1 ligne en moins" - #, c-format -msgid "%ld more lines" -msgstr "%ld lignes en plus" +msgid "%ld more line" +msgid_plural "%ld more lines" +msgstr[0] "%ld ligne en plus" +msgstr[1] "%ld lignes en plus" #, c-format -msgid "%ld fewer lines" -msgstr "%ld lignes en moins" +msgid "%ld line less" +msgid_plural "%ld fewer lines" +msgstr[0] "%ld ligne en moins" +msgstr[1] "%ld lignes en moins" msgid " (Interrupted)" msgstr " (Interrompu)" @@ -4321,31 +4349,26 @@ msgstr "" "Vim" #, c-format -msgid "1 line %sed 1 time" -msgstr "1 ligne %sée 1 fois" - -#, c-format -msgid "1 line %sed %d times" -msgstr "1 ligne %sée %d fois" - -#, c-format -msgid "%ld lines %sed 1 time" -msgstr "%ld lignes %sées 1 fois" +msgid "%ld line %sed %d time" +msgid_plural "%ld line %sed %d times" +msgstr[0] "%ld lignes %sées %d fois" +msgstr[1] "%ld lignes %sées %d fois" #, c-format -msgid "%ld lines %sed %d times" -msgstr "%ld lignes %sées %d fois" +msgid "%ld lines %sed %d time" +msgid_plural "%ld lines %sed %d times" +msgstr[0] "%ld lignes %sées %d fois" +msgstr[1] "%ld lignes %sées %d fois" #, c-format msgid "%ld lines to indent... " msgstr "%ld lignes à indenter... " -msgid "1 line indented " -msgstr "1 ligne indentée " - #, c-format -msgid "%ld lines indented " -msgstr "%ld lignes indentées " +msgid "%ld line indented " +msgid_plural "%ld lines indented " +msgstr[0] "%ld ligne indentée " +msgstr[1] "%ld lignes indentées " msgid "E748: No previously used register" msgstr "E748: Aucun registre n'a été précédemment utilisé" @@ -4354,12 +4377,11 @@ msgstr "E748: Aucun registre n'a été précédemment utilisé" msgid "cannot yank; delete anyway" msgstr "impossible de réaliser une copie ; effacer tout de même" -msgid "1 line changed" -msgstr "1 ligne modifiée" - #, c-format -msgid "%ld lines changed" -msgstr "%ld lignes modifiées" +msgid "%ld line changed" +msgid_plural "%ld lines changed" +msgstr[0] "%ld ligne modifiée" +msgstr[1] "%ld lignes modifiées" #, c-format msgid "freeing %ld lines" @@ -4370,20 +4392,16 @@ msgid " into \"%c" msgstr " dans \"%c" #, c-format -msgid "block of 1 line yanked%s" -msgstr "bloc de 1 ligne copié%s" - -#, c-format -msgid "1 line yanked%s" -msgstr "1 ligne copiée%s" +msgid "block of %ld line yanked%s" +msgid_plural "block of %ld lines yanked%s" +msgstr[0] "bloc de %ld ligne copié%s" +msgstr[1] "bloc de %ld lignes copié%s" #, c-format -msgid "block of %ld lines yanked%s" -msgstr "bloc de %ld lignes copié%s" - -#, c-format -msgid "%ld lines yanked%s" -msgstr "%ld lignes copiées%s" +msgid "%ld line yanked%s" +msgid_plural "%ld lines yanked%s" +msgstr[0] "%ld ligne copiée%s" +msgstr[1] "%ld lignes copiées%s" #, c-format msgid "E353: Nothing in register %s" @@ -4449,8 +4467,8 @@ msgstr "" "sur %lld ; Octet %lld sur %lld" #, c-format -msgid "(+%ld for BOM)" -msgstr "(+%ld pour le BOM)" +msgid "(+%lld for BOM)" +msgstr "(+%lld pour le BOM)" msgid "Thanks for flying Vim" msgstr "Merci d'avoir choisi Vim" @@ -4502,6 +4520,10 @@ msgstr "E835: Conflits avec la valeur de 'fillchars'" msgid "E617: Cannot be changed in the GTK+ 2 GUI" msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2" +#, c-format +msgid "E950: Cannot convert between %s and %s" +msgstr "E950: Impossible de convertir de %s à %s" + msgid "E524: Missing colon" msgstr "E524: ':' manquant" @@ -4563,7 +4585,8 @@ msgid "E542: unbalanced groups" msgstr "E542: parenthèses non équilibrées" msgid "E946: Cannot make a terminal with running job modifiable" -msgstr "E946: terminal avec tâche en cours d'exécution ne peut pas être modifiable" +msgstr "" +"E946: terminal avec tâche en cours d'exécution ne peut pas être modifiable" msgid "E590: A preview window already exists" msgstr "E590: Il existe déjà une fenêtre de prévisualisation" @@ -4571,6 +4594,9 @@ msgstr "E590: Il existe déjà une fenêtre de prévisualisation" msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'" msgstr "W17: L'arabe nécessite l'UTF-8, tapez ':set encoding=utf-8'" +msgid "E954: 24-bit colors are not supported on this environment" +msgstr "E954: Couleurs en 24-bits non-supportées sur cet environnement." + #, c-format msgid "E593: Need at least %d lines" msgstr "E593: Au moins %d lignes sont nécessaires" @@ -4858,6 +4884,9 @@ msgstr "Alerte Vim" msgid "shell returned %d" msgstr "le shell a retourné %d" +msgid "E926: Current location list was changed" +msgstr "E926: La liste d'emplacements courante a changé" + #, c-format msgid "E372: Too many %%%c in format string" msgstr "E372: Trop de %%%c dans la chaîne de format" @@ -4896,9 +4925,6 @@ msgstr "E924: La fenêtre courante doit être fermée" msgid "E925: Current quickfix was changed" msgstr "E925: Le quickfix courant a changé" -msgid "E926: Current location list was changed" -msgstr "E926: La liste d'emplacements courante a changé" - #, c-format msgid "(%d of %d)%s%s: " msgstr "(%d sur %d)%s%s : " @@ -4964,7 +4990,7 @@ msgstr "E55: %s) fermante non ouverte" msgid "E66: \\z( not allowed here" msgstr "E66: \\z( n'est pas autorisé ici" -msgid "E67: \\z1 et al. not allowed here" +msgid "E67: \\z1 - \\z9 not allowed here" msgstr "E67: \\z1 et co. ne sont pas autorisés ici" #, c-format @@ -4975,6 +5001,9 @@ msgstr "E69: ']' manquant après %s%%[" msgid "E70: Empty %s%%[]" msgstr "E70: %s%%[] vide" +msgid "E956: Cannot use pattern recursively" +msgstr "E956: Impossible d'utiliser le motif récursivement" + msgid "E65: Illegal back reference" msgstr "E65: post-référence invalide" @@ -5061,6 +5090,9 @@ msgstr "E877: (regexp NFA) Classe de caractère invalide : %ld" msgid "E867: (NFA) Unknown operator '\\z%c'" msgstr "E867: (NFA) Opérateur inconnu '\\z%c'" +msgid "E951: \\% value too large" +msgstr "E951: valeur \\% trop grande" + #, c-format msgid "E867: (NFA) Unknown operator '\\%%%c'" msgstr "E867: (NFA) Opérateur inconnu '\\%%%c'" @@ -5075,8 +5107,8 @@ msgstr "E869: (NFA) Opérateur inconnu '\\@%c'" msgid "E870: (NFA regexp) Error reading repetition limits" msgstr "E870: (regexp NFA) Erreur à la lecture des limites de répétition" -msgid "E871: (NFA regexp) Can't have a multi follow a multi !" -msgstr "E871: (regexp NFA) Un multi ne peut pas suivre un multi !" +msgid "E871: (NFA regexp) Can't have a multi follow a multi" +msgstr "E871: (regexp NFA) Un multi ne peut pas suivre un multi" msgid "E872: (NFA regexp) Too many '('" msgstr "E872: (regexp NFA) Trop de '('" @@ -5087,7 +5119,12 @@ msgstr "E879: (regexp NFA) Trop de \\z(" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (NFA regexp) erreur de terminaison" -msgid "E874: (NFA) Could not pop the stack !" +msgid "Could not open temporary log file for writing, displaying on stderr... " +msgstr "" +"Impossible d'ouvrir le fichier de log temporaire en écriture, affichage sur " +"stderr... " + +msgid "E874: (NFA) Could not pop the stack!" msgstr "E874: (NFA) Impossible de dépiler !" msgid "" @@ -5104,19 +5141,6 @@ msgid "E878: (NFA) Could not allocate memory for branch traversal!" msgstr "" "E878: (NFA) Impossible d'allouer la mémoire pour parcourir les branches !" -msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " -msgstr "" -"Impossible d'ouvrir le fichier de log temporaire en écriture, affichage sur " -"stderr ... " - -#, c-format -msgid "(NFA) COULD NOT OPEN %s !" -msgstr "(NFA) IMPOSSIBLE D'OUVRIR %s !" - -msgid "Could not open temporary log file for writing " -msgstr "Impossible d'ouvrir le fichier de log en écriture" - msgid " VREPLACE" msgstr " VREMPLACEMENT" @@ -5336,7 +5360,7 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: Erreur lors de la lecture de fichier de suggestions : %s" #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "Lecture du fichier d'affixes %s..." #, c-format @@ -5476,7 +5500,7 @@ msgid "%s value differs from what is used in another .aff file" msgstr "La valeur de %s est différente de celle d'un autre fichier .aff" #, c-format -msgid "Reading dictionary file %s ..." +msgid "Reading dictionary file %s..." msgstr "Lecture du fichier orthographique %s..." #, c-format @@ -5484,8 +5508,8 @@ msgid "E760: No word count in %s" msgstr "E760: Nombre de mots non indiqué dans %s" #, c-format -msgid "line %6d, word %6d - %s" -msgstr "ligne %6d, mot %6d - %s" +msgid "line %6d, word %6ld - %s" +msgstr "ligne %6d, mot %6ld - %s" #, c-format msgid "Duplicate word in %s line %d: %s" @@ -5504,7 +5528,7 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "%d mot(s) ignoré(s) avec des caractères non-ASCII dans %s" #, c-format -msgid "Reading word file %s ..." +msgid "Reading word file %s..." msgstr "Lecture de la liste de mots %s..." #, c-format @@ -5561,7 +5585,7 @@ msgid "Total number of words: %d" msgstr "Nombre total de mots : %d" #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "Écriture du fichier de suggestions %s..." #, c-format @@ -5571,8 +5595,9 @@ msgstr "Estimation de mémoire consommée : %d octets" msgid "E751: Output file name must not have region name" msgstr "E751: Le nom du fichier ne doit pas contenir de nom de région" -msgid "E754: Only up to 8 regions supported" -msgstr "E754: 8 régions au maximum sont supportées" +#, c-format +msgid "E754: Only up to %ld regions supported" +msgstr "E754: %ld régions au maximum supportées" #, c-format msgid "E755: Invalid region in %s" @@ -5582,7 +5607,7 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "Alerte : la composition et NOBREAK sont tous les deux spécifiés" #, c-format -msgid "Writing spell file %s ..." +msgid "Writing spell file %s..." msgstr "Écriture du fichier orthographique %s..." msgid "Done!" @@ -5611,6 +5636,9 @@ msgstr "E783: caractère dupliqué dans l'entrée MAP" msgid "No Syntax items defined for this buffer" msgstr "Aucun élément de syntaxe défini pour ce tampon" +msgid "'redrawtime' exceeded, syntax highlighting disabled" +msgstr "'redrawtime' écoulé, surbrillance de syntaxe désactivée" + msgid "syntax conceal on" msgstr "\"syntax conceal\" activée" @@ -5641,6 +5669,9 @@ msgstr "" msgid "syntax iskeyword " msgstr "syntaxe iskeyword " +msgid "syntax iskeyword not set" +msgstr "iskeyword n'est pas activé" + #, c-format msgid "E391: No such syntax cluster: %s" msgstr "E391: Aucune grappe de syntaxe %s" @@ -5967,6 +5998,10 @@ msgstr "" msgid "Cannot open $VIMRUNTIME/rgb.txt" msgstr "Impossible d'ouvrir $VIMRUNTIME/rgb.txt" +#, c-format +msgid "Kill job in \"%s\"?" +msgstr "Terminer la tâche d'exécution dans \"%s\"?" + msgid "Terminal" msgstr "Terminal" @@ -5982,6 +6017,13 @@ msgstr "en cours" msgid "finished" msgstr "fini" +#, c-format +msgid "E953: File exists: %s" +msgstr "E953: Le fichier existe déjà : %s" + +msgid "E955: Not a terminal buffer" +msgstr "E955: Ce n'est pas un buffer de terminal" + msgid "new shell started\n" msgstr "nouveau shell démarré\n" @@ -6121,8 +6163,10 @@ msgid "number changes when saved" msgstr "numéro modif. instant enregistré" #, c-format -msgid "%ld seconds ago" -msgstr "il y a %ld secondes" +msgid "%ld second ago" +msgid_plural "%ld seconds ago" +msgstr[0] "il y a %ld seconde" +msgstr[1] "il y a %ld secondes" msgid "E790: undojoin is not allowed after undo" msgstr "E790: undojoin n'est pas autorisé après une annulation" @@ -6280,6 +6324,10 @@ msgstr "E133: :return en dehors d'une fonction" msgid "E107: Missing parentheses: %s" msgstr "E107: Parenthèses manquantes : %s" +#, c-format +msgid "%s (%s, compiled %s)" +msgstr "%s (%s, compilé %s)" + msgid "" "\n" "MS-Windows 64-bit GUI version" @@ -6313,24 +6361,17 @@ msgstr "" msgid "" "\n" -"MacOS X (unix) version" +"macOS version" msgstr "" "\n" -"Version MaxOS X (unix)" +"Version macOS" msgid "" "\n" -"MacOS X version" +"macOS version w/o darwin feat." msgstr "" "\n" -"Version MacOS X" - -msgid "" -"\n" -"MacOS version" -msgstr "" -"\n" -"Version MacOS" +"Version macOS sans fonctionalités darwin" msgid "" "\n" @@ -6434,9 +6475,6 @@ msgstr "avec interface graphique Carbon." msgid "with Cocoa GUI." msgstr "avec interface graphique Cocoa." -msgid "with (classic) GUI." -msgstr "avec interface graphique (classic)." - msgid " Features included (+) or not (-):\n" msgstr " Fonctionnalités incluses (+) ou non (-) :\n" @@ -6742,6 +6780,14 @@ msgid "E475: Invalid argument: %s" msgstr "E475: Argument invalide : %s" #, c-format +msgid "E475: Invalid value for argument %s" +msgstr "E475: Valeur d'argument invalide : %s" + +#, c-format +msgid "E475: Invalid value for argument %s: %s" +msgstr "E475: Valeur d'argument invalide %s : %s" + +#, c-format msgid "E15: Invalid expression: %s" msgstr "E15: Expression invalide : %s" @@ -6759,6 +6805,9 @@ msgstr "E17: \"%s\" est un répertoire" msgid "E364: Library call failed for \"%s()\"" msgstr "E364: L'appel à la bibliothèque a échoué pour \"%s()\"" +msgid "E667: Fsync failed" +msgstr "E667: Fsynch a échoué" + #, c-format msgid "E448: Could not load library function %s" msgstr "E448: Impossible de charger la fonction %s de la bibliothèque" @@ -7033,6 +7082,9 @@ msgstr "E850: Nom de registre invalide" msgid "E919: Directory not found in '%s': \"%s\"" msgstr "E919: Répertoire introuvable dans '%s' : \"%s\"" +msgid "E952: Autocommand caused recursive behavior" +msgstr "E952: Une autocommande a causé une récursivité" + msgid "search hit TOP, continuing at BOTTOM" msgstr "La recherche a atteint le HAUT, et continue en BAS" @@ -7307,3 +7359,47 @@ msgid "" msgstr "" "Impossible d'initialiser le chemin : sys.math n'est pas une liste\n" "Vous devez maintenant ajouter vim.VIM_SPECIAL_PATH à sys.path" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*.*)\t*.*\n" +msgstr "" +"Fichiers de macros Vim (*.vim)\t*.vim\n" +"Tous les fichiers (*.*)\t*.*\n" + +msgid "All Files (*.*)\t*.*\n" +msgstr "Tous les fichiers (*.)\t*.*\n" + +msgid "" +"All Files (*.*)\t*.*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB code (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"Tous les fichiers (*.*)\t*.*\n" +"Source C (*.c, *.h)\t*.c;*.h\n" +"Source C++ (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Code VB (*.bas, *.frm)\t*.bas;*.frm\n" +"Fichiers Vim (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*)\t*\n" +msgstr "" +"Fichiers de macros Vim (*.vim)\t*.vim\n" +"Tous les fichiers (*)\t*\n" + +msgid "All Files (*)\t*\n" +msgstr "Tous les fichiers (*)\t*\n" + +msgid "" +"All Files (*)\t*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"Tous les fichiers (*)\t*\n" +"Source C (*.c, *.h)\t*.c;*.h\n" +"Source C++ (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Fichiers Vim (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" diff --git a/src/nvim/po/ga.po b/src/nvim/po/ga.po index d409560f6b..617b805eb8 100644 --- a/src/nvim/po/ga.po +++ b/src/nvim/po/ga.po @@ -2021,7 +2021,7 @@ msgstr "E216: Níl a leithéid de ghrúpa nó theagmhas: %s" #. Highlight title msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Uathorduithe ---" @@ -2040,7 +2040,7 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: uathordú neadaithe ródhomhain" #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Uathorduithe do \"%s\"" #, c-format @@ -2953,7 +2953,7 @@ msgstr "-q [comhadearr] cuir comhad leis an chéad earráid in eagar" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -3071,8 +3071,8 @@ msgstr "-f\t\t\tNá húsáid newcli chun fuinneog a oscailt" msgid "-dev <device>\t\tUse <device> for I/O" msgstr "-dev <gléas>\t\tBain úsáid as <gléas> do I/A" -msgid "-A\t\t\tstart in Arabic mode" -msgstr "-A\t\t\ttosaigh sa mhód Araibise" +msgid "-A\t\t\tStart in Arabic mode" +msgstr "-A\t\t\tTosaigh sa mhód Araibise" msgid "-H\t\t\tStart in Hebrew mode" msgstr "-H\t\t\tTosaigh sa mhód Eabhraise" @@ -4797,8 +4797,8 @@ msgstr "E55: %s) corr" msgid "E66: \\z( not allowed here" msgstr "E66: ní cheadaítear \\z( anseo" -msgid "E67: \\z1 et al. not allowed here" -msgstr "E67: ní cheadaítear \\z1 et al. anseo" +msgid "E67: \\z1 - \\z9 not allowed here" +msgstr "E67: ní cheadaítear \\z1 - \\z9 anseo" #, c-format msgid "E69: Missing ] after %s%%[" @@ -4911,8 +4911,8 @@ msgid "E870: (NFA regexp) Error reading repetition limits" msgstr "E870: (slonn NFA) Earráid agus teorainneacha athdhéanta á léamh" #. Can't have a multi follow a multi. -msgid "E871: (NFA regexp) Can't have a multi follow a multi !" -msgstr "E871: (slonn NFA) Ní cheadaítear ilchodach tar éis ilchodach!" +msgid "E871: (NFA regexp) Can't have a multi follow a multi" +msgstr "E871: (slonn NFA) Ní cheadaítear ilchodach tar éis ilchodach" #. Too many `(' msgid "E872: (NFA regexp) Too many '('" @@ -4924,7 +4924,7 @@ msgstr "E879: (slonn NFA) An iomarca \\z(" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (slonn NFA) críochnú neamhoiriúnach" -msgid "E874: (NFA) Could not pop the stack !" +msgid "E874: (NFA) Could not pop the stack!" msgstr "E874: (NFA) Níorbh fhéidir an chruach a phlobadh!" msgid "" @@ -4943,7 +4943,7 @@ msgstr "" "thrasnaíl!" msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " +"Could not open temporary log file for writing, displaying on stderr... " msgstr "" "Níorbh fhéidir logchomhad sealadach a oscailt le scríobh ann, á thaispeáint " "ar stderr..." @@ -5178,7 +5178,7 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: earráid agus comhad .sug á léamh: %s" #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "Comhad foircinn %s á léamh..." #, c-format @@ -5314,8 +5314,8 @@ msgid "%s value differs from what is used in another .aff file" msgstr "Tá difear idir luach %s agus an luach i gcomhad .aff eile" #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Foclóir %s á léamh ..." +msgid "Reading dictionary file %s..." +msgstr "Foclóir %s á léamh..." #, c-format msgid "E760: No word count in %s" @@ -5342,8 +5342,8 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "Rinneadh neamhshuim ar %d focal le carachtair neamh-ASCII i %s" #, c-format -msgid "Reading word file %s ..." -msgstr "Comhad focail %s á léamh ..." +msgid "Reading word file %s..." +msgstr "Comhad focail %s á léamh..." #, c-format msgid "Duplicate /encoding= line ignored in %s line %d: %s" @@ -5404,8 +5404,8 @@ msgid "Total number of words: %d" msgstr "Líon iomlán na bhfocal: %d" #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Comhad moltaí %s á scríobh ..." +msgid "Writing suggestion file %s..." +msgstr "Comhad moltaí %s á scríobh..." #, c-format msgid "Estimated runtime memory use: %d bytes" @@ -5425,8 +5425,8 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "Rabhadh: sonraíodh comhfhocail agus NOBREAK araon" #, c-format -msgid "Writing spell file %s ..." -msgstr "Comhad litrithe %s á scríobh ..." +msgid "Writing spell file %s..." +msgstr "Comhad litrithe %s á scríobh..." msgid "Done!" msgstr "Críochnaithe!" diff --git a/src/nvim/po/it.po b/src/nvim/po/it.po index c95faf1dce..9d5709e1ab 100644 --- a/src/nvim/po/it.po +++ b/src/nvim/po/it.po @@ -1,6 +1,8 @@ -# Italian Translation for Vim +# Italian translation for Vim # -# FIRST AUTHOR Antonio Colombo <azc100@gmail.com>, 2000 +# Antonio Colombo <azc100@gmail.com>, 2000 +# Vlad Sandrini <vlad.gently@gmail.com>, 2002 +# Luciano Montanaro <mikelima@cirulla.net>, 2006 # # Ogni commento è benvenuto... # Every remark is very welcome... @@ -884,7 +886,6 @@ msgstr "E730: uso di Lista come Stringa" msgid "E731: using Dictionary as a String" msgstr "E731: uso di Dizionario come Stringa" -# nuovo msgid "E908: using an invalid value as a String" msgstr "E908: uso di un valore non valido come Stringa" @@ -1417,6 +1418,11 @@ msgstr "E904: l'ultimo argomento per espressione/chiamata dev'essere numerico" msgid "E904: third argument for call must be a list" msgstr "E904: il terzo argomento della chiamata dev'essere una Lista" +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld riga: " +msgstr[1] "+-%s%3ld righe: " + #, c-format msgid "E905: received unknown command: %s" msgstr "E905: recevuto comando non conosciuto: %s" @@ -1429,6 +1435,13 @@ msgstr "E630: %s(): scrittura in mancanza di connessione" msgid "E631: %s(): write failed" msgstr "E631: %s(): scrittura non riuscita" +msgid "Oldval = \"%s\"" +msgstr "Vecchioval = \"%s\"" + +#, c-format +msgid "Newval = \"%s\"" +msgstr "Nuovoval = \"%s\"" + #, c-format msgid "frame at highest level: %d" msgstr "al livello più alto: %d" @@ -2520,7 +2533,7 @@ msgid "" "--- Auto-Commands ---" msgstr "" "\n" -"--- Auto-Comandi ---" +"--- Autocomandi ---" #: ../fileio.c:6293 #, c-format @@ -3437,11 +3450,11 @@ msgstr "-q [errorfile] apri file col primo errore" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" -" uso:" +" Uso:" #: ../main.c:2189 msgid " vim [arguments] " @@ -4839,6 +4852,9 @@ msgstr "" "\n" "Non posso impostare il contesto di sicurezza per " +msgid "E954: 24-bit colors are not supported on this environment" +msgstr "E954: colori a 24-bit non supportati in questo ambiente" + #, c-format msgid "E151: No match: %s" msgstr "E151: Nessuna corrispondenza: %s" @@ -5151,9 +5167,9 @@ msgstr "E876: (NFA regexp) Non c'è spazio per immagazzinare l'intero NFA " #: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869 msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " +"Could not open temporary log file for writing, displaying on stderr... " msgstr "" -"Non posso aprire il file temporaneo per la scrittura, mostro su stderr ... " +"Non posso aprire il file temporaneo per la scrittura, mostro su stderr... " #: ../regexp_nfa.c:4840 #, c-format @@ -5391,14 +5407,17 @@ msgstr "E944: Intervallo invertito nella classe di caratteri" msgid "E945: Range too large in character class" msgstr "E945: Intervallo troppo ampio nella classe di caratteri" +msgid "E926: Current location list was changed" +msgstr "E926: La lista delle locazioni corrente è stata cambiata" + #, c-format msgid "E779: Old .sug file, needs to be updated: %s" msgstr "E779: File .sug obsoleto, è necessario aggiornarlo: %s" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Lettura file affissi %s ..." +msgid "Reading affix file %s..." +msgstr "Lettura file affissi %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5560,8 +5579,8 @@ msgstr "Il valore di %s è diverso da quello usato in un altro file .aff" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Lettura file dizionario %s ..." +msgid "Reading dictionary file %s..." +msgstr "Lettura file dizionario %s..." #: ../spell.c:5611 #, c-format @@ -5595,8 +5614,8 @@ msgstr "%d parole con caratteri non-ASCII ignorate in %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Lettura file parole %s ..." +msgid "Reading word file %s..." +msgstr "Lettura file parole %s..." #: ../spell.c:6155 #, c-format @@ -5665,8 +5684,8 @@ msgstr "Conteggio totale delle parole: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Scrivo file di suggerimenti %s ..." +msgid "Writing suggestion file %s..." +msgstr "Scrivo file di suggerimenti %s..." #: ../spell.c:7707 ../spell.c:7927 #, c-format @@ -5692,8 +5711,8 @@ msgstr "Avviso: specificati sia composizione sia NOBREAK" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Scrivo file ortografico %s ..." +msgid "Writing spell file %s..." +msgstr "Scrivo file ortografico %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/ja.euc-jp.po b/src/nvim/po/ja.euc-jp.po index 10d7342430..dc3c4368ab 100644 --- a/src/nvim/po/ja.euc-jp.po +++ b/src/nvim/po/ja.euc-jp.po @@ -4,8 +4,8 @@ # Do ":help uganda" in Vim to read copying and usage conditions. # Do ":help credits" in Vim to see a list of people who contributed. # -# Copyright (C) 2001-2016 MURAOKA Taro <koron.kaoriya@gmail.com>, -# vim-jp (http://vim-jp.org/) +# Copyright (C) 2001-2018 MURAOKA Taro <koron.kaoriya@gmail.com>, +# vim-jp <http://vim-jp.org/> # # THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. # @@ -13,16 +13,16 @@ # msgid "" msgstr "" -"Project-Id-Version: Vim 8.0\n" +"Project-Id-Version: Vim 8.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-07-03 23:05+0900\n" -"PO-Revision-Date: 2017-07-12 20:45+0900\n" +"POT-Creation-Date: 2018-07-18 00:43+0900\n" +"PO-Revision-Date: 2017-05-18 00:45+0900\n" "Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n" -"Language-Team: vim-jp (https://github.com/vim-jp/lang-ja)\n" -"Language: Japanese\n" +"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n" +"Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=euc-jp\n" -"Content-Transfer-Encoding: 8-bit\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" msgid "E831: bf_key_init() called with empty password" @@ -50,10 +50,10 @@ msgid "E855: Autocommands caused command to abort" msgstr "E855: autocommand¤¬¥³¥Þ¥ó¥É¤ÎÄä»ß¤ò°ú¤µ¯¤³¤·¤Þ¤·¤¿" msgid "E82: Cannot allocate any buffer, exiting..." -msgstr "E82: ¥Ð¥Ã¥Õ¥¡¤ò1¤Ä¤âºîÀ®¤Ç¤¤Ê¤¤¤Î¤Ç, ½ªÎ»¤·¤Þ¤¹..." +msgstr "E82: ¥Ð¥Ã¥Õ¥¡¤ò1¤Ä¤âºîÀ®¤Ç¤¤Ê¤¤¤Î¤Ç¡¢½ªÎ»¤·¤Þ¤¹..." msgid "E83: Cannot allocate buffer, using other one..." -msgstr "E83: ¥Ð¥Ã¥Õ¥¡¤òºîÀ®¤Ç¤¤Ê¤¤¤Î¤Ç, ¾¤Î¤ò»ÈÍѤ·¤Þ¤¹..." +msgstr "E83: ¥Ð¥Ã¥Õ¥¡¤òºîÀ®¤Ç¤¤Ê¤¤¤Î¤Ç¡¢Â¾¤Î¤ò»ÈÍѤ·¤Þ¤¹..." msgid "E931: Buffer cannot be registered" msgstr "E931: ¥Ð¥Ã¥Õ¥¡¤òÅÐÏ¿¤Ç¤¤Þ¤»¤ó" @@ -97,7 +97,6 @@ msgstr "E90: ºÇ¸å¤Î¥Ð¥Ã¥Õ¥¡¤Ï²òÊü¤Ç¤¤Þ¤»¤ó" msgid "E84: No modified buffer found" msgstr "E84: Êѹ¹¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó" -#. back where we started, didn't find anything. msgid "E85: There is no listed buffer" msgstr "E85: ¥ê¥¹¥Èɽ¼¨¤µ¤ì¤ë¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó" @@ -111,6 +110,18 @@ msgstr "E88: ºÇ½é¤Î¥Ð¥Ã¥Õ¥¡¤è¤êÁ°¤Ø¤Ï°Üư¤Ç¤¤Þ¤»¤ó" msgid "E89: No write since last change for buffer %ld (add ! to override)" msgstr "E89: ¥Ð¥Ã¥Õ¥¡ %ld ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤ÇÊѹ¹¤òÇË´þ)" +msgid "E948: Job still running (add ! to end the job)" +msgstr "E948: ¥¸¥ç¥Ö¤Ï¤Þ¤À¼Â¹ÔÃæ¤Ç¤¹ (! ¤òÄɲäǥ¸¥ç¥Ö¤ò½ªÎ»)" + +msgid "E37: No write since last change (add ! to override)" +msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)" + +msgid "E948: Job still running" +msgstr "E948: ¥¸¥ç¥Ö¤Ï¤Þ¤À¼Â¹ÔÃæ¤Ç¤¹" + +msgid "E37: No write since last change" +msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" + msgid "W14: Warning: List of file names overflow" msgstr "W14: ·Ù¹ð: ¥Õ¥¡¥¤¥ë̾¤Î¥ê¥¹¥È¤¬Ä¹²á¤®¤Þ¤¹" @@ -166,7 +177,6 @@ msgstr "¹Ô %ld (Á´ÂÎ %ld) --%d%%-- col " msgid "[No Name]" msgstr "[̵̾]" -#. must be a help buffer msgid "help" msgstr "¥Ø¥ë¥×" @@ -192,6 +202,12 @@ msgstr "" "\n" "# ¥Ð¥Ã¥Õ¥¡¥ê¥¹¥È:\n" +msgid "E382: Cannot write, 'buftype' option is set" +msgstr "E382: 'buftype' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç½ñ¹þ¤á¤Þ¤»¤ó" + +msgid "[Prompt]" +msgstr "[¥×¥í¥ó¥×¥È]" + msgid "[Scratch]" msgstr "[²¼½ñ¤]" @@ -246,10 +262,10 @@ msgstr "E917: %s() ¤Ë¥³¡¼¥ë¥Ð¥Ã¥¯¤Ï»È¤¨¤Þ¤»¤ó" msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" msgstr "" -"E912: raw ¤ä nl ¥â¡¼¥É¤Î¥Á¥ã¥ó¥Í¥ë¤Ë ch_evalexpr()/ch_sendexpr() ¤Ï»È¤¨¤Þ¤»¤ó" +"E912: raw ¤ä nl ¥â¡¼¥É¤Î¥Á¥ã¥Í¥ë¤Ë ch_evalexpr()/ch_sendexpr() ¤Ï»È¤¨¤Þ¤»¤ó" msgid "E906: not an open channel" -msgstr "E906: ³«¤¤¤Æ¤¤¤Ê¤¤¥Á¥ã¥ó¥Í¥ë¤Ç¤¹" +msgstr "E906: ³«¤¤¤Æ¤¤¤Ê¤¤¥Á¥ã¥Í¥ë¤Ç¤¹" msgid "E920: _io file requires _name to be set" msgstr "E920: _io ¥Õ¥¡¥¤¥ë¤Ï _name ¤ÎÀßÄ꤬ɬÍפǤ¹" @@ -360,7 +376,6 @@ msgstr "E791: ¶õ¤Î¥¡¼¥Þ¥Ã¥×¥¨¥ó¥È¥ê" msgid " Keyword completion (^N^P)" msgstr " ¥¡¼¥ï¡¼¥ÉÊä´° (^N^P)" -#. ctrl_x_mode == 0, ^P/^N compl. msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" msgstr " ^X ¥â¡¼¥É (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" @@ -438,10 +453,6 @@ msgstr "¥Õ¥¡¥¤¥ëÆâ¤Î¥Þ¥Ã¥Á" msgid " Adding" msgstr " ÄɲÃÃæ" -#. showmode might reset the internal line pointers, so it must -#. * be called before line = ml_get(), or when this address is no -#. * longer needed. -- Acevedo. -#. msgid "-- Searching..." msgstr "-- ¸¡º÷Ãæ..." @@ -462,7 +473,6 @@ msgstr "%d ÈÖÌܤγºÅö (Á´³ºÅö %d ¸ÄÃæ)" msgid "match %d" msgstr "%d ÈÖÌܤγºÅö" -#. maximum nesting of lists and dicts msgid "E18: Unexpected characters in :let" msgstr "E18: ͽ´ü¤»¤Ìʸ»ú¤¬ :let ¤Ë¤¢¤ê¤Þ¤·¤¿" @@ -515,7 +525,6 @@ msgstr "E710: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë¥¿¡¼¥²¥Ã¥È¤è¤ê¤â¿¤¤Í×ÁǤ¬¤¢¤ê¤Þ¤¹" msgid "E711: List value has not enough items" msgstr "E711: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë½½Ê¬¤Ê¿ô¤ÎÍ×ÁǤ¬¤¢¤ê¤Þ¤»¤ó" -# msgid "E690: Missing \"in\" after :for" msgstr "E690: :for ¤Î¸å¤Ë \"in\" ¤¬¤¢¤ê¤Þ¤»¤ó" @@ -523,8 +532,6 @@ msgstr "E690: :for ¤Î¸å¤Ë \"in\" ¤¬¤¢¤ê¤Þ¤»¤ó" msgid "E108: No such variable: \"%s\"" msgstr "E108: ¤½¤ÎÊÑ¿ô¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\"" -#. For historic reasons this error is not given for a list or dict. -#. * E.g., the b: dict could be locked/unlocked. #, c-format msgid "E940: Cannot lock or unlock variable %s" msgstr "E940: ÊÑ¿ô %s ¤Ï¥í¥Ã¥¯¤Þ¤¿¤Ï¥¢¥ó¥í¥Ã¥¯¤Ç¤¤Þ¤»¤ó" @@ -535,21 +542,6 @@ msgstr "E743: (¥¢¥ó)¥í¥Ã¥¯¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹" msgid "E109: Missing ':' after '?'" msgstr "E109: '?' ¤Î¸å¤Ë ':' ¤¬¤¢¤ê¤Þ¤»¤ó" -msgid "E691: Can only compare List with List" -msgstr "E691: ¥ê¥¹¥È·¿¤Ï¥ê¥¹¥È·¿¤È¤·¤«Èæ³Ó¤Ç¤¤Þ¤»¤ó" - -msgid "E692: Invalid operation for List" -msgstr "E692: ¥ê¥¹¥È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹" - -msgid "E735: Can only compare Dictionary with Dictionary" -msgstr "E735: ¼½ñ·¿¤Ï¼½ñ·¿¤È¤·¤«Èæ³Ó¤Ç¤¤Þ¤»¤ó" - -msgid "E736: Invalid operation for Dictionary" -msgstr "E736: ¼½ñ·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹" - -msgid "E694: Invalid operation for Funcrefs" -msgstr "E694: ´Ø¿ô»²¾È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹" - msgid "E804: Cannot use '%' with Float" msgstr "E804: '%' ¤òÉâÆ°¾®¿ôÅÀ¿ô¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó" @@ -589,7 +581,7 @@ msgid "E805: Using a Float as a Number" msgstr "E805: ÉâÆ°¾®¿ôÅÀ¿ô¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E703: Using a Funcref as a Number" -msgstr "E703: ´Ø¿ô»²¾È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£" +msgstr "E703: ´Ø¿ô»²¾È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E745: Using a List as a Number" msgstr "E745: ¥ê¥¹¥È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" @@ -601,10 +593,10 @@ msgid "E910: Using a Job as a Number" msgstr "E910: ¥¸¥ç¥Ö¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E913: Using a Channel as a Number" -msgstr "E913: ¥Á¥ã¥ó¥Í¥ë¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£" +msgstr "E913: ¥Á¥ã¥Í¥ë¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E891: Using a Funcref as a Float" -msgstr "E891: ´Ø¿ô»²¾È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£" +msgstr "E891: ´Ø¿ô»²¾È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E892: Using a String as a Float" msgstr "E892: ʸ»úÎó¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" @@ -622,7 +614,7 @@ msgid "E911: Using a Job as a Float" msgstr "E911: ¥¸¥ç¥Ö¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E914: Using a Channel as a Float" -msgstr "E914: ¥Á¥ã¥ó¥Í¥ë¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£" +msgstr "E914: ¥Á¥ã¥Í¥ë¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" msgid "E729: using Funcref as a String" msgstr "E729: ´Ø¿ô»²¾È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹" @@ -676,6 +668,21 @@ msgstr "" "\n" "\tºÇ¸å¤Ë¥»¥Ã¥È¤·¤¿¥¹¥¯¥ê¥×¥È: " +msgid "E691: Can only compare List with List" +msgstr "E691: ¥ê¥¹¥È·¿¤Ï¥ê¥¹¥È·¿¤È¤·¤«Èæ³Ó¤Ç¤¤Þ¤»¤ó" + +msgid "E692: Invalid operation for List" +msgstr "E692: ¥ê¥¹¥È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹" + +msgid "E735: Can only compare Dictionary with Dictionary" +msgstr "E735: ¼½ñ·¿¤Ï¼½ñ·¿¤È¤·¤«Èæ³Ó¤Ç¤¤Þ¤»¤ó" + +msgid "E736: Invalid operation for Dictionary" +msgstr "E736: ¼½ñ·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹" + +msgid "E694: Invalid operation for Funcrefs" +msgstr "E694: ´Ø¿ô»²¾È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹" + msgid "map() argument" msgstr "map() ¤Î°ú¿ô" @@ -698,15 +705,15 @@ msgstr "add() ¤Î°ú¿ô" msgid "E785: complete() can only be used in Insert mode" msgstr "E785: complete() ¤ÏÁÞÆþ¥â¡¼¥É¤Ç¤·¤«ÍøÍѤǤ¤Þ¤»¤ó" -#. -#. * Yes this is ugly, I don't particularly like it either. But doing it -#. * this way has the compelling advantage that translations need not to -#. * be touched at all. See below what 'ok' and 'ync' are used for. -#. msgid "&Ok" msgstr "&Ok" #, c-format +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld ¹Ô: " + +#, c-format msgid "E700: Unknown function: %s" msgstr "E700: ̤ÃΤδؿô¤Ç¤¹: %s" @@ -810,10 +817,22 @@ msgid "E921: Invalid callback argument" msgstr "E921: ̵¸ú¤Ê¥³¡¼¥ë¥Ð¥Ã¥¯°ú¿ô¤Ç¤¹" #, c-format +msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s" +msgstr "<%s>%s%s %d, 16¿Ê¿ô %02x, 8¿Ê¿ô %03o, ¥À¥¤¥°¥é¥Õ %s" + +#, c-format msgid "<%s>%s%s %d, Hex %02x, Octal %03o" msgstr "<%s>%s%s %d, 16¿Ê¿ô %02x, 8¿Ê¿ô %03o" #, c-format +msgid "> %d, Hex %04x, Oct %o, Digr %s" +msgstr "> %d, 16¿Ê¿ô %04x, 8¿Ê¿ô %o, ¥À¥¤¥°¥é¥Õ %s" + +#, c-format +msgid "> %d, Hex %08x, Oct %o, Digr %s" +msgstr "> %d, 16¿Ê¿ô %08x, 8¿Ê¿ô %o, ¥À¥¤¥°¥é¥Õ %s" + +#, c-format msgid "> %d, Hex %04x, Octal %o" msgstr "> %d, 16¿Ê¿ô %04x, 8¿Ê¿ô %o" @@ -846,7 +865,7 @@ msgid "%sviminfo: %s in line: " msgstr "%sviminfo: %s ¹ÔÌÜ: " msgid "E136: viminfo: Too many errors, skipping rest of file" -msgstr "E136: viminfo: ¥¨¥é¡¼¤¬Â¿²á¤®¤ë¤Î¤Ç, °Ê¹ß¤Ï¥¹¥¥Ã¥×¤·¤Þ¤¹" +msgstr "E136: viminfo: ¥¨¥é¡¼¤¬Â¿²á¤®¤ë¤Î¤Ç¡¢°Ê¹ß¤Ï¥¹¥¥Ã¥×¤·¤Þ¤¹" #, c-format msgid "Reading viminfo file \"%s\"%s%s%s" @@ -864,7 +883,6 @@ msgstr " µì¥Õ¥¡¥¤¥ë·²" msgid " FAILED" msgstr " ¼ºÇÔ" -#. avoid a wait_return for this message, it's annoying #, c-format msgid "E137: Viminfo file is not writable: %s" msgstr "E137: viminfo¥Õ¥¡¥¤¥ë¤¬½ñ¹þ¤ß¤Ç¤¤Þ¤»¤ó: %s" @@ -885,7 +903,6 @@ msgstr "viminfo¥Õ¥¡¥¤¥ë \"%s\" ¤ò½ñ¹þ¤ßÃæ" msgid "E886: Can't rename viminfo file to %s!" msgstr "E886: viminfo¥Õ¥¡¥¤¥ë¤ò %s ¤ØÌ¾Á°Êѹ¹¤Ç¤¤Þ¤»¤ó!" -#. Write the info: #, c-format msgid "# This viminfo file was generated by Vim %s.\n" msgstr "# ¤³¤Î viminfo ¥Õ¥¡¥¤¥ë¤Ï Vim %s ¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Þ¤·¤¿.\n" @@ -1004,7 +1021,6 @@ msgstr " (·× 1 ¹ÔÆâ)" msgid " on %ld lines" msgstr " (·× %ld ¹ÔÆâ)" -#. will increment global_busy to break out of the loop msgid "E147: Cannot do :global recursive with a range" msgstr "E147: :global ¤òÈϰÏÉÕ¤¤ÇºÆµ¢Åª¤Ë¤Ï»È¤¨¤Þ¤»¤ó" @@ -1121,6 +1137,14 @@ msgid "Entering Debug mode. Type \"cont\" to continue." msgstr "¥Ç¥Ð¥Ã¥°¥â¡¼¥É¤ËÆþ¤ê¤Þ¤¹. ³¤±¤ë¤Ë¤Ï \"cont\" ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤." #, c-format +msgid "Oldval = \"%s\"" +msgstr "¸Å¤¤ÃÍ = \"%s\"" + +#, c-format +msgid "Newval = \"%s\"" +msgstr "¿·¤·¤¤ÃÍ = \"%s\"" + +#, c-format msgid "line %ld: %s" msgstr "¹Ô %ld: %s" @@ -1150,6 +1174,10 @@ msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" msgid "%3d %s %s line %ld" msgstr "%3d %s %s ¹Ô %ld" +#, c-format +msgid "%3d expr %s" +msgstr "%3d expr %s" + msgid "E750: First use \":profile start {fname}\"" msgstr "E750: ½é¤á¤Ë \":profile start {fname}\" ¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤" @@ -1157,8 +1185,9 @@ msgstr "E750: ½é¤á¤Ë \":profile start {fname}\" ¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤" msgid "Save changes to \"%s\"?" msgstr "Êѹ¹¤ò \"%s\" ¤ËÊݸ¤·¤Þ¤¹¤«?" -msgid "Untitled" -msgstr "̵Âê" +#, c-format +msgid "E947: Job still running in buffer \"%s\"" +msgstr "E947: ¥¸¥ç¥Ö¤Ï¥Ð¥Ã¥Õ¥¡ \"%s\" ¤Ç¤Þ¤À¼Â¹ÔÃæ¤Ç¤¹" #, c-format msgid "E162: No write since last change for buffer \"%s\"" @@ -1293,7 +1322,7 @@ msgid "E493: Backwards range given" msgstr "E493: µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿" msgid "Backwards range given, OK to swap" -msgstr "µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿, ÆþÂØ¤¨¤Þ¤¹¤«?" +msgstr "µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿¡¢ÆþÂØ¤¨¤Þ¤¹¤«?" msgid "E494: Use w or w>>" msgstr "E494: w ¤â¤·¤¯¤Ï w>> ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤" @@ -1304,17 +1333,14 @@ msgstr "" "¤µ¤¤" msgid "E319: Sorry, the command is not available in this version" -msgstr "E319: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ÏÍøÍѤǤ¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤" - -msgid "E172: Only one file name allowed" -msgstr "E172: ¥Õ¥¡¥¤¥ë̾¤Ï 1 ¤Ä¤Ë¤·¤Æ¤¯¤À¤µ¤¤" +msgstr "E319: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ÏÍøÍѤǤ¤Þ¤»¤ó¡¢¤´¤á¤ó¤Ê¤µ¤¤" msgid "1 more file to edit. Quit anyway?" -msgstr "ÊÔ½¸¤¹¤Ù¤¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹¤¬, ½ªÎ»¤·¤Þ¤¹¤«?" +msgstr "ÊÔ½¸¤¹¤Ù¤¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹¤¬¡¢½ªÎ»¤·¤Þ¤¹¤«?" #, c-format msgid "%d more files to edit. Quit anyway?" -msgstr "ÊÔ½¸¤¹¤Ù¤¥Õ¥¡¥¤¥ë¤¬¤¢¤È %d ¸Ä¤¢¤ê¤Þ¤¹¤¬, ½ªÎ»¤·¤Þ¤¹¤«?" +msgstr "ÊÔ½¸¤¹¤Ù¤¥Õ¥¡¥¤¥ë¤¬¤¢¤È %d ¸Ä¤¢¤ê¤Þ¤¹¤¬¡¢½ªÎ»¤·¤Þ¤¹¤«?" msgid "E173: 1 more file to edit" msgstr "E173: ÊÔ½¸¤¹¤Ù¤¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹" @@ -1365,7 +1391,7 @@ msgid "E183: User defined commands must start with an uppercase letter" msgstr "E183: ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó" msgid "E841: Reserved name, cannot be used for user defined command" -msgstr "E841: ͽÌó̾¤Ê¤Î¤Ç, ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤ËÍøÍѤǤ¤Þ¤»¤ó" +msgstr "E841: ͽÌó̾¤Ê¤Î¤Ç¡¢¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤ËÍøÍѤǤ¤Þ¤»¤ó" #, c-format msgid "E184: No such user-defined command: %s" @@ -1401,6 +1427,9 @@ msgstr "E784: ºÇ¸å¤Î¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" msgid "Already only one tab page" msgstr "´û¤Ë¥¿¥Ö¥Ú¡¼¥¸¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó" +msgid "Edit File in new tab page" +msgstr "¿·¤·¤¤¥¿¥Ö¥Ú¡¼¥¸¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹" + msgid "Edit File in new window" msgstr "¿·¤·¤¤¥¦¥£¥ó¥É¥¦¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹" @@ -1416,7 +1445,7 @@ msgstr "Äɲåե¡¥¤¥ë" msgid "E747: Cannot change directory, buffer is modified (add ! to override)" msgstr "" -"E747: ¥Ð¥Ã¥Õ¥¡¤¬½¤Àµ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç, ¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤Ç¤¤Þ¤»¤ó (! ¤òÄɲäÇ" +"E747: ¥Ð¥Ã¥Õ¥¡¤¬½¤Àµ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤Ç¤¤Þ¤»¤ó (! ¤òÄɲäÇ" "¾å½ñ)" msgid "E186: No previous directory" @@ -1466,7 +1495,6 @@ msgstr "E189: \"%s\" ¤¬Â¸ºß¤·¤Þ¤¹ (¾å½ñ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤)" msgid "E190: Cannot open \"%s\" for writing" msgstr "E190: \"%s\" ¤ò½ñ¹þ¤ßÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó" -#. set mark msgid "E191: Argument must be a letter or forward/backward quote" msgstr "E191: °ú¿ô¤Ï1ʸ»ú¤Î±Ñ»ú¤«°úÍÑÉä (' ¤« `) ¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó" @@ -1505,13 +1533,15 @@ msgstr "E500: ¶õʸ»úÎó¤È¤·¤ÆÉ¾²Á¤µ¤ì¤Þ¤·¤¿" msgid "E195: Cannot open viminfo file for reading" msgstr "E195: viminfo¥Õ¥¡¥¤¥ë¤òÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó" +msgid "Untitled" +msgstr "̵Âê" + msgid "E196: No digraphs in this version" msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó" msgid "E608: Cannot :throw exceptions with 'Vim' prefix" msgstr "E608: 'Vim' ¤Ç»Ï¤Þ¤ëÎã³°¤Ï :throw ¤Ç¤¤Þ¤»¤ó" -#. always scroll up, don't overwrite #, c-format msgid "Exception thrown: %s" msgstr "Îã³°¤¬È¯À¸¤·¤Þ¤·¤¿: %s" @@ -1528,7 +1558,6 @@ msgstr "Îã³°¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿: %s" msgid "%s, line %ld" msgstr "%s, ¹Ô %ld" -#. always scroll up, don't overwrite #, c-format msgid "Exception caught: %s" msgstr "Îã³°¤¬Ê᪤µ¤ì¤Þ¤·¤¿: %s" @@ -1554,7 +1583,6 @@ msgstr "¥¨¥é¡¼¤È³ä¹þ¤ß" msgid "Error" msgstr "¥¨¥é¡¼" -#. if (pending & CSTP_INTERRUPT) msgid "Interrupt" msgstr "³ä¹þ¤ß" @@ -1597,15 +1625,12 @@ msgstr "E601: :try ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹" msgid "E603: :catch without :try" msgstr "E603: :try ¤Î¤Ê¤¤ :catch ¤¬¤¢¤ê¤Þ¤¹" -#. Give up for a ":catch" after ":finally" and ignore it. -#. * Just parse. msgid "E604: :catch after :finally" msgstr "E604: :finally ¤Î¸å¤Ë :catch ¤¬¤¢¤ê¤Þ¤¹" msgid "E606: :finally without :try" msgstr "E606: :try ¤Î¤Ê¤¤ :finally ¤¬¤¢¤ê¤Þ¤¹" -#. Give up for a multiple ":finally" and ignore it. msgid "E607: multiple :finally" msgstr "E607: Ê£¿ô¤Î :finally ¤¬¤¢¤ê¤Þ¤¹" @@ -1698,7 +1723,6 @@ msgstr "Vim: ɸ½àÆþÎϤ«¤éÆÉ¹þÃæ...\n" msgid "Reading from stdin..." msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ..." -#. Re-opening the original file failed! msgid "E202: Conversion made file unreadable!" msgstr "E202: ÊÑ´¹¤¬¥Õ¥¡¥¤¥ë¤òÆÉ¹þÉԲĤˤ·¤Þ¤·¤¿" @@ -1787,9 +1811,6 @@ msgstr "E509: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òºî¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ºîÀ®)" msgid "E510: Can't make backup file (add ! to override)" msgstr "E510: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òºî¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ºîÀ®)" -msgid "E460: The resource fork would be lost (add ! to override)" -msgstr "E460: ¥ê¥½¡¼¥¹¥Õ¥©¡¼¥¯¤¬¼º¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©)" - msgid "E214: Can't find temp file for writing" msgstr "E214: ÊݸÍѰì»þ¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó" @@ -1802,25 +1823,25 @@ msgstr "E166: ¥ê¥ó¥¯¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤Ë½ñ¹þ¤á¤Þ¤»¤ó" msgid "E212: Can't open file for writing" msgstr "E212: ½ñ¹þ¤ßÍѤ˥ե¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó" -msgid "E667: Fsync failed" -msgstr "E667: fsync ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿" +msgid "E949: File changed while writing" +msgstr "E949: ½ñ¹þ¤ßÃæ¤Ë¥Õ¥¡¥¤¥ë¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿" msgid "E512: Close failed" msgstr "E512: ÊĤ¸¤ë¤³¤È¤Ë¼ºÇÔ" msgid "E513: write error, conversion failed (make 'fenc' empty to override)" -msgstr "E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ¤¤)" +msgstr "E513: ½ñ¹þ¤ß¥¨¥é¡¼¡¢ÊÑ´¹¼ºÇÔ (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ¤¤)" #, c-format msgid "" "E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ, ¹Ô¿ô %ld (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ" +"E513: ½ñ¹þ¤ß¥¨¥é¡¼¡¢ÊÑ´¹¼ºÇÔ¡¢¹Ô¿ô %ld (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ" "¤¤)" msgid "E514: write error (file system full?)" -msgstr "E514: ½ñ¹þ¤ß¥¨¥é¡¼, (¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬ËþÇÕ?)" +msgstr "E514: ½ñ¹þ¤ß¥¨¥é¡¼ (¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬ËþÇÕ?)" msgid " CONVERSION ERROR" msgstr " ÊÑ´¹¥¨¥é¡¼" @@ -1904,9 +1925,6 @@ msgstr "[noeol]" msgid "[Incomplete last line]" msgstr "[ºÇ½ª¹Ô¤¬ÉÔ´°Á´]" -#. don't overwrite messages here -#. must give this prompt -#. don't use emsg() here, don't want to flush the buffers msgid "WARNING: The file has been changed since reading it!!!" msgstr "·Ù¹ð: ÆÉ¹þ¤ó¤À¸å¤Ë¥Õ¥¡¥¤¥ë¤ËÊѹ¹¤¬¤¢¤ê¤Þ¤·¤¿!!!" @@ -1984,7 +2002,6 @@ msgstr "--ºï½üºÑ--" msgid "auto-removing autocommand: %s <buffer=%d>" msgstr "autocommand: %s <¥Ð¥Ã¥Õ¥¡=%d> ¤¬¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤Þ¤¹" -#. the group doesn't exist #, c-format msgid "E367: No such group: \"%s\"" msgstr "E367: ¤½¤Î¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\"" @@ -2007,13 +2024,12 @@ msgstr "E216: ¤½¤Î¤è¤¦¤Ê¥¤¥Ù¥ó¥È¤Ï¤¢¤ê¤Þ¤»¤ó: %s" msgid "E216: No such group or event: %s" msgstr "E216: ¤½¤Î¤è¤¦¤Ê¥°¥ë¡¼¥×¤â¤·¤¯¤Ï¥¤¥Ù¥ó¥È¤Ï¤¢¤ê¤Þ¤»¤ó: %s" -#. Highlight title msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" #, c-format msgid "E680: <buffer=%d>: invalid buffer number " @@ -2029,8 +2045,8 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: autocommand¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹" #, c-format -msgid "%s Auto commands for \"%s\"" -msgstr "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" +msgstr "%s Autocommands for \"%s\"" #, c-format msgid "Executing %s" @@ -2055,6 +2071,11 @@ msgstr "E350: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤òºîÀ®¤Ç¤¤Þ¤»¤ó" msgid "E351: Cannot delete fold with current 'foldmethod'" msgstr "E351: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤òºï½ü¤Ç¤¤Þ¤»¤ó" +#, c-format +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld ¹Ô¤¬ÀÞ¾ö¤Þ¤ì¤Þ¤·¤¿" + msgid "E222: Add to read buffer" msgstr "E222: ÆÉ¹þ¥Ð¥Ã¥Õ¥¡¤ØÄɲÃ" @@ -2100,7 +2121,7 @@ msgid "E230: Cannot read from \"%s\"" msgstr "E230: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤¤Þ¤»¤ó" msgid "E665: Cannot start GUI, no valid font found" -msgstr "E665: ͸ú¤Ê¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¤Î¤Ç, GUI¤ò³«»Ï¤Ç¤¤Þ¤»¤ó" +msgstr "E665: ͸ú¤Ê¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¤Î¤Ç¡¢GUI¤ò³«»Ï¤Ç¤¤Þ¤»¤ó" msgid "E231: 'guifontwide' invalid" msgstr "E231: 'guifontwide' ¤¬Ìµ¸ú¤Ç¤¹" @@ -2113,7 +2134,7 @@ msgid "E254: Cannot allocate color %s" msgstr "E254: %s ¤Î¿§¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó" msgid "No match at cursor, finding next" -msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó, ¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹" +msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó¡¢¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹" msgid "<cannot open> " msgstr "<³«¤±¤Þ¤»¤ó> " @@ -2188,18 +2209,15 @@ msgstr "¸¡º÷ʸ»úÎó:" msgid "Replace with:" msgstr "ÃÖ´¹Ê¸»úÎó:" -#. whole word only button msgid "Match whole word only" msgstr "Àµ³Î¤Ë³ºÅö¤¹¤ë¤â¤Î¤À¤±" -#. match case button msgid "Match case" msgstr "Âçʸ»ú/¾®Ê¸»ú¤ò¶èÊ̤¹¤ë" msgid "Direction" msgstr "Êý¸þ" -#. 'Up' and 'Down' buttons msgid "Up" msgstr "¾å" @@ -2272,14 +2290,12 @@ msgstr "¥¢¥ó¥É¥¥(&U)" msgid "Open tab..." msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯" -msgid "Find string (use '\\\\' to find a '\\')" +msgid "Find string (use '\\\\' to find a '\\')" msgstr "¸¡º÷ʸ»úÎó ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')" -msgid "Find & Replace (use '\\\\' to find a '\\')" +msgid "Find & Replace (use '\\\\' to find a '\\')" msgstr "¸¡º÷¡¦ÃÖ´¹ ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')" -#. We fake this: Use a filter that doesn't select anything and a default -#. * file name that won't be used. msgid "Not Used" msgstr "»È¤ï¤ì¤Þ¤»¤ó" @@ -2351,7 +2367,6 @@ msgstr "Vim - ¥Õ¥©¥ó¥ÈÁªÂò" msgid "Name:" msgstr "̾Á°:" -#. create toggle button msgid "Show size in Points" msgstr "¥µ¥¤¥º¤ò¥Ý¥¤¥ó¥È¤Çɽ¼¨¤¹¤ë" @@ -2597,7 +2612,6 @@ msgstr "E261: cscopeÀܳ %s ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿" msgid "cscope connection %s closed" msgstr "cscopeÀܳ %s ¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿" -#. should not reach here msgid "E570: fatal error in cs_manage_matches" msgstr "E570: cs_manage_matches ¤ÇÃ×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹" @@ -2643,8 +2657,8 @@ msgid "" "E895: Sorry, this command is disabled, the MzScheme's racket/base module " "could not be loaded." msgstr "" -"E895: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤. MzScheme ¤Î racket/base ¥â¥¸¥å¡¼¥ë" -"¤¬¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿." +"E895: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤. MzScheme ¤Î racket/base ¥â¥¸¥å¡¼" +"¥ë¤¬¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿." msgid "invalid expression" msgstr "̵¸ú¤Ê¼°¤Ç¤¹" @@ -2697,6 +2711,19 @@ msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹" msgid "not allowed in the Vim sandbox" msgstr "¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: ¥é¥¤¥Ö¥é¥ê %s ¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿" + +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Perl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿." + +msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +msgstr "" +"E299: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ï Safe ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Ê¤¤Perl¥¹¥¯¥ê¥×¥È¤Ï¶Ø¤¸¤é¤ì" +"¤Æ¤¤¤Þ¤¹" + msgid "E836: This Vim cannot execute :python after using :py3" msgstr "E836: ¤³¤ÎVim¤Ç¤Ï :py3 ¤ò»È¤Ã¤¿¸å¤Ë :python ¤ò»È¤¨¤Þ¤»¤ó" @@ -2704,14 +2731,14 @@ msgid "" "E263: Sorry, this command is disabled, the Python library could not be " "loaded." msgstr "" -"E263: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Python¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó" -"¤Ç¤·¤¿." +"E263: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Python¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»" +"¤ó¤Ç¤·¤¿." msgid "" "E887: Sorry, this command is disabled, the Python's site module could not be " "loaded." msgstr "" -"E887: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤. Python ¤Î site ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É" +"E887: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤. Python ¤Î site ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É" "¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿." # Added at 07-Feb-2004. @@ -2727,8 +2754,8 @@ msgstr "E265: $_ ¤Ïʸ»úÎó¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó" msgid "" "E266: Sorry, this command is disabled, the Ruby library could not be loaded." msgstr "" -"E266: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Ruby¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç" -"¤·¤¿." +"E266: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Ruby¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó" +"¤Ç¤·¤¿." msgid "E267: unexpected return" msgstr "E267: ͽ´ü¤»¤Ì return ¤Ç¤¹" @@ -2758,7 +2785,6 @@ msgstr "̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹" msgid "not implemented yet" msgstr "¤Þ¤À¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" -#. ??? msgid "cannot set line(s)" msgstr "¹Ô¤òÀßÄê¤Ç¤¤Þ¤»¤ó" @@ -2800,7 +2826,6 @@ msgid "" msgstr "" "¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¾Ãµî¤µ¤ì¤Þ¤·¤¿" -#. This should never happen. Famous last word? msgid "" "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim." "org" @@ -2815,7 +2840,7 @@ msgstr "" msgid "" "E571: Sorry, this command is disabled: the Tcl library could not be loaded." msgstr "" -"E571: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Tcl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç" +"E571: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Tcl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç" "¤·¤¿." #, c-format @@ -2902,7 +2927,6 @@ msgstr "Vim: ·Ù¹ð: üËö¤Ø¤Î½ÐÎϤǤϤ¢¤ê¤Þ¤»¤ó\n" msgid "Vim: Warning: Input is not from a terminal\n" msgstr "Vim: ·Ù¹ð: üËö¤«¤é¤ÎÆþÎϤǤϤ¢¤ê¤Þ¤»¤ó\n" -#. just in case.. msgid "pre-vimrc command line" msgstr "vimrcÁ°¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó" @@ -2932,7 +2956,7 @@ msgstr "-q [errorfile] ºÇ½é¤Î¥¨¥é¡¼¤ÇÊÔ½¸¤¹¤ë" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -2998,7 +3022,7 @@ msgid "-d\t\t\tDiff mode (like \"vimdiff\")" msgstr "-d\t\t\tº¹Ê¬¥â¡¼¥É (\"vidiff\" ¤ÈƱ¤¸)" msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" -msgstr "-y\t\t\t¥¤¡¼¥¸¡¼¥â¡¼¥É (\"evim\" ¤ÈƱ¤¸, ¥â¡¼¥É̵)" +msgstr "-y\t\t\t¥¤¡¼¥¸¡¼¥â¡¼¥É (\"evim\" ¤ÈƱ¤¸¡¢¥â¡¼¥É̵)" msgid "-R\t\t\tReadonly mode (like \"view\")" msgstr "-R\t\t\tÆÉ¹þÀìÍѥ⡼¥É (\"view\" ¤ÈƱ¤¸)" @@ -3048,7 +3072,7 @@ msgstr "-f\t\t\t¥¦¥£¥ó¥É¥¦¤ò³«¤¯¤Î¤Ë newcli ¤ò»ÈÍѤ·¤Ê¤¤" msgid "-dev <device>\t\tUse <device> for I/O" msgstr "-dev <device>\t\tI/O¤Ë <device> ¤ò»ÈÍѤ¹¤ë" -msgid "-A\t\t\tstart in Arabic mode" +msgid "-A\t\t\tStart in Arabic mode" msgstr "-A\t\t\t¥¢¥é¥Ó¥¢¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë" msgid "-H\t\t\tStart in Hebrew mode" @@ -3121,7 +3145,7 @@ msgid "--remote <files>\tEdit <files> in a Vim server if possible" msgstr "--remote <files>\t²Äǽ¤Ê¤é¤ÐVim¥µ¡¼¥Ð¡¼¤Ç <files> ¤òÊÔ½¸¤¹¤ë" msgid "--remote-silent <files> Same, don't complain if there is no server" -msgstr "--remote-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤" +msgstr "--remote-silent <files> Ʊ¾å¡¢¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤" msgid "" "--remote-wait <files> As --remote but wait for files to have been edited" @@ -3130,7 +3154,7 @@ msgstr "--remote-wait <files>\t--remote¸å ¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¤¬½ª¤ï¤ë¤Î¤òÂÔ¤Ä" msgid "" "--remote-wait-silent <files> Same, don't complain if there is no server" msgstr "" -"--remote-wait-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤" +"--remote-wait-silent <files> Ʊ¾å¡¢¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤" msgid "" "--remote-tab[-wait][-silent] <files> As --remote but use tab page per file" @@ -3156,8 +3180,11 @@ msgstr "--startuptime <file>\tµ¯Æ°¤Ë¤«¤«¤Ã¤¿»þ´Ö¤Î¾ÜºÙ¤ò <file> ¤Ø½ÐÎϤ¹¤ë" msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo" msgstr "-i <viminfo>\t\t.viminfo¤ÎÂå¤ï¤ê¤Ë <viminfo> ¤ò»È¤¦" +msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo" +msgstr "--clean\t\t'nocompatible'¡¢Vim¤Î´ûÄê¡¢¥×¥é¥°¥¤¥ó¤Ê¤·¡¢viminfo¤Ê¤·" + msgid "-h or --help\tPrint Help (this message) and exit" -msgstr "-h or --help\t¥Ø¥ë¥×(¤³¤Î¥á¥Ã¥»¡¼¥¸)¤òɽ¼¨¤·½ªÎ»¤¹¤ë" +msgstr "-h or --help\t¥Ø¥ë¥×(¤³¤Î¥á¥Ã¥»¡¼¥¸)¤òɽ¼¨¤·½ªÎ»¤¹¤ë" msgid "--version\t\tPrint version information and exit" msgstr "--version\t\t¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤òɽ¼¨¤·½ªÎ»¤¹¤ë" @@ -3254,11 +3281,9 @@ msgstr "--windowid <HWND>\t°Û¤Ê¤ëWin32 widget¤ÎÆâÉô¤ËVim¤ò³«¤¯" msgid "No display" msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó" -#. Failed to send, abort. msgid ": Send failed.\n" msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n" -#. Let vim start normally. msgid ": Send failed. Trying to execute locally\n" msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿. ¥í¡¼¥«¥ë¤Ç¤Î¼Â¹Ô¤ò»î¤ß¤Æ¤¤¤Þ¤¹\n" @@ -3279,7 +3304,6 @@ msgstr "¥Þ¡¼¥¯¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó" msgid "E283: No marks matching \"%s\"" msgstr "E283: \"%s\" ¤Ë³ºÅö¤¹¤ë¥Þ¡¼¥¯¤¬¤¢¤ê¤Þ¤»¤ó" -#. Highlight title msgid "" "\n" "mark line col file/text" @@ -3287,7 +3311,6 @@ msgstr "" "\n" "mark ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥¥¹¥È" -#. Highlight title msgid "" "\n" " jump line col file/text" @@ -3295,7 +3318,6 @@ msgstr "" "\n" " jump ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥¥¹¥È" -#. Highlight title msgid "" "\n" "change line col text" @@ -3310,7 +3332,6 @@ msgstr "" "\n" "# ¥Õ¥¡¥¤¥ë¥Þ¡¼¥¯:\n" -#. Write the jumplist with -' msgid "" "\n" "# Jumplist (newest first):\n" @@ -3379,9 +3400,8 @@ msgstr "E298: ¥Ö¥í¥Ã¥¯ 2 ¤ò¼èÆÀ¤Ç¤¤Þ¤»¤ó?" msgid "E843: Error while updating swap file crypt" msgstr "E843: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î°Å¹æ¤ò¹¹¿·Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿" -#. could not (re)open the swap file, what can we do???? msgid "E301: Oops, lost the swap file!!!" -msgstr "E301: ¤ª¤Ã¤È, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤Þ¤·¤¿!!!" +msgstr "E301: ¤ª¤Ã¤È¡¢¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤Þ¤·¤¿!!!" msgid "E302: Could not rename swap file" msgstr "E302: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÊѤ¨¤é¤ì¤Þ¤»¤ó" @@ -3466,7 +3486,7 @@ msgid "" "If you entered a new crypt key but did not write the text file," msgstr "" "\n" -"¿·¤·¤¤°Å¹æ¥¡¼¤òÆþÎϤ·¤¿¤¢¤È¤Ë¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï," +"¿·¤·¤¤°Å¹æ¥¡¼¤òÆþÎϤ·¤¿¤¢¤È¤Ë¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢" msgid "" "\n" @@ -3480,7 +3500,7 @@ msgid "" "If you wrote the text file after changing the crypt key press enter" msgstr "" "\n" -"°Å¹æ¥¡¼¤òÊѤ¨¤¿¤¢¤È¤Ë¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤¿¾ì¹ç¤Ï, ¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤È" +"°Å¹æ¥¡¼¤òÊѤ¨¤¿¤¢¤È¤Ë¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤¿¾ì¹ç¤Ï¡¢¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤È" msgid "" "\n" @@ -3540,7 +3560,7 @@ msgid "" "(You might want to write out this file under another name\n" msgstr "" "\n" -"(Êѹ¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤¿¤á¤Ë, ¤³¤Î¥Õ¥¡¥¤¥ë¤òÊ̤Î̾Á°¤ÇÊݸ¤·¤¿¾å¤Ç\n" +"(Êѹ¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤¿¤á¤Ë¡¢¤³¤Î¥Õ¥¡¥¤¥ë¤òÊ̤Î̾Á°¤ÇÊݸ¤·¤¿¾å¤Ç\n" msgid "and run diff with the original file to check for changes)" msgstr "¸¶ËÜ¥Õ¥¡¥¤¥ë¤È¤Î diff ¤ò¼Â¹Ô¤¹¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦)" @@ -3560,7 +3580,6 @@ msgstr "" msgid "Using crypt key from swap file for the text file.\n" msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¼èÆÀ¤·¤¿°Å¹æ¥¡¼¤ò¥Æ¥¥¹¥È¥Õ¥¡¥¤¥ë¤Ë»È¤¤¤Þ¤¹.\n" -#. use msg() to start the scrolling properly msgid "Swap files found:" msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ê£¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿:" @@ -3730,8 +3749,6 @@ msgstr "¼¡¤Î¥Õ¥¡¥¤¥ë¤ò³«¤¤¤Æ¤¤¤ëºÇÃæ \"" msgid " NEWER than swap file!\n" msgstr " ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤è¤ê¤â¿·¤·¤¤¤Ç¤¹!\n" -#. Some of these messages are long to allow translation to -#. * other languages. msgid "" "\n" "(1) Another program may be editing the same file. If this is the case,\n" @@ -3740,9 +3757,9 @@ msgid "" msgstr "" "\n" "(1) ÊÌ¤Î¥×¥í¥°¥é¥à¤¬Æ±¤¸¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó.\n" -" ¤³¤Î¾ì¹ç¤Ë¤Ï, Êѹ¹¤ò¤·¤Æ¤·¤Þ¤¦¤È1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ°Û¤Ê¤ë2¤Ä¤Î\n" -" ¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤¤Æ¤·¤Þ¤¦¤Î¤Ç, ¤½¤¦¤·¤Ê¤¤¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤.\n" -" ½ªÎ»¤¹¤ë¤«, Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\n" +" ¤³¤Î¾ì¹ç¤Ë¤Ï¡¢Êѹ¹¤ò¤·¤Æ¤·¤Þ¤¦¤È1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ°Û¤Ê¤ë2¤Ä¤Î\n" +" ¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤¤Æ¤·¤Þ¤¦¤Î¤Ç¡¢¤½¤¦¤·¤Ê¤¤¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤.\n" +" ½ªÎ»¤¹¤ë¤«¡¢Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\n" msgid "(2) An edit session for this file crashed.\n" msgstr "(2) ¤³¤Î¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¥»¥Ã¥·¥ç¥ó¤¬¥¯¥é¥Ã¥·¥å¤·¤¿.\n" @@ -3758,7 +3775,7 @@ msgstr "" " ¤ò»ÈÍѤ·¤ÆÊѹ¹¤ò¥ê¥«¥Ð¡¼¤·¤Þ¤¹(\":help recovery\" ¤ò»²¾È).\n" msgid " If you did this already, delete the swap file \"" -msgstr " ´û¤Ë¤³¤ì¤ò¹Ô¤Ê¤Ã¤¿¤Î¤Ê¤é¤Ð, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"" +msgstr " ´û¤Ë¤³¤ì¤ò¹Ô¤Ê¤Ã¤¿¤Î¤Ê¤é¤Ð¡¢¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"" msgid "" "\"\n" @@ -3820,7 +3837,6 @@ msgstr "E328: ¥á¥Ë¥å¡¼¤Ï¾¤Î¥â¡¼¥É¤Ë¤À¤±¤¢¤ê¤Þ¤¹" msgid "E329: No menu \"%s\"" msgstr "E329: \"%s\" ¤È¤¤¤¦¥á¥Ë¥å¡¼¤Ï¤¢¤ê¤Þ¤»¤ó" -#. Only a mnemonic or accelerator is not valid. msgid "E792: Empty menu name" msgstr "E792: ¥á¥Ë¥å¡¼Ì¾¤¬¶õ¤Ç¤¹" @@ -3833,8 +3849,6 @@ msgstr "E331: ¥á¥Ë¥å¡¼¥Ð¡¼¤Ë¤ÏľÀÜ¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÄɲäǤ¤Þ¤»¤ó" msgid "E332: Separator cannot be part of a menu path" msgstr "E332: ¶èÀÚ¤ê¤Ï¥á¥Ë¥å¡¼¥Ñ¥¹¤Î°ìÉô¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó" -#. Now we have found the matching menu, and we list the mappings -#. Highlight title msgid "" "\n" "--- Menus ---" @@ -3845,6 +3859,10 @@ msgstr "" msgid "Tear off this menu" msgstr "¤³¤Î¥á¥Ë¥å¡¼¤òÀÚ¤ê¼è¤ë" +#, c-format +msgid "E335: Menu not defined for %s mode" +msgstr "E335: %s ¤Ë¤Ï¥á¥Ë¥å¡¼¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" + msgid "E333: Menu path must lead to a menu item" msgstr "E333: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó" @@ -3852,10 +3870,6 @@ msgstr "E333: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó" msgid "E334: Menu not found: %s" msgstr "E334: ¥á¥Ë¥å¡¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s" -#, c-format -msgid "E335: Menu not defined for %s mode" -msgstr "E335: %s ¤Ë¤Ï¥á¥Ë¥å¡¼¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" - msgid "E336: Menu path must lead to a sub-menu" msgstr "E336: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥µ¥Ö¥á¥Ë¥å¡¼¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó" @@ -3925,9 +3939,8 @@ msgstr "¥Õ¥¡¥¤¥ëÊݸ¥À¥¤¥¢¥í¥°" msgid "Open File dialog" msgstr "¥Õ¥¡¥¤¥ëÆÉ¹þ¥À¥¤¥¢¥í¥°" -#. TODO: non-GUI file selector here msgid "E338: Sorry, no file browser in console mode" -msgstr "E338: ¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤Ç¤Ï¥Õ¥¡¥¤¥ë¥Ö¥é¥¦¥¶¤ò»È¤¨¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤" +msgstr "E338: ¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤Ç¤Ï¥Õ¥¡¥¤¥ë¥Ö¥é¥¦¥¶¤ò»È¤¨¤Þ¤»¤ó¡¢¤´¤á¤ó¤Ê¤µ¤¤" msgid "E766: Insufficient arguments for printf()" msgstr "E766: printf() ¤Î°ú¿ô¤¬ÉÔ½½Ê¬¤Ç¤¹" @@ -4125,7 +4138,6 @@ msgstr "%ld ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ " msgid "E748: No previously used register" msgstr "E748: ¤Þ¤À¥ì¥¸¥¹¥¿¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó" -#. must display the prompt msgid "cannot yank; delete anyway" msgstr "¥ä¥ó¥¯¤Ç¤¤Þ¤»¤ó; ¤È¤Ë¤«¤¯¾Ãµî" @@ -4140,25 +4152,30 @@ msgstr "%ld ¹Ô¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿" msgid "freeing %ld lines" msgstr "%ld ¹Ô¤ò²òÊüÃæ" -msgid "block of 1 line yanked" -msgstr "1 ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" +#, c-format +msgid " into \"%c" +msgstr " \"%c ¤Ë" -msgid "1 line yanked" -msgstr "1 ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" +#, c-format +msgid "block of 1 line yanked%s" +msgstr "1 ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" + +#, c-format +msgid "1 line yanked%s" +msgstr "1 ¹Ô¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" #, c-format -msgid "block of %ld lines yanked" -msgstr "%ld ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" +msgid "block of %ld lines yanked%s" +msgstr "%ld ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" #, c-format -msgid "%ld lines yanked" -msgstr "%ld ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" +msgid "%ld lines yanked%s" +msgstr "%ld ¹Ô¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿" #, c-format msgid "E353: Nothing in register %s" msgstr "E353: ¥ì¥¸¥¹¥¿ %s ¤Ë¤Ï²¿¤â¤¢¤ê¤Þ¤»¤ó" -#. Highlight title msgid "" "\n" "--- Registers ---" @@ -4213,11 +4230,8 @@ msgstr "" "%lld" #, c-format -msgid "(+%ld for BOM)" -msgstr "(+%ld for BOM)" - -msgid "%<%f%h%m%=Page %N" -msgstr "%<%f%h%m%=%N ¥Ú¡¼¥¸" +msgid "(+%lld for BOM)" +msgstr "(+%lld for BOM)" msgid "Thanks for flying Vim" msgstr "Vim ¤ò»È¤Ã¤Æ¤¯¤ì¤Æ¤¢¤ê¤¬¤È¤¦" @@ -4269,6 +4283,10 @@ msgstr "E835: 'fillchars'¤ÎÃͤËÌ·½â¤¬¤¢¤ê¤Þ¤¹" msgid "E617: Cannot be changed in the GTK+ 2 GUI" msgstr "E617: GTK+2 GUI¤Ç¤ÏÊѹ¹¤Ç¤¤Þ¤»¤ó" +#, c-format +msgid "E950: Cannot convert between %s and %s" +msgstr "E950: %s ¤È %s ¤Î´Ö¤ÇÊÑ´¹¤Ç¤¤Þ¤»¤ó" + msgid "E524: Missing colon" msgstr "E524: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó" @@ -4326,12 +4344,18 @@ msgstr "E541: Í×ÁǤ¬Â¿²á¤®¤Þ¤¹" msgid "E542: unbalanced groups" msgstr "E542: ¥°¥ë¡¼¥×¤¬Äà¹ç¤¤¤Þ¤»¤ó" +msgid "E946: Cannot make a terminal with running job modifiable" +msgstr "E946: ¼Â¹ÔÃæ¤Î¥¸¥ç¥Ö¤¬¤¢¤ëüËö¤ÏÊѹ¹²Äǽ¤Ë¤Ç¤¤Þ¤»¤ó" + msgid "E590: A preview window already exists" msgstr "E590: ¥×¥ì¥Ó¥å¡¼¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¸ºß¤·¤Þ¤¹" msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'" msgstr "" -"W17: ¥¢¥é¥Ó¥¢Ê¸»ú¤Ë¤ÏUTF-8¤¬É¬ÍפʤΤÇ, ':set encoding=utf-8' ¤·¤Æ¤¯¤À¤µ¤¤" +"W17: ¥¢¥é¥Ó¥¢Ê¸»ú¤Ë¤ÏUTF-8¤¬É¬ÍפʤΤǡ¢':set encoding=utf-8' ¤·¤Æ¤¯¤À¤µ¤¤" + +msgid "E954: 24-bit colors are not supported on this environment" +msgstr "E954: 24bit¿§¤Ï¤³¤Î´Ä¶¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" #, c-format msgid "E593: Need at least %d lines" @@ -4345,9 +4369,6 @@ msgstr "E594: ºÇÄã %d ¤Î¥«¥é¥àÉý¤¬É¬ÍפǤ¹" msgid "E355: Unknown option: %s" msgstr "E355: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹: %s" -#. There's another character after zeros or the string -#. * is empty. In both cases, we are trying to set a -#. * num option using a string. #, c-format msgid "E521: Number required: &%s = '%s'" msgstr "E521: ¿ô»ú¤¬É¬ÍפǤ¹: &%s = '%s'" @@ -4420,7 +4441,6 @@ msgstr "¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤òÊѹ¹¤Ç¤¤Þ¤»¤ó?!\n" msgid "mch_get_shellsize: not a console??\n" msgstr "mch_get_shellsize: ¥³¥ó¥½¡¼¥ë¤Ç¤Ï¤Ê¤¤??\n" -#. if Vim opened a window: Executing a shell may cause crashes msgid "E360: Cannot execute shell with -f option" msgstr "E360: -f ¥ª¥×¥·¥ç¥ó¤Ç¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤¤Þ¤»¤ó" @@ -4621,6 +4641,9 @@ msgstr "Vim¤Î·Ù¹ð" msgid "shell returned %d" msgstr "¥·¥§¥ë¤¬¥³¡¼¥É %d ¤Ç½ªÎ»¤·¤Þ¤·¤¿" +msgid "E926: Current location list was changed" +msgstr "E926: ¸½ºß¤Î¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿" + #, c-format msgid "E372: Too many %%%c in format string" msgstr "E372: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë %%%c ¤¬Â¿²á¤®¤Þ¤¹" @@ -4644,7 +4667,6 @@ msgstr "E376: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ÎÁ°ÃÖ¤Ë̵¸ú¤Ê %%%c ¤¬¤¢¤ê¤Þ¤¹" msgid "E377: Invalid %%%c in format string" msgstr "E377: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë̵¸ú¤Ê %%%c ¤¬¤¢¤ê¤Þ¤¹" -#. nothing found msgid "E378: 'errorformat' contains no pattern" msgstr "E378: 'errorformat' ¤Ë¥Ñ¥¿¡¼¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó" @@ -4660,9 +4682,6 @@ msgstr "E924: ¸½ºß¤Î¥¦¥£¥ó¥É¥¦¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿" msgid "E925: Current quickfix was changed" msgstr "E925: ¸½ºß¤Î quickfix ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿" -msgid "E926: Current location list was changed" -msgstr "E926: ¸½ºß¤Î¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿" - #, c-format msgid "(%d of %d)%s%s: " msgstr "(%d of %d)%s%s: " @@ -4683,9 +4702,6 @@ msgstr "E381: quickfix ¥¹¥¿¥Ã¥¯¤ÎÀèÆ¬¤Ç¤¹" msgid "No entries" msgstr "¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó" -msgid "E382: Cannot write, 'buftype' option is set" -msgstr "E382: 'buftype' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç½ñ¹þ¤ß¤Þ¤»¤ó" - msgid "Error file" msgstr "¥¨¥é¡¼¥Õ¥¡¥¤¥ë" @@ -4706,7 +4722,6 @@ msgstr "E777: ʸ»úÎ󤫥ꥹ¥È¤¬É¬ÍפǤ¹" msgid "E369: invalid item in %s%%[]" msgstr "E369: ̵¸ú¤Ê¹àÌܤǤ¹: %s%%[]" -# #, c-format msgid "E769: Missing ] after %s[" msgstr "E769: %s[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó" @@ -4729,15 +4744,12 @@ msgstr "E54: %s( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó" msgid "E55: Unmatched %s)" msgstr "E55: %s) ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó" -# msgid "E66: \\z( not allowed here" msgstr "E66: \\z( ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" -# -msgid "E67: \\z1 et al. not allowed here" -msgstr "E67: \\z1 ¤½¤Î¾¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" +msgid "E67: \\z1 - \\z9 not allowed here" +msgstr "E67: \\z1 - \\z9 ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" -# #, c-format msgid "E69: Missing ] after %s%%[" msgstr "E69: %s%%[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó" @@ -4746,7 +4758,9 @@ msgstr "E69: %s%%[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó" msgid "E70: Empty %s%%[]" msgstr "E70: %s%%[] ¤¬¶õ¤Ç¤¹" -# +msgid "E956: Cannot use pattern recursively" +msgstr "E956: ¥Ñ¥¿¡¼¥ó¤òºÆµ¢Åª¤Ë»È¤¦¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" + msgid "E65: Illegal back reference" msgstr "E65: ÉÔÀµ¤Ê¸åÊý»²¾È¤Ç¤¹" @@ -4779,7 +4793,6 @@ msgstr "E61:%s* ¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹" msgid "E62: Nested %s%c" msgstr "E62:%s%c ¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹" -# msgid "E63: invalid use of \\_" msgstr "E63: \\_ ¤Î̵¸ú¤Ê»ÈÍÑÊýË¡¤Ç¤¹" @@ -4787,16 +4800,13 @@ msgstr "E63: \\_ ¤Î̵¸ú¤Ê»ÈÍÑÊýË¡¤Ç¤¹" msgid "E64: %s%c follows nothing" msgstr "E64:%s%c ¤Î¸å¤Ë¤Ê¤Ë¤â¤¢¤ê¤Þ¤»¤ó" -# msgid "E68: Invalid character after \\z" msgstr "E68: \\z ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿" -# #, c-format msgid "E678: Invalid character after %s%%[dxouU]" msgstr "E678: %s%%[dxouU] ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿" -# #, c-format msgid "E71: Invalid character after %s%%" msgstr "E71: %s%% ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿" @@ -4829,7 +4839,6 @@ msgstr "E865: (NFA) ´üÂÔ¤è¤êÁ᤯Àµµ¬É½¸½¤Î½ªÃ¼¤ËÅþ㤷¤Þ¤·¤¿" msgid "E866: (NFA regexp) Misplaced %c" msgstr "E866: (NFA Àµµ¬É½¸½) °ÌÃÖ¤¬¸í¤Ã¤Æ¤¤¤Þ¤¹: %c" -# #, c-format msgid "E877: (NFA regexp) Invalid character class: %ld" msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹: %ld" @@ -4838,11 +4847,13 @@ msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹: %ld" msgid "E867: (NFA) Unknown operator '\\z%c'" msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\z%c'" +msgid "E951: \\% value too large" +msgstr "E951: \\% Ãͤ¬Ä¹²á¤®¤Þ¤¹" + #, c-format msgid "E867: (NFA) Unknown operator '\\%%%c'" msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\%%%c'" -#. should never happen msgid "E868: Error building NFA with equivalence class!" msgstr "E868: Åù²Á¥¯¥é¥¹¤ò´Þ¤àNFA¹½Ãۤ˼ºÇÔ¤·¤Þ¤·¤¿!" @@ -4853,11 +4864,9 @@ msgstr "E869: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\@%c'" msgid "E870: (NFA regexp) Error reading repetition limits" msgstr "E870: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤·¤ÎÀ©¸Â²ó¿ô¤òÆÉ¹þÃæ¤Ë¥¨¥é¡¼" -#. Can't have a multi follow a multi. -msgid "E871: (NFA regexp) Can't have a multi follow a multi !" -msgstr "E871: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤· ¤Î¸å¤Ë ·«¤êÊÖ¤· ¤Ï¤Ç¤¤Þ¤»¤ó!" +msgid "E871: (NFA regexp) Can't have a multi follow a multi" +msgstr "E871: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤· ¤Î¸å¤Ë ·«¤êÊÖ¤· ¤Ï¤Ç¤¤Þ¤»¤ó" -#. Too many `(' msgid "E872: (NFA regexp) Too many '('" msgstr "E872: (NFA Àµµ¬É½¸½) '(' ¤¬Â¿²á¤®¤Þ¤¹" @@ -4867,7 +4876,12 @@ msgstr "E879: (NFA Àµµ¬É½¸½) \\z( ¤¬Â¿²á¤®¤Þ¤¹" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (NFA Àµµ¬É½¸½) ½ªÃ¼µ¹æ¤¬¤¢¤ê¤Þ¤»¤ó" -msgid "E874: (NFA) Could not pop the stack !" +msgid "Could not open temporary log file for writing, displaying on stderr... " +msgstr "" +"NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£¥í¥°¤Ïɸ½à¥¨¥é¡¼" +"½ÐÎϤ˽ÐÎϤ·¤Þ¤¹¡£" + +msgid "E874: (NFA) Could not pop the stack!" msgstr "E874: (NFA) ¥¹¥¿¥Ã¥¯¤ò¥Ý¥Ã¥×¤Ç¤¤Þ¤»¤ó!" msgid "" @@ -4883,19 +4897,6 @@ msgstr "E876: (NFA Àµµ¬É½¸½) NFAÁ´ÂΤòÊݸ¤¹¤ë¤Ë¤Ï¶õ¤¥¹¥Ú¡¼¥¹¤¬Â¤ê¤Þ¤»¤ó" msgid "E878: (NFA) Could not allocate memory for branch traversal!" msgstr "E878: (NFA) ¸½ºß²£ÃÇÃæ¤Î¥Ö¥é¥ó¥Á¤Ë½½Ê¬¤Ê¥á¥â¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó!" -msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " -msgstr "" -"NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£¥í¥°¤Ïɸ½à½ÐÎϤË" -"½ÐÎϤ·¤Þ¤¹¡£" - -#, c-format -msgid "(NFA) COULD NOT OPEN %s !" -msgstr "(NFA) ¥í¥°¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó!" - -msgid "Could not open temporary log file for writing " -msgstr "NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£" - msgid " VREPLACE" msgstr " ²¾ÁÛÃÖ´¹" @@ -4965,7 +4966,6 @@ msgstr "E386: ';' ¤Î¤¢¤È¤Ë¤Ï '?' ¤« '/' ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë" msgid " (includes previously listed match)" msgstr " (Á°¤ËÎóµó¤·¤¿³ºÅö²Õ½ê¤ò´Þ¤à)" -#. cursor at status line msgid "--- Included files " msgstr "--- ¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë " @@ -4987,7 +4987,7 @@ msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥¹¥¥ã¥óÃæ: %s" #, c-format msgid "Searching included file %s" -msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥¹¥¥ã¥óÃæ %s" +msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¸¡º÷Ãæ %s" msgid "E387: Match is on current line" msgstr "E387: ¸½ºß¹Ô¤Ë³ºÅö¤¬¤¢¤ê¤Þ¤¹" @@ -5038,14 +5038,12 @@ msgid "Warning: region %s not supported" msgstr "·Ù¹ð9: %s ¤È¤¤¤¦ÈϰϤϥµ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" msgid "Sorry, no suggestions" -msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó" +msgstr "»Äǰ¤Ç¤¹¤¬¡¢½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó" #, c-format msgid "Sorry, only %ld suggestions" -msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï %ld ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó" +msgstr "»Äǰ¤Ç¤¹¤¬¡¢½¤Àµ¸õÊä¤Ï %ld ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó" -#. for when 'cmdheight' > 1 -#. avoid more prompt #, c-format msgid "Change \"%.*s\" to:" msgstr "\"%.*s\" ¤ò¼¡¤ØÊÑ´¹:" @@ -5090,7 +5088,7 @@ msgid "E757: This does not look like a spell file" msgstr "E757: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹" msgid "E771: Old spell file, needs to be updated" -msgstr "E771: ¸Å¤¤¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç, ¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤" +msgstr "E771: ¸Å¤¤¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç¡¢¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤" msgid "E772: Spell file is for newer version of Vim" msgstr "E772: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î Vim ÍѤΥ¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ç¤¹" @@ -5104,7 +5102,7 @@ msgstr "E778: .sug ¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹: %s" #, c-format msgid "E779: Old .sug file, needs to be updated: %s" -msgstr "E779: ¸Å¤¤ .sug ¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç, ¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤: %s" +msgstr "E779: ¸Å¤¤ .sug ¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç¡¢¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤: %s" #, c-format msgid "E780: .sug file is for newer version of Vim: %s" @@ -5119,7 +5117,7 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: .sug ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿: %s" #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "affix ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þÃæ..." #, c-format @@ -5256,16 +5254,16 @@ msgid "%s value differs from what is used in another .aff file" msgstr "ÃÍ %s ¤Ï¾¤Î .aff ¥Õ¥¡¥¤¥ë¤Ç»ÈÍѤµ¤ì¤¿¤Î¤È°Û¤Ê¤ê¤Þ¤¹" #, c-format -msgid "Reading dictionary file %s ..." -msgstr "¼½ñ¥Õ¥¡¥¤¥ë %s ¤ò¥¹¥¥ã¥óÃæ..." +msgid "Reading dictionary file %s..." +msgstr "¼½ñ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤ßÃæ..." #, c-format msgid "E760: No word count in %s" msgstr "E760: %s ¤Ë¤Ïñ¸ì¿ô¤¬¤¢¤ê¤Þ¤»¤ó" #, c-format -msgid "line %6d, word %6d - %s" -msgstr "¹Ô %6d, ñ¸ì %6d - %s" +msgid "line %6d, word %6ld - %s" +msgstr "¹Ô %6d, ñ¸ì %6ld - %s" #, c-format msgid "Duplicate word in %s line %d: %s" @@ -5284,8 +5282,8 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿ (%s Æâ)" #, c-format -msgid "Reading word file %s ..." -msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ %s ..." +msgid "Reading word file %s..." +msgstr "ñ¸ì¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤ßÃæ..." #, c-format msgid "Duplicate /encoding= line ignored in %s line %d: %s" @@ -5301,7 +5299,7 @@ msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /regions= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s" #, c-format msgid "Too many regions in %s line %d: %s" -msgstr "%s ¤Î %d ¹ÔÌÜ, ÈϰϻØÄ꤬¿²á¤®¤Þ¤¹: %s" +msgstr "%s ¤Î %d ¹ÔÌÜ¡¢ÈϰϻØÄ꤬¿²á¤®¤Þ¤¹: %s" #, c-format msgid "/ line ignored in %s line %d: %s" @@ -5329,10 +5327,6 @@ msgstr "¥Î¡¼¥É %d ¸Ä(Á´ %d ¸ÄÃæ) ¤ò°µ½Ì¤·¤Þ¤·¤¿; »Ä¤ê %d (%d%%)" msgid "Reading back spell file..." msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤òµÕÆÉ¹þÃæ" -#. -#. * Go through the trie of good words, soundfold each word and add it to -#. * the soundfold trie. -#. msgid "Performing soundfolding..." msgstr "²»À¼¾ö¹þ¤ß¤ò¼Â¹ÔÃæ..." @@ -5345,7 +5339,7 @@ msgid "Total number of words: %d" msgstr "Áíñ¸ì¿ô: %d" #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "½¤Àµ¸õÊä¥Õ¥¡¥¤¥ë \"%s\" ¤ò½ñ¹þ¤ßÃæ..." #, c-format @@ -5355,8 +5349,9 @@ msgstr "¿äÄê¥á¥â¥ê»ÈÍÑÎÌ: %d ¥Ð¥¤¥È" msgid "E751: Output file name must not have region name" msgstr "E751: ½ÐÎÏ¥Õ¥¡¥¤¥ë̾¤Ë¤ÏÈϰÏ̾¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó" -msgid "E754: Only up to 8 regions supported" -msgstr "E754: ÈÏ°Ï¤Ï 8 ¸Ä¤Þ¤Ç¤·¤«¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" +#, c-format +msgid "E754: Only up to %ld regions supported" +msgstr "E754: ÈÏ°Ï¤Ï %ld ¸Ä¤Þ¤Ç¤·¤«¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" #, c-format msgid "E755: Invalid region in %s" @@ -5366,7 +5361,7 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "·Ù¹ð: Ê£¹ç¥Õ¥é¥°¤È NOBREAK ¤¬Î¾Êý¤È¤â»ØÄꤵ¤ì¤Þ¤·¤¿" #, c-format -msgid "Writing spell file %s ..." +msgid "Writing spell file %s..." msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë %s ¤ò½ñ¹þ¤ßÃæ..." msgid "Done!" @@ -5387,8 +5382,6 @@ msgstr "ñ¸ì '%.*s' ¤¬ %s ¤ØÄɲ䵤ì¤Þ¤·¤¿" msgid "E763: Word characters differ between spell files" msgstr "E763: ñ¸ì¤Îʸ»ú¤¬¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤È°Û¤Ê¤ê¤Þ¤¹" -#. This should have been checked when generating the .spl -#. * file. msgid "E783: duplicate char in MAP entry" msgstr "E783: MAP ¥¨¥ó¥È¥ê¤Ë½Åʣʸ»ú¤¬Â¸ºß¤·¤Þ¤¹" @@ -5654,7 +5647,6 @@ msgstr "E428: ºÇ¸å¤Î³ºÅö¥¿¥°¤ò±Û¤¨¤Æ¿Ê¤à¤³¤È¤Ï¤Ç¤¤Þ¤»¤ó" msgid "File \"%s\" does not exist" msgstr "¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó" -#. Give an indication of the number of matching tags #, c-format msgid "tag %d of %d%s" msgstr "¥¿¥° %d (Á´%d%s)" @@ -5669,7 +5661,6 @@ msgstr " ¥¿¥°¤ò°Û¤Ê¤ëcase¤Ç»ÈÍѤ·¤Þ¤¹!" msgid "E429: File \"%s\" does not exist" msgstr "E429: ¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó" -#. Highlight title msgid "" "\n" " # TO tag FROM line in file/text" @@ -5700,7 +5691,6 @@ msgstr "ľÁ°¤Î %ld ¥Ð¥¤¥È" msgid "E432: Tags file not sorted: %s" msgstr "E432: ¥¿¥°¥Õ¥¡¥¤¥ë¤¬¥½¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó: %s" -#. never opened any tags file msgid "E433: No tags file" msgstr "E433: ¥¿¥°¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó" @@ -5736,7 +5726,6 @@ msgstr "E436: termcap¤Ë \"%s\" ¤Î¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó" msgid "E437: terminal capability \"cm\" required" msgstr "E437: üËö¤Ë \"cm\" µ¡Ç½¤¬É¬ÍפǤ¹" -#. Highlight title msgid "" "\n" "--- Terminal keys ---" @@ -5747,6 +5736,32 @@ msgstr "" msgid "Cannot open $VIMRUNTIME/rgb.txt" msgstr "$VIMRUNTIME/rgb.txt¤ò³«¤±¤Þ¤»¤ó" +#, c-format +msgid "Kill job in \"%s\"?" +msgstr "\"%s\" Æâ¤Î¥¸¥ç¥Ö¤ò½ªÎ»¤·¤Þ¤¹¤«?" + +msgid "Terminal" +msgstr "üËö" + +msgid "Terminal-finished" +msgstr "üËö (½ªÎ»)" + +msgid "active" +msgstr "¥¢¥¯¥Æ¥£¥Ö" + +msgid "running" +msgstr "¼Â¹ÔÃæ" + +msgid "finished" +msgstr "½ªÎ»" + +#, c-format +msgid "E953: File exists: %s" +msgstr "E953: ¥Õ¥¡¥¤¥ë¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s" + +msgid "E955: Not a terminal buffer" +msgstr "E955: üËö¥Ð¥Ã¥Õ¥¡¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó" + msgid "new shell started\n" msgstr "¿·¤·¤¤¥·¥§¥ë¤òµ¯Æ°¤·¤Þ¤¹\n" @@ -5756,12 +5771,9 @@ msgstr "Vim: ÆþÎϤòÆÉ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ë¤è¤ê½ªÎ»¤·¤Þ¤¹...\n" msgid "Used CUT_BUFFER0 instead of empty selection" msgstr "¶õ¤ÎÁªÂòÎΰè¤Î¤«¤ï¤ê¤ËCUT_BUFFER0¤¬»ÈÍѤµ¤ì¤Þ¤·¤¿" -#. This happens when the FileChangedRO autocommand changes the -#. * file in a way it becomes shorter. msgid "E881: Line count changed unexpectedly" msgstr "E881: ͽ´ü¤»¤º¹Ô¥«¥¦¥ó¥È¤¬ÊѤï¤ê¤Þ¤·¤¿" -#. must display the prompt msgid "No undo possible; continue anyway" msgstr "²Äǽ¤Ê¥¢¥ó¥É¥¥¤Ï¤¢¤ê¤Þ¤»¤ó: ¤È¤ê¤¢¤¨¤ºÂ³¤±¤Þ¤¹" @@ -5896,7 +5908,7 @@ msgstr "E440: ¥¢¥ó¥É¥¥¹Ô¤¬¤¢¤ê¤Þ¤»¤ó" #, c-format msgid "E122: Function %s already exists, add ! to replace it" -msgstr "E122: ´Ø¿ô %s ¤ÏÄêµÁºÑ¤Ç¤¹, ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤" +msgstr "E122: ´Ø¿ô %s ¤ÏÄêµÁºÑ¤Ç¤¹¡¢ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤" msgid "E717: Dictionary entry already exists" msgstr "E717: ¼½ñ·¿Æâ¤Ë¥¨¥ó¥È¥ê¤¬´û¤Ë¸ºß¤·¤Þ¤¹" @@ -6022,6 +6034,10 @@ msgstr "E133: ´Ø¿ô³°¤Ë :return ¤¬¤¢¤ê¤Þ¤·¤¿" msgid "E107: Missing parentheses: %s" msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s" +#, c-format +msgid "%s (%s, compiled %s)" +msgstr "%s (%s, compiled %s)" + msgid "" "\n" "MS-Windows 64-bit GUI version" @@ -6055,24 +6071,17 @@ msgstr "" msgid "" "\n" -"MacOS X (unix) version" -msgstr "" -"\n" -"MacOS X (unix) ÈÇ" - -msgid "" -"\n" -"MacOS X version" +"macOS version" msgstr "" "\n" -"MacOS X ÈÇ" +"macOS ÈÇ" msgid "" "\n" -"MacOS version" +"macOS version w/o darwin feat." msgstr "" "\n" -"MacOS ÈÇ" +"macOS ÈÇ (darwin ̵¤·)" msgid "" "\n" @@ -6176,9 +6185,6 @@ msgstr "with Carbon GUI." msgid "with Cocoa GUI." msgstr "with Cocoa GUI." -msgid "with (classic) GUI." -msgstr "with (¥¯¥é¥·¥Ã¥¯) GUI." - msgid " Features included (+) or not (-):\n" msgstr " µ¡Ç½¤Î°ìÍ÷ ͸ú(+)/̵¸ú(-)\n" @@ -6276,7 +6282,7 @@ msgid "menu Help->Orphans for information " msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×->¸É»ù ¤ò»²¾È¤·¤Æ²¼¤µ¤¤ " msgid "Running modeless, typed text is inserted" -msgstr "¥â¡¼¥É̵¤Ç¼Â¹ÔÃæ, ¥¿¥¤¥×¤·¤¿Ê¸»ú¤¬ÁÞÆþ¤µ¤ì¤Þ¤¹" +msgstr "¥â¡¼¥É̵¤Ç¼Â¹ÔÃæ¡£¥¿¥¤¥×¤·¤¿Ê¸»ú¤¬ÁÞÆþ¤µ¤ì¤Þ¤¹" msgid "menu Edit->Global Settings->Toggle Insert Mode " msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸->Á´ÂÎÀßÄê->ÁÞÆþ(½é¿´¼Ô)¥â¡¼¥ÉÀÚÂØ " @@ -6355,19 +6361,6 @@ msgstr "E802: ̵¸ú¤Ê ID: %ld (1 °Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó)" msgid "E803: ID not found: %ld" msgstr "E803: ID ¤Ï¤¢¤ê¤Þ¤»¤ó: %ld" -#, c-format -msgid "E370: Could not load library %s" -msgstr "E370: ¥é¥¤¥Ö¥é¥ê %s ¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿" - -msgid "Sorry, this command is disabled: the Perl library could not be loaded." -msgstr "" -"¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹, ¤´¤á¤ó¤Ê¤µ¤¤: Perl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿." - -msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" -msgstr "" -"E299: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ï Safe ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Ê¤¤Perl¥¹¥¯¥ê¥×¥È¤Ï¶Ø¤¸¤é¤ì" -"¤Æ¤¤¤Þ¤¹" - msgid "Edit with &multiple Vims" msgstr "Ê£¿ô¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&M)" @@ -6380,7 +6373,6 @@ msgstr "Vim¤Çº¹Ê¬¤òɽ¼¨¤¹¤ë" msgid "Edit with &Vim" msgstr "Vim¤ÇÊÔ½¸¤¹¤ë (&V)" -#. Now concatenate msgid "Edit with existing Vim - " msgstr "µ¯Æ°ºÑ¤ÎVim¤ÇÊÔ½¸¤¹¤ë - " @@ -6399,10 +6391,6 @@ msgstr "¥Ñ¥¹¤¬Ä¹²á¤®¤Þ¤¹!" msgid "--No lines in buffer--" msgstr "--¥Ð¥Ã¥Õ¥¡¤Ë¹Ô¤¬¤¢¤ê¤Þ¤»¤ó--" -#. -#. * The error messages that can be shared are included here. -#. * Excluded are errors that are only used once and debugging messages. -#. msgid "E470: Command aborted" msgstr "E470: ¥³¥Þ¥ó¥É¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿" @@ -6476,6 +6464,14 @@ msgid "E475: Invalid argument: %s" msgstr "E475: ̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s" #, c-format +msgid "E475: Invalid value for argument %s" +msgstr "E475: °ú¿ô %s ¤ËÂФ·¤ÆÌµ¸ú¤ÊÃͤǤ¹" + +#, c-format +msgid "E475: Invalid value for argument %s: %s" +msgstr "E475: °ú¿ô %s ¤ËÂФ·¤ÆÌµ¸ú¤ÊÃͤǤ¹: %s" + +#, c-format msgid "E15: Invalid expression: %s" msgstr "E15: ̵¸ú¤Ê¼°¤Ç¤¹: %s" @@ -6493,6 +6489,9 @@ msgstr "E17: \"%s\" ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹" msgid "E364: Library call failed for \"%s()\"" msgstr "E364: \"%s\"() ¤Î¥é¥¤¥Ö¥é¥ê¸Æ½Ð¤Ë¼ºÇÔ¤·¤Þ¤·¤¿" +msgid "E667: Fsync failed" +msgstr "E667: fsync ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿" + #, c-format msgid "E448: Could not load library function %s" msgstr "E448: ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô %s ¤ò¥í¡¼¥É¤Ç¤¤Þ¤»¤ó¤Ç¤·¤¿" @@ -6504,7 +6503,7 @@ msgid "E20: Mark not set" msgstr "E20: ¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó" msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: 'modifiable' ¤¬¥ª¥Õ¤Ê¤Î¤Ç, Êѹ¹¤Ç¤¤Þ¤»¤ó" +msgstr "E21: 'modifiable' ¤¬¥ª¥Õ¤Ê¤Î¤Ç¡¢Êѹ¹¤Ç¤¤Þ¤»¤ó" msgid "E22: Scripts nested too deep" msgstr "E22: ¥¹¥¯¥ê¥×¥È¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹" @@ -6587,12 +6586,6 @@ msgstr "E484: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó" msgid "E485: Can't read file %s" msgstr "E485: ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤á¤Þ¤»¤ó" -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)" - -msgid "E37: No write since last change" -msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó" - msgid "E38: Null argument" msgstr "E38: °ú¿ô¤¬¶õ¤Ç¤¹" @@ -6737,7 +6730,7 @@ msgid "E449: Invalid expression received" msgstr "E449: ̵¸ú¤Ê¼°¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿" msgid "E463: Region is guarded, cannot modify" -msgstr "E463: Îΰ褬Êݸ¤ì¤Æ¤¤¤ë¤Î¤Ç, Êѹ¹¤Ç¤¤Þ¤»¤ó" +msgstr "E463: Îΰ褬Êݸ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢Êѹ¹¤Ç¤¤Þ¤»¤ó" msgid "E744: NetBeans does not allow changes in read-only files" msgstr "E744: NetBeans ¤ÏÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤³¤È¤òµö¤·¤Þ¤»¤ó" @@ -6769,6 +6762,9 @@ msgstr "E850: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾¤Ç¤¹" msgid "E919: Directory not found in '%s': \"%s\"" msgstr "E919: ¥Ç¥£¥ì¥¯¥È¥ê¤¬ '%s' ¤ÎÃæ¤Ë¤¢¤ê¤Þ¤»¤ó: \"%s\"" +msgid "E952: Autocommand caused recursive behavior" +msgstr "E952: Autocommand¤¬ºÆµ¢¤ò°ú¤µ¯¤³¤·¤Þ¤·¤¿" + msgid "search hit TOP, continuing at BOTTOM" msgstr "¾å¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç²¼¤ËÌá¤ê¤Þ¤¹" @@ -6872,7 +6868,6 @@ msgstr "¥ê¥¹¥È¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó" msgid "list index out of range" msgstr "¥ê¥¹¥ÈÈϰϳ°¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¹" -#. No more suitable format specifications in python-2.3 #, c-format msgid "internal error: failed to get vim list item %d" msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿" @@ -7032,3 +7027,47 @@ msgid "" msgstr "" "¥Ñ¥¹¤ÎÀßÄê¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: sys.path ¤¬¥ê¥¹¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó\n" "¤¹¤°¤Ë vim.VIM_SPECIAL_PATH ¤ò sys.path ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*.*)\t*.*\n" +msgstr "" +"Vim¥Þ¥¯¥í¥Õ¥¡¥¤¥ë (*.vim)\t*.vim\n" +"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*.*)\t*.*\n" + +msgid "All Files (*.*)\t*.*\n" +msgstr "¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*.*)\t*.*\n" + +msgid "" +"All Files (*.*)\t*.*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB code (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*.*)\t*.*\n" +"C¥½¡¼¥¹ (*.c, *.h)\t*.c;*.h\n" +"C++¥½¡¼¥¹ (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB¥³¡¼¥É (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim¥Õ¥¡¥¤¥ë (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*)\t*\n" +msgstr "" +"Vim ¥Þ¥¯¥í¥Õ¥¡¥¤¥ë (*.vim)\t*.vim\n" +"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*)\t*\n" + +msgid "All Files (*)\t*\n" +msgstr "¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*)\t*\n" + +msgid "" +"All Files (*)\t*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*)\t*\n" +"C¥½¡¼¥¹ (*.c, *.h)\t*.c;*.h\n" +"C++¥½¡¼¥¹ (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim¥Õ¥¡¥¤¥ë (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" diff --git a/src/nvim/po/ja.po b/src/nvim/po/ja.po index 39b4a89517..4c5661464a 100644 --- a/src/nvim/po/ja.po +++ b/src/nvim/po/ja.po @@ -4,8 +4,8 @@ # Do ":help uganda" in Vim to read copying and usage conditions. # Do ":help credits" in Vim to see a list of people who contributed. # -# Copyright (C) 2001-2016 MURAOKA Taro <koron.kaoriya@gmail.com>, -# vim-jp (http://vim-jp.org/) +# Copyright (C) 2001-2018 MURAOKA Taro <koron.kaoriya@gmail.com>, +# vim-jp <http://vim-jp.org/> # # THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE. # @@ -13,16 +13,16 @@ # msgid "" msgstr "" -"Project-Id-Version: Vim 8.0\n" +"Project-Id-Version: Vim 8.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-07-03 23:05+0900\n" -"PO-Revision-Date: 2017-07-12 20:45+0900\n" +"POT-Creation-Date: 2018-07-18 00:43+0900\n" +"PO-Revision-Date: 2017-05-18 00:45+0900\n" "Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n" -"Language-Team: vim-jp (https://github.com/vim-jp/lang-ja)\n" -"Language: Japanese\n" +"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n" +"Language: ja\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8-bit\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" msgid "E831: bf_key_init() called with empty password" @@ -50,10 +50,10 @@ msgid "E855: Autocommands caused command to abort" msgstr "E855: autocommandãŒã‚³ãƒžãƒ³ãƒ‰ã®åœæ¢ã‚’引ãèµ·ã“ã—ã¾ã—ãŸ" msgid "E82: Cannot allocate any buffer, exiting..." -msgstr "E82: ãƒãƒƒãƒ•ã‚¡ã‚’1ã¤ã‚‚作æˆã§ããªã„ã®ã§, 終了ã—ã¾ã™..." +msgstr "E82: ãƒãƒƒãƒ•ã‚¡ã‚’1ã¤ã‚‚作æˆã§ããªã„ã®ã§ã€çµ‚了ã—ã¾ã™..." msgid "E83: Cannot allocate buffer, using other one..." -msgstr "E83: ãƒãƒƒãƒ•ァを作æˆã§ããªã„ã®ã§, ä»–ã®ã‚’使用ã—ã¾ã™..." +msgstr "E83: ãƒãƒƒãƒ•ァを作æˆã§ããªã„ã®ã§ã€ä»–ã®ã‚’使用ã—ã¾ã™..." msgid "E931: Buffer cannot be registered" msgstr "E931: ãƒãƒƒãƒ•ァを登録ã§ãã¾ã›ã‚“" @@ -97,7 +97,6 @@ msgstr "E90: 最後ã®ãƒãƒƒãƒ•ã‚¡ã¯è§£æ”¾ã§ãã¾ã›ã‚“" msgid "E84: No modified buffer found" msgstr "E84: 変更ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“" -#. back where we started, didn't find anything. msgid "E85: There is no listed buffer" msgstr "E85: リスト表示ã•れるãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“" @@ -111,6 +110,18 @@ msgstr "E88: 最åˆã®ãƒãƒƒãƒ•ァよりå‰ã¸ã¯ç§»å‹•ã§ãã¾ã›ã‚“" msgid "E89: No write since last change for buffer %ld (add ! to override)" msgstr "E89: ãƒãƒƒãƒ•ã‚¡ %ld ã®å¤‰æ›´ã¯ä¿å˜ã•れã¦ã„ã¾ã›ã‚“ (! ã§å¤‰æ›´ã‚’ç ´æ£„)" +msgid "E948: Job still running (add ! to end the job)" +msgstr "E948: ジョブã¯ã¾ã 実行ä¸ã§ã™ (! ã‚’è¿½åŠ ã§ã‚¸ãƒ§ãƒ–を終了)" + +msgid "E37: No write since last change (add ! to override)" +msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å˜ã•れã¦ã„ã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§å¤‰æ›´ã‚’ç ´æ£„)" + +msgid "E948: Job still running" +msgstr "E948: ジョブã¯ã¾ã 実行ä¸ã§ã™" + +msgid "E37: No write since last change" +msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å˜ã•れã¦ã„ã¾ã›ã‚“" + msgid "W14: Warning: List of file names overflow" msgstr "W14: è¦å‘Š: ファイルåã®ãƒªã‚¹ãƒˆãŒé•·éŽãŽã¾ã™" @@ -166,7 +177,6 @@ msgstr "行 %ld (全体 %ld) --%d%%-- col " msgid "[No Name]" msgstr "[ç„¡å]" -#. must be a help buffer msgid "help" msgstr "ヘルプ" @@ -192,6 +202,12 @@ msgstr "" "\n" "# ãƒãƒƒãƒ•ァリスト:\n" +msgid "E382: Cannot write, 'buftype' option is set" +msgstr "E382: 'buftype' オプションãŒè¨å®šã•れã¦ã„ã‚‹ã®ã§æ›¸è¾¼ã‚ã¾ã›ã‚“" + +msgid "[Prompt]" +msgstr "[プãƒãƒ³ãƒ—ト]" + msgid "[Scratch]" msgstr "[下書ã]" @@ -246,10 +262,10 @@ msgstr "E917: %s() ã«ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ä½¿ãˆã¾ã›ã‚“" msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" msgstr "" -"E912: raw ã‚„ nl モードã®ãƒãƒ£ãƒ³ãƒãƒ«ã« ch_evalexpr()/ch_sendexpr() ã¯ä½¿ãˆã¾ã›ã‚“" +"E912: raw ã‚„ nl モードã®ãƒãƒ£ãƒãƒ«ã« ch_evalexpr()/ch_sendexpr() ã¯ä½¿ãˆã¾ã›ã‚“" msgid "E906: not an open channel" -msgstr "E906: é–‹ã„ã¦ã„ãªã„ãƒãƒ£ãƒ³ãƒãƒ«ã§ã™" +msgstr "E906: é–‹ã„ã¦ã„ãªã„ãƒãƒ£ãƒãƒ«ã§ã™" msgid "E920: _io file requires _name to be set" msgstr "E920: _io ファイル㯠_name ã®è¨å®šãŒå¿…è¦ã§ã™" @@ -360,7 +376,6 @@ msgstr "E791: 空ã®ã‚ーマップエントリ" msgid " Keyword completion (^N^P)" msgstr " ã‚ーワード補完 (^N^P)" -#. ctrl_x_mode == 0, ^P/^N compl. msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" msgstr " ^X モード (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" @@ -438,10 +453,6 @@ msgstr "ファイル内ã®ãƒžãƒƒãƒ" msgid " Adding" msgstr " è¿½åŠ ä¸" -#. showmode might reset the internal line pointers, so it must -#. * be called before line = ml_get(), or when this address is no -#. * longer needed. -- Acevedo. -#. msgid "-- Searching..." msgstr "-- 検索ä¸..." @@ -462,7 +473,6 @@ msgstr "%d 番目ã®è©²å½“ (全該当 %d 個ä¸)" msgid "match %d" msgstr "%d 番目ã®è©²å½“" -#. maximum nesting of lists and dicts msgid "E18: Unexpected characters in :let" msgstr "E18: 予期ã›ã¬æ–‡å—㌠:let ã«ã‚りã¾ã—ãŸ" @@ -515,7 +525,6 @@ msgstr "E710: リスト型変数ã«ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚ˆã‚Šã‚‚多ã„è¦ç´ ãŒã‚り msgid "E711: List value has not enough items" msgstr "E711: リスト型変数ã«ååˆ†ãªæ•°ã®è¦ç´ ãŒã‚りã¾ã›ã‚“" -# msgid "E690: Missing \"in\" after :for" msgstr "E690: :for ã®å¾Œã« \"in\" ãŒã‚りã¾ã›ã‚“" @@ -523,8 +532,6 @@ msgstr "E690: :for ã®å¾Œã« \"in\" ãŒã‚りã¾ã›ã‚“" msgid "E108: No such variable: \"%s\"" msgstr "E108: ãã®å¤‰æ•°ã¯ã‚りã¾ã›ã‚“: \"%s\"" -#. For historic reasons this error is not given for a list or dict. -#. * E.g., the b: dict could be locked/unlocked. #, c-format msgid "E940: Cannot lock or unlock variable %s" msgstr "E940: 変数 %s ã¯ãƒãƒƒã‚¯ã¾ãŸã¯ã‚¢ãƒ³ãƒãƒƒã‚¯ã§ãã¾ã›ã‚“" @@ -535,21 +542,6 @@ msgstr "E743: (アン)ãƒãƒƒã‚¯ã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚ŒåãŒæ·±éŽãŽã¾ã™" msgid "E109: Missing ':' after '?'" msgstr "E109: '?' ã®å¾Œã« ':' ãŒã‚りã¾ã›ã‚“" -msgid "E691: Can only compare List with List" -msgstr "E691: リスト型ã¯ãƒªã‚¹ãƒˆåž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“" - -msgid "E692: Invalid operation for List" -msgstr "E692: リスト型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™" - -msgid "E735: Can only compare Dictionary with Dictionary" -msgstr "E735: 辞書型ã¯è¾žæ›¸åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“" - -msgid "E736: Invalid operation for Dictionary" -msgstr "E736: 辞書型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™" - -msgid "E694: Invalid operation for Funcrefs" -msgstr "E694: 関数å‚ç…§åž‹ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™" - msgid "E804: Cannot use '%' with Float" msgstr "E804: '%' ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“" @@ -589,7 +581,7 @@ msgid "E805: Using a Float as a Number" msgstr "E805: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E703: Using a Funcref as a Number" -msgstr "E703: 関数å‚照型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚" +msgstr "E703: 関数å‚照型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E745: Using a List as a Number" msgstr "E745: リスト型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" @@ -601,10 +593,10 @@ msgid "E910: Using a Job as a Number" msgstr "E910: ジョブを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E913: Using a Channel as a Number" -msgstr "E913: ãƒãƒ£ãƒ³ãƒãƒ«ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚" +msgstr "E913: ãƒãƒ£ãƒãƒ«ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E891: Using a Funcref as a Float" -msgstr "E891: 関数å‚ç…§åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚" +msgstr "E891: 関数å‚ç…§åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E892: Using a String as a Float" msgstr "E892: æ–‡å—åˆ—ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" @@ -622,7 +614,7 @@ msgid "E911: Using a Job as a Float" msgstr "E911: ã‚¸ãƒ§ãƒ–ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E914: Using a Channel as a Float" -msgstr "E914: ãƒãƒ£ãƒ³ãƒãƒ«ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚" +msgstr "E914: ãƒãƒ£ãƒãƒ«ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" msgid "E729: using Funcref as a String" msgstr "E729: 関数å‚照型を文å—列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™" @@ -676,6 +668,21 @@ msgstr "" "\n" "\t最後ã«ã‚»ãƒƒãƒˆã—ãŸã‚¹ã‚¯ãƒªãƒ—ト: " +msgid "E691: Can only compare List with List" +msgstr "E691: リスト型ã¯ãƒªã‚¹ãƒˆåž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“" + +msgid "E692: Invalid operation for List" +msgstr "E692: リスト型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™" + +msgid "E735: Can only compare Dictionary with Dictionary" +msgstr "E735: 辞書型ã¯è¾žæ›¸åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“" + +msgid "E736: Invalid operation for Dictionary" +msgstr "E736: 辞書型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™" + +msgid "E694: Invalid operation for Funcrefs" +msgstr "E694: 関数å‚ç…§åž‹ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™" + msgid "map() argument" msgstr "map() ã®å¼•æ•°" @@ -698,15 +705,15 @@ msgstr "add() ã®å¼•æ•°" msgid "E785: complete() can only be used in Insert mode" msgstr "E785: complete() ã¯æŒ¿å…¥ãƒ¢ãƒ¼ãƒ‰ã§ã—ã‹åˆ©ç”¨ã§ãã¾ã›ã‚“" -#. -#. * Yes this is ugly, I don't particularly like it either. But doing it -#. * this way has the compelling advantage that translations need not to -#. * be touched at all. See below what 'ok' and 'ync' are used for. -#. msgid "&Ok" msgstr "&Ok" #, c-format +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld 行: " + +#, c-format msgid "E700: Unknown function: %s" msgstr "E700: 未知ã®é–¢æ•°ã§ã™: %s" @@ -810,10 +817,22 @@ msgid "E921: Invalid callback argument" msgstr "E921: 無効ãªã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯å¼•æ•°ã§ã™" #, c-format +msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s" +msgstr "<%s>%s%s %d, 16進数 %02x, 8進数 %03o, ダイグラフ %s" + +#, c-format msgid "<%s>%s%s %d, Hex %02x, Octal %03o" msgstr "<%s>%s%s %d, 16進数 %02x, 8進数 %03o" #, c-format +msgid "> %d, Hex %04x, Oct %o, Digr %s" +msgstr "> %d, 16進数 %04x, 8進数 %o, ダイグラフ %s" + +#, c-format +msgid "> %d, Hex %08x, Oct %o, Digr %s" +msgstr "> %d, 16進数 %08x, 8進数 %o, ダイグラフ %s" + +#, c-format msgid "> %d, Hex %04x, Octal %o" msgstr "> %d, 16進数 %04x, 8進数 %o" @@ -846,7 +865,7 @@ msgid "%sviminfo: %s in line: " msgstr "%sviminfo: %s 行目: " msgid "E136: viminfo: Too many errors, skipping rest of file" -msgstr "E136: viminfo: エラーãŒå¤šéŽãŽã‚‹ã®ã§, 以é™ã¯ã‚¹ã‚ップã—ã¾ã™" +msgstr "E136: viminfo: エラーãŒå¤šéŽãŽã‚‹ã®ã§ã€ä»¥é™ã¯ã‚¹ã‚ップã—ã¾ã™" #, c-format msgid "Reading viminfo file \"%s\"%s%s%s" @@ -864,7 +883,6 @@ msgstr " 旧ファイル群" msgid " FAILED" msgstr " 失敗" -#. avoid a wait_return for this message, it's annoying #, c-format msgid "E137: Viminfo file is not writable: %s" msgstr "E137: viminfoãƒ•ã‚¡ã‚¤ãƒ«ãŒæ›¸è¾¼ã¿ã§ãã¾ã›ã‚“: %s" @@ -885,7 +903,6 @@ msgstr "viminfoファイル \"%s\" を書込ã¿ä¸" msgid "E886: Can't rename viminfo file to %s!" msgstr "E886: viminfoファイルを %s ã¸åå‰å¤‰æ›´ã§ãã¾ã›ã‚“!" -#. Write the info: #, c-format msgid "# This viminfo file was generated by Vim %s.\n" msgstr "# ã“ã® viminfo ファイル㯠Vim %s ã«ã‚ˆã£ã¦ç”Ÿæˆã•れã¾ã—ãŸ.\n" @@ -1004,7 +1021,6 @@ msgstr " (計 1 行内)" msgid " on %ld lines" msgstr " (計 %ld 行内)" -#. will increment global_busy to break out of the loop msgid "E147: Cannot do :global recursive with a range" msgstr "E147: :global を範囲付ãã§å†å¸°çš„ã«ã¯ä½¿ãˆã¾ã›ã‚“" @@ -1121,6 +1137,14 @@ msgid "Entering Debug mode. Type \"cont\" to continue." msgstr "デãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰ã«å…¥ã‚Šã¾ã™. ç¶šã‘ã‚‹ã«ã¯ \"cont\" ã¨å…¥åŠ›ã—ã¦ãã ã•ã„." #, c-format +msgid "Oldval = \"%s\"" +msgstr "å¤ã„値 = \"%s\"" + +#, c-format +msgid "Newval = \"%s\"" +msgstr "æ–°ã—ã„値 = \"%s\"" + +#, c-format msgid "line %ld: %s" msgstr "行 %ld: %s" @@ -1150,6 +1174,10 @@ msgstr "ブレークãƒã‚¤ãƒ³ãƒˆãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“" msgid "%3d %s %s line %ld" msgstr "%3d %s %s 行 %ld" +#, c-format +msgid "%3d expr %s" +msgstr "%3d expr %s" + msgid "E750: First use \":profile start {fname}\"" msgstr "E750: åˆã‚ã« \":profile start {fname}\" を実行ã—ã¦ãã ã•ã„" @@ -1157,8 +1185,9 @@ msgstr "E750: åˆã‚ã« \":profile start {fname}\" を実行ã—ã¦ãã ã•ã„" msgid "Save changes to \"%s\"?" msgstr "変更を \"%s\" ã«ä¿å˜ã—ã¾ã™ã‹?" -msgid "Untitled" -msgstr "無題" +#, c-format +msgid "E947: Job still running in buffer \"%s\"" +msgstr "E947: ジョブã¯ãƒãƒƒãƒ•ã‚¡ \"%s\" ã§ã¾ã 実行ä¸ã§ã™" #, c-format msgid "E162: No write since last change for buffer \"%s\"" @@ -1293,7 +1322,7 @@ msgid "E493: Backwards range given" msgstr "E493: 逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸ" msgid "Backwards range given, OK to swap" -msgstr "逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸ, 入替ãˆã¾ã™ã‹?" +msgstr "逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸã€å…¥æ›¿ãˆã¾ã™ã‹?" msgid "E494: Use w or w>>" msgstr "E494: w ã‚‚ã—ã㯠w>> を使用ã—ã¦ãã ã•ã„" @@ -1304,17 +1333,14 @@ msgstr "" "ã•ã„" msgid "E319: Sorry, the command is not available in this version" -msgstr "E319: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„" - -msgid "E172: Only one file name allowed" -msgstr "E172: ファイルå㯠1 ã¤ã«ã—ã¦ãã ã•ã„" +msgstr "E319: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“ã€ã”ã‚ã‚“ãªã•ã„" msgid "1 more file to edit. Quit anyway?" -msgstr "編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™ãŒ, 終了ã—ã¾ã™ã‹?" +msgstr "編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™ãŒã€çµ‚了ã—ã¾ã™ã‹?" #, c-format msgid "%d more files to edit. Quit anyway?" -msgstr "編集ã™ã¹ãファイルãŒã‚㨠%d 個ã‚りã¾ã™ãŒ, 終了ã—ã¾ã™ã‹?" +msgstr "編集ã™ã¹ãファイルãŒã‚㨠%d 個ã‚りã¾ã™ãŒã€çµ‚了ã—ã¾ã™ã‹?" msgid "E173: 1 more file to edit" msgstr "E173: 編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™" @@ -1365,7 +1391,7 @@ msgid "E183: User defined commands must start with an uppercase letter" msgstr "E183: ユーザー定義コマンドã¯è‹±å¤§æ–‡å—ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“" msgid "E841: Reserved name, cannot be used for user defined command" -msgstr "E841: 予約åãªã®ã§, ユーザー定義コマンドã«åˆ©ç”¨ã§ãã¾ã›ã‚“" +msgstr "E841: 予約åãªã®ã§ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼å®šç¾©ã‚³ãƒžãƒ³ãƒ‰ã«åˆ©ç”¨ã§ãã¾ã›ã‚“" #, c-format msgid "E184: No such user-defined command: %s" @@ -1401,6 +1427,9 @@ msgstr "E784: 最後ã®ã‚¿ãƒ–ページを閉ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" msgid "Already only one tab page" msgstr "æ—¢ã«ã‚¿ãƒ–ページã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“" +msgid "Edit File in new tab page" +msgstr "æ–°ã—ã„タブページã§ãƒ•ァイルを編集ã—ã¾ã™" + msgid "Edit File in new window" msgstr "æ–°ã—ã„ウィンドウã§ãƒ•ァイルを編集ã—ã¾ã™" @@ -1416,7 +1445,7 @@ msgstr "è¿½åŠ ãƒ•ã‚¡ã‚¤ãƒ«" msgid "E747: Cannot change directory, buffer is modified (add ! to override)" msgstr "" -"E747: ãƒãƒƒãƒ•ã‚¡ãŒä¿®æ£ã•れã¦ã„ã‚‹ã®ã§, ディレクトリを変更ã§ãã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§" +"E747: ãƒãƒƒãƒ•ã‚¡ãŒä¿®æ£ã•れã¦ã„ã‚‹ã®ã§ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’変更ã§ãã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§" "上書)" msgid "E186: No previous directory" @@ -1466,7 +1495,6 @@ msgstr "E189: \"%s\" ãŒå˜åœ¨ã—ã¾ã™ (上書ã™ã‚‹ã«ã¯ ! ã‚’è¿½åŠ ã—ã¦ã msgid "E190: Cannot open \"%s\" for writing" msgstr "E190: \"%s\" を書込ã¿ç”¨ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“" -#. set mark msgid "E191: Argument must be a letter or forward/backward quote" msgstr "E191: 引数ã¯1æ–‡å—ã®è‹±å—ã‹å¼•用符 (' ã‹ `) ã§ãªã‘れã°ã„ã‘ã¾ã›ã‚“" @@ -1505,13 +1533,15 @@ msgstr "E500: 空文å—列ã¨ã—ã¦è©•価ã•れã¾ã—ãŸ" msgid "E195: Cannot open viminfo file for reading" msgstr "E195: viminfoファイルをèªè¾¼ç”¨ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“" +msgid "Untitled" +msgstr "無題" + msgid "E196: No digraphs in this version" msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå—ã¯ã‚りã¾ã›ã‚“" msgid "E608: Cannot :throw exceptions with 'Vim' prefix" msgstr "E608: 'Vim' ã§å§‹ã¾ã‚‹ä¾‹å¤–㯠:throw ã§ãã¾ã›ã‚“" -#. always scroll up, don't overwrite #, c-format msgid "Exception thrown: %s" msgstr "例外ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" @@ -1528,7 +1558,6 @@ msgstr "例外ãŒç ´æ£„ã•れã¾ã—ãŸ: %s" msgid "%s, line %ld" msgstr "%s, 行 %ld" -#. always scroll up, don't overwrite #, c-format msgid "Exception caught: %s" msgstr "ä¾‹å¤–ãŒæ•æ‰ã•れã¾ã—ãŸ: %s" @@ -1554,7 +1583,6 @@ msgstr "エラーã¨å‰²è¾¼ã¿" msgid "Error" msgstr "エラー" -#. if (pending & CSTP_INTERRUPT) msgid "Interrupt" msgstr "割込ã¿" @@ -1597,15 +1625,12 @@ msgstr "E601: :try ã®å…¥ã‚ŒåãŒæ·±éŽãŽã¾ã™" msgid "E603: :catch without :try" msgstr "E603: :try ã®ãªã„ :catch ãŒã‚りã¾ã™" -#. Give up for a ":catch" after ":finally" and ignore it. -#. * Just parse. msgid "E604: :catch after :finally" msgstr "E604: :finally ã®å¾Œã« :catch ãŒã‚りã¾ã™" msgid "E606: :finally without :try" msgstr "E606: :try ã®ãªã„ :finally ãŒã‚りã¾ã™" -#. Give up for a multiple ":finally" and ignore it. msgid "E607: multiple :finally" msgstr "E607: 複数㮠:finally ãŒã‚りã¾ã™" @@ -1698,7 +1723,6 @@ msgstr "Vim: 標準入力ã‹ã‚‰èªè¾¼ä¸...\n" msgid "Reading from stdin..." msgstr "標準入力ã‹ã‚‰èªè¾¼ã¿ä¸..." -#. Re-opening the original file failed! msgid "E202: Conversion made file unreadable!" msgstr "E202: 変æ›ãŒãƒ•ァイルをèªè¾¼ä¸å¯ã«ã—ã¾ã—ãŸ" @@ -1787,9 +1811,6 @@ msgstr "E509: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを作れã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§å¼ msgid "E510: Can't make backup file (add ! to override)" msgstr "E510: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを作れã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§å¼·åˆ¶ä½œæˆ)" -msgid "E460: The resource fork would be lost (add ! to override)" -msgstr "E460: リソースフォークãŒå¤±ã‚れるã‹ã‚‚ã—れã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§å¼·åˆ¶)" - msgid "E214: Can't find temp file for writing" msgstr "E214: ä¿å˜ç”¨ä¸€æ™‚ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" @@ -1802,25 +1823,25 @@ msgstr "E166: リンクã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸è¾¼ã‚ã¾ã›ã‚“" msgid "E212: Can't open file for writing" msgstr "E212: 書込ã¿ç”¨ã«ãƒ•ァイルを開ã‘ã¾ã›ã‚“" -msgid "E667: Fsync failed" -msgstr "E667: fsync ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgid "E949: File changed while writing" +msgstr "E949: 書込ã¿ä¸ã«ãƒ•ァイルãŒå¤‰æ›´ã•れã¾ã—ãŸ" msgid "E512: Close failed" msgstr "E512: é–‰ã˜ã‚‹ã“ã¨ã«å¤±æ•—" msgid "E513: write error, conversion failed (make 'fenc' empty to override)" -msgstr "E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•— (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•ã„)" +msgstr "E513: 書込ã¿ã‚¨ãƒ©ãƒ¼ã€å¤‰æ›å¤±æ•— (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•ã„)" #, c-format msgid "" "E513: write error, conversion failed in line %ld (make 'fenc' empty to " "override)" msgstr "" -"E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•—, 行数 %ld (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•" +"E513: 書込ã¿ã‚¨ãƒ©ãƒ¼ã€å¤‰æ›å¤±æ•—ã€è¡Œæ•° %ld (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•" "ã„)" msgid "E514: write error (file system full?)" -msgstr "E514: 書込ã¿ã‚¨ãƒ©ãƒ¼, (ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ãŒæº€æ¯?)" +msgstr "E514: 書込ã¿ã‚¨ãƒ©ãƒ¼ (ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ãŒæº€æ¯?)" msgid " CONVERSION ERROR" msgstr " 変æ›ã‚¨ãƒ©ãƒ¼" @@ -1904,9 +1925,6 @@ msgstr "[noeol]" msgid "[Incomplete last line]" msgstr "[最終行ãŒä¸å®Œå…¨]" -#. don't overwrite messages here -#. must give this prompt -#. don't use emsg() here, don't want to flush the buffers msgid "WARNING: The file has been changed since reading it!!!" msgstr "è¦å‘Š: èªè¾¼ã‚“ã 後ã«ãƒ•ァイルã«å¤‰æ›´ãŒã‚りã¾ã—ãŸ!!!" @@ -1984,7 +2002,6 @@ msgstr "--削除済--" msgid "auto-removing autocommand: %s <buffer=%d>" msgstr "autocommand: %s <ãƒãƒƒãƒ•ã‚¡=%d> ãŒè‡ªå‹•çš„ã«å‰Šé™¤ã•れã¾ã™" -#. the group doesn't exist #, c-format msgid "E367: No such group: \"%s\"" msgstr "E367: ãã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: \"%s\"" @@ -2007,13 +2024,12 @@ msgstr "E216: ãã®ã‚ˆã†ãªã‚¤ãƒ™ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“: %s" msgid "E216: No such group or event: %s" msgstr "E216: ãã®ã‚ˆã†ãªã‚°ãƒ«ãƒ¼ãƒ—ã‚‚ã—ãã¯ã‚¤ãƒ™ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“: %s" -#. Highlight title msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" #, c-format msgid "E680: <buffer=%d>: invalid buffer number " @@ -2029,8 +2045,8 @@ msgid "E218: autocommand nesting too deep" msgstr "E218: autocommandã®å…¥ã‚ŒåãŒæ·±éŽãŽã¾ã™" #, c-format -msgid "%s Auto commands for \"%s\"" -msgstr "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" +msgstr "%s Autocommands for \"%s\"" #, c-format msgid "Executing %s" @@ -2055,6 +2071,11 @@ msgstr "E350: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’作æˆã§ãã¾ã›ã‚“" msgid "E351: Cannot delete fold with current 'foldmethod'" msgstr "E351: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’削除ã§ãã¾ã›ã‚“" +#, c-format +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld è¡ŒãŒæŠ˜ç•³ã¾ã‚Œã¾ã—ãŸ" + msgid "E222: Add to read buffer" msgstr "E222: èªè¾¼ãƒãƒƒãƒ•ã‚¡ã¸è¿½åŠ " @@ -2100,7 +2121,7 @@ msgid "E230: Cannot read from \"%s\"" msgstr "E230: \"%s\"ã‹ã‚‰èªè¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" msgid "E665: Cannot start GUI, no valid font found" -msgstr "E665: 有効ãªãƒ•ォントãŒè¦‹ã¤ã‹ã‚‰ãªã„ã®ã§, GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“" +msgstr "E665: 有効ãªãƒ•ォントãŒè¦‹ã¤ã‹ã‚‰ãªã„ã®ã§ã€GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“" msgid "E231: 'guifontwide' invalid" msgstr "E231: 'guifontwide' ãŒç„¡åйã§ã™" @@ -2113,7 +2134,7 @@ msgid "E254: Cannot allocate color %s" msgstr "E254: %s ã®è‰²ã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“" msgid "No match at cursor, finding next" -msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚りã¾ã›ã‚“, 次を検索ã—ã¦ã„ã¾ã™" +msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚りã¾ã›ã‚“ã€æ¬¡ã‚’検索ã—ã¦ã„ã¾ã™" msgid "<cannot open> " msgstr "<é–‹ã‘ã¾ã›ã‚“> " @@ -2188,18 +2209,15 @@ msgstr "検索文å—列:" msgid "Replace with:" msgstr "ç½®æ›æ–‡å—列:" -#. whole word only button msgid "Match whole word only" msgstr "æ£ç¢ºã«è©²å½“ã™ã‚‹ã‚‚ã®ã ã‘" -#. match case button msgid "Match case" msgstr "大文å—/å°æ–‡å—を区別ã™ã‚‹" msgid "Direction" msgstr "æ–¹å‘" -#. 'Up' and 'Down' buttons msgid "Up" msgstr "上" @@ -2272,14 +2290,12 @@ msgstr "アンドゥ(&U)" msgid "Open tab..." msgstr "タブページを開ã" -msgid "Find string (use '\\\\' to find a '\\')" +msgid "Find string (use '\\\\' to find a '\\')" msgstr "検索文å—列 ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')" -msgid "Find & Replace (use '\\\\' to find a '\\')" +msgid "Find & Replace (use '\\\\' to find a '\\')" msgstr "æ¤œç´¢ãƒ»ç½®æ› ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')" -#. We fake this: Use a filter that doesn't select anything and a default -#. * file name that won't be used. msgid "Not Used" msgstr "使ã‚れã¾ã›ã‚“" @@ -2351,7 +2367,6 @@ msgstr "Vim - ãƒ•ã‚©ãƒ³ãƒˆé¸æŠž" msgid "Name:" msgstr "åå‰:" -#. create toggle button msgid "Show size in Points" msgstr "サイズをãƒã‚¤ãƒ³ãƒˆã§è¡¨ç¤ºã™ã‚‹" @@ -2597,7 +2612,6 @@ msgstr "E261: cscope接続 %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" msgid "cscope connection %s closed" msgstr "cscope接続 %s ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ" -#. should not reach here msgid "E570: fatal error in cs_manage_matches" msgstr "E570: cs_manage_matches ã§è‡´å‘½çš„ãªã‚¨ãƒ©ãƒ¼ã§ã™" @@ -2643,8 +2657,8 @@ msgid "" "E895: Sorry, this command is disabled, the MzScheme's racket/base module " "could not be loaded." msgstr "" -"E895: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„. MzScheme ã® racket/base モジュール" -"ãŒãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ." +"E895: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„. MzScheme ã® racket/base モジュー" +"ルãŒãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ." msgid "invalid expression" msgstr "無効ãªå¼ã§ã™" @@ -2697,6 +2711,19 @@ msgstr "範囲外ã®è¡Œç•ªå·ã§ã™" msgid "not allowed in the Vim sandbox" msgstr "サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“" +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: ライブラリ %s ã‚’ãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Perlライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ." + +msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +msgstr "" +"E299: サンドボックスã§ã¯ Safe モジュールを使用ã—ãªã„Perlスクリプトã¯ç¦ã˜ã‚‰ã‚Œ" +"ã¦ã„ã¾ã™" + msgid "E836: This Vim cannot execute :python after using :py3" msgstr "E836: ã“ã®Vimã§ã¯ :py3 を使ã£ãŸå¾Œã« :python を使ãˆã¾ã›ã‚“" @@ -2704,14 +2731,14 @@ msgid "" "E263: Sorry, this command is disabled, the Python library could not be " "loaded." msgstr "" -"E263: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Pythonライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“" -"ã§ã—ãŸ." +"E263: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Pythonライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›" +"ã‚“ã§ã—ãŸ." msgid "" "E887: Sorry, this command is disabled, the Python's site module could not be " "loaded." msgstr "" -"E887: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„. Python ã® site モジュールをãƒãƒ¼ãƒ‰" +"E887: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„. Python ã® site モジュールをãƒãƒ¼ãƒ‰" "ã§ãã¾ã›ã‚“ã§ã—ãŸ." # Added at 07-Feb-2004. @@ -2727,8 +2754,8 @@ msgstr "E265: $_ ã¯æ–‡å—列ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“ msgid "" "E266: Sorry, this command is disabled, the Ruby library could not be loaded." msgstr "" -"E266: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Rubyライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§" -"ã—ãŸ." +"E266: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Rubyライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“" +"ã§ã—ãŸ." msgid "E267: unexpected return" msgstr "E267: 予期ã›ã¬ return ã§ã™" @@ -2758,7 +2785,6 @@ msgstr "無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™" msgid "not implemented yet" msgstr "ã¾ã 実装ã•れã¦ã„ã¾ã›ã‚“" -#. ??? msgid "cannot set line(s)" msgstr "行をè¨å®šã§ãã¾ã›ã‚“" @@ -2800,7 +2826,6 @@ msgid "" msgstr "" "コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«æ¶ˆåŽ»ã•れã¾ã—ãŸ" -#. This should never happen. Famous last word? msgid "" "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim." "org" @@ -2815,7 +2840,7 @@ msgstr "" msgid "" "E571: Sorry, this command is disabled: the Tcl library could not be loaded." msgstr "" -"E571: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Tclライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§" +"E571: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Tclライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§" "ã—ãŸ." #, c-format @@ -2902,7 +2927,6 @@ msgstr "Vim: è¦å‘Š: 端末ã¸ã®å‡ºåŠ›ã§ã¯ã‚りã¾ã›ã‚“\n" msgid "Vim: Warning: Input is not from a terminal\n" msgstr "Vim: è¦å‘Š: 端末ã‹ã‚‰ã®å…¥åŠ›ã§ã¯ã‚りã¾ã›ã‚“\n" -#. just in case.. msgid "pre-vimrc command line" msgstr "vimrcå‰ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³" @@ -2932,7 +2956,7 @@ msgstr "-q [errorfile] 最åˆã®ã‚¨ãƒ©ãƒ¼ã§ç·¨é›†ã™ã‚‹" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -2998,7 +3022,7 @@ msgid "-d\t\t\tDiff mode (like \"vimdiff\")" msgstr "-d\t\t\t差分モード (\"vidiff\" ã¨åŒã˜)" msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" -msgstr "-y\t\t\tイージーモード (\"evim\" ã¨åŒã˜, モード無)" +msgstr "-y\t\t\tイージーモード (\"evim\" ã¨åŒã˜ã€ãƒ¢ãƒ¼ãƒ‰ç„¡)" msgid "-R\t\t\tReadonly mode (like \"view\")" msgstr "-R\t\t\tèªè¾¼å°‚用モード (\"view\" ã¨åŒã˜)" @@ -3048,7 +3072,7 @@ msgstr "-f\t\t\tウィンドウを開ãã®ã« newcli を使用ã—ãªã„" msgid "-dev <device>\t\tUse <device> for I/O" msgstr "-dev <device>\t\tI/Oã« <device> を使用ã™ã‚‹" -msgid "-A\t\t\tstart in Arabic mode" +msgid "-A\t\t\tStart in Arabic mode" msgstr "-A\t\t\tアラビア語モードã§èµ·å‹•ã™ã‚‹" msgid "-H\t\t\tStart in Hebrew mode" @@ -3121,7 +3145,7 @@ msgid "--remote <files>\tEdit <files> in a Vim server if possible" msgstr "--remote <files>\tå¯èƒ½ãªã‚‰ã°Vimサーãƒãƒ¼ã§ <files> を編集ã™ã‚‹" msgid "--remote-silent <files> Same, don't complain if there is no server" -msgstr "--remote-silent <files> åŒä¸Š, サーãƒãƒ¼ãŒç„¡ãã¦ã‚‚è¦å‘Šæ–‡ã‚’出力ã—ãªã„" +msgstr "--remote-silent <files> åŒä¸Šã€ã‚µãƒ¼ãƒãƒ¼ãŒç„¡ãã¦ã‚‚è¦å‘Šæ–‡ã‚’出力ã—ãªã„" msgid "" "--remote-wait <files> As --remote but wait for files to have been edited" @@ -3130,7 +3154,7 @@ msgstr "--remote-wait <files>\t--remote後 ファイルã®ç·¨é›†ãŒçµ‚ã‚ã‚‹ã®ã msgid "" "--remote-wait-silent <files> Same, don't complain if there is no server" msgstr "" -"--remote-wait-silent <files> åŒä¸Š, サーãƒãƒ¼ãŒç„¡ãã¦ã‚‚è¦å‘Šæ–‡ã‚’出力ã—ãªã„" +"--remote-wait-silent <files> åŒä¸Šã€ã‚µãƒ¼ãƒãƒ¼ãŒç„¡ãã¦ã‚‚è¦å‘Šæ–‡ã‚’出力ã—ãªã„" msgid "" "--remote-tab[-wait][-silent] <files> As --remote but use tab page per file" @@ -3156,8 +3180,11 @@ msgstr "--startuptime <file>\tèµ·å‹•ã«ã‹ã‹ã£ãŸæ™‚é–“ã®è©³ç´°ã‚’ <file> 㸠msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo" msgstr "-i <viminfo>\t\t.viminfoã®ä»£ã‚り㫠<viminfo> を使ã†" +msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo" +msgstr "--clean\t\t'nocompatible'ã€Vimã®æ—¢å®šã€ãƒ—ラグインãªã—ã€viminfoãªã—" + msgid "-h or --help\tPrint Help (this message) and exit" -msgstr "-h or --help\tヘルプ(ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸)を表示ã—終了ã™ã‚‹" +msgstr "-h or --help\tヘルプ(ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸)を表示ã—終了ã™ã‚‹" msgid "--version\t\tPrint version information and exit" msgstr "--version\t\tãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…å ±ã‚’è¡¨ç¤ºã—終了ã™ã‚‹" @@ -3254,11 +3281,9 @@ msgstr "--windowid <HWND>\tç•°ãªã‚‹Win32 widgetã®å†…部ã«Vimã‚’é–‹ã" msgid "No display" msgstr "ディスプレイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#. Failed to send, abort. msgid ": Send failed.\n" msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n" -#. Let vim start normally. msgid ": Send failed. Trying to execute locally\n" msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ. ãƒãƒ¼ã‚«ãƒ«ã§ã®å®Ÿè¡Œã‚’試ã¿ã¦ã„ã¾ã™\n" @@ -3279,7 +3304,6 @@ msgstr "マークãŒè¨å®šã•れã¦ã„ã¾ã›ã‚“" msgid "E283: No marks matching \"%s\"" msgstr "E283: \"%s\" ã«è©²å½“ã™ã‚‹ãƒžãƒ¼ã‚¯ãŒã‚りã¾ã›ã‚“" -#. Highlight title msgid "" "\n" "mark line col file/text" @@ -3287,7 +3311,6 @@ msgstr "" "\n" "mark 行 列 ファイル/テã‚スト" -#. Highlight title msgid "" "\n" " jump line col file/text" @@ -3295,7 +3318,6 @@ msgstr "" "\n" " jump 行 列 ファイル/テã‚スト" -#. Highlight title msgid "" "\n" "change line col text" @@ -3310,7 +3332,6 @@ msgstr "" "\n" "# ファイルマーク:\n" -#. Write the jumplist with -' msgid "" "\n" "# Jumplist (newest first):\n" @@ -3379,9 +3400,8 @@ msgstr "E298: ブãƒãƒƒã‚¯ 2 ã‚’å–å¾—ã§ãã¾ã›ã‚“?" msgid "E843: Error while updating swap file crypt" msgstr "E843: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æš—å·ã‚’æ›´æ–°ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" -#. could not (re)open the swap file, what can we do???? msgid "E301: Oops, lost the swap file!!!" -msgstr "E301: ãŠã£ã¨, スワップファイルãŒå¤±ã‚れã¾ã—ãŸ!!!" +msgstr "E301: ãŠã£ã¨ã€ã‚¹ãƒ¯ãƒƒãƒ—ファイルãŒå¤±ã‚れã¾ã—ãŸ!!!" msgid "E302: Could not rename swap file" msgstr "E302: スワップファイルã®åå‰ã‚’変ãˆã‚‰ã‚Œã¾ã›ã‚“" @@ -3466,7 +3486,7 @@ msgid "" "If you entered a new crypt key but did not write the text file," msgstr "" "\n" -"æ–°ã—ã„æš—å·ã‚ーを入力ã—ãŸã‚ã¨ã«ãƒ†ã‚ストファイルをä¿å˜ã—ã¦ã„ãªã„å ´åˆã¯," +"æ–°ã—ã„æš—å·ã‚ーを入力ã—ãŸã‚ã¨ã«ãƒ†ã‚ストファイルをä¿å˜ã—ã¦ã„ãªã„å ´åˆã¯ã€" msgid "" "\n" @@ -3480,7 +3500,7 @@ msgid "" "If you wrote the text file after changing the crypt key press enter" msgstr "" "\n" -"æš—å·ã‚ーを変ãˆãŸã‚ã¨ã«ãƒ†ã‚ストファイルをä¿å˜ã—ãŸå ´åˆã¯, テã‚ストファイルã¨" +"æš—å·ã‚ーを変ãˆãŸã‚ã¨ã«ãƒ†ã‚ストファイルをä¿å˜ã—ãŸå ´åˆã¯ã€ãƒ†ã‚ストファイルã¨" msgid "" "\n" @@ -3540,7 +3560,7 @@ msgid "" "(You might want to write out this file under another name\n" msgstr "" "\n" -"(変更をãƒã‚§ãƒƒã‚¯ã™ã‚‹ãŸã‚ã«, ã“ã®ãƒ•ァイルを別ã®åå‰ã§ä¿å˜ã—ãŸä¸Šã§\n" +"(変更をãƒã‚§ãƒƒã‚¯ã™ã‚‹ãŸã‚ã«ã€ã“ã®ãƒ•ァイルを別ã®åå‰ã§ä¿å˜ã—ãŸä¸Šã§\n" msgid "and run diff with the original file to check for changes)" msgstr "原本ファイルã¨ã® diff を実行ã™ã‚‹ã¨è‰¯ã„ã§ã—ょã†)" @@ -3560,7 +3580,6 @@ msgstr "" msgid "Using crypt key from swap file for the text file.\n" msgstr "スワップファイルã‹ã‚‰å–å¾—ã—ãŸæš—å·ã‚ーをテã‚ストファイルã«ä½¿ã„ã¾ã™.\n" -#. use msg() to start the scrolling properly msgid "Swap files found:" msgstr "スワップファイルãŒè¤‡æ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ:" @@ -3730,8 +3749,6 @@ msgstr "次ã®ãƒ•ァイルを開ã„ã¦ã„ã‚‹æœ€ä¸ \"" msgid " NEWER than swap file!\n" msgstr " スワップファイルよりも新ã—ã„ã§ã™!\n" -#. Some of these messages are long to allow translation to -#. * other languages. msgid "" "\n" "(1) Another program may be editing the same file. If this is the case,\n" @@ -3740,9 +3757,9 @@ msgid "" msgstr "" "\n" "(1) 別ã®ãƒ—ãƒã‚°ãƒ©ãƒ ãŒåŒã˜ãƒ•ァイルを編集ã—ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“.\n" -" ã“ã®å ´åˆã«ã¯, 変更をã—ã¦ã—ã¾ã†ã¨1ã¤ã®ãƒ•ァイルã«å¯¾ã—ã¦ç•°ãªã‚‹2ã¤ã®\n" -" インスタンスãŒã§ãã¦ã—ã¾ã†ã®ã§, ãã†ã—ãªã„よã†ã«æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„.\n" -" 終了ã™ã‚‹ã‹, 注æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\n" +" ã“ã®å ´åˆã«ã¯ã€å¤‰æ›´ã‚’ã—ã¦ã—ã¾ã†ã¨1ã¤ã®ãƒ•ァイルã«å¯¾ã—ã¦ç•°ãªã‚‹2ã¤ã®\n" +" インスタンスãŒã§ãã¦ã—ã¾ã†ã®ã§ã€ãã†ã—ãªã„よã†ã«æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„.\n" +" 終了ã™ã‚‹ã‹ã€æ³¨æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\n" msgid "(2) An edit session for this file crashed.\n" msgstr "(2) ã“ã®ãƒ•ァイルã®ç·¨é›†ã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸ.\n" @@ -3758,7 +3775,7 @@ msgstr "" " を使用ã—ã¦å¤‰æ›´ã‚’リカãƒãƒ¼ã—ã¾ã™(\":help recovery\" ã‚’å‚ç…§).\n" msgid " If you did this already, delete the swap file \"" -msgstr " æ—¢ã«ã“れを行ãªã£ãŸã®ãªã‚‰ã°, スワップファイル \"" +msgstr " æ—¢ã«ã“れを行ãªã£ãŸã®ãªã‚‰ã°ã€ã‚¹ãƒ¯ãƒƒãƒ—ファイル \"" msgid "" "\"\n" @@ -3820,7 +3837,6 @@ msgstr "E328: メニューã¯ä»–ã®ãƒ¢ãƒ¼ãƒ‰ã«ã ã‘ã‚りã¾ã™" msgid "E329: No menu \"%s\"" msgstr "E329: \"%s\" ã¨ã„ã†ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã¯ã‚りã¾ã›ã‚“" -#. Only a mnemonic or accelerator is not valid. msgid "E792: Empty menu name" msgstr "E792: メニューåãŒç©ºã§ã™" @@ -3833,8 +3849,6 @@ msgstr "E331: メニューãƒãƒ¼ã«ã¯ç›´æŽ¥ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ ã‚’è¿½åŠ ã§ msgid "E332: Separator cannot be part of a menu path" msgstr "E332: 区切りã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒ‘スã®ä¸€éƒ¨ã§ã¯ã‚りã¾ã›ã‚“" -#. Now we have found the matching menu, and we list the mappings -#. Highlight title msgid "" "\n" "--- Menus ---" @@ -3845,6 +3859,10 @@ msgstr "" msgid "Tear off this menu" msgstr "ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切りå–ã‚‹" +#, c-format +msgid "E335: Menu not defined for %s mode" +msgstr "E335: %s ã«ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“" + msgid "E333: Menu path must lead to a menu item" msgstr "E333: メニューパスã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ を生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“" @@ -3852,10 +3870,6 @@ msgstr "E333: メニューパスã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ を生ã˜ãªã‘れ㰠msgid "E334: Menu not found: %s" msgstr "E334: メニューãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s" -#, c-format -msgid "E335: Menu not defined for %s mode" -msgstr "E335: %s ã«ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“" - msgid "E336: Menu path must lead to a sub-menu" msgstr "E336: メニューパスã¯ã‚µãƒ–メニューを生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“" @@ -3925,9 +3939,8 @@ msgstr "ファイルä¿å˜ãƒ€ã‚¤ã‚¢ãƒã‚°" msgid "Open File dialog" msgstr "ファイルèªè¾¼ãƒ€ã‚¤ã‚¢ãƒã‚°" -#. TODO: non-GUI file selector here msgid "E338: Sorry, no file browser in console mode" -msgstr "E338: コンソールモードã§ã¯ãƒ•ァイルブラウザを使ãˆã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„" +msgstr "E338: コンソールモードã§ã¯ãƒ•ァイルブラウザを使ãˆã¾ã›ã‚“ã€ã”ã‚ã‚“ãªã•ã„" msgid "E766: Insufficient arguments for printf()" msgstr "E766: printf() ã®å¼•æ•°ãŒä¸å分ã§ã™" @@ -4125,7 +4138,6 @@ msgstr "%ld 行をインデントã—ã¾ã—㟠" msgid "E748: No previously used register" msgstr "E748: ã¾ã レジスタを使用ã—ã¦ã„ã¾ã›ã‚“" -#. must display the prompt msgid "cannot yank; delete anyway" msgstr "ヤンクã§ãã¾ã›ã‚“; ã¨ã«ã‹ã消去" @@ -4140,25 +4152,30 @@ msgstr "%ld 行ãŒå¤‰æ›´ã•れã¾ã—ãŸ" msgid "freeing %ld lines" msgstr "%ld 行を解放ä¸" -msgid "block of 1 line yanked" -msgstr "1 行ã®ãƒ–ãƒãƒƒã‚¯ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ" +#, c-format +msgid " into \"%c" +msgstr " \"%c ã«" -msgid "1 line yanked" -msgstr "1 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ" +#, c-format +msgid "block of 1 line yanked%s" +msgstr "1 行ã®ãƒ–ãƒãƒƒã‚¯ãŒ%sヤンクã•れã¾ã—ãŸ" + +#, c-format +msgid "1 line yanked%s" +msgstr "1 行ãŒ%sヤンクã•れã¾ã—ãŸ" #, c-format -msgid "block of %ld lines yanked" -msgstr "%ld 行ã®ãƒ–ãƒãƒƒã‚¯ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ" +msgid "block of %ld lines yanked%s" +msgstr "%ld 行ã®ãƒ–ãƒãƒƒã‚¯ãŒ%sヤンクã•れã¾ã—ãŸ" #, c-format -msgid "%ld lines yanked" -msgstr "%ld 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ" +msgid "%ld lines yanked%s" +msgstr "%ld 行ãŒ%sヤンクã•れã¾ã—ãŸ" #, c-format msgid "E353: Nothing in register %s" msgstr "E353: レジスタ %s ã«ã¯ä½•ã‚‚ã‚りã¾ã›ã‚“" -#. Highlight title msgid "" "\n" "--- Registers ---" @@ -4213,11 +4230,8 @@ msgstr "" "%lld" #, c-format -msgid "(+%ld for BOM)" -msgstr "(+%ld for BOM)" - -msgid "%<%f%h%m%=Page %N" -msgstr "%<%f%h%m%=%N ページ" +msgid "(+%lld for BOM)" +msgstr "(+%lld for BOM)" msgid "Thanks for flying Vim" msgstr "Vim を使ã£ã¦ãれã¦ã‚りãŒã¨ã†" @@ -4269,6 +4283,10 @@ msgstr "E835: 'fillchars'ã®å€¤ã«çŸ›ç›¾ãŒã‚りã¾ã™" msgid "E617: Cannot be changed in the GTK+ 2 GUI" msgstr "E617: GTK+2 GUIã§ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" +#, c-format +msgid "E950: Cannot convert between %s and %s" +msgstr "E950: %s 㨠%s ã®é–“ã§å¤‰æ›ã§ãã¾ã›ã‚“" + msgid "E524: Missing colon" msgstr "E524: コãƒãƒ³ãŒã‚りã¾ã›ã‚“" @@ -4326,12 +4344,18 @@ msgstr "E541: è¦ç´ ãŒå¤šéŽãŽã¾ã™" msgid "E542: unbalanced groups" msgstr "E542: グループãŒé‡£åˆã„ã¾ã›ã‚“" +msgid "E946: Cannot make a terminal with running job modifiable" +msgstr "E946: 実行ä¸ã®ã‚¸ãƒ§ãƒ–ãŒã‚る端末ã¯å¤‰æ›´å¯èƒ½ã«ã§ãã¾ã›ã‚“" + msgid "E590: A preview window already exists" msgstr "E590: ãƒ—ãƒ¬ãƒ“ãƒ¥ãƒ¼ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«å˜åœ¨ã—ã¾ã™" msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'" msgstr "" -"W17: アラビア文å—ã«ã¯UTF-8ãŒå¿…è¦ãªã®ã§, ':set encoding=utf-8' ã—ã¦ãã ã•ã„" +"W17: アラビア文å—ã«ã¯UTF-8ãŒå¿…è¦ãªã®ã§ã€':set encoding=utf-8' ã—ã¦ãã ã•ã„" + +msgid "E954: 24-bit colors are not supported on this environment" +msgstr "E954: 24bit色ã¯ã“ã®ç’°å¢ƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" #, c-format msgid "E593: Need at least %d lines" @@ -4345,9 +4369,6 @@ msgstr "E594: 最低 %d ã®ã‚«ãƒ©ãƒ å¹…ãŒå¿…è¦ã§ã™" msgid "E355: Unknown option: %s" msgstr "E355: 未知ã®ã‚ªãƒ—ションã§ã™: %s" -#. There's another character after zeros or the string -#. * is empty. In both cases, we are trying to set a -#. * num option using a string. #, c-format msgid "E521: Number required: &%s = '%s'" msgstr "E521: æ•°å—ãŒå¿…è¦ã§ã™: &%s = '%s'" @@ -4420,7 +4441,6 @@ msgstr "コンソールモードを変更ã§ãã¾ã›ã‚“?!\n" msgid "mch_get_shellsize: not a console??\n" msgstr "mch_get_shellsize: コンソールã§ã¯ãªã„??\n" -#. if Vim opened a window: Executing a shell may cause crashes msgid "E360: Cannot execute shell with -f option" msgstr "E360: -f オプションã§ã‚·ã‚§ãƒ«ã‚’実行ã§ãã¾ã›ã‚“" @@ -4621,6 +4641,9 @@ msgstr "Vimã®è¦å‘Š" msgid "shell returned %d" msgstr "シェルãŒã‚³ãƒ¼ãƒ‰ %d ã§çµ‚了ã—ã¾ã—ãŸ" +msgid "E926: Current location list was changed" +msgstr "E926: ç¾åœ¨ã®ãƒã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒªã‚¹ãƒˆãŒå¤‰æ›´ã•れã¾ã—ãŸ" + #, c-format msgid "E372: Too many %%%c in format string" msgstr "E372: フォーマット文å—列㫠%%%c ãŒå¤šéŽãŽã¾ã™" @@ -4644,7 +4667,6 @@ msgstr "E376: フォーマット文å—列ã®å‰ç½®ã«ç„¡åŠ¹ãª %%%c ãŒã‚り㾠msgid "E377: Invalid %%%c in format string" msgstr "E377: フォーマット文å—列ã«ç„¡åŠ¹ãª %%%c ãŒã‚りã¾ã™" -#. nothing found msgid "E378: 'errorformat' contains no pattern" msgstr "E378: 'errorformat' ã«ãƒ‘ã‚¿ãƒ¼ãƒ³ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" @@ -4660,9 +4682,6 @@ msgstr "E924: ç¾åœ¨ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ" msgid "E925: Current quickfix was changed" msgstr "E925: ç¾åœ¨ã® quickfix ãŒå¤‰æ›´ã•れã¾ã—ãŸ" -msgid "E926: Current location list was changed" -msgstr "E926: ç¾åœ¨ã®ãƒã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒªã‚¹ãƒˆãŒå¤‰æ›´ã•れã¾ã—ãŸ" - #, c-format msgid "(%d of %d)%s%s: " msgstr "(%d of %d)%s%s: " @@ -4683,9 +4702,6 @@ msgstr "E381: quickfix スタックã®å…ˆé ã§ã™" msgid "No entries" msgstr "エントリãŒã‚りã¾ã›ã‚“" -msgid "E382: Cannot write, 'buftype' option is set" -msgstr "E382: 'buftype' オプションãŒè¨å®šã•れã¦ã„ã‚‹ã®ã§æ›¸è¾¼ã¿ã¾ã›ã‚“" - msgid "Error file" msgstr "エラーファイル" @@ -4706,7 +4722,6 @@ msgstr "E777: æ–‡å—列ã‹ãƒªã‚¹ãƒˆãŒå¿…è¦ã§ã™" msgid "E369: invalid item in %s%%[]" msgstr "E369: 無効ãªé …ç›®ã§ã™: %s%%[]" -# #, c-format msgid "E769: Missing ] after %s[" msgstr "E769: %s[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“" @@ -4729,15 +4744,12 @@ msgstr "E54: %s( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“" msgid "E55: Unmatched %s)" msgstr "E55: %s) ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“" -# msgid "E66: \\z( not allowed here" msgstr "E66: \\z( ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" -# -msgid "E67: \\z1 et al. not allowed here" -msgstr "E67: \\z1 ãã®ä»–ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" +msgid "E67: \\z1 - \\z9 not allowed here" +msgstr "E67: \\z1 - \\z9 ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" -# #, c-format msgid "E69: Missing ] after %s%%[" msgstr "E69: %s%%[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“" @@ -4746,7 +4758,9 @@ msgstr "E69: %s%%[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“" msgid "E70: Empty %s%%[]" msgstr "E70: %s%%[] ãŒç©ºã§ã™" -# +msgid "E956: Cannot use pattern recursively" +msgstr "E956: パターンをå†å¸°çš„ã«ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" + msgid "E65: Illegal back reference" msgstr "E65: 䏿£ãªå¾Œæ–¹å‚ç…§ã§ã™" @@ -4779,7 +4793,6 @@ msgstr "E61:%s* ãŒå…¥ã‚Œåã«ãªã£ã¦ã„ã¾ã™" msgid "E62: Nested %s%c" msgstr "E62:%s%c ãŒå…¥ã‚Œåã«ãªã£ã¦ã„ã¾ã™" -# msgid "E63: invalid use of \\_" msgstr "E63: \\_ ã®ç„¡åйãªä½¿ç”¨æ–¹æ³•ã§ã™" @@ -4787,16 +4800,13 @@ msgstr "E63: \\_ ã®ç„¡åйãªä½¿ç”¨æ–¹æ³•ã§ã™" msgid "E64: %s%c follows nothing" msgstr "E64:%s%c ã®å¾Œã«ãªã«ã‚‚ã‚りã¾ã›ã‚“" -# msgid "E68: Invalid character after \\z" msgstr "E68: \\z ã®å¾Œã«ä¸æ£ãªæ–‡å—ãŒã‚りã¾ã—ãŸ" -# #, c-format msgid "E678: Invalid character after %s%%[dxouU]" msgstr "E678: %s%%[dxouU] ã®å¾Œã«ä¸æ£ãªæ–‡å—ãŒã‚りã¾ã—ãŸ" -# #, c-format msgid "E71: Invalid character after %s%%" msgstr "E71: %s%% ã®å¾Œã«ä¸æ£ãªæ–‡å—ãŒã‚りã¾ã—ãŸ" @@ -4829,7 +4839,6 @@ msgstr "E865: (NFA) æœŸå¾…ã‚ˆã‚Šæ—©ãæ£è¦è¡¨ç¾ã®çµ‚端ã«åˆ°é”ã—ã¾ã—㟠msgid "E866: (NFA regexp) Misplaced %c" msgstr "E866: (NFA æ£è¦è¡¨ç¾) ä½ç½®ãŒèª¤ã£ã¦ã„ã¾ã™: %c" -# #, c-format msgid "E877: (NFA regexp) Invalid character class: %ld" msgstr "E877: (NFA æ£è¦è¡¨ç¾) ç„¡åŠ¹ãªæ–‡å—クラス: %ld" @@ -4838,11 +4847,13 @@ msgstr "E877: (NFA æ£è¦è¡¨ç¾) ç„¡åŠ¹ãªæ–‡å—クラス: %ld" msgid "E867: (NFA) Unknown operator '\\z%c'" msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\z%c'" +msgid "E951: \\% value too large" +msgstr "E951: \\% 値ãŒé•·éŽãŽã¾ã™" + #, c-format msgid "E867: (NFA) Unknown operator '\\%%%c'" msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\%%%c'" -#. should never happen msgid "E868: Error building NFA with equivalence class!" msgstr "E868: ç‰ä¾¡ã‚¯ãƒ©ã‚¹ã‚’å«ã‚€NFA構築ã«å¤±æ•—ã—ã¾ã—ãŸ!" @@ -4853,11 +4864,9 @@ msgstr "E869: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\@%c'" msgid "E870: (NFA regexp) Error reading repetition limits" msgstr "E870: (NFA æ£è¦è¡¨ç¾) 繰り返ã—ã®åˆ¶é™å›žæ•°ã‚’èªè¾¼ä¸ã«ã‚¨ãƒ©ãƒ¼" -#. Can't have a multi follow a multi. -msgid "E871: (NFA regexp) Can't have a multi follow a multi !" -msgstr "E871: (NFA æ£è¦è¡¨ç¾) 繰り返㗠ã®å¾Œã« 繰り返㗠ã¯ã§ãã¾ã›ã‚“!" +msgid "E871: (NFA regexp) Can't have a multi follow a multi" +msgstr "E871: (NFA æ£è¦è¡¨ç¾) 繰り返㗠ã®å¾Œã« 繰り返㗠ã¯ã§ãã¾ã›ã‚“" -#. Too many `(' msgid "E872: (NFA regexp) Too many '('" msgstr "E872: (NFA æ£è¦è¡¨ç¾) '(' ãŒå¤šéŽãŽã¾ã™" @@ -4867,7 +4876,12 @@ msgstr "E879: (NFA æ£è¦è¡¨ç¾) \\z( ãŒå¤šéŽãŽã¾ã™" msgid "E873: (NFA regexp) proper termination error" msgstr "E873: (NFA æ£è¦è¡¨ç¾) 終端記å·ãŒã‚りã¾ã›ã‚“" -msgid "E874: (NFA) Could not pop the stack !" +msgid "Could not open temporary log file for writing, displaying on stderr... " +msgstr "" +"NFAæ£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。ãƒã‚°ã¯æ¨™æº–エラー" +"出力ã«å‡ºåŠ›ã—ã¾ã™ã€‚" + +msgid "E874: (NFA) Could not pop the stack!" msgstr "E874: (NFA) スタックをãƒãƒƒãƒ—ã§ãã¾ã›ã‚“!" msgid "" @@ -4883,19 +4897,6 @@ msgstr "E876: (NFA æ£è¦è¡¨ç¾) NFA全体をä¿å˜ã™ã‚‹ã«ã¯ç©ºãスペー゠msgid "E878: (NFA) Could not allocate memory for branch traversal!" msgstr "E878: (NFA) ç¾åœ¨æ¨ªæ–ä¸ã®ãƒ–ランãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“!" -msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " -msgstr "" -"NFAæ£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。ãƒã‚°ã¯æ¨™æº–出力ã«" -"出力ã—ã¾ã™ã€‚" - -#, c-format -msgid "(NFA) COULD NOT OPEN %s !" -msgstr "(NFA) ãƒã‚°ãƒ•ァイル %s ã‚’é–‹ã‘ã¾ã›ã‚“!" - -msgid "Could not open temporary log file for writing " -msgstr "NFAæ£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。" - msgid " VREPLACE" msgstr " 仮想置æ›" @@ -4965,7 +4966,6 @@ msgstr "E386: ';' ã®ã‚ã¨ã«ã¯ '?' ã‹ '/' ãŒæœŸå¾…ã•れã¦ã„ã‚‹" msgid " (includes previously listed match)" msgstr " (å‰ã«åˆ—挙ã—ãŸè©²å½“箇所をå«ã‚€)" -#. cursor at status line msgid "--- Included files " msgstr "--- インクルードã•れãŸãƒ•ァイル " @@ -4987,7 +4987,7 @@ msgstr "インクルードã•れãŸãƒ•ァイルをスã‚ャンä¸: %s" #, c-format msgid "Searching included file %s" -msgstr "インクルードã•れãŸãƒ•ァイルをスã‚ãƒ£ãƒ³ä¸ %s" +msgstr "インクルードã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’æ¤œç´¢ä¸ %s" msgid "E387: Match is on current line" msgstr "E387: ç¾åœ¨è¡Œã«è©²å½“ãŒã‚りã¾ã™" @@ -5038,14 +5038,12 @@ msgid "Warning: region %s not supported" msgstr "è¦å‘Š9: %s ã¨ã„ã†ç¯„囲ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" msgid "Sorry, no suggestions" -msgstr "残念ã§ã™ãŒ, ä¿®æ£å€™è£œã¯ã‚りã¾ã›ã‚“" +msgstr "残念ã§ã™ãŒã€ä¿®æ£å€™è£œã¯ã‚りã¾ã›ã‚“" #, c-format msgid "Sorry, only %ld suggestions" -msgstr "残念ã§ã™ãŒ, ä¿®æ£å€™è£œã¯ %ld 個ã—ã‹ã‚りã¾ã›ã‚“" +msgstr "残念ã§ã™ãŒã€ä¿®æ£å€™è£œã¯ %ld 個ã—ã‹ã‚りã¾ã›ã‚“" -#. for when 'cmdheight' > 1 -#. avoid more prompt #, c-format msgid "Change \"%.*s\" to:" msgstr "\"%.*s\" を次ã¸å¤‰æ›:" @@ -5090,7 +5088,7 @@ msgid "E757: This does not look like a spell file" msgstr "E757: スペルファイルã§ã¯ãªã„よã†ã§ã™" msgid "E771: Old spell file, needs to be updated" -msgstr "E771: å¤ã„スペルファイルãªã®ã§, アップデートã—ã¦ãã ã•ã„" +msgstr "E771: å¤ã„スペルファイルãªã®ã§ã€ã‚¢ãƒƒãƒ—デートã—ã¦ãã ã•ã„" msgid "E772: Spell file is for newer version of Vim" msgstr "E772: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Vim 用ã®ã‚¹ãƒšãƒ«ãƒ•ァイルã§ã™" @@ -5104,7 +5102,7 @@ msgstr "E778: .sug ファイルã§ã¯ãªã„よã†ã§ã™: %s" #, c-format msgid "E779: Old .sug file, needs to be updated: %s" -msgstr "E779: å¤ã„ .sug ファイルãªã®ã§, アップデートã—ã¦ãã ã•ã„: %s" +msgstr "E779: å¤ã„ .sug ファイルãªã®ã§ã€ã‚¢ãƒƒãƒ—デートã—ã¦ãã ã•ã„: %s" #, c-format msgid "E780: .sug file is for newer version of Vim: %s" @@ -5119,7 +5117,7 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: .sug ファイルã®èªè¾¼ä¸ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s" #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "affix ファイル %s ã‚’èªè¾¼ä¸..." #, c-format @@ -5256,16 +5254,16 @@ msgid "%s value differs from what is used in another .aff file" msgstr "値 %s ã¯ä»–ã® .aff ファイルã§ä½¿ç”¨ã•れãŸã®ã¨ç•°ãªã‚Šã¾ã™" #, c-format -msgid "Reading dictionary file %s ..." -msgstr "辞書ファイル %s をスã‚ャンä¸..." +msgid "Reading dictionary file %s..." +msgstr "辞書ファイル %s ã‚’èªè¾¼ã¿ä¸..." #, c-format msgid "E760: No word count in %s" msgstr "E760: %s ã«ã¯å˜èªžæ•°ãŒã‚りã¾ã›ã‚“" #, c-format -msgid "line %6d, word %6d - %s" -msgstr "行 %6d, å˜èªž %6d - %s" +msgid "line %6d, word %6ld - %s" +msgstr "行 %6d, å˜èªž %6ld - %s" #, c-format msgid "Duplicate word in %s line %d: %s" @@ -5284,8 +5282,8 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "éžASCIIæ–‡å—ã‚’å«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—㟠(%s 内)" #, c-format -msgid "Reading word file %s ..." -msgstr "標準入力ã‹ã‚‰èªè¾¼ã¿ä¸ %s ..." +msgid "Reading word file %s..." +msgstr "å˜èªžãƒ•ァイル %s ã‚’èªè¾¼ã¿ä¸..." #, c-format msgid "Duplicate /encoding= line ignored in %s line %d: %s" @@ -5301,7 +5299,7 @@ msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/regions= 行を無視ã—ã¾ã—ãŸ: %s" #, c-format msgid "Too many regions in %s line %d: %s" -msgstr "%s ã® %d 行目, 範囲指定ãŒå¤šéŽãŽã¾ã™: %s" +msgstr "%s ã® %d 行目ã€ç¯„囲指定ãŒå¤šéŽãŽã¾ã™: %s" #, c-format msgid "/ line ignored in %s line %d: %s" @@ -5329,10 +5327,6 @@ msgstr "ノード %d 個(å…¨ %d 個ä¸) を圧縮ã—ã¾ã—ãŸ; 残り %d (%d%%)" msgid "Reading back spell file..." msgstr "スペルファイルを逆èªè¾¼ä¸" -#. -#. * Go through the trie of good words, soundfold each word and add it to -#. * the soundfold trie. -#. msgid "Performing soundfolding..." msgstr "音声畳込ã¿ã‚’実行ä¸..." @@ -5345,7 +5339,7 @@ msgid "Total number of words: %d" msgstr "ç·å˜èªžæ•°: %d" #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "ä¿®æ£å€™è£œãƒ•ァイル \"%s\" を書込ã¿ä¸..." #, c-format @@ -5355,8 +5349,9 @@ msgstr "推定メモリ使用é‡: %d ãƒã‚¤ãƒˆ" msgid "E751: Output file name must not have region name" msgstr "E751: 出力ファイルåã«ã¯ç¯„囲åã‚’å«ã‚られã¾ã›ã‚“" -msgid "E754: Only up to 8 regions supported" -msgstr "E754: 範囲㯠8 個ã¾ã§ã—ã‹ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +#, c-format +msgid "E754: Only up to %ld regions supported" +msgstr "E754: 範囲㯠%ld 個ã¾ã§ã—ã‹ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" #, c-format msgid "E755: Invalid region in %s" @@ -5366,7 +5361,7 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "è¦å‘Š: 複åˆãƒ•ラグ㨠NOBREAK ãŒä¸¡æ–¹ã¨ã‚‚指定ã•れã¾ã—ãŸ" #, c-format -msgid "Writing spell file %s ..." +msgid "Writing spell file %s..." msgstr "スペルファイル %s を書込ã¿ä¸..." msgid "Done!" @@ -5387,8 +5382,6 @@ msgstr "å˜èªž '%.*s' ㌠%s ã¸è¿½åŠ ã•れã¾ã—ãŸ" msgid "E763: Word characters differ between spell files" msgstr "E763: å˜èªžã®æ–‡å—ãŒã‚¹ãƒšãƒ«ãƒ•ァイルã¨ç•°ãªã‚Šã¾ã™" -#. This should have been checked when generating the .spl -#. * file. msgid "E783: duplicate char in MAP entry" msgstr "E783: MAP エントリã«é‡è¤‡æ–‡å—ãŒå˜åœ¨ã—ã¾ã™" @@ -5654,7 +5647,6 @@ msgstr "E428: 最後ã®è©²å½“ã‚¿ã‚°ã‚’è¶Šãˆã¦é€²ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" msgid "File \"%s\" does not exist" msgstr "ファイル \"%s\" ãŒã‚りã¾ã›ã‚“" -#. Give an indication of the number of matching tags #, c-format msgid "tag %d of %d%s" msgstr "ã‚¿ã‚° %d (å…¨%d%s)" @@ -5669,7 +5661,6 @@ msgstr " ã‚¿ã‚°ã‚’ç•°ãªã‚‹caseã§ä½¿ç”¨ã—ã¾ã™!" msgid "E429: File \"%s\" does not exist" msgstr "E429: ファイル \"%s\" ãŒã‚りã¾ã›ã‚“" -#. Highlight title msgid "" "\n" " # TO tag FROM line in file/text" @@ -5700,7 +5691,6 @@ msgstr "ç›´å‰ã® %ld ãƒã‚¤ãƒˆ" msgid "E432: Tags file not sorted: %s" msgstr "E432: タグファイルãŒã‚½ãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“: %s" -#. never opened any tags file msgid "E433: No tags file" msgstr "E433: タグファイルãŒã‚りã¾ã›ã‚“" @@ -5736,7 +5726,6 @@ msgstr "E436: termcapã« \"%s\" ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“" msgid "E437: terminal capability \"cm\" required" msgstr "E437: 端末㫠\"cm\" 機能ãŒå¿…è¦ã§ã™" -#. Highlight title msgid "" "\n" "--- Terminal keys ---" @@ -5747,6 +5736,32 @@ msgstr "" msgid "Cannot open $VIMRUNTIME/rgb.txt" msgstr "$VIMRUNTIME/rgb.txtã‚’é–‹ã‘ã¾ã›ã‚“" +#, c-format +msgid "Kill job in \"%s\"?" +msgstr "\"%s\" 内ã®ã‚¸ãƒ§ãƒ–を終了ã—ã¾ã™ã‹?" + +msgid "Terminal" +msgstr "端末" + +msgid "Terminal-finished" +msgstr "端末 (終了)" + +msgid "active" +msgstr "アクティブ" + +msgid "running" +msgstr "実行ä¸" + +msgid "finished" +msgstr "終了" + +#, c-format +msgid "E953: File exists: %s" +msgstr "E953: ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ—¢ã«å˜åœ¨ã—ã¾ã™: %s" + +msgid "E955: Not a terminal buffer" +msgstr "E955: 端末ãƒãƒƒãƒ•ã‚¡ã§ã¯ã‚りã¾ã›ã‚“" + msgid "new shell started\n" msgstr "æ–°ã—ã„シェルを起動ã—ã¾ã™\n" @@ -5756,12 +5771,9 @@ msgstr "Vim: 入力をèªè¾¼ã¿ä¸ã®ã‚¨ãƒ©ãƒ¼ã«ã‚ˆã‚Šçµ‚了ã—ã¾ã™...\n" msgid "Used CUT_BUFFER0 instead of empty selection" msgstr "空ã®é¸æŠžé ˜åŸŸã®ã‹ã‚りã«CUT_BUFFER0ãŒä½¿ç”¨ã•れã¾ã—ãŸ" -#. This happens when the FileChangedRO autocommand changes the -#. * file in a way it becomes shorter. msgid "E881: Line count changed unexpectedly" msgstr "E881: 予期ã›ãšè¡Œã‚«ã‚¦ãƒ³ãƒˆãŒå¤‰ã‚りã¾ã—ãŸ" -#. must display the prompt msgid "No undo possible; continue anyway" msgstr "å¯èƒ½ãªã‚¢ãƒ³ãƒ‰ã‚¥ã¯ã‚りã¾ã›ã‚“: ã¨ã‚Šã‚ãˆãšç¶šã‘ã¾ã™" @@ -5896,7 +5908,7 @@ msgstr "E440: アンドゥ行ãŒã‚りã¾ã›ã‚“" #, c-format msgid "E122: Function %s already exists, add ! to replace it" -msgstr "E122: 関数 %s ã¯å®šç¾©æ¸ˆã§ã™, å†å®šç¾©ã™ã‚‹ã«ã¯ ! ã‚’è¿½åŠ ã—ã¦ãã ã•ã„" +msgstr "E122: 関数 %s ã¯å®šç¾©æ¸ˆã§ã™ã€å†å®šç¾©ã™ã‚‹ã«ã¯ ! ã‚’è¿½åŠ ã—ã¦ãã ã•ã„" msgid "E717: Dictionary entry already exists" msgstr "E717: 辞書型内ã«ã‚¨ãƒ³ãƒˆãƒªãŒæ—¢ã«å˜åœ¨ã—ã¾ã™" @@ -6022,6 +6034,10 @@ msgstr "E133: 関数外㫠:return ãŒã‚りã¾ã—ãŸ" msgid "E107: Missing parentheses: %s" msgstr "E107: カッコ '(' ãŒã‚りã¾ã›ã‚“: %s" +#, c-format +msgid "%s (%s, compiled %s)" +msgstr "%s (%s, compiled %s)" + msgid "" "\n" "MS-Windows 64-bit GUI version" @@ -6055,24 +6071,17 @@ msgstr "" msgid "" "\n" -"MacOS X (unix) version" -msgstr "" -"\n" -"MacOS X (unix) 版" - -msgid "" -"\n" -"MacOS X version" +"macOS version" msgstr "" "\n" -"MacOS X 版" +"macOS 版" msgid "" "\n" -"MacOS version" +"macOS version w/o darwin feat." msgstr "" "\n" -"MacOS 版" +"macOS 版 (darwin ç„¡ã—)" msgid "" "\n" @@ -6176,9 +6185,6 @@ msgstr "with Carbon GUI." msgid "with Cocoa GUI." msgstr "with Cocoa GUI." -msgid "with (classic) GUI." -msgstr "with (クラシック) GUI." - msgid " Features included (+) or not (-):\n" msgstr " 機能ã®ä¸€è¦§ 有効(+)/無効(-)\n" @@ -6276,7 +6282,7 @@ msgid "menu Help->Orphans for information " msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ヘルプ->å¤å… ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„ " msgid "Running modeless, typed text is inserted" -msgstr "モード無ã§å®Ÿè¡Œä¸, タイプã—ãŸæ–‡å—ãŒæŒ¿å…¥ã•れã¾ã™" +msgstr "モード無ã§å®Ÿè¡Œä¸ã€‚タイプã—ãŸæ–‡å—ãŒæŒ¿å…¥ã•れã¾ã™" msgid "menu Edit->Global Settings->Toggle Insert Mode " msgstr "メニュー㮠編集->全体è¨å®š->挿入(åˆå¿ƒè€…)モード切替 " @@ -6355,19 +6361,6 @@ msgstr "E802: 無効㪠ID: %ld (1 以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)" msgid "E803: ID not found: %ld" msgstr "E803: ID ã¯ã‚りã¾ã›ã‚“: %ld" -#, c-format -msgid "E370: Could not load library %s" -msgstr "E370: ライブラリ %s ã‚’ãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -msgid "Sorry, this command is disabled: the Perl library could not be loaded." -msgstr "" -"ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™, ã”ã‚ã‚“ãªã•ã„: Perlライブラリをãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ." - -msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" -msgstr "" -"E299: サンドボックスã§ã¯ Safe モジュールを使用ã—ãªã„Perlスクリプトã¯ç¦ã˜ã‚‰ã‚Œ" -"ã¦ã„ã¾ã™" - msgid "Edit with &multiple Vims" msgstr "複数ã®Vimã§ç·¨é›†ã™ã‚‹ (&M)" @@ -6380,7 +6373,6 @@ msgstr "Vimã§å·®åˆ†ã‚’表示ã™ã‚‹" msgid "Edit with &Vim" msgstr "Vimã§ç·¨é›†ã™ã‚‹ (&V)" -#. Now concatenate msgid "Edit with existing Vim - " msgstr "起動済ã®Vimã§ç·¨é›†ã™ã‚‹ - " @@ -6399,10 +6391,6 @@ msgstr "パスãŒé•·éŽãŽã¾ã™!" msgid "--No lines in buffer--" msgstr "--ãƒãƒƒãƒ•ã‚¡ã«è¡ŒãŒã‚りã¾ã›ã‚“--" -#. -#. * The error messages that can be shared are included here. -#. * Excluded are errors that are only used once and debugging messages. -#. msgid "E470: Command aborted" msgstr "E470: コマンドãŒä¸æ–ã•れã¾ã—ãŸ" @@ -6476,6 +6464,14 @@ msgid "E475: Invalid argument: %s" msgstr "E475: 無効ãªå¼•æ•°ã§ã™: %s" #, c-format +msgid "E475: Invalid value for argument %s" +msgstr "E475: 引数 %s ã«å¯¾ã—ã¦ç„¡åйãªå€¤ã§ã™" + +#, c-format +msgid "E475: Invalid value for argument %s: %s" +msgstr "E475: 引数 %s ã«å¯¾ã—ã¦ç„¡åйãªå€¤ã§ã™: %s" + +#, c-format msgid "E15: Invalid expression: %s" msgstr "E15: 無効ãªå¼ã§ã™: %s" @@ -6493,6 +6489,9 @@ msgstr "E17: \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™" msgid "E364: Library call failed for \"%s()\"" msgstr "E364: \"%s\"() ã®ãƒ©ã‚¤ãƒ–ラリ呼出ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgid "E667: Fsync failed" +msgstr "E667: fsync ã«å¤±æ•—ã—ã¾ã—ãŸ" + #, c-format msgid "E448: Could not load library function %s" msgstr "E448: ライブラリã®é–¢æ•° %s ã‚’ãƒãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ" @@ -6504,7 +6503,7 @@ msgid "E20: Mark not set" msgstr "E20: マークã¯è¨å®šã•れã¦ã„ã¾ã›ã‚“" msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: 'modifiable' ãŒã‚ªãƒ•ãªã®ã§, 変更ã§ãã¾ã›ã‚“" +msgstr "E21: 'modifiable' ãŒã‚ªãƒ•ãªã®ã§ã€å¤‰æ›´ã§ãã¾ã›ã‚“" msgid "E22: Scripts nested too deep" msgstr "E22: スクリプトã®å…¥ã‚ŒåãŒæ·±éŽãŽã¾ã™" @@ -6587,12 +6586,6 @@ msgstr "E484: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“" msgid "E485: Can't read file %s" msgstr "E485: ファイル %s ã‚’èªè¾¼ã‚ã¾ã›ã‚“" -msgid "E37: No write since last change (add ! to override)" -msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å˜ã•れã¦ã„ã¾ã›ã‚“ (! ã‚’è¿½åŠ ã§å¤‰æ›´ã‚’ç ´æ£„)" - -msgid "E37: No write since last change" -msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å˜ã•れã¦ã„ã¾ã›ã‚“" - msgid "E38: Null argument" msgstr "E38: 引数ãŒç©ºã§ã™" @@ -6737,7 +6730,7 @@ msgid "E449: Invalid expression received" msgstr "E449: 無効ãªå¼ã‚’å—ã‘å–りã¾ã—ãŸ" msgid "E463: Region is guarded, cannot modify" -msgstr "E463: é ˜åŸŸãŒä¿è·ã•れã¦ã„ã‚‹ã®ã§, 変更ã§ãã¾ã›ã‚“" +msgstr "E463: é ˜åŸŸãŒä¿è·ã•れã¦ã„ã‚‹ã®ã§ã€å¤‰æ›´ã§ãã¾ã›ã‚“" msgid "E744: NetBeans does not allow changes in read-only files" msgstr "E744: NetBeans ã¯èªè¾¼å°‚用ファイルを変更ã™ã‚‹ã“ã¨ã‚’許ã—ã¾ã›ã‚“" @@ -6769,6 +6762,9 @@ msgstr "E850: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿åã§ã™" msgid "E919: Directory not found in '%s': \"%s\"" msgstr "E919: ディレクトリ㌠'%s' ã®ä¸ã«ã‚りã¾ã›ã‚“: \"%s\"" +msgid "E952: Autocommand caused recursive behavior" +msgstr "E952: AutocommandãŒå†å¸°ã‚’引ãèµ·ã“ã—ã¾ã—ãŸ" + msgid "search hit TOP, continuing at BOTTOM" msgstr "上ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸‹ã«æˆ»ã‚Šã¾ã™" @@ -6872,7 +6868,6 @@ msgstr "リストã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚ーワード引数をå—ã‘付㑠msgid "list index out of range" msgstr "リスト範囲外ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" -#. No more suitable format specifications in python-2.3 #, c-format msgid "internal error: failed to get vim list item %d" msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´ %d ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ" @@ -7032,3 +7027,47 @@ msgid "" msgstr "" "パスã®è¨å®šã«å¤±æ•—ã—ã¾ã—ãŸ: sys.path ãŒãƒªã‚¹ãƒˆã§ã¯ã‚りã¾ã›ã‚“\n" "ã™ãã« vim.VIM_SPECIAL_PATH ã‚’ sys.path ã«è¿½åŠ ã—ã¦ãã ã•ã„" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*.*)\t*.*\n" +msgstr "" +"Vimマクãƒãƒ•ァイル (*.vim)\t*.vim\n" +"ã™ã¹ã¦ã®ãƒ•ァイル (*.*)\t*.*\n" + +msgid "All Files (*.*)\t*.*\n" +msgstr "ã™ã¹ã¦ã®ãƒ•ァイル (*.*)\t*.*\n" + +msgid "" +"All Files (*.*)\t*.*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB code (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"ã™ã¹ã¦ã®ãƒ•ァイル (*.*)\t*.*\n" +"Cソース (*.c, *.h)\t*.c;*.h\n" +"C++ソース (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VBコード (*.bas, *.frm)\t*.bas;*.frm\n" +"Vimファイル (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*)\t*\n" +msgstr "" +"Vim マクãƒãƒ•ァイル (*.vim)\t*.vim\n" +"ã™ã¹ã¦ã®ãƒ•ァイル (*)\t*\n" + +msgid "All Files (*)\t*\n" +msgstr "ã™ã¹ã¦ã®ãƒ•ァイル (*)\t*\n" + +msgid "" +"All Files (*)\t*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"ã™ã¹ã¦ã®ãƒ•ァイル (*)\t*\n" +"Cソース (*.c, *.h)\t*.c;*.h\n" +"C++ソース (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vimファイル (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" diff --git a/src/nvim/po/ko.UTF-8.po b/src/nvim/po/ko.UTF-8.po index 6173283135..e90081bcfd 100644 --- a/src/nvim/po/ko.UTF-8.po +++ b/src/nvim/po/ko.UTF-8.po @@ -2460,7 +2460,7 @@ msgstr "E216: 그런 그룹ì´ë‚˜ ì´ë²¤íЏ ì—†ìŒ: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- ìžë™-ëª…ë ¹ ---" @@ -3378,7 +3378,7 @@ msgstr "-q [ì—러파ì¼] 첫 번째 ì—러가 난 íŒŒì¼ ê³ ì¹˜ê¸°" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -4772,6 +4772,9 @@ msgstr "E447: pathì—서 \"%s\" 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다" msgid "shell returned %d" msgstr "ì‰˜ì´ %dì„(를) ëŒë ¤ì£¼ì—ˆìŠµë‹ˆë‹¤" +msgid "E926: Current location list was changed" +msgstr "E926: í˜„ìž¬ì˜ location listê°€ 바뀌었습니다" + #, c-format msgid "E372: Too many %%%c in format string" msgstr "E372: í˜•ì‹ ë¬¸ìžì—´ì— %%%cì´(ê°€) 너무 많습니다" @@ -5282,7 +5285,7 @@ msgstr "E770: spell 파ì¼ì— ì§€ì›ë˜ì§€ 않는 섹션" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "affix íŒŒì¼ %s ì½ëŠ” 중" #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 @@ -5445,7 +5448,7 @@ msgstr "%s ê°’ì´ ë‹¤ë¥¸ .aff 파ì¼ì—서 ì‚¬ìš©ëœ ê²ƒê³¼ 다릅니다" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." +msgid "Reading dictionary file %s..." msgstr "ì‚¬ì „ íŒŒì¼ %s ì½ëŠ” 중 ..." #: ../spell.c:5611 @@ -5455,8 +5458,8 @@ msgstr "E760: %sì— ë‹¨ì–´ 카운트가 없습니다" #: ../spell.c:5669 #, c-format -msgid "line %6d, word %6d - %s" -msgstr "ë¼ì¸ %6d, 단어 %6d - %s" +msgid "line %6d, word %6ld - %s" +msgstr "ë¼ì¸ %6d, 단어 %6ld - %s" #: ../spell.c:5691 #, c-format @@ -5480,7 +5483,7 @@ msgstr "ë¬´ì‹œëœ %dê°œì˜ ì•„ìŠ¤í‚¤ë¬¸ìžì—´ì´ 아닌 단어가 %sì— ìžˆìŠµë‹ #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." +msgid "Reading word file %s..." msgstr "단어 íŒŒì¼ %s ì½ëŠ” 중 ..." #: ../spell.c:6155 @@ -5550,7 +5553,7 @@ msgstr "ì´ ë‹¨ì–´ 수: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "%s ì œì•ˆ 파ì¼ì„ 쓰는 중 ..." #: ../spell.c:7707 ../spell.c:7927 @@ -5577,7 +5580,7 @@ msgstr "ê²½ê³ : compound와 NOBREAK 둘 다 명시ë¨" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." +msgid "Writing spell file %s..." msgstr "spell íŒŒì¼ %s 쓰는 중 ..." #: ../spell.c:7925 diff --git a/src/nvim/po/nb.po b/src/nvim/po/nb.po index fefcf20b69..b99e8ce465 100644 --- a/src/nvim/po/nb.po +++ b/src/nvim/po/nb.po @@ -2483,7 +2483,7 @@ msgstr "E216: Gruppen eller handlingen finnes ikke: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autokommandoer ---" @@ -2507,7 +2507,7 @@ msgstr "E218: Nøsting av autokommandoer for dyp" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Autokommandoer for \"%s\"" #: ../fileio.c:7149 @@ -3392,7 +3392,7 @@ msgstr "-q [feilfil] rediger fil med første feil" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5302,8 +5302,8 @@ msgstr "Advarsel: Region %s ikke støttet" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Leser affiksfil %s ..." +msgid "Reading affix file %s..." +msgstr "Leser affiksfil %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5462,8 +5462,8 @@ msgstr "%s-verdi er forskjellig fra det som er bruk i en annen .aff-fil" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Leser ordlistefil %s ..." +msgid "Reading dictionary file %s..." +msgstr "Leser ordlistefil %s..." #: ../spell.c:5611 #, c-format @@ -5497,8 +5497,8 @@ msgstr "Ignorerte %d ord med ikke-ASCII-tegn i %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Leser ordfil %s ..." +msgid "Reading word file %s..." +msgstr "Leser ordfil %s..." #: ../spell.c:6155 #, c-format @@ -5568,8 +5568,8 @@ msgstr "Totalt antall ord: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Skriver forslagsfil %s ..." +msgid "Writing suggestion file %s..." +msgstr "Skriver forslagsfil %s..." #: ../spell.c:7707 ../spell.c:7927 #, c-format @@ -5595,8 +5595,8 @@ msgstr "" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Lagrer stavefil %s ..." +msgid "Writing spell file %s..." +msgstr "Lagrer stavefil %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/nl.po b/src/nvim/po/nl.po index f2877903f2..56bcd94e79 100644 --- a/src/nvim/po/nl.po +++ b/src/nvim/po/nl.po @@ -2471,10 +2471,10 @@ msgstr "E216: onbekende groep of 'event': %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" #: ../fileio.c:6293 #, c-format @@ -2495,8 +2495,8 @@ msgstr "E218: hierarchie van aanroepen autocommands te diep" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" -msgstr "%s 'Auto commands' voor \"%s\"" +msgid "%s Autocommands for \"%s\"" +msgstr "%s 'Autocommands' voor \"%s\"" #: ../fileio.c:7149 #, c-format @@ -3389,7 +3389,7 @@ msgstr "-q [foutbestand] bewerk bestand dat eerste fout bevat" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/po/no.po b/src/nvim/po/no.po index fefcf20b69..b99e8ce465 100644 --- a/src/nvim/po/no.po +++ b/src/nvim/po/no.po @@ -2483,7 +2483,7 @@ msgstr "E216: Gruppen eller handlingen finnes ikke: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autokommandoer ---" @@ -2507,7 +2507,7 @@ msgstr "E218: Nøsting av autokommandoer for dyp" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Autokommandoer for \"%s\"" #: ../fileio.c:7149 @@ -3392,7 +3392,7 @@ msgstr "-q [feilfil] rediger fil med første feil" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5302,8 +5302,8 @@ msgstr "Advarsel: Region %s ikke støttet" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Leser affiksfil %s ..." +msgid "Reading affix file %s..." +msgstr "Leser affiksfil %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5462,8 +5462,8 @@ msgstr "%s-verdi er forskjellig fra det som er bruk i en annen .aff-fil" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Leser ordlistefil %s ..." +msgid "Reading dictionary file %s..." +msgstr "Leser ordlistefil %s..." #: ../spell.c:5611 #, c-format @@ -5497,8 +5497,8 @@ msgstr "Ignorerte %d ord med ikke-ASCII-tegn i %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Leser ordfil %s ..." +msgid "Reading word file %s..." +msgstr "Leser ordfil %s..." #: ../spell.c:6155 #, c-format @@ -5568,8 +5568,8 @@ msgstr "Totalt antall ord: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Skriver forslagsfil %s ..." +msgid "Writing suggestion file %s..." +msgstr "Skriver forslagsfil %s..." #: ../spell.c:7707 ../spell.c:7927 #, c-format @@ -5595,8 +5595,8 @@ msgstr "" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Lagrer stavefil %s ..." +msgid "Writing spell file %s..." +msgstr "Lagrer stavefil %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/pl.UTF-8.po b/src/nvim/po/pl.UTF-8.po index c65602344e..a348bf6203 100644 --- a/src/nvim/po/pl.UTF-8.po +++ b/src/nvim/po/pl.UTF-8.po @@ -1,5 +1,4 @@ -# translation of pl.po to Polish -# Polish Translation for Vim +# Polish translation for Vim # # updated 2013 for vim-7.4 # @@ -14,7 +13,7 @@ msgstr "" "Last-Translator: Mikolaj Machowski <mikmach@wp.pl>\n" "Language: pl\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " @@ -2441,7 +2440,7 @@ msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autokomendy ---" @@ -2465,7 +2464,7 @@ msgstr "E218: zbyt głębokie zagnieżdżenie autokomend" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Autokomend dla \"%s\"" #: ../fileio.c:7149 @@ -3358,7 +3357,7 @@ msgstr "-q [errorfile] edytuj plik, zawierajÄ…cy pierwszy błąd" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5279,8 +5278,8 @@ msgstr "Ostrzeżenie: region %s nie jest wspierany" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Czytam plik afiksów %s ..." +msgid "Reading affix file %s..." +msgstr "Czytam plik afiksów %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5442,8 +5441,8 @@ msgstr "Wartość %s różni siÄ™ od tej użytej w innym pliku .aff" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Czytam plik sÅ‚ownika %s ..." +msgid "Reading dictionary file %s..." +msgstr "Czytam plik sÅ‚ownika %s..." #: ../spell.c:5611 #, c-format @@ -5480,8 +5479,8 @@ msgstr "ZignorowaÅ‚em %d słów ze znakami nie ASCII w %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "OdczytujÄ™ plik wyrazów %s ..." +msgid "Reading word file %s..." +msgstr "OdczytujÄ™ plik wyrazów %s..." #: ../spell.c:6155 #, c-format @@ -5550,8 +5549,8 @@ msgstr "CaÅ‚kowita liczba słów: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "ZapisujÄ™ plik sugestii %s ..." +msgid "Writing suggestion file %s..." +msgstr "ZapisujÄ™ plik sugestii %s..." #: ../spell.c:7707 ../spell.c:7927 #, c-format @@ -5577,8 +5576,8 @@ msgstr "Ostrzeżenie: okreÅ›lono zarówno zÅ‚ożenia jak i NOBREAK" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "ZapisujÄ™ plik sprawdzania pisowni %s ..." +msgid "Writing spell file %s..." +msgstr "ZapisujÄ™ plik sprawdzania pisowni %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/pt_BR.po b/src/nvim/po/pt_BR.po index f8d6ac3011..543f0bce27 100644 --- a/src/nvim/po/pt_BR.po +++ b/src/nvim/po/pt_BR.po @@ -3212,7 +3212,7 @@ msgstr "E216: Grupo ou evento inexistente: %s" #: ../fileio.c:6002 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autocomandos ---" @@ -5306,7 +5306,7 @@ msgstr "Aviso: região %s não é suportada" #: ../spell.c:4366 #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "Lendo arquivo de afixos %s..." #: ../spell.c:4405 ../spell.c:5451 ../spell.c:5956 @@ -5506,8 +5506,8 @@ msgstr "Foram ignoradas %d palavra(s) com caracteres não-ASCII em %s" #: ../spell.c:5931 #, c-format -msgid "Reading word file %s ..." -msgstr "Lendo arquivo de palavras %s ..." +msgid "Reading word file %s..." +msgstr "Lendo arquivo de palavras %s..." #: ../spell.c:5971 #, c-format @@ -6169,7 +6169,7 @@ msgstr "-q [arq.erro] editar arquivo e abrir no primeiro erro" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/po/ru.po b/src/nvim/po/ru.po index 12022d02c8..e5be489d72 100644 --- a/src/nvim/po/ru.po +++ b/src/nvim/po/ru.po @@ -2458,7 +2458,7 @@ msgstr "E216: ÐеÑущеÑÑ‚Ð²ÑƒÑŽÑ‰Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° или Ñобытие: % #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Ðвтокоманды ---" @@ -2482,7 +2482,7 @@ msgstr "E218: Ñлишком глубоко вложенные автокомаР#: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Ðвтокоманды Ð´Ð»Ñ \"%s\"" #: ../fileio.c:7149 @@ -3382,7 +3382,7 @@ msgstr "" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5102,7 +5102,7 @@ msgstr "E876: (рег. выражение ÐКÐ) недоÑтаточно Ð¼ÐµÑ #: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869 msgid "" -"Could not open temporary log file for writing, displaying on stderr ... " +"Could not open temporary log file for writing, displaying on stderr... " msgstr "" "Ðевозможно открыть файл временного журнала Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, вывод на stderr..." @@ -5345,8 +5345,8 @@ msgstr "Предупреждение: регион %s не поддерживаР#: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Чтение файла аффикÑов %s ..." +msgid "Reading affix file %s..." +msgstr "Чтение файла аффикÑов %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5509,8 +5509,8 @@ msgstr "%s имеет другое значение, чем в файле .aff" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Чтение файла ÑÐ»Ð¾Ð²Ð°Ñ€Ñ %s ..." +msgid "Reading dictionary file %s..." +msgstr "Чтение файла ÑÐ»Ð¾Ð²Ð°Ñ€Ñ %s..." #: ../spell.c:5611 #, c-format @@ -5544,8 +5544,8 @@ msgstr "Пропущено %d Ñлов Ñ Ð½Ðµ ASCII Ñимволами в %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Чтение файла Ñлов %s ..." +msgid "Reading word file %s..." +msgstr "Чтение файла Ñлов %s..." #: ../spell.c:6155 #, c-format @@ -5614,7 +5614,7 @@ msgstr "Общее количеÑтво Ñлов: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "ЗапиÑÑŒ файла Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸Ñправлений правопиÑÐ°Ð½Ð¸Ñ %s" #: ../spell.c:7707 ../spell.c:7927 @@ -5641,8 +5641,8 @@ msgstr "Предупреждение: оба ÑоÑтавные и указанР#: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "ЗапиÑÑŒ файла правопиÑÐ°Ð½Ð¸Ñ %s ..." +msgid "Writing spell file %s..." +msgstr "ЗапиÑÑŒ файла правопиÑÐ°Ð½Ð¸Ñ %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/sk.cp1250.po b/src/nvim/po/sk.cp1250.po index bf205938fa..74b8e1039c 100644 --- a/src/nvim/po/sk.cp1250.po +++ b/src/nvim/po/sk.cp1250.po @@ -2472,7 +2472,7 @@ msgstr "E216: Udalos alebo skupina %s neexistuje" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Automatické príkazy ---" @@ -2496,7 +2496,7 @@ msgstr "E218: vnorenia automatického príkazu sú príliš hlboké" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Automatické príkazy pre \"%s\"" #: ../fileio.c:7149 @@ -3390,7 +3390,7 @@ msgstr "-q [chybový súbor] upravi súbor na mieste výskytu prvej chyby" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5314,8 +5314,8 @@ msgstr "Varovanie: región %s nie je podporovaný" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Naèítavam súbor s príponami %s ..." +msgid "Reading affix file %s..." +msgstr "Naèítavam súbor s príponami %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5473,8 +5473,8 @@ msgstr "Hodnota %s sa odlišuje od hodnoty použitej v inom .aff súbore" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Naèítavam slovník %s ..." +msgid "Reading dictionary file %s..." +msgstr "Naèítavam slovník %s..." #: ../spell.c:5611 #, c-format @@ -5508,8 +5508,8 @@ msgstr "Ignorovaných %d slov s nepísmennými znakmi v %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Naèítavam súbor so slovami %s ..." +msgid "Reading word file %s..." +msgstr "Naèítavam súbor so slovami %s..." #: ../spell.c:6155 #, c-format @@ -5606,8 +5606,8 @@ msgstr "Varovanie: špecifikované spájanie a nezalamovanie" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Ukládám slovníkový súbor %s ..." +msgid "Writing spell file %s..." +msgstr "Ukládám slovníkový súbor %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/sk.po b/src/nvim/po/sk.po index 3c92ec3c34..d3f954f6d8 100644 --- a/src/nvim/po/sk.po +++ b/src/nvim/po/sk.po @@ -2472,7 +2472,7 @@ msgstr "E216: Udalos» alebo skupina %s neexistuje" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Automatické príkazy ---" @@ -2496,7 +2496,7 @@ msgstr "E218: vnorenia automatického príkazu sú príli¹ hlboké" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Automatické príkazy pre \"%s\"" #: ../fileio.c:7149 @@ -3390,7 +3390,7 @@ msgstr "-q [chybový súbor] upravi» súbor na mieste výskytu prvej chyby" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5314,8 +5314,8 @@ msgstr "Varovanie: región %s nie je podporovaný" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." -msgstr "Naèítavam súbor s príponami %s ..." +msgid "Reading affix file %s..." +msgstr "Naèítavam súbor s príponami %s..." #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 #, c-format @@ -5473,8 +5473,8 @@ msgstr "Hodnota %s sa odli¹uje od hodnoty pou¾itej v inom .aff súbore" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Naèítavam slovník %s ..." +msgid "Reading dictionary file %s..." +msgstr "Naèítavam slovník %s..." #: ../spell.c:5611 #, c-format @@ -5508,8 +5508,8 @@ msgstr "Ignorovaných %d slov s nepísmennými znakmi v %s" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." -msgstr "Naèítavam súbor so slovami %s ..." +msgid "Reading word file %s..." +msgstr "Naèítavam súbor so slovami %s..." #: ../spell.c:6155 #, c-format @@ -5606,8 +5606,8 @@ msgstr "Varovanie: ¹pecifikované spájanie a nezalamovanie" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." -msgstr "Ukládám slovníkový súbor %s ..." +msgid "Writing spell file %s..." +msgstr "Ukládám slovníkový súbor %s..." #: ../spell.c:7925 msgid "Done!" diff --git a/src/nvim/po/sr.po b/src/nvim/po/sr.po new file mode 100644 index 0000000000..88c5d18866 --- /dev/null +++ b/src/nvim/po/sr.po @@ -0,0 +1,7115 @@ +# Serbian Cyrillic translation for Vim +# +# Do ":help uganda" in Vim to read copying and usage conditions. +# Do ":help credits" in Vim to see a list of people who contributed. +# Copyright (C) 2017 +# This file is distributed under the same license as the Vim package. +# FIRST AUTHOR Ivan PeÅ¡ić <ivan.pesic@gmail.com>, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: Vim(Serbian)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-05-15 11:55+0400\n" +"PO-Revision-Date: 2018-05-15 10:50+0400\n" +"Last-Translator: Ivan PeÅ¡ić <ivan.pesic@gmail.com>\n" +"Language-Team: Serbian\n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +msgid "E831: bf_key_init() called with empty password" +msgstr "E831: bf_key_init() је позвана Ñа празном лозинком" + +msgid "E820: sizeof(uint32_t) != 4" +msgstr "E820: sizeof(uint32_t) != 4" + +msgid "E817: Blowfish big/little endian use wrong" +msgstr "E817: Blowfish употреба big/little endian је погрешна" + +msgid "E818: sha256 test failed" +msgstr "E818: sha256 теÑÑ‚ није уÑпео" + +msgid "E819: Blowfish test failed" +msgstr "E819: Blowfish теÑÑ‚ није уÑпео" + +msgid "[Location List]" +msgstr "[ЛиÑта локација]" + +msgid "[Quickfix List]" +msgstr "[Quickfix лиÑта]" + +msgid "E855: Autocommands caused command to abort" +msgstr "E855: Ðутокоманде Ñу изазвале прекид команде" + +msgid "E82: Cannot allocate any buffer, exiting..." +msgstr "E82: Ðе може да Ñе резервише меморија ни за један бафер, излазак..." + +msgid "E83: Cannot allocate buffer, using other one..." +msgstr "E83: Ðе може да Ñе резервише меморија за бафер, кориÑти Ñе други..." + +msgid "E931: Buffer cannot be registered" +msgstr "E931: Бафер не може да Ñе региÑтрује" + +msgid "E937: Attempt to delete a buffer that is in use" +msgstr "E937: Покушај бриÑања бафера који је у употреби" + +msgid "E515: No buffers were unloaded" +msgstr "E515: Ðиједан бафер није уклоњен из меморије" + +msgid "E516: No buffers were deleted" +msgstr "E516: Ðиједан бафер није обриÑан" + +msgid "E517: No buffers were wiped out" +msgstr "E517: Ðиједан бафер није очишћен" + +msgid "1 buffer unloaded" +msgstr "1 бафер је уклоњен из меморије" + +#, c-format +msgid "%d buffers unloaded" +msgstr "%d бафера је уклоњено из меморије" + +msgid "1 buffer deleted" +msgstr "1 бафер је обриÑан" + +#, c-format +msgid "%d buffers deleted" +msgstr "%d бафера је обриÑано" + +msgid "1 buffer wiped out" +msgstr "1 бафер је очишћен" + +#, c-format +msgid "%d buffers wiped out" +msgstr "%d бафера је очишћено" + +msgid "E90: Cannot unload last buffer" +msgstr "E90: ПоÑледњи бафер не може да Ñе уклони из меморије" + +msgid "E84: No modified buffer found" +msgstr "E84: Ðије пронађен измењени бафер" + +msgid "E85: There is no listed buffer" +msgstr "E85: Ðема бафера на лиÑти" + +msgid "E87: Cannot go beyond last buffer" +msgstr "E87: Ðе може да Ñе иде иза поÑледњег бафера" + +msgid "E88: Cannot go before first buffer" +msgstr "E88: Ðе може да Ñе иде иÑпред првог бафера" + +#, c-format +msgid "E89: No write since last change for buffer %ld (add ! to override)" +msgstr "" +"E89: Од поÑледње измене није било упиÑа за бафер %ld (додајте ! да " +"премоÑтите)" + +msgid "E948: Job still running (add ! to end the job)" +msgstr "E948: Задатак Ñе још извршава (додајте ! да зауÑтавите задатак)" + +msgid "E37: No write since last change (add ! to override)" +msgstr "E37: Ðије било упиÑа од поÑледње промене (додајте ! да премоÑтите)" + +msgid "E948: Job still running" +msgstr "E948: Задатак Ñе и даље извршава" + +msgid "E37: No write since last change" +msgstr "E37: Ðије било упиÑа од поÑледње промене" + +msgid "W14: Warning: List of file names overflow" +msgstr "" +"W14: Упозорење: Прекорачена је макÑимална величина лиÑте имена датотека" + +#, c-format +msgid "E92: Buffer %ld not found" +msgstr "E92: Бафер %ld није пронађен" + +#, c-format +msgid "E93: More than one match for %s" +msgstr "E93: Више од једног подударања Ñа %s" + +#, c-format +msgid "E94: No matching buffer for %s" +msgstr "E94: Ðиједан бафер Ñе не подудара Ñа %s" + +#, c-format +msgid "line %ld" +msgstr "линија %ld" + +msgid "E95: Buffer with this name already exists" +msgstr "E95: Бафер Ñа овим именом већ поÑтоји" + +msgid " [Modified]" +msgstr "[Измењено]" + +msgid "[Not edited]" +msgstr "[Ðије уређивано]" + +msgid "[New file]" +msgstr "[Ðова датотека]" + +msgid "[Read errors]" +msgstr "[Грешке при читању]" + +msgid "[RO]" +msgstr "[СЧ]" + +msgid "[readonly]" +msgstr "[Ñамо за читање]" + +#, c-format +msgid "1 line --%d%%--" +msgstr "1 линија --%d%%--" + +#, c-format +msgid "%ld lines --%d%%--" +msgstr "%ld линија --%d%%--" + +#, c-format +msgid "line %ld of %ld --%d%%-- col " +msgstr "линија %ld од %ld --%d%%-- кол " + +msgid "[No Name]" +msgstr "[Без имена]" + +msgid "help" +msgstr "помоћ" + +msgid "[Help]" +msgstr "[Помоћ]" + +msgid "[Preview]" +msgstr "[Преглед]" + +msgid "All" +msgstr "Све" + +msgid "Bot" +msgstr "Дно" + +msgid "Top" +msgstr "Врх" + +msgid "" +"\n" +"# Buffer list:\n" +msgstr "" +"\n" +"# ЛиÑта бафера:\n" + +msgid "E382: Cannot write, 'buftype' option is set" +msgstr "E382: Ð£Ð¿Ð¸Ñ Ð½Ð¸Ñ˜Ðµ могућ, поÑтављена је 'buftype' опција" + +msgid "[Scratch]" +msgstr "[Празно]" + +msgid "" +"\n" +"--- Signs ---" +msgstr "" +"\n" +"--- Знаци ---" + +#, c-format +msgid "Signs for %s:" +msgstr "Знаци за %s:" + +#, c-format +msgid " line=%ld id=%d name=%s" +msgstr " линија=%ld ид=%d име=%s" + +msgid "E902: Cannot connect to port" +msgstr "E902: Повезивање на порт није могуће" + +msgid "E901: gethostbyname() in channel_open()" +msgstr "E901: gethostbyname() у channel_open()" + +msgid "E898: socket() in channel_open()" +msgstr "E898: socket() у channel_open()" + +msgid "E903: received command with non-string argument" +msgstr "E903: примњена команда Ñа аргуменом који није Ñтринг" + +msgid "E904: last argument for expr/call must be a number" +msgstr "E904: поÑледњи аргумент за expr/call мора бити број" + +msgid "E904: third argument for call must be a list" +msgstr "E904: трећи аргумент за call мора бити лиÑта" + +#, c-format +msgid "E905: received unknown command: %s" +msgstr "E905: примљена непозната команда: %s" + +#, c-format +msgid "E630: %s(): write while not connected" +msgstr "E630: %s(): ÑƒÐ¿Ð¸Ñ Ð´Ð¾Ðº није уÑпоÑтављена веза" + +#, c-format +msgid "E631: %s(): write failed" +msgstr "E631: %s(): ÑƒÐ¿Ð¸Ñ Ð½Ð¸Ñ˜Ðµ уÑпео" + +#, c-format +msgid "E917: Cannot use a callback with %s()" +msgstr "E917: Callback не може да Ñе кориÑти Ñа %s()" + +msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" +msgstr "" +"E912: ch_evalexpr()/ch_sendexpr() не може да Ñе кориÑти Ñа raw или nl каналом" + +msgid "E906: not an open channel" +msgstr "E906: није отворен канал" + +msgid "E920: _io file requires _name to be set" +msgstr "E920: _io датотека захтева да _name буде поÑтављено" + +msgid "E915: in_io buffer requires in_buf or in_name to be set" +msgstr "E915: in_io бафер захтева да in_buf или in_name буде поÑтављено" + +#, c-format +msgid "E918: buffer must be loaded: %s" +msgstr "E918: бафер мора бити учитан: %s" + +msgid "E821: File is encrypted with unknown method" +msgstr "E821: Датотека је шифрована непознатом методом" + +msgid "Warning: Using a weak encryption method; see :help 'cm'" +msgstr "Упозорење: КориÑти Ñе Ñлаба метода шифрирања; погледајте :help 'cm'" + +msgid "Enter encryption key: " +msgstr "УнеÑите кључ за шифрирање: " + +msgid "Enter same key again: " +msgstr "УнеÑите иÑти кључ поново: " + +msgid "Keys don't match!" +msgstr "Кључеви ниÑу иÑти!" + +msgid "[crypted]" +msgstr "[шифровано]" + +#, c-format +msgid "E720: Missing colon in Dictionary: %s" +msgstr "E720: ÐедоÑтаје тачка-зарез у Речнику: %s" + +#, c-format +msgid "E721: Duplicate key in Dictionary: \"%s\"" +msgstr "E721: Дупликат кључа у Речнику: \"%s\"" + +#, c-format +msgid "E722: Missing comma in Dictionary: %s" +msgstr "E722: ÐедоÑтаје зарез у Речнику: %s" + +#, c-format +msgid "E723: Missing end of Dictionary '}': %s" +msgstr "E723: ÐедоÑтаје крај Речника '}': %s" + +msgid "extend() argument" +msgstr "extend() аргумент" + +#, c-format +msgid "E737: Key already exists: %s" +msgstr "E737: Кључ већ поÑтоји: %s" + +#, c-format +msgid "E96: Cannot diff more than %ld buffers" +msgstr "E96: Ðе може да Ñе упоређује више од %ld бафера" + +msgid "E810: Cannot read or write temp files" +msgstr "E810: Ðије могуће читање или ÑƒÐ¿Ð¸Ñ Ñƒ привремене датотеке" + +msgid "E97: Cannot create diffs" +msgstr "E97: Ðије могуће креирање diff-ова" + +msgid "Patch file" +msgstr "Patch датотека" + +msgid "E816: Cannot read patch output" +msgstr "E816: Ðије могуће читање patch излаза" + +msgid "E98: Cannot read diff output" +msgstr "E98: Ðије могуће читање diff излаза" + +msgid "E99: Current buffer is not in diff mode" +msgstr "E99: Текући бафер није у diff режиму" + +msgid "E793: No other buffer in diff mode is modifiable" +msgstr "E793: Ðиједан други бафер у diff режиму није измењив" + +msgid "E100: No other buffer in diff mode" +msgstr "E100: ниједан други бафер није у diff режиму" + +msgid "E101: More than two buffers in diff mode, don't know which one to use" +msgstr "E101: Више од два бафера Ñу у diff режиму, не знам који да кориÑтим" + +#, c-format +msgid "E102: Can't find buffer \"%s\"" +msgstr "E102: Бафер \"%s\" не може да Ñе пронађе" + +#, c-format +msgid "E103: Buffer \"%s\" is not in diff mode" +msgstr "E103: Бафер \"%s\" није у diff режиму" + +msgid "E787: Buffer changed unexpectedly" +msgstr "E787: Бафер је неочекивано измењен" + +msgid "E104: Escape not allowed in digraph" +msgstr "E104: Escape није дозвољен у digraph" + +msgid "E544: Keymap file not found" +msgstr "E544: Keymap датотека није пронађена" + +msgid "E105: Using :loadkeymap not in a sourced file" +msgstr "E105: Коришћење :loadkeymap ван датотеке која Ñе учитава као Ñкрипта" + +msgid "E791: Empty keymap entry" +msgstr "E791: Празна keymap Ñтавка" + +msgid " Keyword completion (^N^P)" +msgstr " Довршавање кључне речи (^N^P)" + +msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" +msgstr " ^X режим (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)" + +msgid " Whole line completion (^L^N^P)" +msgstr " Довршавање целе линије (^L^N^P)" + +msgid " File name completion (^F^N^P)" +msgstr " Довршавање имена датотеке (^F^N^P)" + +msgid " Tag completion (^]^N^P)" +msgstr " Довршавање ознаке (^]^N^P)" + +msgid " Path pattern completion (^N^P)" +msgstr " Довршавање шаблона путање (^N^P)" + +msgid " Definition completion (^D^N^P)" +msgstr " Довршавање дефиниције (^D^N^P)" + +msgid " Dictionary completion (^K^N^P)" +msgstr " Довршавање речника (^K^N^P)" + +msgid " Thesaurus completion (^T^N^P)" +msgstr " Довршавање речника Ñинонима (^T^N^P)" + +msgid " Command-line completion (^V^N^P)" +msgstr " Довршавање командне линије (^V^N^P)" + +msgid " User defined completion (^U^N^P)" +msgstr " КориÑнички дефиниÑано довршавање (^U^N^P)" + +msgid " Omni completion (^O^N^P)" +msgstr " Omni довршавање (^O^N^P)" + +msgid " Spelling suggestion (s^N^P)" +msgstr " ПравопиÑни предлог (s^N^P)" + +msgid " Keyword Local completion (^N^P)" +msgstr " Довршавање локалне кључне речи (^N^P)" + +msgid "Hit end of paragraph" +msgstr "ДоÑтигнут крај паÑуÑа" + +msgid "E839: Completion function changed window" +msgstr "E839: Функција довршавања је променила прозор" + +msgid "E840: Completion function deleted text" +msgstr "E840: Функција довршавања је обриÑала текÑÑ‚" + +msgid "'dictionary' option is empty" +msgstr "Опција 'dictionary' је празна" + +msgid "'thesaurus' option is empty" +msgstr "Опција 'thesaurus' је празна" + +#, c-format +msgid "Scanning dictionary: %s" +msgstr "Скенирање речника: %s" + +msgid " (insert) Scroll (^E/^Y)" +msgstr " (уметање) Скроловање (^E/^Y)" + +msgid " (replace) Scroll (^E/^Y)" +msgstr " (замена) Скроловање (^E/^Y)" + +#, c-format +msgid "Scanning: %s" +msgstr "Скенирање: %s" + +msgid "Scanning tags." +msgstr "Скенирање ознака." + +msgid "match in file" +msgstr "подударање у датотеци" + +msgid " Adding" +msgstr " Додавање" + +msgid "-- Searching..." +msgstr "-- Претрага..." + +msgid "Back at original" +msgstr "Ðазад на оригинал" + +msgid "Word from other line" +msgstr "Реч из друге линије" + +msgid "The only match" +msgstr "Једино подударање" + +#, c-format +msgid "match %d of %d" +msgstr "подударање %d од %d" + +#, c-format +msgid "match %d" +msgstr "подударање %d" + +msgid "E18: Unexpected characters in :let" +msgstr "E18: Ðеочекивани карактери у :let" + +#, c-format +msgid "E121: Undefined variable: %s" +msgstr "E121: ÐедефиниÑана променљива: %s" + +msgid "E111: Missing ']'" +msgstr "E111: ÐедоÑтаје ']'" + +msgid "E719: Cannot use [:] with a Dictionary" +msgstr "E719: Ðе може да Ñе кориÑти [:] Ñа Речником" + +#, c-format +msgid "E734: Wrong variable type for %s=" +msgstr "E734: Погрешан тип променљиве за %s=" + +#, c-format +msgid "E461: Illegal variable name: %s" +msgstr "E461: Ðедозвољено име променљиве: %s" + +msgid "E806: using Float as a String" +msgstr "E806: коришћење Float као String" + +msgid "E687: Less targets than List items" +msgstr "E687: Мање одредишта него Ñтавки ЛиÑте" + +msgid "E688: More targets than List items" +msgstr "E688: Више одредишта него Ñтавки ЛиÑте" + +msgid "Double ; in list of variables" +msgstr "Дупле ; у лиÑти променљивих" + +#, c-format +msgid "E738: Can't list variables for %s" +msgstr "E738: Ðе може да Ñе прикаже лиÑта променљивих за %s" + +msgid "E689: Can only index a List or Dictionary" +msgstr "E689: Само ЛиÑта или Речник могу да Ñе индекÑирају" + +msgid "E708: [:] must come last" +msgstr "E708: [:] мора да буде поÑледња" + +msgid "E709: [:] requires a List value" +msgstr "E709: [:] захтева вредноÑÑ‚ типа List" + +msgid "E710: List value has more items than target" +msgstr "E710: ВредноÑÑ‚ типа List има више Ñтавки него одредиште" + +msgid "E711: List value has not enough items" +msgstr "E711: ВредноÑÑ‚ типа List нема довољно Ñтавки" + +msgid "E690: Missing \"in\" after :for" +msgstr "E690: ÐедоÑтаје \"in\" након :for" + +#, c-format +msgid "E108: No such variable: \"%s\"" +msgstr "E108: Ðе поÑтоји таква променљива: \"%s\"" + +#, c-format +msgid "E940: Cannot lock or unlock variable %s" +msgstr "E940: Ðе може да Ñе откључа или закључа променљива %s" + +msgid "E743: variable nested too deep for (un)lock" +msgstr "E743: променљива је угњеждена Ñувише дубоко да би Ñе за(от)кључала" + +msgid "E109: Missing ':' after '?'" +msgstr "E109: ÐедоÑтаје ':' након '?'" + +msgid "E804: Cannot use '%' with Float" +msgstr "E804: '%' не може да Ñе кориÑти Ñа Float" + +msgid "E110: Missing ')'" +msgstr "E110: ÐедоÑтаје ')'" + +msgid "E695: Cannot index a Funcref" +msgstr "E695: Funcref не може да Ñе индекÑира" + +msgid "E909: Cannot index a special variable" +msgstr "E909: Специјална променљива не може да Ñе индекÑира" + +#, c-format +msgid "E112: Option name missing: %s" +msgstr "E112: ÐедоÑтаје име опције: %s" + +#, c-format +msgid "E113: Unknown option: %s" +msgstr "E113: Ðепозната опција: %s" + +#, c-format +msgid "E114: Missing quote: %s" +msgstr "E114: ÐедоÑтаје наводник: %s" + +#, c-format +msgid "E115: Missing quote: %s" +msgstr "E115: ÐедоÑтаје наводник: %s" + +msgid "Not enough memory to set references, garbage collection aborted!" +msgstr "" +"Ðема довољно меморије за поÑтављање референци, прекинуто је Ñкупљање отпада" + +msgid "E724: variable nested too deep for displaying" +msgstr "E724: променљива је угњеждена предубоко да би Ñе приказала" + +msgid "E805: Using a Float as a Number" +msgstr "E805: КориÑти Ñе Float као Number" + +msgid "E703: Using a Funcref as a Number" +msgstr "E703: КориÑти Ñе Funcref као Number" + +msgid "E745: Using a List as a Number" +msgstr "E745: КориÑти Ñе List као Number" + +msgid "E728: Using a Dictionary as a Number" +msgstr "E728: КориÑти Ñе Dictionary као Number" + +msgid "E910: Using a Job as a Number" +msgstr "E910: КориÑти Ñе Job као Number" + +msgid "E913: Using a Channel as a Number" +msgstr "E913: КориÑти Ñе Channel као Number" + +msgid "E891: Using a Funcref as a Float" +msgstr "E891: КориÑти Ñе Funcref као Float" + +msgid "E892: Using a String as a Float" +msgstr "E892: КориÑти Ñе String као Float" + +msgid "E893: Using a List as a Float" +msgstr "E893: КориÑти Ñе List као Float" + +msgid "E894: Using a Dictionary as a Float" +msgstr "E894: КориÑти Ñе Dictionary као Float" + +msgid "E907: Using a special value as a Float" +msgstr "E907: КориÑти Ñе Ñпецијална вредноÑÑ‚ као Float" + +msgid "E911: Using a Job as a Float" +msgstr "E911: КориÑти Ñе Job као Float" + +msgid "E914: Using a Channel as a Float" +msgstr "E914: КориÑти Ñе Channel као Float" + +msgid "E729: using Funcref as a String" +msgstr "E729: кориÑти Ñе Funcref као String" + +msgid "E730: using List as a String" +msgstr "E730: кориÑти Ñе List као String" + +msgid "E731: using Dictionary as a String" +msgstr "E731: кориÑти Ñе Dictionary као String" + +msgid "E908: using an invalid value as a String" +msgstr "E908: кориÑти Ñе недозвољена вредноÑÑ‚ као String" + +#, c-format +msgid "E795: Cannot delete variable %s" +msgstr "E795: Променљива %s не може да Ñе обрише" + +#, c-format +msgid "E704: Funcref variable name must start with a capital: %s" +msgstr "E704: Име Funcref мора да почне великим Ñловом: %s" + +#, c-format +msgid "E705: Variable name conflicts with existing function: %s" +msgstr "E705: Име променљиве је у конфликту Ñа поÑтојећом функцијом: %s" + +#, c-format +msgid "E741: Value is locked: %s" +msgstr "E741: ВредноÑÑ‚ је закључана: %s" + +msgid "Unknown" +msgstr "Ðепознато" + +#, c-format +msgid "E742: Cannot change value of %s" +msgstr "E742: ВредноÑÑ‚ %s не може да Ñе промени" + +msgid "E698: variable nested too deep for making a copy" +msgstr "E698: променљива је предубоко угњеждена да би Ñе направила копија" + +msgid "" +"\n" +"# global variables:\n" +msgstr "" +"\n" +"# глобалне променљиве:\n" + +msgid "" +"\n" +"\tLast set from " +msgstr "" +"\n" +"\tПоÑледњи Ñет од " + +msgid "E691: Can only compare List with List" +msgstr "E691: List може да Ñе пореди Ñамо Ñа List" + +msgid "E692: Invalid operation for List" +msgstr "E692: ÐеиÑправна операција за List" + +msgid "E735: Can only compare Dictionary with Dictionary" +msgstr "E735: Dictionary може да Ñе пореди Ñамо Ñа Dictionary" + +msgid "E736: Invalid operation for Dictionary" +msgstr "E736: ÐеиÑправна операција за Dictionary" + +msgid "E694: Invalid operation for Funcrefs" +msgstr "E694: ÐеиÑправна операција за Funcrefs" + +msgid "map() argument" +msgstr "map() аргумент" + +msgid "filter() argument" +msgstr "filter() аргумент" + +#, c-format +msgid "E686: Argument of %s must be a List" +msgstr "E686: Ðргумент за %s мора бити List" + +msgid "E928: String required" +msgstr "E928: Захтева Ñе String" + +msgid "E808: Number or Float required" +msgstr "E808: Захтева Ñе Number или Float" + +msgid "add() argument" +msgstr "add() аргумент" + +msgid "E785: complete() can only be used in Insert mode" +msgstr "E785: complete() може да Ñе кориÑти Ñамо у режиму Уметање" + +msgid "&Ok" +msgstr "&Ок" + +#, c-format +msgid "+-%s%3ld line: " +msgid_plural "+-%s%3ld lines: " +msgstr[0] "+-%s%3ld линија: " +msgstr[1] "+-%s%3ld линија: " + +#, c-format +msgid "E700: Unknown function: %s" +msgstr "E700: Ðепозната функција: %s" + +msgid "E922: expected a dict" +msgstr "E922: очекивао Ñе dict" + +msgid "E923: Second argument of function() must be a list or a dict" +msgstr "E923: Други аргумент function() мора бити list или dict" + +msgid "" +"&OK\n" +"&Cancel" +msgstr "" +"&OK\n" +"О&ткажи" + +msgid "called inputrestore() more often than inputsave()" +msgstr "inputrestore() је позвана више пута него inputsave()" + +msgid "insert() argument" +msgstr "insert() аргумент" + +msgid "E786: Range not allowed" +msgstr "E786: ОпÑег није дозвољен" + +msgid "E916: not a valid job" +msgstr "E916: није валидан job" + +msgid "E701: Invalid type for len()" +msgstr "E701: ÐеиÑправан тип за len()" + +#, c-format +msgid "E798: ID is reserved for \":match\": %ld" +msgstr "E798: ИД је резервиÑан за \":match\": %ld" + +msgid "E726: Stride is zero" +msgstr "E726: Корак је нула" + +msgid "E727: Start past end" +msgstr "E727: Почетак иза краја" + +msgid "<empty>" +msgstr "<празно>" + +msgid "E240: No connection to the X server" +msgstr "E240: Ðема везе Ñа X Ñервером" + +#, c-format +msgid "E241: Unable to send to %s" +msgstr "E241: Слање ка %s није могуће" + +msgid "E277: Unable to read a server reply" +msgstr "E277: Ðе може да Ñе прочита одговор Ñервера" + +msgid "E941: already started a server" +msgstr "E941: Ñервер је већ покренут" + +msgid "E942: +clientserver feature not available" +msgstr "E942: МогућноÑÑ‚ +clientserver није доÑтупна" + +msgid "remove() argument" +msgstr "remove() аргумент" + +msgid "E655: Too many symbolic links (cycle?)" +msgstr "E655: Превише Ñимболичких веза (циклуÑ?)" + +msgid "reverse() argument" +msgstr "reverse() аргумент" + +msgid "E258: Unable to send to client" +msgstr "E258: Слање ка клијенту није могуће" + +#, c-format +msgid "E927: Invalid action: '%s'" +msgstr "E927: ÐеиÑправна акција: '%s'" + +msgid "sort() argument" +msgstr "sort() аргумент" + +msgid "uniq() argument" +msgstr "uniq() аргумент" + +msgid "E702: Sort compare function failed" +msgstr "E702: Sort функција поређења није уÑпела" + +msgid "E882: Uniq compare function failed" +msgstr "E882: Uniq функција поређења није уÑпела" + +msgid "(Invalid)" +msgstr "(ÐеиÑправно)" + +#, c-format +msgid "E935: invalid submatch number: %d" +msgstr "E935: неиÑправан број подпоклапања: %d" + +msgid "E677: Error writing temp file" +msgstr "E677: Грешка при упиÑу temp датотеке" + +msgid "E921: Invalid callback argument" +msgstr "E921: ÐеиÑправан callback аргумент" + +#, c-format +msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s" +msgstr "<%s>%s%s %d, Ð¥ÐµÐºÑ %02x, Окт %03o, Дигр %s" + +#, c-format +msgid "<%s>%s%s %d, Hex %02x, Octal %03o" +msgstr "<%s>%s%s %d, Ð¥ÐµÐºÑ %02x, Октално %03o" + +#, c-format +msgid "> %d, Hex %04x, Oct %o, Digr %s" +msgstr "> %d, Ð¥ÐµÐºÑ %04x, Окт %o, Дигр %s" + +#, c-format +msgid "> %d, Hex %08x, Oct %o, Digr %s" +msgstr "> %d, Ð¥ÐµÐºÑ %08x, Окт %o, Дигр %s" + +#, c-format +msgid "> %d, Hex %04x, Octal %o" +msgstr "> %d, Ð¥ÐµÐºÑ %04x, Октално %o" + +#, c-format +msgid "> %d, Hex %08x, Octal %o" +msgstr "> %d, Ð¥ÐµÐºÑ %08x, Октално %o" + +msgid "E134: Move lines into themselves" +msgstr "E134: Премештање линија у Ñаме Ñебе" + +msgid "1 line moved" +msgstr "1 линија премештена" + +#, c-format +msgid "%ld lines moved" +msgstr "%ld линија премештено" + +#, c-format +msgid "%ld lines filtered" +msgstr "%ld линија филтрирано" + +msgid "E135: *Filter* Autocommands must not change current buffer" +msgstr "E135: *Филтер* Ðутокоманде не Ñмеју да мењају текући бафер" + +msgid "[No write since last change]\n" +msgstr "[Ðема упиÑа од поÑледње промене]\n" + +#, c-format +msgid "%sviminfo: %s in line: " +msgstr "%sviminfo: %s у линији: " + +msgid "E136: viminfo: Too many errors, skipping rest of file" +msgstr "E136: viminfo: Превише грешака, оÑтатак датотеке Ñе преÑкаче" + +#, c-format +msgid "Reading viminfo file \"%s\"%s%s%s" +msgstr "Читање viminfo датотеке \"%s\"%s%s%s" + +msgid " info" +msgstr " инфо" + +msgid " marks" +msgstr " маркера" + +msgid " oldfiles" +msgstr " Ñтарихдатотека" + +msgid " FAILED" +msgstr " ÐЕУСПЕЛО" + +#, c-format +msgid "E137: Viminfo file is not writable: %s" +msgstr "E137: Viminfo датотека није упиÑива: %s" + +#, c-format +msgid "E929: Too many viminfo temp files, like %s!" +msgstr "E929: Превише viminfo temp датотека, као %s!" + +#, c-format +msgid "E138: Can't write viminfo file %s!" +msgstr "E138: Viminfo датотека %s не може да Ñе упише!" + +#, c-format +msgid "Writing viminfo file \"%s\"" +msgstr "УпиÑивање viminfo датотеке \"%s\"" + +#, c-format +msgid "E886: Can't rename viminfo file to %s!" +msgstr "E886: Viminfo датотека не може да Ñе преименује у %s!" + +#, c-format +msgid "# This viminfo file was generated by Vim %s.\n" +msgstr "# Ову viminfo датотеку је генериÑао Vim %s.\n" + +msgid "" +"# You may edit it if you're careful!\n" +"\n" +msgstr "" +"# Можете да је уређујете ако Ñте опрезни!\n" +"\n" + +msgid "# Value of 'encoding' when this file was written\n" +msgstr "# ВредноÑÑ‚ опције 'encoding' када је ова датотека напиÑана\n" + +msgid "Illegal starting char" +msgstr "ÐеиÑправан почетни карактер" + +msgid "" +"\n" +"# Bar lines, copied verbatim:\n" +msgstr "" +"\n" +"# Преградне линије, копиране доÑловно:\n" + +msgid "Save As" +msgstr "Сачувај као" + +msgid "Write partial file?" +msgstr "Да упишем парцијалну датотеку?" + +msgid "E140: Use ! to write partial buffer" +msgstr "E140: КориÑтите ! да биÑте упиÑали парцијални бафер" + +#, c-format +msgid "Overwrite existing file \"%s\"?" +msgstr "Да препишем поÑтојећи датотеку \"%s\"?" + +#, c-format +msgid "Swap file \"%s\" exists, overwrite anyway?" +msgstr "Swap датотека \"%s\" поÑтоји, да је препишем у Ñваком Ñлучају?" + +#, c-format +msgid "E768: Swap file exists: %s (:silent! overrides)" +msgstr "E768: Swap датотека поÑтоји: %s (:silent! премошћава)" + +#, c-format +msgid "E141: No file name for buffer %ld" +msgstr "E141: Ðема имена датотеке за бафер %ld" + +msgid "E142: File not written: Writing is disabled by 'write' option" +msgstr "E142: Датотека није упиÑана: УпиÑивање је онемогућено опцијом 'write'" + +#, c-format +msgid "" +"'readonly' option is set for \"%s\".\n" +"Do you wish to write anyway?" +msgstr "" +"'readonly' опција је поÑтављена за \"%s\".\n" +"Да ли ипак желите да упишете?" + +#, c-format +msgid "" +"File permissions of \"%s\" are read-only.\n" +"It may still be possible to write it.\n" +"Do you wish to try?" +msgstr "" +"Дозволе датотеке \"%s\" омогућавају Ñамо читање.\n" +"Можда је ипак могуће да Ñе упише.\n" +"Да ли желите да покушате?" + +#, c-format +msgid "E505: \"%s\" is read-only (add ! to override)" +msgstr "E505: \"%s\" је Ñамо за читање (додајте ! за премошћавање)" + +msgid "Edit File" +msgstr "Уреди датотеку" + +#, c-format +msgid "E143: Autocommands unexpectedly deleted new buffer %s" +msgstr "E143: Ðутокоманде Ñу неочекивано обриÑале нов бафер %s" + +msgid "E144: non-numeric argument to :z" +msgstr "E144: ненумерички аргумент за :z" + +msgid "E145: Shell commands not allowed in rvim" +msgstr "E145: Shell команде ниÑу дозвољене у rvim" + +msgid "E146: Regular expressions can't be delimited by letters" +msgstr "E146: Регуларни изрази не могу да Ñе раздвајају Ñловима" + +#, c-format +msgid "replace with %s (y/n/a/q/l/^E/^Y)?" +msgstr "заменити Ñа %s (y/n/a/q/l/^E/^Y)?" + +msgid "(Interrupted) " +msgstr "(Прекинуто)" + +msgid "1 match" +msgstr "1 подударање" + +msgid "1 substitution" +msgstr "1 замена" + +#, c-format +msgid "%ld matches" +msgstr "%ld подударања" + +#, c-format +msgid "%ld substitutions" +msgstr "%ld замена" + +msgid " on 1 line" +msgstr " у 1 линији" + +#, c-format +msgid " on %ld lines" +msgstr " у %ld линија" + +msgid "E147: Cannot do :global recursive with a range" +msgstr "E147: :global не може да Ñе изврши рекурзивно Ñа опÑегом" + +msgid "E148: Regular expression missing from global" +msgstr "E148: У global недоÑтаје регуларни израз" + +#, c-format +msgid "Pattern found in every line: %s" +msgstr "Шаблон је пронаћен у Ñвакој линији: %s" + +#, c-format +msgid "Pattern not found: %s" +msgstr "Шаблон није пронађен: %s" + +msgid "" +"\n" +"# Last Substitute String:\n" +"$" +msgstr "" +"\n" +"# ПоÑледњи Стринг за замену:\n" +"$" + +msgid "E478: Don't panic!" +msgstr "E478: Ðе паничите!" + +#, c-format +msgid "E661: Sorry, no '%s' help for %s" +msgstr "E661: Жао нам је, нема '%s' помоћи за %s" + +#, c-format +msgid "E149: Sorry, no help for %s" +msgstr "E149: Жао нам је, нема помоћи за %s" + +#, c-format +msgid "Sorry, help file \"%s\" not found" +msgstr "Жао нам је, датотека помоћи \"%s\" није пронађена" + +#, c-format +msgid "E151: No match: %s" +msgstr "E151: Ðема подударања: %s" + +#, c-format +msgid "E152: Cannot open %s for writing" +msgstr "E152: %s не може да Ñе отвори за упиÑ" + +#, c-format +msgid "E153: Unable to open %s for reading" +msgstr "E153: %s не може да Ñе отвори за читање" + +#, c-format +msgid "E670: Mix of help file encodings within a language: %s" +msgstr "E670: Помешано је више кодирања фајлова помоћи за језик: %s" + +#, c-format +msgid "E154: Duplicate tag \"%s\" in file %s/%s" +msgstr "E154: Дуплирана ознака \"%s\" у датотеци %s/%s" + +#, c-format +msgid "E150: Not a directory: %s" +msgstr "E150: Ðије директоријум: %s" + +#, c-format +msgid "E160: Unknown sign command: %s" +msgstr "E160: Ðепозната знак команда: %s" + +msgid "E156: Missing sign name" +msgstr "E156: ÐедоÑтаје име знака" + +msgid "E612: Too many signs defined" +msgstr "E612: ДефиниÑано је превише знакова" + +#, c-format +msgid "E239: Invalid sign text: %s" +msgstr "E239: ÐеиÑправан текÑÑ‚ знака: %s" + +#, c-format +msgid "E155: Unknown sign: %s" +msgstr "E155: Ðепознат знак: %s" + +msgid "E159: Missing sign number" +msgstr "E159: ÐедоÑтаје број знака" + +#, c-format +msgid "E158: Invalid buffer name: %s" +msgstr "E158: ÐеиÑправно име бафера: %s" + +msgid "E934: Cannot jump to a buffer that does not have a name" +msgstr "E934: Ðе може да Ñе Ñкочи на бафер који нема име`" + +#, c-format +msgid "E157: Invalid sign ID: %ld" +msgstr "E157: ÐеиÑправан ИД знака: %ld" + +#, c-format +msgid "E885: Not possible to change sign %s" +msgstr "E885: Знак %s не може да Ñе промени" + +msgid " (NOT FOUND)" +msgstr " (ÐИЈЕ ПРОÐÐЂЕÐО)" + +msgid " (not supported)" +msgstr " (није подржано)" + +msgid "[Deleted]" +msgstr "[ОбриÑано]" + +msgid "No old files" +msgstr "Ðема Ñтарих датотека" + +msgid "Entering Debug mode. Type \"cont\" to continue." +msgstr "Улазак у Debug режим. Откуцајте \"cont\" за наÑтавак." + +#, c-format +msgid "Oldval = \"%s\"" +msgstr "Старавред = \"%s\"" + +#, c-format +msgid "Newval = \"%s\"" +msgstr "Ðоваавред = \"%s\"" + +#, c-format +msgid "line %ld: %s" +msgstr "линија %ld: %s" + +#, c-format +msgid "cmd: %s" +msgstr "ком: %s" + +msgid "frame is zero" +msgstr "оквир је нула" + +#, c-format +msgid "frame at highest level: %d" +msgstr "оквир је на највишем нивоу: %d" + +#, c-format +msgid "Breakpoint in \"%s%s\" line %ld" +msgstr "Прекидна тачка у \"%s%s\" линија %ld" + +#, c-format +msgid "E161: Breakpoint not found: %s" +msgstr "E161: Прекидна тачка није пронађена: %s" + +msgid "No breakpoints defined" +msgstr "Ðије дефиниÑана ниједна прекидна тачка" + +#, c-format +msgid "%3d %s %s line %ld" +msgstr "%3d %s %s линија %ld" + +#, c-format +msgid "%3d expr %s" +msgstr "%3d израз %s" + +msgid "E750: First use \":profile start {fname}\"" +msgstr "E750: Ðајпре кориÑтите \":profile start {fname}\"" + +#, c-format +msgid "Save changes to \"%s\"?" +msgstr "Да Ñачувам промене у \"%s\"?" + +#, c-format +msgid "E947: Job still running in buffer \"%s\"" +msgstr "E947: Задатак Ñе и даље извршава у баферу \"%s\"" + +#, c-format +msgid "E162: No write since last change for buffer \"%s\"" +msgstr "E162: Ðије било упиÑа од поÑледње промене за бафер \"%s\"" + +msgid "Warning: Entered other buffer unexpectedly (check autocommands)" +msgstr "Упозорење: Ðеочекивано Ñе прешло у други бафер (проверите аутокоманде)" + +msgid "E163: There is only one file to edit" +msgstr "E163: ПоÑтоји Ñамо једна датотека за уређивање" + +msgid "E164: Cannot go before first file" +msgstr "E164: Ðе може да Ñе иде иÑпред прве датотеке" + +msgid "E165: Cannot go beyond last file" +msgstr "E165: Ðе може да Ñе иде иÑпред прве датотеке" + +#, c-format +msgid "E666: compiler not supported: %s" +msgstr "E666: компајлер није подржан: %s" + +#, c-format +msgid "Searching for \"%s\" in \"%s\"" +msgstr "Тражи Ñе \"%s\" у \"%s\"" + +#, c-format +msgid "Searching for \"%s\"" +msgstr "Тражи Ñе\"%s\"" + +#, c-format +msgid "not found in '%s': \"%s\"" +msgstr "није пронађено у '%s': \"%s\"" + +#, c-format +msgid "W20: Required python version 2.x not supported, ignoring file: %s" +msgstr "" +"W20: Захтевани python version 2.x није подржан, датотека: %s Ñе игнорише" + +#, c-format +msgid "W21: Required python version 3.x not supported, ignoring file: %s" +msgstr "" +"W21: Захтевани python version 3.x није подржан, датотека: %s Ñе игнорише" + +msgid "Source Vim script" +msgstr "Изворна Vim Ñкрипта" + +#, c-format +msgid "Cannot source a directory: \"%s\"" +msgstr "Директоријум не може да буде извор: \"%s\"" + +#, c-format +msgid "could not source \"%s\"" +msgstr "не може бити извор \"%s\"" + +#, c-format +msgid "line %ld: could not source \"%s\"" +msgstr "линија %ld: не може бити извор \"%s\"" + +#, c-format +msgid "sourcing \"%s\"" +msgstr "прибављање \"%s\"" + +#, c-format +msgid "line %ld: sourcing \"%s\"" +msgstr "линија %ld: прибављање \"%s\"" + +#, c-format +msgid "finished sourcing %s" +msgstr "завршено прибављање %s" + +#, c-format +msgid "continuing in %s" +msgstr "наÑтавља Ñе у %s" + +msgid "modeline" +msgstr "режимÑка линија (modeline)" + +msgid "--cmd argument" +msgstr "--cmd аргумент" + +msgid "-c argument" +msgstr "-c аргумент" + +msgid "environment variable" +msgstr "променљива окружења" + +msgid "error handler" +msgstr "процедура за обраду грешке" + +msgid "W15: Warning: Wrong line separator, ^M may be missing" +msgstr "W15: Упозорење: Погрешан Ñепаратор линије, можда недоÑтаје ^M" + +msgid "E167: :scriptencoding used outside of a sourced file" +msgstr "E167: :scriptencoding Ñе кориÑти ван изворишне датотеке" + +msgid "E168: :finish used outside of a sourced file" +msgstr "E168: :finish Ñе кориÑти ван изворишне датотеке" + +#, c-format +msgid "Current %slanguage: \"%s\"" +msgstr "Текући %sјезик: \"%s\"" + +#, c-format +msgid "E197: Cannot set language to \"%s\"" +msgstr "E197: Језик не може да Ñе поÑтави на \"%s\"" + +msgid "Entering Ex mode. Type \"visual\" to go to Normal mode." +msgstr "" +"Улазак у Ex режим. Откуцајте \"visual\" да биÑте прешли у Ðормални режим." + +msgid "E501: At end-of-file" +msgstr "E501: Ðа крају-датотеке" + +msgid "E169: Command too recursive" +msgstr "E169: Команда је Ñувише рекурзивна" + +#, c-format +msgid "E605: Exception not caught: %s" +msgstr "E605: Изузетак није ухваћен: %s" + +msgid "End of sourced file" +msgstr "Крај изворишне датотеке" + +msgid "End of function" +msgstr "Крај функције" + +msgid "E464: Ambiguous use of user-defined command" +msgstr "E464: ДвоÑмиÑлена употреба кориÑнички дефиниÑане команде" + +msgid "E492: Not an editor command" +msgstr "E492: Ðије команда едитора" + +msgid "E493: Backwards range given" +msgstr "E493: Задат је опÑег уназад" + +msgid "Backwards range given, OK to swap" +msgstr "Задат је опÑег уназад, ОК да Ñе замени" + +msgid "E494: Use w or w>>" +msgstr "E494: КориÑтите w или w>>" + +msgid "E943: Command table needs to be updated, run 'make cmdidxs'" +msgstr "E943: Табела команди мора да Ñе оÑвежи, покрените 'make cmdidxs'" + +msgid "E319: Sorry, the command is not available in this version" +msgstr "E319: Жао нам је, та команда није доÑтупна у овој верзији" + +msgid "1 more file to edit. Quit anyway?" +msgstr "Још 1 датотека за уређивање. Ипак желите да напуÑтите програм?" + +#, c-format +msgid "%d more files to edit. Quit anyway?" +msgstr "Још %d датотека за уређивање. Ипак желите да напуÑтите програм?" + +msgid "E173: 1 more file to edit" +msgstr "E173: Још 1 датотека за уређивање" + +#, c-format +msgid "E173: %ld more files to edit" +msgstr "E173: Још %ld датотека за уређивање" + +msgid "E174: Command already exists: add ! to replace it" +msgstr "E174: Команда већ поÑтоји: додајте ! да је замените" + +msgid "" +"\n" +" Name Args Address Complete Definition" +msgstr "" +"\n" +" Име Ðргум ÐдреÑа Довршење Дефиниција" + +msgid "No user-defined commands found" +msgstr "ÐиÑу пронађене кориÑнички дефиниÑане команде" + +msgid "E175: No attribute specified" +msgstr "E175: Ðије наведен ни један атрибут" + +msgid "E176: Invalid number of arguments" +msgstr "E176: ÐеиÑправан број аргумената" + +msgid "E177: Count cannot be specified twice" +msgstr "E177: Бројач не може да Ñе наведе два пута" + +msgid "E178: Invalid default value for count" +msgstr "E178: ÐеÑправна подразумевана вредноÑÑ‚ за бројач" + +msgid "E179: argument required for -complete" +msgstr "E179: потребан је аргумент за -complete" + +msgid "E179: argument required for -addr" +msgstr "E179: потребан је аргумент за -addr" + +#, c-format +msgid "E181: Invalid attribute: %s" +msgstr "E181: ÐеиÑправан атрибут: %s" + +msgid "E182: Invalid command name" +msgstr "E182: ÐеиÑправно име команде" + +msgid "E183: User defined commands must start with an uppercase letter" +msgstr "E183: КориÑнички дефиниÑане команде морају да почну великим Ñловом" + +msgid "E841: Reserved name, cannot be used for user defined command" +msgstr "" +"E841: РезервиÑано име, не може да Ñе кориÑти за кориÑнички дефиниÑану команду" + +#, c-format +msgid "E184: No such user-defined command: %s" +msgstr "E184: Ðе поÑтоји таква кориÑнички дефиниÑана команда: %s" + +#, c-format +msgid "E180: Invalid address type value: %s" +msgstr "E180: ÐеиÑправна вредноÑÑ‚ адреÑног типа: %s" + +#, c-format +msgid "E180: Invalid complete value: %s" +msgstr "E180: ÐеиÑправна вредноÑÑ‚ довршавања: %s" + +msgid "E468: Completion argument only allowed for custom completion" +msgstr "E468: Ðргумент довршавања је дозвољен Ñамо за прилагођена довршавања" + +msgid "E467: Custom completion requires a function argument" +msgstr "E467: Прилагођено довршавање захтева аргумент функције" + +msgid "unknown" +msgstr "непознато" + +#, c-format +msgid "E185: Cannot find color scheme '%s'" +msgstr "E185: Шема боја '%s' не може да Ñе пронађе" + +msgid "Greetings, Vim user!" +msgstr "Поздрав, кориÑниче Vim-a" + +msgid "E784: Cannot close last tab page" +msgstr "E784: ПоÑледња картица не може да Ñе затвори" + +msgid "Already only one tab page" +msgstr "Већ Ñте на Ñамо једној картици" + +msgid "Edit File in new window" +msgstr "Уређивање Датотеке у новом прозору" + +#, c-format +msgid "Tab page %d" +msgstr "Картица %d" + +msgid "No swap file" +msgstr "Ðема swap датотеке" + +msgid "Append File" +msgstr "Додавање на крај Датотеке" + +msgid "E747: Cannot change directory, buffer is modified (add ! to override)" +msgstr "" +"E747: Директоријум не може да Ñе промени, бафер је измењен (додајте ! за " +"премошћавање)" + +msgid "E186: No previous directory" +msgstr "E186: Ðема претгодног директоријума" + +msgid "E187: Unknown" +msgstr "E187: Ðепознато" + +msgid "E465: :winsize requires two number arguments" +msgstr "E465: :winsize захтева два бројчана аргумента" + +#, c-format +msgid "Window position: X %d, Y %d" +msgstr "Позиција прозора: X %d, Y %d" + +msgid "E188: Obtaining window position not implemented for this platform" +msgstr "E188: Добављање позиције прозора није имплементирано за ову платформу" + +msgid "E466: :winpos requires two number arguments" +msgstr "E466: :winpos захтева два бројчана аргумента" + +msgid "E930: Cannot use :redir inside execute()" +msgstr "E930: :redir не може да Ñе кориÑти унутар execute()" + +msgid "Save Redirection" +msgstr "Сачувај Редирекцију" + +msgid "Save View" +msgstr "Сачувај Поглед" + +msgid "Save Session" +msgstr "Сачувај СеÑију" + +msgid "Save Setup" +msgstr "Сачувај Подешавање" + +#, c-format +msgid "E739: Cannot create directory: %s" +msgstr "E739: Директоријум не може да Ñе креира: %s" + +#, c-format +msgid "E189: \"%s\" exists (add ! to override)" +msgstr "E189: \"%s\" поÑтоји (додајте ! за премошћавање)" + +#, c-format +msgid "E190: Cannot open \"%s\" for writing" +msgstr "E190: \"%s\" не може да Ñе отвори за упиÑ" + +msgid "E191: Argument must be a letter or forward/backward quote" +msgstr "E191: Ðргумент мора бити Ñлово или апоÑтроф/обрнути апоÑтроф" + +msgid "E192: Recursive use of :normal too deep" +msgstr "E192: Рекурзивно коришћење :normal је Ñувише дубоко" + +msgid "E809: #< is not available without the +eval feature" +msgstr "E809: #< није доÑтупно без +eval могућноÑти" + +msgid "E194: No alternate file name to substitute for '#'" +msgstr "E194: Ðема алтернативног имена које би заменило '#'" + +msgid "E495: no autocommand file name to substitute for \"<afile>\"" +msgstr "E495: нема имена датотеке за аутокоманде које би заменило \"<afile>\"" + +msgid "E496: no autocommand buffer number to substitute for \"<abuf>\"" +msgstr "E496: нема броја бафера за аутокоманду који би заменио \"<abuf>\"" + +msgid "E497: no autocommand match name to substitute for \"<amatch>\"" +msgstr "E497: нема имена подударања аутокоманде које би заменило \"<amatch>\"" + +msgid "E498: no :source file name to substitute for \"<sfile>\"" +msgstr "E498: нема имена :source датотеке које би заменило \"<sfile>\"" + +msgid "E842: no line number to use for \"<slnum>\"" +msgstr "E842: нема броја линије који би Ñе кориÑтио за \"<slnum>\"" + +#, no-c-format +msgid "E499: Empty file name for '%' or '#', only works with \":p:h\"" +msgstr "E499: Празно име датотеке за'%' or '#', функционише Ñамо Ñа \":p:h\"" + +msgid "E500: Evaluates to an empty string" +msgstr "E500: Резултат израчунавања је празан Ñтринг" + +msgid "E195: Cannot open viminfo file for reading" +msgstr "E195: viminfo датотека не може да Ñе отвори за читање" + +msgid "Untitled" +msgstr "Без наÑлова" + +msgid "E196: No digraphs in this version" +msgstr "E196: У овој верзији нема диграфа" + +msgid "E608: Cannot :throw exceptions with 'Vim' prefix" +msgstr "E608: :throw изузетка Ñа 'Vim' префикÑом није дозвољен" + +#, c-format +msgid "Exception thrown: %s" +msgstr "Бачен је изузетак: %s" + +#, c-format +msgid "Exception finished: %s" +msgstr "Изузетак је завршен: %s" + +#, c-format +msgid "Exception discarded: %s" +msgstr "Изузетак је одбачен: %s" + +#, c-format +msgid "%s, line %ld" +msgstr "%s, линија %ld" + +#, c-format +msgid "Exception caught: %s" +msgstr "Изузетак је ухваћен: %s" + +#, c-format +msgid "%s made pending" +msgstr "%s је Ñтављен на чекање" + +#, c-format +msgid "%s resumed" +msgstr "%s је поново активан" + +#, c-format +msgid "%s discarded" +msgstr "%s је одбачен" + +msgid "Exception" +msgstr "Изузетак" + +msgid "Error and interrupt" +msgstr "Грешка и прекид" + +msgid "Error" +msgstr "Грешка" + +msgid "Interrupt" +msgstr "Прекид" + +msgid "E579: :if nesting too deep" +msgstr "E579: :if угњеждавање је Ñувише дубоко" + +msgid "E580: :endif without :if" +msgstr "E580: :endif без :if" + +msgid "E581: :else without :if" +msgstr "E581: :else без :if" + +msgid "E582: :elseif without :if" +msgstr "E582: :elseif без :if" + +msgid "E583: multiple :else" +msgstr "E583: вишеÑтруко :else" + +msgid "E584: :elseif after :else" +msgstr "E584: :elseif након :else" + +msgid "E585: :while/:for nesting too deep" +msgstr "E585: :while/:for угњеждавање је Ñувише дубоко" + +msgid "E586: :continue without :while or :for" +msgstr "E586: :continue без :while или :for" + +msgid "E587: :break without :while or :for" +msgstr "E587: :break без :while или :for" + +msgid "E732: Using :endfor with :while" +msgstr "E732: Коришћење :endfor Ñа :while" + +msgid "E733: Using :endwhile with :for" +msgstr "E733: Коришћење :endwhile Ñа :for" + +msgid "E601: :try nesting too deep" +msgstr "E601: :try угњеждавање је Ñувише дубоко" + +msgid "E603: :catch without :try" +msgstr "E603: :catch без :try" + +msgid "E604: :catch after :finally" +msgstr "E604: :catch након :finally" + +msgid "E606: :finally without :try" +msgstr "E606: :finally без :try" + +msgid "E607: multiple :finally" +msgstr "E607: вишеÑтруко :finally" + +msgid "E602: :endtry without :try" +msgstr "E602: :endtry без :try" + +msgid "E193: :endfunction not inside a function" +msgstr "E193: :endfunction није унутар функције" + +msgid "E788: Not allowed to edit another buffer now" +msgstr "E788: Уређивање другог бафера тренутно није дозвољено" + +msgid "E811: Not allowed to change buffer information now" +msgstr "E811: Мењање информација о баферу тренутно није дозвољено" + +msgid "tagname" +msgstr "ознака" + +msgid " kind file\n" +msgstr " врÑта датотеке\n" + +msgid "'history' option is zero" +msgstr "опција 'history' је нула" + +#, c-format +msgid "" +"\n" +"# %s History (newest to oldest):\n" +msgstr "" +"\n" +"# %s ИÑторија (од најновијег ка најÑтаријем):\n" + +msgid "Command Line" +msgstr "Командна линија" + +msgid "Search String" +msgstr "Стринг за претрагу" + +msgid "Expression" +msgstr "Израз" + +msgid "Input Line" +msgstr "Линија за уноÑ" + +msgid "Debug Line" +msgstr "Debug линија" + +msgid "E198: cmd_pchar beyond the command length" +msgstr "E198: cmd_pchar је иза дужине команде" + +msgid "E199: Active window or buffer deleted" +msgstr "E199: Active window or buffer deleted" + +msgid "E812: Autocommands changed buffer or buffer name" +msgstr "E812: Ðутокоманде Ñу промениле багер или име бафера" + +msgid "Illegal file name" +msgstr "Ðедозвољено име датотеке" + +msgid "is a directory" +msgstr "је директоријум" + +msgid "is not a file" +msgstr "није датотека" + +msgid "is a device (disabled with 'opendevice' option)" +msgstr "је уређај (онемогућен опцијом 'opendevice')" + +msgid "[New File]" +msgstr "[Ðова датотека]" + +msgid "[New DIRECTORY]" +msgstr "[Ðов ДИРЕКТОРИЈУМ]" + +msgid "[File too big]" +msgstr "[Датотека је Ñувише велика]" + +msgid "[Permission Denied]" +msgstr "[Дозвола одбијена]" + +msgid "E200: *ReadPre autocommands made the file unreadable" +msgstr "E200: *ReadPre аутокоманде Ñу учиниле датотеку нечитљивом" + +msgid "E201: *ReadPre autocommands must not change current buffer" +msgstr "E201: *ReadPre аутокоманде не Ñмеју да измене текући бафер" + +msgid "Vim: Reading from stdin...\n" +msgstr "Vim: Читање Ñа stdin...\n" + +msgid "Reading from stdin..." +msgstr "Читање Ñа stdin..." + +msgid "E202: Conversion made file unreadable!" +msgstr "E202: Конверзија је учинила датотеку нечитљивом!" + +msgid "[fifo/socket]" +msgstr "[fifo/утичница]" + +msgid "[fifo]" +msgstr "[fifo]" + +msgid "[socket]" +msgstr "[утичница]" + +msgid "[character special]" +msgstr "[Ñпецијални карактер]" + +msgid "[CR missing]" +msgstr "[недоÑтаје CR]" + +msgid "[long lines split]" +msgstr "[дуге линије преломљене]" + +msgid "[NOT converted]" +msgstr "[ÐИЈЕ конвертовано]" + +msgid "[converted]" +msgstr "[конвертовано]" + +#, c-format +msgid "[CONVERSION ERROR in line %ld]" +msgstr "[ГРЕШКРКОÐВЕРЗИЈЕ у линији %ld]" + +#, c-format +msgid "[ILLEGAL BYTE in line %ld]" +msgstr "[ÐЕДОЗВОЉЕРБÐЈТ у линији %ld]" + +msgid "[READ ERRORS]" +msgstr "[ГРЕШКЕ ПРИ ЧИТÐЊУ]" + +msgid "Can't find temp file for conversion" +msgstr "Привремена датотека за конверзију не може да Ñе пронађе" + +msgid "Conversion with 'charconvert' failed" +msgstr "Конверзија Ñа 'charconvert' није уÑпела" + +msgid "can't read output of 'charconvert'" +msgstr "излаз 'charconvert' не може да Ñе прочита" + +msgid "E676: No matching autocommands for acwrite buffer" +msgstr "E676: Ðема одговарајућих аутокоманди за acwrite бафер" + +msgid "E203: Autocommands deleted or unloaded buffer to be written" +msgstr "" +"E203: Ðутокоманде Ñу обриÑале или уклониле из меморије бафер који требало да " +"буде упиÑан" + +msgid "E204: Autocommand changed number of lines in unexpected way" +msgstr "E204: Ðутокоманде Ñу на неочекиван начин промениле број линија" + +msgid "NetBeans disallows writes of unmodified buffers" +msgstr "NetBeans не дозвољава ÑƒÐ¿Ð¸Ñ Ð½ÐµÐ¸Ð·Ð¼ÐµÑšÐµÐ½Ð¸Ñ… бафера" + +msgid "Partial writes disallowed for NetBeans buffers" +msgstr "Парцијални упиÑи ниÑу дозвољени за NetBeans бафере" + +msgid "is not a file or writable device" +msgstr "није датотека или уређај на који може да Ñе упиÑује" + +msgid "writing to device disabled with 'opendevice' option" +msgstr "ÑƒÐ¿Ð¸Ñ Ð½Ð° уређај је онемогућен опцијом 'opendevice'" + +msgid "is read-only (add ! to override)" +msgstr "је Ñамо за читање (додајте ! за премошћавање)" + +msgid "E506: Can't write to backup file (add ! to override)" +msgstr "" +"E506: Ðе може да Ñе упише у резервну датотеку (додајте ! за премошћавање)" + +msgid "E507: Close error for backup file (add ! to override)" +msgstr "" +"E507: Грешка код затварања за резервну датотеку (додајте ! за премошћавање)" + +msgid "E508: Can't read file for backup (add ! to override)" +msgstr "" +"E508: Резервна датотека не може да Ñе прочита (додајте ! за премошћавање)" + +msgid "E509: Cannot create backup file (add ! to override)" +msgstr "" +"E509: Резервна датотека не може да Ñе креира (додајте ! за премошћавање)" + +msgid "E510: Can't make backup file (add ! to override)" +msgstr "" +"E510: Резервна датотека не може да Ñе направи (додајте ! за премошћавање)" + +msgid "E214: Can't find temp file for writing" +msgstr "E214: Привремена датотека за ÑƒÐ¿Ð¸Ñ Ð½Ðµ може да Ñе пронађе" + +msgid "E213: Cannot convert (add ! to write without conversion)" +msgstr "E213: Конверзија није могућа (додајте ! за ÑƒÐ¿Ð¸Ñ Ð±ÐµÐ· конверзије)" + +msgid "E166: Can't open linked file for writing" +msgstr "E166: Повезана датотека не може да Ñе отвори за упиÑ" + +msgid "E212: Can't open file for writing" +msgstr "E212: Датотека не може да Ñе отвори за упиÑ" + +msgid "E949: File changed while writing" +msgstr "E949: Датотека је промењена током упиÑа" + +msgid "E512: Close failed" +msgstr "E512: Затварање није уÑпело" + +msgid "E513: write error, conversion failed (make 'fenc' empty to override)" +msgstr "" +"E513: грешка при упиÑу, конверзија није уÑпела (оÑтавите 'fenc' празно да " +"премоÑтите)" + +#, c-format +msgid "" +"E513: write error, conversion failed in line %ld (make 'fenc' empty to " +"override)" +msgstr "" +"E513: грешка при упиÑу, конверзија није уÑпела у линији %ld (оÑтавите 'fenc' " +"празно да премоÑтите)" + +msgid "E514: write error (file system full?)" +msgstr "E514: грешка при упиÑу (ÑиÑтем датотека је пун?)" + +msgid " CONVERSION ERROR" +msgstr " ГРЕШКРКОÐВЕРЗИЈЕ" + +#, c-format +msgid " in line %ld;" +msgstr " у линији %ld;" + +msgid "[Device]" +msgstr "[Уређај]" + +msgid "[New]" +msgstr "[Ðово]" + +msgid " [a]" +msgstr " [н]" + +msgid " appended" +msgstr " наÑтављено" + +msgid " [w]" +msgstr " [у]" + +msgid " written" +msgstr " упиÑано" + +msgid "E205: Patchmode: can't save original file" +msgstr "E205: Patch режим: оригинална датотека не може да Ñе Ñачува" + +msgid "E206: patchmode: can't touch empty original file" +msgstr "E206: Patch режим: не може да Ñе креира празна оригинална датотека" + +msgid "E207: Can't delete backup file" +msgstr "E207: Резервна датотека не може да Ñе обрише" + +msgid "" +"\n" +"WARNING: Original file may be lost or damaged\n" +msgstr "" +"\n" +"УПОЗОРЕЊЕ: Оригинална датотека је можда изгубљена или оштећена\n" + +msgid "don't quit the editor until the file is successfully written!" +msgstr "не напуштајте едитор док Ñе датотека уÑпешно не упише!" + +msgid "[dos]" +msgstr "[dos]" + +msgid "[dos format]" +msgstr "[dos формат]" + +msgid "[mac]" +msgstr "[mac]" + +msgid "[mac format]" +msgstr "[mac формат]" + +msgid "[unix]" +msgstr "[unix]" + +msgid "[unix format]" +msgstr "[unix формат]" + +msgid "1 line, " +msgstr "1 линија, " + +#, c-format +msgid "%ld lines, " +msgstr "%ld линија, " + +msgid "1 character" +msgstr "1 карактер" + +#, c-format +msgid "%lld characters" +msgstr "%lld карактера" + +msgid "[noeol]" +msgstr "[noeol]" + +msgid "[Incomplete last line]" +msgstr "[ПоÑледња линија није комплетна]" + +msgid "WARNING: The file has been changed since reading it!!!" +msgstr "УПОЗОРЕЊЕ: Ова датотека је промењена од кад је прочитана!!!" + +msgid "Do you really want to write to it" +msgstr "Да ли заиÑта желите да пишете у њу" + +#, c-format +msgid "E208: Error writing to \"%s\"" +msgstr "E208: Грешка при упиÑу у \"%s\"" + +#, c-format +msgid "E209: Error closing \"%s\"" +msgstr "E209: Грешка при затварању \"%s\"" + +#, c-format +msgid "E210: Error reading \"%s\"" +msgstr "E210: Грешка при читању \"%s\"" + +msgid "E246: FileChangedShell autocommand deleted buffer" +msgstr "E246: FileChangedShell аутокоманда је обриÑала бафер" + +#, c-format +msgid "E211: File \"%s\" no longer available" +msgstr "E211: Датотека \"%s\" више није доÑтупна" + +#, c-format +msgid "" +"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as " +"well" +msgstr "" +"W12: Упозорење: Датотека \"%s\" је измењена и бафер у програму Vim је такође " +"измењен" + +msgid "See \":help W12\" for more info." +msgstr "Погледајте \":help W12\" за више информација." + +#, c-format +msgid "W11: Warning: File \"%s\" has changed since editing started" +msgstr "" +"W11: Упозорење: Датотека \"%s\" је измењена откад је започето уређивање" + +msgid "See \":help W11\" for more info." +msgstr "Погледајте \":help W11\" за више информација." + +#, c-format +msgid "W16: Warning: Mode of file \"%s\" has changed since editing started" +msgstr "" +"W16: Упозорење: Режим датотеке \"%s\" је измењен откад је започето уређивање" + +msgid "See \":help W16\" for more info." +msgstr "Погледајте \":help W16\" за више информација." + +#, c-format +msgid "W13: Warning: File \"%s\" has been created after editing started" +msgstr "W13: Упозорење: Датотека \"%s\" је креирана након почетка уређивања" + +msgid "Warning" +msgstr "Упозорење" + +msgid "" +"&OK\n" +"&Load File" +msgstr "" +"&OK\n" +"&Учитај датотеку" + +#, c-format +msgid "E462: Could not prepare for reloading \"%s\"" +msgstr "E462: Припрема за поновно учитавање \"%s\" није била могућа" + +#, c-format +msgid "E321: Could not reload \"%s\"" +msgstr "E321: \"%s\" не може поново да Ñе учита" + +msgid "--Deleted--" +msgstr "--ОбриÑано--" + +#, c-format +msgid "auto-removing autocommand: %s <buffer=%d>" +msgstr "ауто-уклањајућа аутокоманда: %s <бафер=%d>" + +#, c-format +msgid "E367: No such group: \"%s\"" +msgstr "E367: Ðема такве групе: \"%s\"" + +msgid "E936: Cannot delete the current group" +msgstr "E936: Текућа група не може да Ñе обрише" + +msgid "W19: Deleting augroup that is still in use" +msgstr "W19: БриÑање augroup која је још у употреби" + +#, c-format +msgid "E215: Illegal character after *: %s" +msgstr "E215: Ðедозвољени карактер након *: %s" + +#, c-format +msgid "E216: No such event: %s" +msgstr "E216: Ðема таквог догађаја: %s" + +#, c-format +msgid "E216: No such group or event: %s" +msgstr "E216: Ðема такве групе или догађаја: %s" + +msgid "" +"\n" +"--- Autocommands ---" +msgstr "" +"\n" +"--- Ðутокоманде ---" + +#, c-format +msgid "E680: <buffer=%d>: invalid buffer number " +msgstr "E680: <бафер=%d>: неиÑправан број бафера " + +msgid "E217: Can't execute autocommands for ALL events" +msgstr "E217: Ðутокоманде за СВЕ догађаје не могу да Ñе изврше" + +msgid "No matching autocommands" +msgstr "Ðема подударајућих аутокоманди" + +msgid "E218: autocommand nesting too deep" +msgstr "E218: Угњеждавање аутокоманде је Ñувише дубоко" + +#, c-format +msgid "%s Autocommands for \"%s\"" +msgstr "%s Ðутокоманде за \"%s\"" + +#, c-format +msgid "Executing %s" +msgstr "Извршавање %s" + +#, c-format +msgid "autocommand %s" +msgstr "аутокоманда %s" + +msgid "E219: Missing {." +msgstr "E219: ÐедоÑтаје {." + +msgid "E220: Missing }." +msgstr "E220: ÐедоÑтаје }." + +msgid "E490: No fold found" +msgstr "E490: Ðије пронађено ниједно Ñклапање" + +msgid "E350: Cannot create fold with current 'foldmethod'" +msgstr "E350: Склапање не може да Ñе креира Ñа текућим 'foldmethod'" + +msgid "E351: Cannot delete fold with current 'foldmethod'" +msgstr "E351: Склапање не може да Ñе обрише Ñа текћим 'foldmethod'" + +#, c-format +msgid "+--%3ld line folded " +msgid_plural "+--%3ld lines folded " +msgstr[0] "+--%3ld линија подвијена" +msgstr[1] "+--%3ld линија подвијено" + +msgid "E222: Add to read buffer" +msgstr "E222: Додавање у бафер читања" + +msgid "E223: recursive mapping" +msgstr "E223: рекурзивно мапирање" + +#, c-format +msgid "E224: global abbreviation already exists for %s" +msgstr "E224: глобална Ñкраћеница за %s већ поÑтоји" + +#, c-format +msgid "E225: global mapping already exists for %s" +msgstr "E225: глобално мапирање за %s већ поÑтоји" + +#, c-format +msgid "E226: abbreviation already exists for %s" +msgstr "E226: Ñкраћеница за %s већ поÑтоји" + +#, c-format +msgid "E227: mapping already exists for %s" +msgstr "E227: мапирање за %s већ поÑтоји" + +msgid "No abbreviation found" +msgstr "Скраћеница није пронађена" + +msgid "No mapping found" +msgstr "Мапирање није пронађено" + +msgid "E228: makemap: Illegal mode" +msgstr "E228: makemap: Ðедозвољен режим" + +msgid "E851: Failed to create a new process for the GUI" +msgstr "E851: Креирање новог процеÑа за GUI није уÑпело" + +msgid "E852: The child process failed to start the GUI" +msgstr "E852: ÐŸÑ€Ð¾Ñ†ÐµÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ð°Ðº није уÑпео да покрене GUI" + +msgid "E229: Cannot start the GUI" +msgstr "E229: GUI не може да Ñе покрене" + +#, c-format +msgid "E230: Cannot read from \"%s\"" +msgstr "E230: Из \"%s\" не може да Ñе чита" + +msgid "E665: Cannot start GUI, no valid font found" +msgstr "E665: GUI не може да Ñе покрене, није пронађен валидан фонт" + +msgid "E231: 'guifontwide' invalid" +msgstr "E231: 'guifontwide' неиÑправан" + +msgid "E599: Value of 'imactivatekey' is invalid" +msgstr "E599: ВредноÑÑ‚ 'imactivatekey' није иÑправна" + +#, c-format +msgid "E254: Cannot allocate color %s" +msgstr "E254: Боја %s не може да Ñе алоцира" + +msgid "No match at cursor, finding next" +msgstr "Ðема подударања на меÑту курÑора, тражи Ñе даље" + +msgid "<cannot open> " +msgstr "<не може да Ñе отвори> " + +#, c-format +msgid "E616: vim_SelFile: can't get font %s" +msgstr "E616: vim_SelFile: не може да Ñе добије фонт %s" + +msgid "E614: vim_SelFile: can't return to current directory" +msgstr "E614: vim_SelFile: повратак у текући директоријум није могућ" + +msgid "Pathname:" +msgstr "Име путање:" + +msgid "E615: vim_SelFile: can't get current directory" +msgstr "E615: vim_SelFile: не може да Ñе добије текући директоријум" + +msgid "OK" +msgstr "ОК" + +msgid "Cancel" +msgstr "Откажи" + +msgid "Scrollbar Widget: Could not get geometry of thumb pixmap." +msgstr "Scrollbar Widget: Ðе може да Ñе добије геометрија thumb pixmap." + +msgid "Vim dialog" +msgstr "Vim дијалог" + +msgid "E232: Cannot create BalloonEval with both message and callback" +msgstr "" +"E232: Ðе може да Ñе креира BalloonEval и Ñа поруком и Ñа повратним позивом" + +msgid "_Cancel" +msgstr "_Откажи" + +msgid "_Save" +msgstr "_Сачувај" + +msgid "_Open" +msgstr "_Отвори" + +msgid "_OK" +msgstr "_OK" + +msgid "" +"&Yes\n" +"&No\n" +"&Cancel" +msgstr "" +"&Да\n" +"&Ðе\n" +"&Откажи" + +msgid "Yes" +msgstr "Да" + +msgid "No" +msgstr "Ðе" + +msgid "Input _Methods" +msgstr "_Методе уноÑа" + +msgid "VIM - Search and Replace..." +msgstr "VIM - Претрага and Замена..." + +msgid "VIM - Search..." +msgstr "VIM - Претрага..." + +msgid "Find what:" +msgstr "Пронађи:" + +msgid "Replace with:" +msgstr "Замени Ñа:" + +msgid "Match whole word only" +msgstr "Само целе речи подударају" + +msgid "Match case" +msgstr "Мала/велика Ñлова" + +msgid "Direction" +msgstr "Смер" + +msgid "Up" +msgstr "Горе" + +msgid "Down" +msgstr "Доле" + +msgid "Find Next" +msgstr "Пронађи наредно" + +msgid "Replace" +msgstr "Замени" + +msgid "Replace All" +msgstr "Замени Ñве" + +msgid "_Close" +msgstr "_Затвори" + +msgid "Vim: Received \"die\" request from session manager\n" +msgstr "Vim: Примљен је \"die\" захтев од менаџера ÑеÑије\n" + +msgid "Close tab" +msgstr "Затвори картицу" + +msgid "New tab" +msgstr "Ðова картица" + +msgid "Open Tab..." +msgstr "Отвори картицу..." + +msgid "Vim: Main window unexpectedly destroyed\n" +msgstr "Vim: Главни прозор је неочекивано уништен\n" + +msgid "&Filter" +msgstr "&Филтер" + +msgid "&Cancel" +msgstr "&Откажи" + +msgid "Directories" +msgstr "Директоријуми" + +msgid "Filter" +msgstr "Филтер" + +msgid "&Help" +msgstr "&Помоћ" + +msgid "Files" +msgstr "Датотеке" + +msgid "&OK" +msgstr "&ОК" + +msgid "Selection" +msgstr "Селекција" + +msgid "Find &Next" +msgstr "Пронађи &Следеће" + +msgid "&Replace" +msgstr "&Замени" + +msgid "Replace &All" +msgstr "Замени Ñ&Ве" + +msgid "&Undo" +msgstr "О&позови" + +msgid "Open tab..." +msgstr "Отвори картицу" + +msgid "Find string (use '\\\\' to find a '\\')" +msgstr "Пронађи Ñтринг (кориÑтите '\\\\' да пронађете '\\')" + +msgid "Find & Replace (use '\\\\' to find a '\\')" +msgstr "Пронађи & Замени (кориÑтите '\\\\' да пронађете '\\')" + +msgid "Not Used" +msgstr "Ðе кориÑти Ñе" + +msgid "Directory\t*.nothing\n" +msgstr "Директоријум\t*.ништа\n" + +#, c-format +msgid "E671: Cannot find window title \"%s\"" +msgstr "E671: ÐаÑлов прозора \"%s\" не може да Ñе пронађе" + +#, c-format +msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." +msgstr "E243: Ðргумент није подржан: \"-%s\"; КориÑтите OLE верзију." + +msgid "E672: Unable to open window inside MDI application" +msgstr "E672: Ðије могуће отварање прозора унутар MDI апликације" + +msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect" +msgstr "" +"Vim E458: colormap ÑƒÐ½Ð¾Ñ Ð½Ðµ може да Ñе алоцира, неке боје Ñу можда неиÑправне" + +#, c-format +msgid "E250: Fonts for the following charsets are missing in fontset %s:" +msgstr "E250: Фонтови за Ñледеће Ñетове карактера недоÑтају у фонтÑету %s:" + +#, c-format +msgid "E252: Fontset name: %s" +msgstr "E252: Име фонтÑета: %s" + +#, c-format +msgid "Font '%s' is not fixed-width" +msgstr "Фонт %s' није фикÑне ширине" + +#, c-format +msgid "E253: Fontset name: %s" +msgstr "E253: Име фонтÑета: %s" + +#, c-format +msgid "Font0: %s" +msgstr "Фонт0: %s" + +#, c-format +msgid "Font1: %s" +msgstr "Фонт1: %s" + +#, c-format +msgid "Font%ld width is not twice that of font0" +msgstr "Ширина фонт%ld није двоÑтрука од ширине фонт0" + +#, c-format +msgid "Font0 width: %ld" +msgstr "Фонт0 ширина: %ld" + +#, c-format +msgid "Font1 width: %ld" +msgstr "Фонт1 ширина: %ld" + +msgid "Invalid font specification" +msgstr "ÐеиÑправна Ñпецификација фонта" + +msgid "&Dismiss" +msgstr "О&дбаци" + +msgid "no specific match" +msgstr "нема поÑебног подударања" + +msgid "Vim - Font Selector" +msgstr "Vim - Фонт Ñелектор" + +msgid "Name:" +msgstr "Име:" + +msgid "Show size in Points" +msgstr "Прикажи величину у Тачкама" + +msgid "Encoding:" +msgstr "Кодирање:" + +msgid "Font:" +msgstr "Фонт:" + +msgid "Style:" +msgstr "Стил:" + +msgid "Size:" +msgstr "Величина:" + +msgid "E256: Hangul automata ERROR" +msgstr "E256: ГРЕШКРHangul аутомата" + +msgid "E550: Missing colon" +msgstr "E550: ÐедоÑтаје двотачка" + +msgid "E551: Illegal component" +msgstr "E551: ÐеиÑправна компонента" + +msgid "E552: digit expected" +msgstr "E552: очекује Ñе цифра" + +#, c-format +msgid "Page %d" +msgstr "Страна %d" + +msgid "No text to be printed" +msgstr "Ðема текÑта за штампу" + +#, c-format +msgid "Printing page %d (%d%%)" +msgstr "Штампање Ñтране %d (%d%%)" + +#, c-format +msgid " Copy %d of %d" +msgstr " Копија %d од %d" + +#, c-format +msgid "Printed: %s" +msgstr "Одштампано: %s" + +msgid "Printing aborted" +msgstr "Штампање прекинуто" + +msgid "E455: Error writing to PostScript output file" +msgstr "E455: Грешка приликом упиÑа у PostScript излазну датотеку" + +#, c-format +msgid "E624: Can't open file \"%s\"" +msgstr "E624: Датотека \"%s\" не може да Ñе отвори" + +#, c-format +msgid "E457: Can't read PostScript resource file \"%s\"" +msgstr "E457: PostScript resource датотека \"%s\" не може да Ñе чита" + +#, c-format +msgid "E618: file \"%s\" is not a PostScript resource file" +msgstr "E618: датотека \"%s\" није PostScript resource датотека" + +#, c-format +msgid "E619: file \"%s\" is not a supported PostScript resource file" +msgstr "E619: датотека \"%s\" није подржана PostScript resource датотека" + +#, c-format +msgid "E621: \"%s\" resource file has wrong version" +msgstr "E621: \"%s\" resource датотека је погрешне верзије" + +msgid "E673: Incompatible multi-byte encoding and character set." +msgstr "E673: Вишебајтно кодирање и Ñкуп карактера ниÑу компатибилни." + +msgid "E674: printmbcharset cannot be empty with multi-byte encoding." +msgstr "E674: printmbcharset не може бити празно Ñа вишебајтним кодирањем." + +msgid "E675: No default font specified for multi-byte printing." +msgstr "E675: Ðије наведен подразумевани фонт за вишебајтно штампање." + +msgid "E324: Can't open PostScript output file" +msgstr "E324: PostScript излазна датотека не може да Ñе отвори" + +#, c-format +msgid "E456: Can't open file \"%s\"" +msgstr "E456: Датотека \"%s\" не може да Ñе отвори" + +msgid "E456: Can't find PostScript resource file \"prolog.ps\"" +msgstr "E456: PostScript resource датотека \"prolog.ps\" не може да Ñе пронађе" + +msgid "E456: Can't find PostScript resource file \"cidfont.ps\"" +msgstr "" +"E456: PostScript resource датотека \"cidfont.ps\" не може да Ñе пронађе" + +#, c-format +msgid "E456: Can't find PostScript resource file \"%s.ps\"" +msgstr "E456: PostScript resource датотека \"%s.ps\" не може да Ñе пронађе" + +#, c-format +msgid "E620: Unable to convert to print encoding \"%s\"" +msgstr "E620: Ðије могућа конверзија у кодирање за штампу \"%s\"" + +msgid "Sending to printer..." +msgstr "Слање штампачу..." + +msgid "E365: Failed to print PostScript file" +msgstr "E365: PostScript датотека није уÑпела да Ñе одштампа" + +msgid "Print job sent." +msgstr "Задатак штампе је поÑлат" + +msgid "Add a new database" +msgstr "Додај нову базу" + +msgid "Query for a pattern" +msgstr "Упит за шаблон" + +msgid "Show this message" +msgstr "Прикажи ову поруку" + +msgid "Kill a connection" +msgstr "Затвори везу" + +msgid "Reinit all connections" +msgstr "Поново иницијализуј Ñве везе" + +msgid "Show connections" +msgstr "Прикажи везе" + +#, c-format +msgid "E560: Usage: cs[cope] %s" +msgstr "E560: Употреба: cs[cope] %s" + +msgid "This cscope command does not support splitting the window.\n" +msgstr "Ова cscope команда не подржава поделу прозора.\n" + +msgid "E562: Usage: cstag <ident>" +msgstr "E562: Употреба: cstag <ident>" + +msgid "E257: cstag: tag not found" +msgstr "E257: cstag: ознака није пронађена" + +#, c-format +msgid "E563: stat(%s) error: %d" +msgstr "E563: stat(%s) грешка: %d" + +msgid "E563: stat error" +msgstr "E563: stat грешка" + +#, c-format +msgid "E564: %s is not a directory or a valid cscope database" +msgstr "E564: %s није директоријум или валидна cscope база података" + +#, c-format +msgid "Added cscope database %s" +msgstr "cscope база података %s је додата" + +#, c-format +msgid "E262: error reading cscope connection %ld" +msgstr "E262: грешка код читања cscope везе %ld" + +msgid "E561: unknown cscope search type" +msgstr "E561: непознат cscope тип претраге" + +msgid "E566: Could not create cscope pipes" +msgstr "E566: cscope процеÑни токови ниÑу могли да Ñе креирају" + +msgid "E622: Could not fork for cscope" +msgstr "E622: Рачвање за cscope није уÑпело" + +msgid "cs_create_connection setpgid failed" +msgstr "cs_create_connection setpgid није уÑпео" + +msgid "cs_create_connection exec failed" +msgstr "cs_create_connection exec није уÑпео" + +msgid "cs_create_connection: fdopen for to_fp failed" +msgstr "cs_create_connection: fdopen за to_fp није уÑпео" + +msgid "cs_create_connection: fdopen for fr_fp failed" +msgstr "cs_create_connection: fdopen за fr_fp није уÑпео" + +msgid "E623: Could not spawn cscope process" +msgstr "E623: Мрешћење cscope процеÑа није уÑпело" + +msgid "E567: no cscope connections" +msgstr "E567: нема cscope веза" + +#, c-format +msgid "E469: invalid cscopequickfix flag %c for %c" +msgstr "E469: неиÑправан cscopequickfix индикатор %c за %c" + +#, c-format +msgid "E259: no matches found for cscope query %s of %s" +msgstr "E259: ниÑу пронађена подударања за cscope упит %s на %s" + +msgid "cscope commands:\n" +msgstr "cscope команде:\n" + +#, c-format +msgid "%-5s: %s%*s (Usage: %s)" +msgstr "%-5s: %s%*s (Употреба: %s)" + +msgid "" +"\n" +" a: Find assignments to this symbol\n" +" c: Find functions calling this function\n" +" d: Find functions called by this function\n" +" e: Find this egrep pattern\n" +" f: Find this file\n" +" g: Find this definition\n" +" i: Find files #including this file\n" +" s: Find this C symbol\n" +" t: Find this text string\n" +msgstr "" +"\n" +" a: Пронађи доделе овом Ñимболу\n" +" c: Пронађи функције које позивају ову функцију\n" +" d: Пронађи функције које зове ова функција\n" +" e: Пронађи овај egrep шаблон\n" +" f: Пронађи ову датотеку\n" +" g: Пронађи ову дефиницију\n" +" i: Пронађи датотеке које #includе ову датотеку\n" +" s: Пронађи овај C Ñимбол\n" +" t: Пронађи овај текÑÑ‚ Ñтринг\n" + +#, c-format +msgid "E625: cannot open cscope database: %s" +msgstr "E625: cscope database: %s не може да Ñе отвори" + +msgid "E626: cannot get cscope database information" +msgstr "E626: Инфорамције о cscope бази података не могу да Ñе добију" + +msgid "E568: duplicate cscope database not added" +msgstr "E568: Дупликат cscope база података није додата" + +#, c-format +msgid "E261: cscope connection %s not found" +msgstr "E261: cscope веза %s није пронађена" + +#, c-format +msgid "cscope connection %s closed" +msgstr "cscope веза %s је затворена" + +msgid "E570: fatal error in cs_manage_matches" +msgstr "E570: фатална грешка у cs_manage_matches" + +#, c-format +msgid "Cscope tag: %s" +msgstr "Cscope ознака: %s" + +msgid "" +"\n" +" # line" +msgstr "" +"\n" +" # линија" + +msgid "filename / context / line\n" +msgstr "датотека / контекÑÑ‚ / линија\n" + +#, c-format +msgid "E609: Cscope error: %s" +msgstr "E609: Cscope грешка: %s" + +msgid "All cscope databases reset" +msgstr "Све cscope базе података реÑетоване" + +msgid "no cscope connections\n" +msgstr "нема cscope веза\n" + +msgid " # pid database name prepend path\n" +msgstr " # pid име базе података додај путању иÑпред\n" + +msgid "Lua library cannot be loaded." +msgstr "Lua библиотека не може да Ñе учита" + +msgid "cannot save undo information" +msgstr "инфорамције за опозив не могу да Ñе Ñачувају" + +msgid "" +"E815: Sorry, this command is disabled, the MzScheme libraries could not be " +"loaded." +msgstr "" +"E815: Жао нам је, ова команда је онемогућена, MzScheme библиотеке ниÑу могле " +"да Ñе учитају." + +msgid "" +"E895: Sorry, this command is disabled, the MzScheme's racket/base module " +"could not be loaded." +msgstr "" +"E895: Жао нам је, ова команда је онемогућена, MzScheme-ов racket/base модул " +"није могао да Ñе учита." + +msgid "invalid expression" +msgstr "неиÑправан израз" + +msgid "expressions disabled at compile time" +msgstr "изрази Ñу онемогућени у време компилације" + +msgid "hidden option" +msgstr "Ñкривена опција" + +msgid "unknown option" +msgstr "непозната опција" + +msgid "window index is out of range" +msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€Ð° је ван опÑега" + +msgid "couldn't open buffer" +msgstr "бафер не може да Ñе отвори" + +msgid "cannot delete line" +msgstr "линија не може да Ñе обрише" + +msgid "cannot replace line" +msgstr "линија не може да Ñе замени" + +msgid "cannot insert line" +msgstr "линија не може да Ñе уметне" + +msgid "string cannot contain newlines" +msgstr "Ñтринг не може да Ñадржи нове редове" + +msgid "error converting Scheme values to Vim" +msgstr "грешка при конверзији Scheme вредноÑти у Vim" + +msgid "Vim error: ~a" +msgstr "Vim грешка: ~a" + +msgid "Vim error" +msgstr "Vim грешка" + +msgid "buffer is invalid" +msgstr "бафер је неважећи" + +msgid "window is invalid" +msgstr "прозор је неважећи" + +msgid "linenr out of range" +msgstr "linenr је ван опÑега" + +msgid "not allowed in the Vim sandbox" +msgstr "није дозвољено у Vim sandbox-у" + +#, c-format +msgid "E370: Could not load library %s" +msgstr "E370: Библиотека %s није могла да Ñе учита" + +msgid "Sorry, this command is disabled: the Perl library could not be loaded." +msgstr "" +"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да " +"Ñе учита." + +msgid "E299: Perl evaluation forbidden in sandbox without the Safe module" +msgstr "E299: Perl одређивање вредноÑти у sandbox-у је забрањено без Safe модула" + +msgid "E836: This Vim cannot execute :python after using :py3" +msgstr "E836: Овај Vim не може да изврши :python након коришћења :py3" + +msgid "" +"E263: Sorry, this command is disabled, the Python library could not be " +"loaded." +msgstr "" +"E263: Жао нам је, ова команда је онемогућена, Python библиотека није могла " +"да Ñе учита." + +msgid "" +"E887: Sorry, this command is disabled, the Python's site module could not be " +"loaded." +msgstr "" +"E887: Жао нам је, ова команда је онемогућена, Python-ов site модул није " +"могао да Ñе учита." + +msgid "E659: Cannot invoke Python recursively" +msgstr "E659: Python не може да Ñе позива рекурзивно" + +msgid "E837: This Vim cannot execute :py3 after using :python" +msgstr "E837: Овај Vim не може да изврши :py3 након коришћења :python" + +msgid "E265: $_ must be an instance of String" +msgstr "E265: $_ мора да буде инÑтанца String-а" + +msgid "" +"E266: Sorry, this command is disabled, the Ruby library could not be loaded." +msgstr "" +"E266: Жао нам је, ова команда је онемогућена, Ruby библиотека није могла да " +"Ñе учита." + +msgid "E267: unexpected return" +msgstr "E267: неочекиван return" + +msgid "E268: unexpected next" +msgstr "E268: неочекивано next" + +msgid "E269: unexpected break" +msgstr "E269: неочекивано break" + +msgid "E270: unexpected redo" +msgstr "E270: неочекивано redo" + +msgid "E271: retry outside of rescue clause" +msgstr "E271: retry ван rescue клаузуле" + +msgid "E272: unhandled exception" +msgstr "E272: необрађени изузетак" + +#, c-format +msgid "E273: unknown longjmp status %d" +msgstr "E273: непознат longjmp ÑÑ‚Ð°Ñ‚ÑƒÑ %d" + +msgid "invalid buffer number" +msgstr "неиÑправан број бафера" + +msgid "not implemented yet" +msgstr "још није имплементирано" + +msgid "cannot set line(s)" +msgstr "линија(е) не може да Ñе поÑтави" + +msgid "invalid mark name" +msgstr "неиÑправно име маркера" + +msgid "mark not set" +msgstr "маркер није поÑтављен" + +#, c-format +msgid "row %d column %d" +msgstr "ред %d колона %d" + +msgid "cannot insert/append line" +msgstr "линија не може да Ñе уметне/дода на крај" + +msgid "line number out of range" +msgstr "број линије је ван опÑега" + +msgid "unknown flag: " +msgstr "непознат индикатор" + +msgid "unknown vimOption" +msgstr "непозната vimОпција" + +msgid "keyboard interrupt" +msgstr "прекид таÑтатуре" + +msgid "vim error" +msgstr "vim грешка" + +msgid "cannot create buffer/window command: object is being deleted" +msgstr "бафер/прозор команда не може да Ñе креира: објекат Ñе брише" + +msgid "" +"cannot register callback command: buffer/window is already being deleted" +msgstr "" +"команда повратног позива не може да Ñе региÑтрује: бафер/прозор је већ " +"обриÑан" + +msgid "" +"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim." +"org" +msgstr "" +"E280: TCL ФÐТÐЛÐРГРЕШКÐ: reflist је оштећена!? Молимо пријавите ово на " +"vim-dev@vim.org" + +msgid "cannot register callback command: buffer/window reference not found" +msgstr "" +"команда повратног позива не може да Ñе региÑтрује: референца бафера/прозора " +"није пронађена" + +msgid "" +"E571: Sorry, this command is disabled: the Tcl library could not be loaded." +msgstr "" +"E571: Жао нам је, ова команда је онемогућена: Tcl библиотека није могла да " +"Ñе учита." + +#, c-format +msgid "E572: exit code %d" +msgstr "E572: излазни код %d" + +msgid "cannot get line" +msgstr "линија не може да Ñе добије" + +msgid "Unable to register a command server name" +msgstr "Име Ñервера команди није могло да Ñе региÑтрује" + +msgid "E248: Failed to send command to the destination program" +msgstr "E248: Слање команде циљном програму није уÑпело" + +#, c-format +msgid "E573: Invalid server id used: %s" +msgstr "E573: КориÑти Ñе неÑправан ид Ñервера: %s" + +msgid "E251: VIM instance registry property is badly formed. Deleted!" +msgstr "E251: registry ÑвојÑтво VIM инÑтанце је лоше формирано. ОбриÑано!" + +#, c-format +msgid "E938: Duplicate key in JSON: \"%s\"" +msgstr "E938: Дупли кључ у JSON: \"%s\"" + +#, c-format +msgid "E696: Missing comma in List: %s" +msgstr "E696: У ЛиÑти недоÑтаје зарез: %s" + +#, c-format +msgid "E697: Missing end of List ']': %s" +msgstr "E697: ÐедоÑтаје крај ЛиÑте ']': %s" + +msgid "Unknown option argument" +msgstr "Ðепознат аргумент опције" + +msgid "Too many edit arguments" +msgstr "Сувише аргумента уређивања" + +msgid "Argument missing after" +msgstr "Ðргумент недоÑтаје након" + +msgid "Garbage after option argument" +msgstr "Смеће након аргумента опције" + +msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" +msgstr "Сувише \"+command\", \"-c command\" или \"--cmd command\" аргумената" + +msgid "Invalid argument for" +msgstr "ÐеиÑправан аргумент for" + +#, c-format +msgid "%d files to edit\n" +msgstr "%d датотека за уређивање\n" + +msgid "netbeans is not supported with this GUI\n" +msgstr "NetBeans није подржан Ñа овим GUI\n" + +msgid "'-nb' cannot be used: not enabled at compile time\n" +msgstr "'-nb' не може да Ñе кориÑти: није омогућено у време компилације\n" + +msgid "This Vim was not compiled with the diff feature." +msgstr "Овај Vim није компајлиран Ñа diff могућношћу." + +msgid "Attempt to open script file again: \"" +msgstr "Покушај да Ñе поново отвори Ñкрипт датотека: \"" + +msgid "Cannot open for reading: \"" +msgstr "Ðе може да Ñе отвори за читање: \"" + +msgid "Cannot open for script output: \"" +msgstr "Ðе може да Ñе отвори за излаз Ñкрипте: \"" + +msgid "Vim: Error: Failure to start gvim from NetBeans\n" +msgstr "Vim: Грешка: Покретање gvim из NetBeans није уÑпело\n" + +msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n" +msgstr "" +"Vim: Грешка: Ова верзија Vim не може да Ñе покрене из Cygwin терминала\n" + +msgid "Vim: Warning: Output is not to a terminal\n" +msgstr "Vim: Упозорење: Излаз није у терминал\n" + +msgid "Vim: Warning: Input is not from a terminal\n" +msgstr "Vim: Упозорење: Улаз није из терминала\n" + +msgid "pre-vimrc command line" +msgstr "pre-vimrc командна линија" + +#, c-format +msgid "E282: Cannot read from \"%s\"" +msgstr "E282: Ðе може да Ñе чита из \"%s\"" + +msgid "" +"\n" +"More info with: \"vim -h\"\n" +msgstr "" +"\n" +"Више инфо Ñа: \"vim -h\"\n" + +msgid "[file ..] edit specified file(s)" +msgstr "[датотека ..] уређуј наведену(е) датотеку(е)" + +msgid "- read text from stdin" +msgstr "- читај текÑÑ‚ Ñа stdin" + +msgid "-t tag edit file where tag is defined" +msgstr "-t tag уређуј датотеку где је дефиниÑана ознака" + +msgid "-q [errorfile] edit file with first error" +msgstr "-q [дат.грешке] уређуј датотеку Ñа првом грешком" + +msgid "" +"\n" +"\n" +"Usage:" +msgstr "" +"\n" +"\n" +"Употреба:" + +msgid " vim [arguments] " +msgstr " vim [аргументи] " + +msgid "" +"\n" +" or:" +msgstr "" +"\n" +" или:" + +msgid "" +"\n" +"Where case is ignored prepend / to make flag upper case" +msgstr "" +"\n" +"Где Ñе мала/велика Ñлова игноришу Ñтавите иÑпред / како би претворили " +"индикатор у велика Ñлова" + +msgid "" +"\n" +"\n" +"Arguments:\n" +msgstr "" +"\n" +"\n" +"Ðргументи:\n" + +msgid "--\t\t\tOnly file names after this" +msgstr "--\t\t\tСамо имена датотека након овога" + +msgid "--literal\t\tDon't expand wildcards" +msgstr "--literal\t\tÐе развијај џокере" + +msgid "-register\t\tRegister this gvim for OLE" +msgstr "-register\t\tРегиÑтруј овај gvim за OLE" + +msgid "-unregister\t\tUnregister gvim for OLE" +msgstr "-unregister\t\tУклони региÑтрацију gvim за OLE" + +msgid "-g\t\t\tRun using GUI (like \"gvim\")" +msgstr "-g\t\t\tПокрени кориÑтећи GUI (као \"gvim\")" + +msgid "-f or --nofork\tForeground: Don't fork when starting GUI" +msgstr "-f или --nofork\tУ предњем плану: немој да рачваш кад Ñе покреће GUI" + +msgid "-v\t\t\tVi mode (like \"vi\")" +msgstr "-v\t\t\tVi режим (као \"vi\")" + +msgid "-e\t\t\tEx mode (like \"ex\")" +msgstr "-e\t\t\tEx режим (као \"ex\")" + +msgid "-E\t\t\tImproved Ex mode" +msgstr "-E\t\t\tУнапређен Ex режим" + +msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")" +msgstr "-s\t\t\tÐечујни (batch) режим (Ñамо за \"ex\")" + +msgid "-d\t\t\tDiff mode (like \"vimdiff\")" +msgstr "-d\t\t\tDiff режим (као \"vimdiff\")" + +msgid "-y\t\t\tEasy mode (like \"evim\", modeless)" +msgstr "-y\t\t\tEasy режим (као \"evim\", безрежимни)" + +msgid "-R\t\t\tReadonly mode (like \"view\")" +msgstr "-R\t\t\tReadonly режим (као \"view\")" + +msgid "-Z\t\t\tRestricted mode (like \"rvim\")" +msgstr "-Z\t\t\tRestricted режим (као \"rvim\")" + +msgid "-m\t\t\tModifications (writing files) not allowed" +msgstr "-m\t\t\tИзмене (упиÑивање датотека) ниÑу дозвољене" + +msgid "-M\t\t\tModifications in text not allowed" +msgstr "-M\t\t\tИзмене у текÑту ниÑу дозвољене" + +msgid "-b\t\t\tBinary mode" +msgstr "-b\t\t\tБинарни режим" + +msgid "-l\t\t\tLisp mode" +msgstr "-l\t\t\tLisp режим" + +msgid "-C\t\t\tCompatible with Vi: 'compatible'" +msgstr "-C\t\t\tКомпатибилан Ñа Vi: 'compatible'" + +msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'" +msgstr "-N\t\t\tÐе потпуно Vi компатибилан: 'nocompatible'" + +msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]" +msgstr "-V[N][fname]\t\tБуди опширан [ниво N] [бележи поруке у fname]" + +msgid "-D\t\t\tDebugging mode" +msgstr "-D\t\t\tDebugging режим" + +msgid "-n\t\t\tNo swap file, use memory only" +msgstr "-n\t\t\tБез swap датотеке, кориÑти Ñамо меморију" + +msgid "-r\t\t\tList swap files and exit" +msgstr "-r\t\t\tИзлиÑтај swap датотеке и изађи" + +msgid "-r (with file name)\tRecover crashed session" +msgstr "-r (Ñа именом датотеке)\tОбнови Ñрушену ÑеÑију" + +msgid "-L\t\t\tSame as -r" +msgstr "-L\t\t\tИÑто као -r" + +msgid "-f\t\t\tDon't use newcli to open window" +msgstr "-f\t\t\tÐемој да кориÑтиш нов cli да отвориш прозор" + +msgid "-dev <device>\t\tUse <device> for I/O" +msgstr "-dev <уређај>\t\tКориÑти <уређај> за У/И" + +msgid "-A\t\t\tStart in Arabic mode" +msgstr "-A\t\t\tПокрени у ÐрапÑком режиму" + +msgid "-H\t\t\tStart in Hebrew mode" +msgstr "-H\t\t\tПокрени у ХебрејÑком режиму" + +msgid "-F\t\t\tStart in Farsi mode" +msgstr "-F\t\t\tПокрени у ФарÑи режиму" + +msgid "-T <terminal>\tSet terminal type to <terminal>" +msgstr "-T <терминал>\tПоÑтави тип терминала на <терминал>" + +msgid "--not-a-term\t\tSkip warning for input/output not being a terminal" +msgstr "--not-a-term\t\tПреÑкочи упозорење да улаз/излаз није терминал" + +msgid "--ttyfail\t\tExit if input or output is not a terminal" +msgstr "--ttyfail\t\tИзађи ако улаз или излаз ниÑу терминал" + +msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc" +msgstr "-u <vimrc>\t\tКориÑти <vimrc> умеÑто било ког .vimrc" + +msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc" +msgstr "-U <gvimrc>\t\tКориÑти <gvimrc> умеÑто било ког .gvimrc" + +msgid "--noplugin\t\tDon't load plugin scripts" +msgstr "--noplugin\t\tÐе учитавај Ñкрипте додатака" + +msgid "-p[N]\t\tOpen N tab pages (default: one for each file)" +msgstr "-p[N]\t\tОтвори N картица (подразумевано: по једну за Ñваку датотеку)" + +msgid "-o[N]\t\tOpen N windows (default: one for each file)" +msgstr "-o[N]\t\tОтвори N прозора (подразумевано: по један за Ñваку датотеку)" + +msgid "-O[N]\t\tLike -o but split vertically" +msgstr "-O[N]\t\tКао -o али подели по вертикали" + +msgid "+\t\t\tStart at end of file" +msgstr "+\t\t\tПочни на крају датотеке" + +msgid "+<lnum>\t\tStart at line <lnum>" +msgstr "+<бројл>\t\tПочни на линији <бројл>" + +msgid "--cmd <command>\tExecute <command> before loading any vimrc file" +msgstr "" +"--cmd <команда>\tИзврши <команда> пре учитавања било које vimrc датотеке" + +msgid "-c <command>\t\tExecute <command> after loading the first file" +msgstr "-c <команда>\t\tИзврши <команда> након учитавања прве датотеке" + +msgid "-S <session>\t\tSource file <session> after loading the first file" +msgstr "" +"-S <ÑеÑија>\t\tИзворна датотека <ÑеÑија> након учитавања прве " +"датотеке" + +msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>" +msgstr "" +"-s <Ñкриптулаз>\tЧитај команде Ðормалног режима из датотеке <Ñкриптулаз>" + +msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>" +msgstr "" +"-w <Ñкриптизлаз>\tÐадовежи Ñве откуцане команде на крај датотеке " +"<Ñкриптизлаз>" + +msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>" +msgstr "-W <Ñкриптизлаз>\tУпиÑуј Ñве откуцане команде у датотеку <Ñкриптизлаз>" + +msgid "-x\t\t\tEdit encrypted files" +msgstr "-x\t\t\tУређуј шифроване датотеке" + +msgid "-display <display>\tConnect vim to this particular X-server" +msgstr "-display <диÑплеј>\tПовежи vim на овај X-Ñервер" + +msgid "-X\t\t\tDo not connect to X server" +msgstr "-X\t\t\tÐе повезуј Ñе на X Ñервер" + +msgid "--remote <files>\tEdit <files> in a Vim server if possible" +msgstr "--remote <датотеке>\tУређуј <датотеке> у Vim Ñерверу ако је могуће" + +msgid "--remote-silent <files> Same, don't complain if there is no server" +msgstr "--remote-silent <датотеке> ИÑто, не буни Ñе ако нема Ñервера" + +msgid "" +"--remote-wait <files> As --remote but wait for files to have been edited" +msgstr "" +"--remote-wait <датотеке> Као --remote али чекај да датотеке буду уређене" + +msgid "" +"--remote-wait-silent <files> Same, don't complain if there is no server" +msgstr "--remote-wait-silent <датотеке> ИÑто, не буни Ñе ако нема Ñервера" + +msgid "" +"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file" +msgstr "" +"--remote-tab[-wait][-silent] <датотеке> Као --remote али кориÑти једну " +"картицу по датотеци" + +msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit" +msgstr "--remote-send <таÑтери>\tПошаљи <таÑтери> Vim Ñерверу и изађи" + +msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result" +msgstr "" +"--remote-expr <израз>\tИзрачунај <израз> у Vim Ñерверу и одштампај резултат" + +msgid "--serverlist\t\tList available Vim server names and exit" +msgstr "--serverlist\t\tИзлиÑтај имена доÑтупних Vim Ñервера и изађи" + +msgid "--servername <name>\tSend to/become the Vim server <name>" +msgstr "--servername <име>\tПошаљи/поÑтани Vim Ñервер <име>" + +msgid "--startuptime <file>\tWrite startup timing messages to <file>" +msgstr "--startuptime <датотека>\tУпиши поруке о дужини покретања у <датотеку>" + +msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo" +msgstr "-i <viminfo>\t\tКориÑти <viminfo> умеÑто .viminfo" + +msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo" +msgstr "" +"--clean\t\t'nocompatible', Vim подразумеване вредноÑти, без додатака, без " +"viminfo" + +msgid "-h or --help\tPrint Help (this message) and exit" +msgstr "-h or --help\tИÑпиши Помоћ (ову поруку) и изађи" + +msgid "--version\t\tPrint version information and exit" +msgstr "--version\t\tИÑпиши информације о верзији и изађи" + +msgid "" +"\n" +"Arguments recognised by gvim (Motif version):\n" +msgstr "" +"\n" +"Ðргументи које препознаје gvim (Motif верзија):\n" + +msgid "" +"\n" +"Arguments recognised by gvim (neXtaw version):\n" +msgstr "" +"\n" +"Ðргументи које препознаје gvim (neXtaw верзија):\n" + +msgid "" +"\n" +"Arguments recognised by gvim (Athena version):\n" +msgstr "" +"\n" +"Ðргументи које препознаје gvim (Athena верзија):\n" + +msgid "-display <display>\tRun vim on <display>" +msgstr "-display <диÑплеј>\tПокрени vim на <диÑплеј>" + +msgid "-iconic\t\tStart vim iconified" +msgstr "-iconic\t\tПокрени vim као икону" + +msgid "-background <color>\tUse <color> for the background (also: -bg)" +msgstr "-background <боја>\tКориÑти <боја> за позадину (такође: -bg)" + +msgid "-foreground <color>\tUse <color> for normal text (also: -fg)" +msgstr "-foreground <боја>\tКориÑти <боја> за нормални текÑÑ‚ (такође: -fg)" + +msgid "-font <font>\t\tUse <font> for normal text (also: -fn)" +msgstr "-font <фонт>\t\tКориÑти <фонт> за нормални текÑÑ‚ (такође: -fn)" + +msgid "-boldfont <font>\tUse <font> for bold text" +msgstr "-boldfont <фонт>\tКориÑти <фонт> за подебљани текÑÑ‚" + +msgid "-italicfont <font>\tUse <font> for italic text" +msgstr "-italicfont <фонт>\tКориÑти <фонт> за курзивни текÑÑ‚" + +msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)" +msgstr "-geometry <геом>\tКориÑти <геом> за почетну геометрију (такође: -geom)" + +msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)" +msgstr "-borderwidth <ширина>\tКориÑти оквир ширине <ширина> (такође: -bw)" + +msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)" +msgstr "" +"-scrollbarwidth <ширина> КориÑти Линију за Ñкроловање ширине <ширина> " +"(такође: -sw)" + +msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)" +msgstr "" +"-menuheight <ширина>\tКориÑти линију менија виÑине <виÑина> (такође: -mh)" + +msgid "-reverse\t\tUse reverse video (also: -rv)" +msgstr "-reverse\t\tКориÑти обрнути видео (такође: -rv)" + +msgid "+reverse\t\tDon't use reverse video (also: +rv)" +msgstr "+reverse\t\tÐемој да кориÑтиш обрнути видео (такође: +rv)" + +msgid "-xrm <resource>\tSet the specified resource" +msgstr "-xrm <реÑурÑ>\tПоÑтави наведени реÑурÑ" + +msgid "" +"\n" +"Arguments recognised by gvim (GTK+ version):\n" +msgstr "" +"\n" +"Ðргументи које препознаје gvim (GTK+ верзија):\n" + +msgid "-display <display>\tRun vim on <display> (also: --display)" +msgstr "-display <диÑплеј>\tПокрени vim на <диÑплеј> (такође: --display)" + +msgid "--role <role>\tSet a unique role to identify the main window" +msgstr "" +"--role <улога>\tПоÑтави јединÑтвену улогу да би Ñе идентификовао главни " +"прозор" + +msgid "--socketid <xid>\tOpen Vim inside another GTK widget" +msgstr "--socketid <xid>\tОтвори Vim унутар другог GTK виџета" + +msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout" +msgstr "--echo-wid\t\tÐека gvim иÑпише Window ID на stdout" + +msgid "-P <parent title>\tOpen Vim inside parent application" +msgstr "-P <назив родитеља>\tОтвори Vim унутар родитељÑке апликације" + +msgid "--windowid <HWND>\tOpen Vim inside another win32 widget" +msgstr "--windowid <HWND>\tОтвори Vim унутар другог win32 виџета" + +msgid "No display" +msgstr "Ðема приказа" + +msgid ": Send failed.\n" +msgstr ": Слање није уÑпело.\n" + +msgid ": Send failed. Trying to execute locally\n" +msgstr ": Слање није уÑпело. Покушава Ñе локално извршавање\n" + +#, c-format +msgid "%d of %d edited" +msgstr "%d од %d уређено" + +msgid "No display: Send expression failed.\n" +msgstr "Ðема приказа: Израз Ñлања није уÑпео.\n" + +msgid ": Send expression failed.\n" +msgstr ": Израз Ñлања није уÑпео.\n" + +msgid "No marks set" +msgstr "Ðема поÑтављених маркера" + +#, c-format +msgid "E283: No marks matching \"%s\"" +msgstr "E283: Ðема маркера који Ñе подударају Ñа \"%s\"" + +msgid "" +"\n" +"mark line col file/text" +msgstr "" +"\n" +"линија маркера кол датотека/текÑÑ‚" + +msgid "" +"\n" +" jump line col file/text" +msgstr "" +"\n" +" линија Ñкока кол датотека/текÑÑ‚" + +msgid "" +"\n" +"change line col text" +msgstr "" +"\n" +"линија промене кол текÑÑ‚" + +msgid "" +"\n" +"# File marks:\n" +msgstr "" +"\n" +"# Маркери датотеке:\n" + +msgid "" +"\n" +"# Jumplist (newest first):\n" +msgstr "" +"\n" +"# Скок-лиÑта (прво најновији):\n" + +msgid "" +"\n" +"# History of marks within files (newest to oldest):\n" +msgstr "" +"\n" +"# ИÑторија маркера унутар датотека (ок најновијег до најÑтаријег):\n" + +msgid "Missing '>'" +msgstr "ÐедоÑтаје '>'" + +msgid "E543: Not a valid codepage" +msgstr "E543: Ðеважећа кодна Ñтрана" + +msgid "E284: Cannot set IC values" +msgstr "E284: IC вредноÑти не могу да Ñе поÑтаве" + +msgid "E285: Failed to create input context" +msgstr "E285: Креирање контекÑта уноÑа није уÑпело" + +msgid "E286: Failed to open input method" +msgstr "E286: Отварање методе уноÑа није уÑпело" + +msgid "E287: Warning: Could not set destroy callback to IM" +msgstr "" +"E287: Упозорење: ПоÑтављање повратне функције за уништење IM није уÑпело" + +msgid "E288: input method doesn't support any style" +msgstr "E288: метод уноÑа не подржава ниједан Ñтил" + +msgid "E289: input method doesn't support my preedit type" +msgstr "E289: метод уноÑа не подржава мој preedit тип" + +msgid "E293: block was not locked" +msgstr "E293: блок није закључан" + +msgid "E294: Seek error in swap file read" +msgstr "E294: Грешка код поÑтављања показивача за читање swap датотеке" + +msgid "E295: Read error in swap file" +msgstr "E295: Грешка при читању swap датотеке" + +msgid "E296: Seek error in swap file write" +msgstr "E296: Грешка код поÑтављања показивача за ÑƒÐ¿Ð¸Ñ swap датотеке" + +msgid "E297: Write error in swap file" +msgstr "E297: Грешка при упиÑу swap датотеке" + +msgid "E300: Swap file already exists (symlink attack?)" +msgstr "E300: Swap датотека већ поÑтоји (symlink напад?)" + +msgid "E298: Didn't get block nr 0?" +msgstr "E298: Блок бр 0 није добављен?" + +msgid "E298: Didn't get block nr 1?" +msgstr "E298: Блок бр 1 није добављен?" + +msgid "E298: Didn't get block nr 2?" +msgstr "E298: Блок бр 2 није добављен?" + +msgid "E843: Error while updating swap file crypt" +msgstr "E843: Грешка приликом оÑважавања криптовања swap датотеке" + +msgid "E301: Oops, lost the swap file!!!" +msgstr "E301: УупÑ, swap датотека је изгубљена!!!" + +msgid "E302: Could not rename swap file" +msgstr "E302: Промена имена swap датотеке није уÑпела" + +#, c-format +msgid "E303: Unable to open swap file for \"%s\", recovery impossible" +msgstr "" +"E303: Отварање swap датотеке за \"%s\" није уÑпело, опоравак је немогућ" + +msgid "E304: ml_upd_block0(): Didn't get block 0??" +msgstr "E304: ml_upd_block0(): Блок бр 0 није добављен??" + +#, c-format +msgid "E305: No swap file found for %s" +msgstr "E305: За %s није пронађена swap датотека" + +msgid "Enter number of swap file to use (0 to quit): " +msgstr "УнеÑите број swap датотеке која ће да Ñе кориÑти (0 за отказивање): " + +#, c-format +msgid "E306: Cannot open %s" +msgstr "E306: %s не може да Ñе отвори" + +msgid "Unable to read block 0 from " +msgstr "Ðије могуће литање блока 0 из " + +msgid "" +"\n" +"Maybe no changes were made or Vim did not update the swap file." +msgstr "" +"\n" +"Можда ниÑу направљене никакве измене или Vim није оÑвежио swap датотеку." + +msgid " cannot be used with this version of Vim.\n" +msgstr " не може да Ñе кориÑти Ñа овом верзијом Vim-а.\n" + +msgid "Use Vim version 3.0.\n" +msgstr "КориÑтите Vim верзијe 3.0.\n" + +#, c-format +msgid "E307: %s does not look like a Vim swap file" +msgstr "E307: %s не изгледа као Vim swap датотека" + +msgid " cannot be used on this computer.\n" +msgstr " не може да Ñе кориÑти на овом компјутеру.\n" + +msgid "The file was created on " +msgstr "Ова датотека је креирана Ñа " + +msgid "" +",\n" +"or the file has been damaged." +msgstr "" +",\n" +"или је датотека оштећена." + +#, c-format +msgid "" +"E833: %s is encrypted and this version of Vim does not support encryption" +msgstr "E833: %s је шифрована и ова верзија Vim-а не подржава шифровање" + +msgid " has been damaged (page size is smaller than minimum value).\n" +msgstr " је оштећена (величина Ñтранице је маља од минималне вредноÑти).\n" + +#, c-format +msgid "Using swap file \"%s\"" +msgstr "КориÑти Ñе swap датотека \"%s\"" + +#, c-format +msgid "Original file \"%s\"" +msgstr "Оригинална датотека \"%s\"" + +msgid "E308: Warning: Original file may have been changed" +msgstr "E308: Упозорење: Можда је промењена оригинална датотека" + +#, c-format +msgid "Swap file is encrypted: \"%s\"" +msgstr "Swap датотека је шифрована: \"%s\"" + +msgid "" +"\n" +"If you entered a new crypt key but did not write the text file," +msgstr "" +"\n" +"Ðко Ñте унели нов кључ за шифрирање али ниÑте упиÑали текÑÑ‚ датотеку," + +msgid "" +"\n" +"enter the new crypt key." +msgstr "" +"\n" +"унеÑите нови кључ за шифрирање." + +msgid "" +"\n" +"If you wrote the text file after changing the crypt key press enter" +msgstr "" +"\n" +"Ðко Ñте упиÑали текÑÑ‚ датотеку на диÑк након промене кључа за шифрирање " +"притиÑните ентер" + +msgid "" +"\n" +"to use the same key for text file and swap file" +msgstr "" +"\n" +"да биÑте кориÑтили иÑти кључ за текÑÑ‚ датотеку и swap датотеку" + +#, c-format +msgid "E309: Unable to read block 1 from %s" +msgstr "E309: Блок 1 из %s не може да Ñе прочита" + +msgid "???MANY LINES MISSING" +msgstr "??ÐЕДОСТÐЈЕ МÐОГО ЛИÐИЈÐ" + +msgid "???LINE COUNT WRONG" +msgstr "???БРОЈ ЛИÐИЈРЈЕ ПОГРЕШÐÐ" + +msgid "???EMPTY BLOCK" +msgstr "???ПРÐЗÐРБЛОК" + +msgid "???LINES MISSING" +msgstr "???ÐЕДОСТÐЈУ ЛИÐИЈЕ" + +#, c-format +msgid "E310: Block 1 ID wrong (%s not a .swp file?)" +msgstr "E310: ID блока 1 је погрешан (%s није .swp датотека?)" + +msgid "???BLOCK MISSING" +msgstr "???ÐЕДОСТÐЈЕ БЛОК" + +msgid "??? from here until ???END lines may be messed up" +msgstr "??? одавде па до ???КРÐЈ линије Ñу можда забрљане" + +msgid "??? from here until ???END lines may have been inserted/deleted" +msgstr "??? одавде па до ???КРÐЈ линије Ñу можда уметане/бриÑане" + +msgid "???END" +msgstr "???КРÐЈ" + +msgid "E311: Recovery Interrupted" +msgstr "E311: Опоравак је прекинут" + +msgid "" +"E312: Errors detected while recovering; look for lines starting with ???" +msgstr "" +"E312: Откривене Ñу грешке приликом опоравка; потражите линије које почињу " +"Ñа ???" + +msgid "See \":help E312\" for more information." +msgstr "Погледајте \":help E312\" за више информација." + +msgid "Recovery completed. You should check if everything is OK." +msgstr "Опоравак је завршен. Требало би да проверите да ли је Ñве OK." + +msgid "" +"\n" +"(You might want to write out this file under another name\n" +msgstr "" +"\n" +"(Можда биÑте хтели да запишете ову датотеку под другим именом\n" + +msgid "and run diff with the original file to check for changes)" +msgstr "и покренете diff Ñа оригиналном датотеком да провелите има ли измена)" + +msgid "Recovery completed. Buffer contents equals file contents." +msgstr "Опоравак је завршен. Садржај бафера је иÑтоветан Ñадржају датотеке." + +msgid "" +"\n" +"You may want to delete the .swp file now.\n" +"\n" +msgstr "" +"\n" +"Сада можда желите да обришете .swp датотеку.\n" +"\n" + +msgid "Using crypt key from swap file for the text file.\n" +msgstr "За текÑÑ‚ датотеку Ñе кориÑти кључ за шифрирање из swap датотеке.\n" + +msgid "Swap files found:" +msgstr "Пронађене Ñу swap датотеке:" + +msgid " In current directory:\n" +msgstr " У текућем директоријуму:\n" + +msgid " Using specified name:\n" +msgstr " КориÑтећи наведено име:\n" + +msgid " In directory " +msgstr " У директоријуму " + +msgid " -- none --\n" +msgstr " -- ниједна --\n" + +msgid " owned by: " +msgstr " које поÑедује: " + +msgid " dated: " +msgstr " датиране: " + +msgid " dated: " +msgstr " датиране: " + +msgid " [from Vim version 3.0]" +msgstr " [од Vim верзије 3.0]" + +msgid " [does not look like a Vim swap file]" +msgstr " [не изгледа као Vim swap датотека]" + +msgid " file name: " +msgstr " име датотеке: " + +msgid "" +"\n" +" modified: " +msgstr "" +"\n" +" измењено: " + +msgid "YES" +msgstr "ДÐ" + +msgid "no" +msgstr "не" + +msgid "" +"\n" +" user name: " +msgstr "" +"\n" +" кориÑничко име: " + +msgid " host name: " +msgstr " име хоÑта: " + +msgid "" +"\n" +" host name: " +msgstr "" +"\n" +" име хоÑта: " + +msgid "" +"\n" +" process ID: " +msgstr "" +"\n" +" ИД процеÑа: " + +msgid " (still running)" +msgstr " (још Ñе извршава)" + +msgid "" +"\n" +" [not usable with this version of Vim]" +msgstr "" +"\n" +" [није употребљива Ñа овом верзијом Vim-а]" + +msgid "" +"\n" +" [not usable on this computer]" +msgstr "" +"\n" +" [није употребљива на овом компјутеру]" + +msgid " [cannot be read]" +msgstr " [не може да Ñе прочита]" + +msgid " [cannot be opened]" +msgstr " [не може да Ñе отвори]" + +msgid "E313: Cannot preserve, there is no swap file" +msgstr "E313: Ðе може да Ñе презервира, нема swap датотеке" + +msgid "File preserved" +msgstr "Датотека је презервирана" + +msgid "E314: Preserve failed" +msgstr "E314: Презервација није уÑпела" + +#, c-format +msgid "E315: ml_get: invalid lnum: %ld" +msgstr "E315: ml_get: неиÑправан lnum: %ld" + +#, c-format +msgid "E316: ml_get: cannot find line %ld" +msgstr "E316: ml_get: линија %ld не може да Ñе пронађе" + +msgid "E317: pointer block id wrong 3" +msgstr "E317: ид показивача блока је погрешан 3" + +msgid "stack_idx should be 0" +msgstr "stack_idx би требало да је 0" + +msgid "E318: Updated too many blocks?" +msgstr "E318: ОÑвежено превише блокова?" + +msgid "E317: pointer block id wrong 4" +msgstr "E317: ид показивача блока је погрешан 4" + +msgid "deleted block 1?" +msgstr "блок 1 обриÑан?" + +#, c-format +msgid "E320: Cannot find line %ld" +msgstr "E320: Линија %ld не може да Ñе пронађе" + +msgid "E317: pointer block id wrong" +msgstr "E317: ид показивача блока је погрешан" + +msgid "pe_line_count is zero" +msgstr "pe_line_count је нула" + +#, c-format +msgid "E322: line number out of range: %ld past the end" +msgstr "E322: број линије је ван опÑега: %ld иза краја" + +#, c-format +msgid "E323: line count wrong in block %ld" +msgstr "E323: број линија је погрешан у блоку %ld" + +msgid "Stack size increases" +msgstr "Величина Ñтека Ñе повећава" + +msgid "E317: pointer block id wrong 2" +msgstr "E317: ид показивача блока је погрешан 2" + +#, c-format +msgid "E773: Symlink loop for \"%s\"" +msgstr "E773: Symlink петља за \"%s\"" + +msgid "E325: ATTENTION" +msgstr "E325: ПÐЖЊÐ" + +msgid "" +"\n" +"Found a swap file by the name \"" +msgstr "" +"\n" +"Пронађена је swap датотека под именом \"" + +msgid "While opening file \"" +msgstr "Док Ñе отварала датотекa \"" + +msgid " NEWER than swap file!\n" +msgstr " ÐОВИЈРод swap датотеке!\n" + +msgid "" +"\n" +"(1) Another program may be editing the same file. If this is the case,\n" +" be careful not to end up with two different instances of the same\n" +" file when making changes. Quit, or continue with caution.\n" +msgstr "" +"\n" +"(1) Можда други програм уређује иÑту датотеку. Ðко је ово Ñлучај,\n" +" кад правите измене, пазите да не завршите Ñа две различите\n" +" инÑтанце иÑте датотеке. Изађите, или опрезно наÑтавите.\n" + +msgid "(2) An edit session for this file crashed.\n" +msgstr "(2) СеÑија уређивања ове датотеке Ñе Ñрушила.\n" + +msgid " If this is the case, use \":recover\" or \"vim -r " +msgstr " Ðко је ово Ñлучај, кориÑтите \":recover\" или \"vim -r " + +msgid "" +"\"\n" +" to recover the changes (see \":help recovery\").\n" +msgstr "" +"\"\n" +" да опоравите измене (погледајте \":help recovery\").\n" + +msgid " If you did this already, delete the swap file \"" +msgstr " Ðко Ñте ово већ учинили, обришите swap датотеку \"" + +msgid "" +"\"\n" +" to avoid this message.\n" +msgstr "" +"\"\n" +" како би избегли ову поруку.\n" + +msgid "Swap file \"" +msgstr "Swap датотека \"" + +msgid "\" already exists!" +msgstr "\" већ поÑтоји!" + +msgid "VIM - ATTENTION" +msgstr "VIM - ПÐЖЊÐ" + +msgid "Swap file already exists!" +msgstr "Swap датотека већ поÑтоји!" + +msgid "" +"&Open Read-Only\n" +"&Edit anyway\n" +"&Recover\n" +"&Quit\n" +"&Abort" +msgstr "" +"Отвори &Само за читање\n" +"Ипак &Уређуј\n" +"&Опорави\n" +"&Изађи\n" +"&Прекини" + +msgid "" +"&Open Read-Only\n" +"&Edit anyway\n" +"&Recover\n" +"&Delete it\n" +"&Quit\n" +"&Abort" +msgstr "" +"Отвори &Само за читање\n" +"Ипак &Уређуј\n" +"&Опорави\n" +"&Изађи\n" +"&Прекини" + +msgid "E326: Too many swap files found" +msgstr "E326: Пронађено је превише swap датотека" + +msgid "E327: Part of menu-item path is not sub-menu" +msgstr "E327: Део путање Ñтавке менија није подмени" + +msgid "E328: Menu only exists in another mode" +msgstr "E328: Мени поÑтоји Ñамо у другом режиму" + +#, c-format +msgid "E329: No menu \"%s\"" +msgstr "E329: Ðема менија \"%s\"" + +msgid "E792: Empty menu name" +msgstr "E792: Празно име менија" + +msgid "E330: Menu path must not lead to a sub-menu" +msgstr "E330: Путања менија не Ñме да води у подмени" + +msgid "E331: Must not add menu items directly to menu bar" +msgstr "E331: Ставке менија не Ñмеју да Ñе додају директно у линију менија" + +msgid "E332: Separator cannot be part of a menu path" +msgstr "E332: Сепаратор не може да буде део путање менија" + +msgid "" +"\n" +"--- Menus ---" +msgstr "" +"\n" +"--- Менији ---" + +msgid "Tear off this menu" +msgstr "Отцепи овај мени" + +#, c-format +msgid "E335: Menu not defined for %s mode" +msgstr "E335: Мени није дефиниÑан за %s Ñ€eжим" + +msgid "E333: Menu path must lead to a menu item" +msgstr "E333: Путања менија мора да води у Ñтавку менија" + +#, c-format +msgid "E334: Menu not found: %s" +msgstr "E334: Мени није пронађен: %s" + +msgid "E336: Menu path must lead to a sub-menu" +msgstr "E336: Путања менија мора да води у подмени" + +msgid "E337: Menu not found - check menu names" +msgstr "E337: Мени није пронађен - проверите имена менија" + +#, c-format +msgid "Error detected while processing %s:" +msgstr "Откривена је грешка током обраде %s:" + +#, c-format +msgid "line %4ld:" +msgstr "линија %4ld:" + +#, c-format +msgid "E354: Invalid register name: '%s'" +msgstr "E354: ÐеиÑправно име региÑтра: '%s'" + +msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>" +msgstr "Поруке одржава: Иван Пешић <ivan.pesic@gmail.com>" + +msgid "Interrupt: " +msgstr "Прекид: " + +msgid "Press ENTER or type command to continue" +msgstr "Да биÑте наÑтавили, притиÑните ЕÐТЕРили откуцајте команду" + +#, c-format +msgid "%s line %ld" +msgstr "%s линија %ld" + +msgid "-- More --" +msgstr "-- Још --" + +msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit " +msgstr " Ð ÐЗМÐКÐИЦÐ/d/j: екран/Ñтрана/линија наниже, b/u/k: навише, q: излаз " + +msgid "Question" +msgstr "Питање" + +msgid "" +"&Yes\n" +"&No" +msgstr "" +"&Да\n" +"&Ðе" + +msgid "" +"&Yes\n" +"&No\n" +"Save &All\n" +"&Discard All\n" +"&Cancel" +msgstr "" +"&Да\n" +"&Ðе\n" +"Сачувај &Све\n" +"о&Дбаци Ñве\n" +"&Откажи" + +msgid "Select Directory dialog" +msgstr "Дијалог избора директоријума" + +msgid "Save File dialog" +msgstr "Дијалог чувања датотеке" + +msgid "Open File dialog" +msgstr "Дијалог отварања датотеке" + +msgid "E338: Sorry, no file browser in console mode" +msgstr "E338: Жао нам је, нема претраживача датотека у конзолном режиму" + +msgid "E766: Insufficient arguments for printf()" +msgstr "E766: Ðедовољно аргумената за printf()" + +msgid "E807: Expected Float argument for printf()" +msgstr "E807: Очекује Ñе Float аргумент за printf()" + +msgid "E767: Too many arguments to printf()" +msgstr "E767: Сувише аргумената за printf()" + +msgid "W10: Warning: Changing a readonly file" +msgstr "W10: Упозорење: Мења Ñе датотека која може Ñамо да Ñе чита" + +msgid "Type number and <Enter> or click with mouse (empty cancels): " +msgstr "УнеÑите број и <Enter> или кликните мишем (ништа за отказ): " + +msgid "Type number and <Enter> (empty cancels): " +msgstr "УнеÑите број и <Enter> (ништа за отказ): " + +msgid "1 more line" +msgstr "1 линија више" + +msgid "1 line less" +msgstr "1 линија мање" + +#, c-format +msgid "%ld more lines" +msgstr "%ld линија више" + +#, c-format +msgid "%ld fewer lines" +msgstr "%ld линија мање" + +msgid " (Interrupted)" +msgstr " (Прекинуто)" + +msgid "Beep!" +msgstr "Биип!" + +msgid "ERROR: " +msgstr "ГРЕШКÐ: " + +#, c-format +msgid "" +"\n" +"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n" +msgstr "" +"\n" +"[бајтова] укупно алоц-оÑлоб %lu-%lu, у употр %lu, вршна употр %lu\n" + +#, c-format +msgid "" +"[calls] total re/malloc()'s %lu, total free()'s %lu\n" +"\n" +msgstr "" +"[позива] укупно re/malloc()-а %lu, укупно free()-ова %lu\n" +"\n" + +msgid "E340: Line is becoming too long" +msgstr "E340: Линија поÑтаје предугачка" + +#, c-format +msgid "E341: Internal error: lalloc(%ld, )" +msgstr "E341: Интерна грешка: lalloc(%ld, )" + +#, c-format +msgid "E342: Out of memory! (allocating %lu bytes)" +msgstr "E342: Ðема више меморије! (код алокације %lu бајтова)" + +#, c-format +msgid "Calling shell to execute: \"%s\"" +msgstr "Позива Ñе командно окружење да изврши: \"%s\"" + +msgid "E545: Missing colon" +msgstr "E545: ÐедоÑтаје двотачка" + +msgid "E546: Illegal mode" +msgstr "E546: Ðедозвољени режим" + +msgid "E547: Illegal mouseshape" +msgstr "E547: Ðедозвољени mouseshape" + +msgid "E548: digit expected" +msgstr "E548: очекује Ñе цифра" + +msgid "E549: Illegal percentage" +msgstr "E549: Ðедозвољени проценат" + +msgid "E854: path too long for completion" +msgstr "E854: путања је Ñувише дугачка да би Ñе довршила" + +#, c-format +msgid "" +"E343: Invalid path: '**[number]' must be at the end of the path or be " +"followed by '%s'." +msgstr "" +"E343: ÐеиÑправна путања: '**[број]' мора бити на крају путање или да иза " +"њега Ñледи '%s'." + +#, c-format +msgid "E344: Can't find directory \"%s\" in cdpath" +msgstr "E344: Директоријум \"%s\" не може да Ñе пронађе у cdpath" + +#, c-format +msgid "E345: Can't find file \"%s\" in path" +msgstr "E345: Датотека \"%s\" не може да Ñе пронађе у path" + +#, c-format +msgid "E346: No more directory \"%s\" found in cdpath" +msgstr "E346: Директоријум \"%s\" више не може да Ñе пронађе у cdpath" + +#, c-format +msgid "E347: No more file \"%s\" found in path" +msgstr "E347: Датотека \"%s\" више не може да Ñе пронађе у path" + +#, c-format +msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\"" +msgstr "E668: Погрешан режим приÑтупа за инфо датотеку NetBeans везе: \"%s\"" + +#, c-format +msgid "E658: NetBeans connection lost for buffer %ld" +msgstr "E658: NetBeans веза је изгубљена за бафер %ld" + +msgid "E838: netbeans is not supported with this GUI" +msgstr "E838: netbeans није подржан Ñа овим GUI" + +msgid "E511: netbeans already connected" +msgstr "E511: netbeans је већ повезан" + +#, c-format +msgid "E505: %s is read-only (add ! to override)" +msgstr "E505: %s је Ñамо за читање (додајте ! за премошћавање)" + +msgid "E349: No identifier under cursor" +msgstr "E349: Под курÑором није идентификатор" + +msgid "E774: 'operatorfunc' is empty" +msgstr "E774: 'operatorfunc' је празна" + +msgid "E775: Eval feature not available" +msgstr "E775: Eval могућноÑÑ‚ није доÑтупна" + +msgid "Warning: terminal cannot highlight" +msgstr "Упозорење: терминал не може да иÑтакне текÑÑ‚" + +msgid "E348: No string under cursor" +msgstr "E348: Под курÑором нема Ñтринга" + +msgid "E352: Cannot erase folds with current 'foldmethod'" +msgstr "E352: Са текућим 'foldmethod' не могу да Ñе обришу Ñклапања" + +msgid "E664: changelist is empty" +msgstr "E664: лиÑта промена је празна" + +msgid "E662: At start of changelist" +msgstr "E662: Ðа почетку лиÑте промена" + +msgid "E663: At end of changelist" +msgstr "E663: Ðа крају лиÑте промена" + +msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim" +msgstr "" +"Откуцајте :qa! и притиÑните <Ентер> да одбаците Ñве измене и напуÑтите Vim" + +#, c-format +msgid "1 line %sed 1 time" +msgstr "1 линија %sрана 1 пут" + +#, c-format +msgid "1 line %sed %d times" +msgstr "1 линија %sрана %d пута" + +#, c-format +msgid "%ld lines %sed 1 time" +msgstr "%ld линија %sрано 1 пут" + +#, c-format +msgid "%ld lines %sed %d times" +msgstr "%ld линија %sрано %d пута" + +#, c-format +msgid "%ld lines to indent... " +msgstr "%ld за увлачење... " + +msgid "1 line indented " +msgstr "1 линија увучена " + +#, c-format +msgid "%ld lines indented " +msgstr "%ld инија увучено " + +msgid "E748: No previously used register" +msgstr "E748: Ðема претходно коришћеног региÑтра" + +msgid "cannot yank; delete anyway" +msgstr "не може да Ñе тргне; ипак обриÑати" + +msgid "1 line changed" +msgstr "1 линија је промењена" + +#, c-format +msgid "%ld lines changed" +msgstr "%ld линија је промењено" + +#, c-format +msgid "freeing %ld lines" +msgstr "оÑлобађа Ñе %ld линија" + +#, c-format +msgid " into \"%c" +msgstr " у \"%c" + +#, c-format +msgid "block of 1 line yanked%s" +msgstr "блок од 1 линије је тргнут%s" + +#, c-format +msgid "1 line yanked%s" +msgstr "1 линија је тргнута%s" + +#, c-format +msgid "block of %ld lines yanked%s" +msgstr "блок од %ld линија је тргнут%s" + +#, c-format +msgid "%ld lines yanked%s" +msgstr "%ld линија је тргнуто%s" + +#, c-format +msgid "E353: Nothing in register %s" +msgstr "E353: РегиÑтар %s је празан" + +msgid "" +"\n" +"--- Registers ---" +msgstr "" +"\n" +"--- РегиÑтри ---" + +msgid "Illegal register name" +msgstr "Ðеважеће име региÑтра" + +msgid "" +"\n" +"# Registers:\n" +msgstr "" +"\n" +"# РегиÑтри:\n" + +#, c-format +msgid "E574: Unknown register type %d" +msgstr "E574: Ðепознат тип региÑтра %d" + +msgid "" +"E883: search pattern and expression register may not contain two or more " +"lines" +msgstr "" +"E883: региÑтар за шаблон претраге и израз не може да Ñадржи две или више " +"линија" + +#, c-format +msgid "%ld Cols; " +msgstr "%ld Кол; " + +#, c-format +msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes" +msgstr "Изабрано %s%ld од %ld Линија; %lld од %lld Речи; %lld од %lld Бајтова" + +#, c-format +msgid "" +"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of " +"%lld Bytes" +msgstr "" +"Изабрано %s%ld од %ld Линија; %lld од %lld Речи; %lld од %lld Знака; %lld од " +"%lld Бајтова" + +#, c-format +msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld" +msgstr "Кол %s од %s; Линија %ld од %ld; Реч %lld од %lld; Бајт %lld од %lld" + +#, c-format +msgid "" +"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte %" +"lld of %lld" +msgstr "" +"Кол %s од %s; Линија %ld од %ld; Реч %lld од %lld; Знак %lld од %lld; Бајт %" +"lld од %lld" + +#, c-format +msgid "(+%lld for BOM)" +msgstr "(+%lld за BOM)" + +msgid "Thanks for flying Vim" +msgstr "Хвала што летите Ñа Vim" + +msgid "E518: Unknown option" +msgstr "E518: Ðепозната опција" + +msgid "E519: Option not supported" +msgstr "E519: Опција није подржана" + +msgid "E520: Not allowed in a modeline" +msgstr "E520: Ðије довољено у режимÑкој линији" + +msgid "E846: Key code not set" +msgstr "E846: Ðије поÑтављрн код таÑтера" + +msgid "E521: Number required after =" +msgstr "E521: Потребан је број након =" + +msgid "E522: Not found in termcap" +msgstr "E522: Ðије пронађено у termcap" + +#, c-format +msgid "E539: Illegal character <%s>" +msgstr "E539: Ðедозвољен карактер <%s>" + +#, c-format +msgid "For option %s" +msgstr "За опцију %s" + +msgid "E529: Cannot set 'term' to empty string" +msgstr "E529: 'term' не може да Ñе поÑтави на празан Ñтринг" + +msgid "E530: Cannot change term in GUI" +msgstr "E530: term не може да Ñе промени из GUI" + +msgid "E531: Use \":gui\" to start the GUI" +msgstr "E531: КориÑтите \":gui\" да покренете GUI" + +msgid "E589: 'backupext' and 'patchmode' are equal" +msgstr "E589: 'backupext' и 'patchmode' Ñу иÑтоветни" + +msgid "E834: Conflicts with value of 'listchars'" +msgstr "E834: У конфликту Ñа вредношћу 'listchars'" + +msgid "E835: Conflicts with value of 'fillchars'" +msgstr "E835: У конфликту Ñа вредношћу 'fillchars'" + +msgid "E617: Cannot be changed in the GTK+ 2 GUI" +msgstr "E617: Ðе може да Ñе промени у GTK+ 2 GUI" + +#, c-format +msgid "E950: Cannot convert between %s and %s" +msgstr "E950: Ðе може да Ñе конвертује између %s и %s" + +msgid "E524: Missing colon" +msgstr "E524: ÐедоÑтаје двотачка" + +msgid "E525: Zero length string" +msgstr "E525: Стринг дужине нула" + +#, c-format +msgid "E526: Missing number after <%s>" +msgstr "E526: ÐедоÑтаје број након <%s>" + +msgid "E527: Missing comma" +msgstr "E527: ÐедоÑтаје зарез" + +msgid "E528: Must specify a ' value" +msgstr "E528: Мора да Ñе наведе ' вредноÑÑ‚" + +msgid "E595: contains unprintable or wide character" +msgstr "E595: Ñадржи карактер који не може да Ñе одштампа, или широки карактер" + +msgid "E596: Invalid font(s)" +msgstr "E596: ÐеиÑправни фонт(ови)" + +msgid "E597: can't select fontset" +msgstr "E597: fontset не може да Ñе изабере" + +msgid "E598: Invalid fontset" +msgstr "E598: ÐеиÑправан fontset" + +msgid "E533: can't select wide font" +msgstr "E533: широки фонт не може да Ñе изабере" + +msgid "E534: Invalid wide font" +msgstr "E534: ÐеиÑправан широки фонт" + +#, c-format +msgid "E535: Illegal character after <%c>" +msgstr "E535: Ðеважећи карактер након <%c>" + +msgid "E536: comma required" +msgstr "E536: потребан зарез" + +#, c-format +msgid "E537: 'commentstring' must be empty or contain %s" +msgstr "E537: 'commentstring' мора бити празно или да Ñадржи %s" + +msgid "E538: No mouse support" +msgstr "E538: Ðема подршке за миша" + +msgid "E540: Unclosed expression sequence" +msgstr "E540: Ðиз израза није затворен" + +msgid "E541: too many items" +msgstr "E541: превише Ñтавки" + +msgid "E542: unbalanced groups" +msgstr "E542: неуравнотежене групе" + +msgid "E946: Cannot make a terminal with running job modifiable" +msgstr "" +"E946: Терминал Ñа задатком који Ñе извршава не може да Ñе учини измењивим" + +msgid "E590: A preview window already exists" +msgstr "E590: Прозор за преглед већ поÑтоји" + +msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'" +msgstr "W17: ÐрапÑки захтева UTF-8, извршите ':set encoding=utf-8'" + +msgid "E954: 24-bit colors are not supported on this environment" +msgstr "E954: Ово окружење не подржава 24-битне боје" + +#, c-format +msgid "E593: Need at least %d lines" +msgstr "E593: Потребно је најмање %d линија" + +#, c-format +msgid "E594: Need at least %d columns" +msgstr "E594: Потребно је најмање %d колона" + +#, c-format +msgid "E355: Unknown option: %s" +msgstr "E355: Ðепозната опција: %s" + +#, c-format +msgid "E521: Number required: &%s = '%s'" +msgstr "E521: Захтева Ñе број: &%s = '%s'" + +msgid "" +"\n" +"--- Terminal codes ---" +msgstr "" +"\n" +"--- Кодови терминала ---" + +msgid "" +"\n" +"--- Global option values ---" +msgstr "" +"\n" +"--- ВредноÑти глобалних опција ---" + +msgid "" +"\n" +"--- Local option values ---" +msgstr "" +"\n" +"--- ВредноÑти локалних опција ---" + +msgid "" +"\n" +"--- Options ---" +msgstr "" +"\n" +"--- Опције ---" + +msgid "E356: get_varp ERROR" +msgstr "E356: get_varp ГРЕШКÐ" + +#, c-format +msgid "E357: 'langmap': Matching character missing for %s" +msgstr "E357: 'langmap': ÐедоÑтаје одговарајући карактер за %s" + +#, c-format +msgid "E358: 'langmap': Extra characters after semicolon: %s" +msgstr "E358: 'langmap': Има још карактера након тачказареза: %s" + +msgid "cannot open " +msgstr "не може да Ñе отвори " + +msgid "VIM: Can't open window!\n" +msgstr "VIM: Прозор не може да Ñе отвори!\n" + +msgid "Need Amigados version 2.04 or later\n" +msgstr "Потребан је Amigados верзија 2.04 или каÑнији\n" + +#, c-format +msgid "Need %s version %ld\n" +msgstr "Потребан је %s верзија %ld\n" + +msgid "Cannot open NIL:\n" +msgstr "Ðе може да Ñе отвори NIL:\n" + +msgid "Cannot create " +msgstr "Ðе може да Ñе креира " + +#, c-format +msgid "Vim exiting with %d\n" +msgstr "Vim излази Ñа %d\n" + +msgid "cannot change console mode ?!\n" +msgstr "конзолни режим не може да Ñе промени ?!\n" + +msgid "mch_get_shellsize: not a console??\n" +msgstr "mch_get_shellsize: није конзола??\n" + +msgid "E360: Cannot execute shell with -f option" +msgstr "E360: Командно окружење не може да Ñе изврши Ñа -f опцијом" + +msgid "Cannot execute " +msgstr "Ðе може да Ñе изврши " + +msgid "shell " +msgstr "командно окружење " + +msgid " returned\n" +msgstr " вратило\n" + +msgid "ANCHOR_BUF_SIZE too small." +msgstr "ANCHOR_BUF_SIZE Ñувише мали." + +msgid "I/O ERROR" +msgstr "У/И ГРЕШКÐ" + +msgid "Message" +msgstr "Порука" + +msgid "E237: Printer selection failed" +msgstr "E237: Избор штампача није уÑпео" + +#, c-format +msgid "to %s on %s" +msgstr "у %s на %s" + +#, c-format +msgid "E613: Unknown printer font: %s" +msgstr "E613: Ðепознат фонт штампача: %s" + +#, c-format +msgid "E238: Print error: %s" +msgstr "E238: Грешка код штампања: %s" + +#, c-format +msgid "Printing '%s'" +msgstr "Штампа Ñе '%s'" + +#, c-format +msgid "E244: Illegal charset name \"%s\" in font name \"%s\"" +msgstr "E244: Ðедозвољено име Ñета карактера \"%s\" у имену фонту \"%s\"" + +#, c-format +msgid "E244: Illegal quality name \"%s\" in font name \"%s\"" +msgstr "E244: Ðедозвољено име варијанте \"%s\" у имену фонту \"%s\"" + +#, c-format +msgid "E245: Illegal char '%c' in font name \"%s\"" +msgstr "E245: ÐеиÑправан карактер '%c' у имену фонта \"%s\"" + +#, c-format +msgid "Opening the X display took %ld msec" +msgstr "Отварање X приказа је трајало %ld мÑек" + +msgid "" +"\n" +"Vim: Got X error\n" +msgstr "" +"\n" +"Vim: Дошло је до X грешке\n" + +msgid "Testing the X display failed" +msgstr "ТеÑтирање X приказа није уÑпело" + +msgid "Opening the X display timed out" +msgstr "ИÑтекло је макÑимално време за отварање X приказа" + +msgid "" +"\n" +"Could not get security context for " +msgstr "" +"\n" +"Ðије могао да Ñе очита безбедноÑни контекÑÑ‚ за " + +msgid "" +"\n" +"Could not set security context for " +msgstr "" +"\n" +"Ðије могао да Ñе поÑтави безбедноÑни контекÑÑ‚ за " + +#, c-format +msgid "Could not set security context %s for %s" +msgstr "БезбедноÑни контекÑÑ‚ %s за %s није могао да Ñе поÑтави" + +#, c-format +msgid "Could not get security context %s for %s. Removing it!" +msgstr "БезбедноÑни контекÑÑ‚ %s за %s није могао да Ñе очита. Уклања Ñе!" + +msgid "" +"\n" +"Cannot execute shell sh\n" +msgstr "" +"\n" +"Командно окружење sh не може да Ñе изврши\n" + +msgid "" +"\n" +"shell returned " +msgstr "" +"\n" +"командно окружење је вратило " + +msgid "" +"\n" +"Cannot create pipes\n" +msgstr "" +"\n" +"Токови података не могу да Ñе креирају\n" + +msgid "" +"\n" +"Cannot fork\n" +msgstr "" +"\n" +"Рачвање није могуће\n" + +msgid "" +"\n" +"Cannot execute shell " +msgstr "" +"\n" +"Командно окружење не може да Ñе изврши " + +msgid "" +"\n" +"Command terminated\n" +msgstr "" +"\n" +"Команда је прекинута\n" + +msgid "XSMP lost ICE connection" +msgstr "XSMP је изгубио ICE везу" + +#, c-format +msgid "dlerror = \"%s\"" +msgstr "dlerror = \"%s\"" + +msgid "Opening the X display failed" +msgstr "Отварање X приказа није уÑпело" + +msgid "XSMP handling save-yourself request" +msgstr "XSMP опÑлужује Ñачувај-Ñе захтев" + +msgid "XSMP opening connection" +msgstr "XSMP отвара везу" + +msgid "XSMP ICE connection watch failed" +msgstr "XSMP ICE надгледање везе није уÑпело" + +#, c-format +msgid "XSMP SmcOpenConnection failed: %s" +msgstr "XSMP SmcOpenConnection није уÑпело: %s" + +msgid "At line" +msgstr "Код линије" + +msgid "Could not load vim32.dll!" +msgstr "vim32.dll није могла да Ñе учита!" + +msgid "VIM Error" +msgstr "VIM Грешка" + +msgid "Could not fix up function pointers to the DLL!" +msgstr "Показивачи на функције у DLL-у ниÑу могли да Ñе поправе!" + +#, c-format +msgid "Vim: Caught %s event\n" +msgstr "Vim: Ухваћен је %s догађај\n" + +msgid "close" +msgstr "затварање" + +msgid "logoff" +msgstr "одјављивање" + +msgid "shutdown" +msgstr "иÑкључивање" + +msgid "E371: Command not found" +msgstr "E371: Команда није пронађена" + +msgid "" +"VIMRUN.EXE not found in your $PATH.\n" +"External commands will not pause after completion.\n" +"See :help win32-vimrun for more information." +msgstr "" +"VIMRUN.EXE није пронађен у вашем $PATH.\n" +"ЕкÑтерне команде неће моћи да Ñе паузирају након завршетка.\n" +"Погледајте :help win32-vimrun за више информација." + +msgid "Vim Warning" +msgstr "Vim Упозорење" + +#, c-format +msgid "shell returned %d" +msgstr "командно окружење је вратило %d" + +msgid "E926: Current location list was changed" +msgstr "E926: Текућа лиÑта локација је промењена" + +#, c-format +msgid "E372: Too many %%%c in format string" +msgstr "E372: Превише %%%c Ñтрингу формата" + +#, c-format +msgid "E373: Unexpected %%%c in format string" +msgstr "E373: Ðеочекивано %%%c Ñтрингу формата" + +msgid "E374: Missing ] in format string" +msgstr "E374: ÐедоÑтаје ] у Ñтрингу формата" + +#, c-format +msgid "E375: Unsupported %%%c in format string" +msgstr "E375: Ðеподржано %%%c у Ñтрингу формата" + +#, c-format +msgid "E376: Invalid %%%c in format string prefix" +msgstr "E376: Ðеважеће %%%c у префикÑу Ñтринга формата" + +#, c-format +msgid "E377: Invalid %%%c in format string" +msgstr "E377: Ðеважеће %%%c у Ñтрингу формата" + +msgid "E378: 'errorformat' contains no pattern" +msgstr "E378: 'errorformat' не Ñадржи шаблон" + +msgid "E379: Missing or empty directory name" +msgstr "E379: Име директоријума недоÑтаје или је празно" + +msgid "E553: No more items" +msgstr "E553: Ðема више Ñтавки" + +msgid "E924: Current window was closed" +msgstr "E924: Текући прозор је затворен" + +msgid "E925: Current quickfix was changed" +msgstr "E925: Текући quickfix је промењен" + +#, c-format +msgid "(%d of %d)%s%s: " +msgstr "(%d од %d)%s%s: " + +msgid " (line deleted)" +msgstr " (линија обриÑана)" + +#, c-format +msgid "%serror list %d of %d; %d errors " +msgstr "%sлиÑта грешака %d од %d; %d грешака " + +msgid "E380: At bottom of quickfix stack" +msgstr "E380: Ðа дну quickfix Ñтека" + +msgid "E381: At top of quickfix stack" +msgstr "E381: Ðа врху quickfix Ñтека" + +msgid "No entries" +msgstr "Ðема уноÑа" + +msgid "Error file" +msgstr "Датотека грешака" + +msgid "E683: File name missing or invalid pattern" +msgstr "E683: ÐедоÑтаје име датотеке или неважећи шаблон" + +#, c-format +msgid "Cannot open file \"%s\"" +msgstr "Датотека \"%s\" не може да Ñе отвори" + +msgid "E681: Buffer is not loaded" +msgstr "E681: Бафер није учитан" + +msgid "E777: String or List expected" +msgstr "E777: Очекује Ñе String или List" + +#, c-format +msgid "E369: invalid item in %s%%[]" +msgstr "E369: неважећа Ñтавка у %s%%[]" + +#, c-format +msgid "E769: Missing ] after %s[" +msgstr "E769: ÐедоÑтаје ] након %s[" + +msgid "E944: Reverse range in character class" +msgstr "E944: Обрнути опÑег у карактер клаÑи" + +msgid "E945: Range too large in character class" +msgstr "E945: Превелики опÑег у карактер клаÑи" + +#, c-format +msgid "E53: Unmatched %s%%(" +msgstr "E53: Ðеупарена %s%%(" + +#, c-format +msgid "E54: Unmatched %s(" +msgstr "E54: Ðеупарена %s(" + +#, c-format +msgid "E55: Unmatched %s)" +msgstr "E55: Ðеупарена %s)" + +msgid "E66: \\z( not allowed here" +msgstr "E66: \\z( овде није дозвољено" + +msgid "E67: \\z1 - \\z9 not allowed here" +msgstr "E67: \\z1 - \\z9 овде ниÑу дозвољени" + +#, c-format +msgid "E69: Missing ] after %s%%[" +msgstr "E69: ÐедоÑтаје ] након %s%%[" + +#, c-format +msgid "E70: Empty %s%%[]" +msgstr "E70: Празан %s%%[]" + +msgid "E65: Illegal back reference" +msgstr "E65: Ðеважећа повратна референца" + +msgid "E339: Pattern too long" +msgstr "E339: Шаблон је предугачак" + +msgid "E50: Too many \\z(" +msgstr "E50: Превише \\z(" + +#, c-format +msgid "E51: Too many %s(" +msgstr "E51: Превише %s(" + +msgid "E52: Unmatched \\z(" +msgstr "E52: Ðеупарено \\z(" + +#, c-format +msgid "E59: invalid character after %s@" +msgstr "E59: неважећи карактер након %s@" + +#, c-format +msgid "E60: Too many complex %s{...}s" +msgstr "E60: Превише комплекÑних %s{...}s" + +#, c-format +msgid "E61: Nested %s*" +msgstr "E61: Угњеждено %s*" + +#, c-format +msgid "E62: Nested %s%c" +msgstr "E62: Угњеждено %s%c" + +msgid "E63: invalid use of \\_" +msgstr "E63: неиÑправна употреба \\_" + +#, c-format +msgid "E64: %s%c follows nothing" +msgstr "E64: %s%c je иза ничега" + +msgid "E68: Invalid character after \\z" +msgstr "E68: Ðеважећи карактер након \\z" + +#, c-format +msgid "E678: Invalid character after %s%%[dxouU]" +msgstr "E678: Ðеважећи карактер након %s%%[dxouU]" + +#, c-format +msgid "E71: Invalid character after %s%%" +msgstr "E71: Ðеважећи карактер након %s%%" + +#, c-format +msgid "E554: Syntax error in %s{...}" +msgstr "E554: СинтакÑна грешка у %s{...}" + +msgid "External submatches:\n" +msgstr "Спољна подпоклапања:\n" + +#, c-format +msgid "E888: (NFA regexp) cannot repeat %s" +msgstr "E888: (NFA regexp) не може да Ñе понови %s" + +msgid "" +"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be " +"used " +msgstr "" +"E864: Иза \\%#= може да Ñледи једино 0, 1, или 2. КориÑтиће Ñе аутоматÑки " +"енџин " + +msgid "Switching to backtracking RE engine for pattern: " +msgstr "Пребацивање на backtracking RE енџин за шаблон: " + +msgid "E865: (NFA) Regexp end encountered prematurely" +msgstr "E865: Крај (NFA) Regexp израза је доÑтигнут прерано" + +#, c-format +msgid "E866: (NFA regexp) Misplaced %c" +msgstr "E866: (NFA regexp) %c је на погрешном меÑту" + +#, c-format +msgid "E877: (NFA regexp) Invalid character class: %ld" +msgstr "E877: (NFA regexp) Ðеважећа карактер клаÑа: %ld" + +#, c-format +msgid "E867: (NFA) Unknown operator '\\z%c'" +msgstr "E867: (NFA) Ðепознати оператор '\\z%c'" + +msgid "E951: \\% value too large" +msgstr "E951: ВредноÑÑ‚ \\% је предугачка" + +#, c-format +msgid "E867: (NFA) Unknown operator '\\%%%c'" +msgstr "E867: (NFA) Ðепознати оператор '\\%%%c'" + +msgid "E868: Error building NFA with equivalence class!" +msgstr "E868: Грешка при грађењу NFA Ñа клаÑом еквиваленције!" + +#, c-format +msgid "E869: (NFA) Unknown operator '\\@%c'" +msgstr "E869: (NFA) Ðепознати оператор '\\@%c'" + +msgid "E870: (NFA regexp) Error reading repetition limits" +msgstr "E870: (NFA regexp) Грешка при читању граница понављања" + +msgid "E871: (NFA regexp) Can't have a multi follow a multi" +msgstr "E871: (NFA regexp) Мулти не може Ñледи иза мулти" + +msgid "E872: (NFA regexp) Too many '('" +msgstr "E872: (NFA regexp) Превише '('" + +msgid "E879: (NFA regexp) Too many \\z(" +msgstr "E879: (NFA regexp) Превише \\z(" + +msgid "E873: (NFA regexp) proper termination error" +msgstr "E873: (NFA regexp) грешка правилне терминације" + +msgid "E874: (NFA) Could not pop the stack!" +msgstr "E874: (NFA) Скидање Ñа Ñтека није уÑпело!" + +msgid "" +"E875: (NFA regexp) (While converting from postfix to NFA), too many states " +"left on stack" +msgstr "" +"E875: (NFA regexp) (Док је вршена конверзија из postfix у NFA), превише " +"Ñтања је оÑтало на Ñтеку" + +msgid "E876: (NFA regexp) Not enough space to store the whole NFA " +msgstr "" +"E876: (NFA regexp) Ðема довољно проÑтора да Ñе уÑкладишти комплетан NFA " + +msgid "E878: (NFA) Could not allocate memory for branch traversal!" +msgstr "E878: (NFA) Ðије могла да Ñе алоцира меморија за обилазак грана!" + +msgid "" +"Could not open temporary log file for writing, displaying on stderr... " +msgstr "" +"Привремена лог датотека није могла да Ñе отвори за упиÑ, приказује Ñе на " +"stderr... " + +#, c-format +msgid "(NFA) COULD NOT OPEN %s !" +msgstr "(NFA) %s ÐЕ МОЖЕ ДРСЕ ОТВОРИ !" + +msgid "Could not open temporary log file for writing " +msgstr "Привремена лог датотека није могла да Ñе отвори за ÑƒÐ¿Ð¸Ñ " + +msgid " VREPLACE" +msgstr "ВЗÐМЕÐÐ" + +msgid " REPLACE" +msgstr " ЗÐМЕÐÐ" + +msgid " REVERSE" +msgstr " ОБРÐУТО" + +msgid " INSERT" +msgstr " УМЕТÐЊЕ" + +msgid " (insert)" +msgstr " (уметање)" + +msgid " (replace)" +msgstr " (замена)" + +msgid " (vreplace)" +msgstr " (взамена)" + +msgid " Hebrew" +msgstr " хебрејÑки" + +msgid " Arabic" +msgstr " арапÑки" + +msgid " (paste)" +msgstr " (налепи)" + +msgid " VISUAL" +msgstr " ВИЗУЕЛÐО" + +msgid " VISUAL LINE" +msgstr " ВИЗУЕЛÐРЛИÐИЈÐ" + +msgid " VISUAL BLOCK" +msgstr " ВИЗУЕЛÐИ БЛОК" + +msgid " SELECT" +msgstr " ИЗБОР" + +msgid " SELECT LINE" +msgstr " ИЗБОРЛИÐИЈÐ" + +msgid " SELECT BLOCK" +msgstr " ИЗБОРБЛОКÐ" + +msgid "recording" +msgstr "Ñнимање" + +#, c-format +msgid "E383: Invalid search string: %s" +msgstr "E383: ÐеиÑправан Ñтринг за претрагу: %s" + +#, c-format +msgid "E384: search hit TOP without match for: %s" +msgstr "E384: претрага је доÑтигла ВРХ без подударања за: %s" + +#, c-format +msgid "E385: search hit BOTTOM without match for: %s" +msgstr "E385: претрага је доÑтигла ДÐО без подударања за: %s" + +msgid "E386: Expected '?' or '/' after ';'" +msgstr "E386: Ðакон ';' Ñе очекује '?' или '/'" + +msgid " (includes previously listed match)" +msgstr " (укључује претходно наведена подударања)" + +msgid "--- Included files " +msgstr "--- Прикључене датотеке " + +msgid "not found " +msgstr "ниÑу пронађене " + +msgid "in path ---\n" +msgstr "у путањи ---\n" + +msgid " (Already listed)" +msgstr " (Већ наведено)" + +msgid " NOT FOUND" +msgstr " ÐИЈЕ ПРОÐÐЂЕÐО" + +#, c-format +msgid "Scanning included file: %s" +msgstr "Прегледање уметнуте датотеке: %s" + +#, c-format +msgid "Searching included file %s" +msgstr "Претраживање уметнуте датотеке %s" + +msgid "E387: Match is on current line" +msgstr "E387: Подударање је у текућој линији" + +msgid "All included files were found" +msgstr "Све уметнуте датотеке Ñу пронађене" + +msgid "No included files" +msgstr "Ðема уметнутих датотека" + +msgid "E388: Couldn't find definition" +msgstr "E388: Дефиниција не може да Ñе пронађе" + +msgid "E389: Couldn't find pattern" +msgstr "E389: Шаблон за претрагу није пронађен" + +msgid "Substitute " +msgstr "Замена " + +#, c-format +msgid "" +"\n" +"# Last %sSearch Pattern:\n" +"~" +msgstr "" +"\n" +"# ПоÑледњи %sШаблон Претраге:\n" +"~" + +msgid "E756: Spell checking is not enabled" +msgstr "E756: Провера правопиÑа није омогућена" + +#, c-format +msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\"" +msgstr "" +"Упозорење: ЛиÑта речи \"%s_%s.spl\" или \"%s_ascii.spl\" не може да Ñе " +"пронађе" + +#, c-format +msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\"" +msgstr "" +"Упозорење: ЛиÑта речи \"%s.%s.spl\" или \"%s.ascii.spl\" не може да Ñе " +"пронађе" + +msgid "E797: SpellFileMissing autocommand deleted buffer" +msgstr "E797: SpellFileMissing аутокоманда је обриÑала бафер" + +#, c-format +msgid "Warning: region %s not supported" +msgstr "Упозорење: регион %s није подржан" + +msgid "Sorry, no suggestions" +msgstr "Жао нам је, нема ÑугеÑтија" + +#, c-format +msgid "Sorry, only %ld suggestions" +msgstr "Жао нам је, Ñамо %ld ÑугеÑтија" + +#, c-format +msgid "Change \"%.*s\" to:" +msgstr "Променити \"%.*s\" у:" + +#, c-format +msgid " < \"%.*s\"" +msgstr " < \"%.*s\"" + +msgid "E752: No previous spell replacement" +msgstr "E752: Ðема претходне правопиÑне замене" + +#, c-format +msgid "E753: Not found: %s" +msgstr "E753: Ðије пронађено: %s" + +msgid "E758: Truncated spell file" +msgstr "E758: ПравопиÑна датотека је прекраћена" + +#, c-format +msgid "Trailing text in %s line %d: %s" +msgstr "ТекÑÑ‚ вишак у %s линија %d: %s" + +#, c-format +msgid "Affix name too long in %s line %d: %s" +msgstr "Име наÑтавка је предугачко у %s линија %d: %s" + +msgid "E761: Format error in affix file FOL, LOW or UPP" +msgstr "E761: Грешка формата у датотеци наÑтавака FOL, LOW или UPP" + +msgid "E762: Character in FOL, LOW or UPP is out of range" +msgstr "E762: Карактер у FOL, LOW или UPP је ван опÑега" + +msgid "Compressing word tree..." +msgstr "Стабло речи Ñе компреÑује..." + +#, c-format +msgid "Reading spell file \"%s\"" +msgstr "Читање правопиÑне датотеке \"%s\"" + +msgid "E757: This does not look like a spell file" +msgstr "E757: Ово не изгледа као правопиÑна датотека" + +msgid "E771: Old spell file, needs to be updated" +msgstr "E771: Стара правопиÑна датотека, потребно је да Ñе оÑвежи" + +msgid "E772: Spell file is for newer version of Vim" +msgstr "E772: ПравопиÑна датотека је за новију верзију Vim-а" + +msgid "E770: Unsupported section in spell file" +msgstr "E770: Ðеподржана Ñекција у правопиÑној датотеци" + +#, c-format +msgid "E778: This does not look like a .sug file: %s" +msgstr "E778: Ово не изгледа као .sug датотека: %s" + +#, c-format +msgid "E779: Old .sug file, needs to be updated: %s" +msgstr "E779: Стара .sug датотека, потребно је да Ñе оÑвежи: %s" + +#, c-format +msgid "E780: .sug file is for newer version of Vim: %s" +msgstr "E780: .sug датотека је за новију верзију Vim-а: %s" + +#, c-format +msgid "E781: .sug file doesn't match .spl file: %s" +msgstr "E781: .sug датотека не одговара .spl датотеци: %s" + +#, c-format +msgid "E782: error while reading .sug file: %s" +msgstr "E782: грешка приликом читања .sug датотеке: %s" + +#, c-format +msgid "Reading affix file %s..." +msgstr "Читање датотеке наÑтавака %s..." + +#, c-format +msgid "Conversion failure for word in %s line %d: %s" +msgstr "ÐеуÑпешна конверзија за реч у %s линија %d: %s" + +#, c-format +msgid "Conversion in %s not supported: from %s to %s" +msgstr "Конверзија у %s није подржана: из %s у %s" + +#, c-format +msgid "Conversion in %s not supported" +msgstr "Конверзија у %s није подржана" + +#, c-format +msgid "Invalid value for FLAG in %s line %d: %s" +msgstr "Ðеважећа вредноÑÑ‚ за FLAG у %s линија %d: %s" + +#, c-format +msgid "FLAG after using flags in %s line %d: %s" +msgstr "FLAG након коришћења индикатора у %s линија %d: %s" + +#, c-format +msgid "" +"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line " +"%d" +msgstr "" +"ДефиниÑање COMPOUNDFORBIDFLAG након PFX Ñтавке може да дâ погрешне резултате " +"у %s line %d" + +#, c-format +msgid "" +"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line " +"%d" +msgstr "" +"ДефиниÑање COMPOUNDPERMITFLAG након PFX Ñтавке може да дâ погрешне резултате " +"у %s line %d" + +#, c-format +msgid "Wrong COMPOUNDRULES value in %s line %d: %s" +msgstr "Погрешна COMPOUNDRULES вредноÑÑ‚ у %s линија %d: %s" + +#, c-format +msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s" +msgstr "Погрешна COMPOUNDWORDMAX вредноÑÑ‚ у %s линија %d: %s" + +#, c-format +msgid "Wrong COMPOUNDMIN value in %s line %d: %s" +msgstr "Погрешна COMPOUNDMIN вредноÑÑ‚ у %s линија %d: %s" + +#, c-format +msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s" +msgstr "Погрешна COMPOUNDSYLMAX вредноÑÑ‚ у %s линија %d: %s" + +#, c-format +msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s" +msgstr "Погрешна CHECKCOMPOUNDPATTERN вредноÑÑ‚ у %s линија %d: %s" + +#, c-format +msgid "Different combining flag in continued affix block in %s line %d: %s" +msgstr "" +"Различит индикатор комбиновања у наÑтављеном блоку наÑтавака у %s линија %d: " +"%s" + +#, c-format +msgid "Duplicate affix in %s line %d: %s" +msgstr "Дупликат наÑтавка у %s линија %d: %s" + +#, c-format +msgid "" +"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s " +"line %d: %s" +msgstr "" +"ÐаÑтавак Ñе такође кориÑти за BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST у %s" +"линија %d: %s" + +#, c-format +msgid "Expected Y or N in %s line %d: %s" +msgstr "Очекује Ñе Y или N у %s линија %d: %s" + +#, c-format +msgid "Broken condition in %s line %d: %s" +msgstr "Ðеправилан уÑлов у %s линија %d: %s" + +#, c-format +msgid "Expected REP(SAL) count in %s line %d" +msgstr "Очекује Ñе број REP(SAL) у %s линија %d" + +#, c-format +msgid "Expected MAP count in %s line %d" +msgstr "Очекује Ñе број MAP у %s линија %d" + +#, c-format +msgid "Duplicate character in MAP in %s line %d" +msgstr "Дупликат карактера у MAP у %s линија %d" + +#, c-format +msgid "Unrecognized or duplicate item in %s line %d: %s" +msgstr "ÐепрепоÑната или дупла Ñтавка у %s линија %d: %s" + +#, c-format +msgid "Missing FOL/LOW/UPP line in %s" +msgstr "ÐедоÑтаје FOL/LOW/UPP линија у %s" + +msgid "COMPOUNDSYLMAX used without SYLLABLE" +msgstr "COMPOUNDSYLMAX Ñе кориÑти без SYLLABLE" + +msgid "Too many postponed prefixes" +msgstr "Превише закашњених префикÑа" + +msgid "Too many compound flags" +msgstr "Превише индикатора Ñложеница" + +msgid "Too many postponed prefixes and/or compound flags" +msgstr "Превише закашњених префикÑа и/или индикатора Ñложеница" + +#, c-format +msgid "Missing SOFO%s line in %s" +msgstr "ÐедоÑтаје SOFO%s линија у %s" + +#, c-format +msgid "Both SAL and SOFO lines in %s" +msgstr "И SAL и SOFO линије у %s" + +#, c-format +msgid "Flag is not a number in %s line %d: %s" +msgstr "Индикатор није број у %s линија %d: %s" + +#, c-format +msgid "Illegal flag in %s line %d: %s" +msgstr "Ðеважећи индикатор у %s линија %d: %s" + +#, c-format +msgid "%s value differs from what is used in another .aff file" +msgstr "" +"%s вредноÑÑ‚ Ñе разликује од онога што је коришћено у другој .aff датотеци" + +#, c-format +msgid "Reading dictionary file %s..." +msgstr "Читање датотеке речника %s..." + +#, c-format +msgid "E760: No word count in %s" +msgstr "E760: Ðема броја речи у %s" + +#, c-format +msgid "line %6d, word %6ld - %s" +msgstr "линија %6d, реч %6ld - %s" + +#, c-format +msgid "Duplicate word in %s line %d: %s" +msgstr "Дупликат речи у %s линија %d: %s" + +#, c-format +msgid "First duplicate word in %s line %d: %s" +msgstr "Прва реч дупликат у %s линија %d: %s" + +#, c-format +msgid "%d duplicate word(s) in %s" +msgstr "%d реч(и) дупликат(а) у %s" + +#, c-format +msgid "Ignored %d word(s) with non-ASCII characters in %s" +msgstr "ИгнориÑана/о %d реч(и) Ñа не-ASCII карактерима у %s" + +#, c-format +msgid "Reading word file %s..." +msgstr "Читање датотеке речи %s..." + +#, c-format +msgid "Duplicate /encoding= line ignored in %s line %d: %s" +msgstr "Дупликат /encoding= линија је игнориÑана у %s линија %d: %s" + +#, c-format +msgid "/encoding= line after word ignored in %s line %d: %s" +msgstr "/encoding= линија након речи је игнориÑана у %s линија %d: %s" + +#, c-format +msgid "Duplicate /regions= line ignored in %s line %d: %s" +msgstr "Дупликат /regions= линија је игнориÑана у %s линија %d: %s" + +#, c-format +msgid "Too many regions in %s line %d: %s" +msgstr "Превише региона у %s линија %d: %s" + +#, c-format +msgid "/ line ignored in %s line %d: %s" +msgstr "/ линија игнориÑана у %s линија %d: %s" + +#, c-format +msgid "Invalid region nr in %s line %d: %s" +msgstr "Ðеважећи број региона у %s линија %d: %s" + +#, c-format +msgid "Unrecognized flags in %s line %d: %s" +msgstr "Ðепрепознати индикатори у %s линија %d: %s" + +#, c-format +msgid "Ignored %d words with non-ASCII characters" +msgstr "ИгнориÑано је %d рћи Ñа не-ASCII карактерима" + +msgid "E845: Insufficient memory, word list will be incomplete" +msgstr "E845: Ðедовољно меморије, лиÑта речи неће бити комплетна" + +#, c-format +msgid "Compressed %d of %d nodes; %d (%d%%) remaining" +msgstr "КомпреÑовано је %d од %d чворова; преоÑтало је још %d (%d%%)" + +msgid "Reading back spell file..." +msgstr "Читање правопиÑне датотеке..." + +msgid "Performing soundfolding..." +msgstr "Извођење Ñклапања по звучноÑти..." + +#, c-format +msgid "Number of words after soundfolding: %ld" +msgstr "Број речи након Ñклапања по звучноÑти: %ld" + +#, c-format +msgid "Total number of words: %d" +msgstr "Укупан број речи: %d" + +#, c-format +msgid "Writing suggestion file %s..." +msgstr "УпиÑивање датотеке предлога %s..." + +#, c-format +msgid "Estimated runtime memory use: %d bytes" +msgstr "Процењена потребна величина меморије у време извршавања: %d бајтова" + +msgid "E751: Output file name must not have region name" +msgstr "E751: Име излазне датотеке не Ñме да има име региона" + +#, c-format +msgid "E754: Only up to %ld regions supported" +msgstr "E754: Подржано је Ñамо до %ld региона" + +#, c-format +msgid "E755: Invalid region in %s" +msgstr "E755: Ðеважећи регион у %s" + +msgid "Warning: both compounding and NOBREAK specified" +msgstr "Упозорење: наведени Ñу и Ñлагање и NOBREAK" + +#, c-format +msgid "Writing spell file %s..." +msgstr "УпиÑивање правопиÑне датотеке %s..." + +msgid "Done!" +msgstr "Завршено!" + +#, c-format +msgid "E765: 'spellfile' does not have %ld entries" +msgstr "E765: 'spellfile' не Ñадржи %ld Ñтавке" + +#, c-format +msgid "Word '%.*s' removed from %s" +msgstr "Реч '%.*s' је уклоњена из %s" + +#, c-format +msgid "Word '%.*s' added to %s" +msgstr "Реч '%.*s' је додата у %s" + +msgid "E763: Word characters differ between spell files" +msgstr "E763: Карактери у речи Ñе разликују између правопиÑних датотека" + +msgid "E783: duplicate char in MAP entry" +msgstr "E783: карактер дупликат у MAP Ñтавци" + +msgid "No Syntax items defined for this buffer" +msgstr "За оба јбафер ниÑу дефиниÑане ÑинтакÑне Ñтавке" + +msgid "syntax conceal on" +msgstr "Ñкривање ÑинтакÑе укључено" + +msgid "syntax conceal off" +msgstr "Ñкривање ÑинтакÑе иÑкључено" + +#, c-format +msgid "E390: Illegal argument: %s" +msgstr "E390: Ðеважећи аргумент: %s" + +msgid "syntax case ignore" +msgstr "мала/велика Ñлова Ñе не разликују у ÑинтакÑи" + +msgid "syntax case match" +msgstr "мала/велика Ñлова Ñе разликују у ÑинтакÑи" + +msgid "syntax spell toplevel" +msgstr "ÑинтакÑа правопиÑа toplevel" + +msgid "syntax spell notoplevel" +msgstr "ÑинтакÑа правопиÑа notoplevel" + +msgid "syntax spell default" +msgstr "ÑинтакÑа правопиÑа подразумевано" + +msgid "syntax iskeyword " +msgstr "ÑинтакÑа iskeyword " + +#, c-format +msgid "E391: No such syntax cluster: %s" +msgstr "E391: Ðе поÑтоји такав ÑинтакÑни клаÑтер: %s" + +msgid "syncing on C-style comments" +msgstr "Ñинхронизација на коментарима C-Ñтила" + +msgid "no syncing" +msgstr "без Ñинхронизације" + +msgid "syncing starts " +msgstr "Ñинхронизација почиње " + +msgid " lines before top line" +msgstr " линија пре линије на врху" + +msgid "" +"\n" +"--- Syntax sync items ---" +msgstr "" +"\n" +"--- Ставке Ñинхро ÑинтакÑе ---" + +msgid "" +"\n" +"syncing on items" +msgstr "" +"\n" +"Ñинхро на Ñтавкама" + +msgid "" +"\n" +"--- Syntax items ---" +msgstr "" +"\n" +"--- Ставке ÑинтакÑе ---" + +#, c-format +msgid "E392: No such syntax cluster: %s" +msgstr "E392: не поÑтоји такав ÑинтакÑни клаÑтер: %s" + +msgid "minimal " +msgstr "минимално " + +msgid "maximal " +msgstr "макÑимално " + +msgid "; match " +msgstr "; подударања " + +msgid " line breaks" +msgstr " прелома линије" + +msgid "E395: contains argument not accepted here" +msgstr "E395: Ñадржи аргумент који Ñе овде не прихвата" + +msgid "E844: invalid cchar value" +msgstr "E844: неважећа cchar вредноÑÑ‚" + +msgid "E393: group[t]here not accepted here" +msgstr "E393: group[t]here Ñе овде не прихвата" + +#, c-format +msgid "E394: Didn't find region item for %s" +msgstr "E394: Ставка региона није пронађена за %s" + +msgid "E397: Filename required" +msgstr "E397: Потребно име датотеке" + +msgid "E847: Too many syntax includes" +msgstr "E847: Превише ÑинтакÑних уметања" + +#, c-format +msgid "E789: Missing ']': %s" +msgstr "E789: ÐедоÑтаје ']': %s" + +#, c-format +msgid "E890: trailing char after ']': %s]%s" +msgstr "E890: карактер вишка након ']': %s]%s" + +#, c-format +msgid "E398: Missing '=': %s" +msgstr "E398: ÐедоÑтаје '=': %s" + +#, c-format +msgid "E399: Not enough arguments: syntax region %s" +msgstr "E399: Ðема довољно аргумената: ÑинтакÑни регион %s" + +msgid "E848: Too many syntax clusters" +msgstr "E848: Превише ÑинтакÑних клаÑтера" + +msgid "E400: No cluster specified" +msgstr "E400: Ðије наведен ниједан клаÑтер" + +#, c-format +msgid "E401: Pattern delimiter not found: %s" +msgstr "E401: Ðије пронађен граничник шаблона: %s" + +#, c-format +msgid "E402: Garbage after pattern: %s" +msgstr "E402: Смеће након шаблона: %s" + +msgid "E403: syntax sync: line continuations pattern specified twice" +msgstr "E403: ÑинтакÑна Ñинхро: шаблон наÑтављања линије је наведен двапут" + +#, c-format +msgid "E404: Illegal arguments: %s" +msgstr "E404: Ðеважећи аргументи: %s" + +#, c-format +msgid "E405: Missing equal sign: %s" +msgstr "E405: недоÑтаје знак једнакоÑти: %s" + +#, c-format +msgid "E406: Empty argument: %s" +msgstr "E406: Празан аргумент: %s" + +#, c-format +msgid "E407: %s not allowed here" +msgstr "E407: %s овде није дозвољено" + +#, c-format +msgid "E408: %s must be first in contains list" +msgstr "E408: %s мора да буде прво у contains лиÑти" + +#, c-format +msgid "E409: Unknown group name: %s" +msgstr "E409: Ðепознато име групе: %s" + +#, c-format +msgid "E410: Invalid :syntax subcommand: %s" +msgstr "E410: Ðеважећа :syntax подкоманда: %s" + +msgid "" +" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN" +msgstr "" +" УКУПÐО БРОЈ ПОДУД ÐÐЈСПОРИЈЕ ПРОСЕК ИМЕ ШÐБЛОÐ" + +msgid "E679: recursive loop loading syncolor.vim" +msgstr "E679: Рекурзивна петља код учитавања syncolor.vim" + +#, c-format +msgid "E411: highlight group not found: %s" +msgstr "E411: група иÑтицања није пронађена: %s" + +#, c-format +msgid "E412: Not enough arguments: \":highlight link %s\"" +msgstr "E412: Ðема довољно аргумената: \":highlight link %s\"" + +#, c-format +msgid "E413: Too many arguments: \":highlight link %s\"" +msgstr "E413: Сувише аргумената: \":highlight link %s\"" + +msgid "E414: group has settings, highlight link ignored" +msgstr "E414: група има поÑтавке, highlight link Ñе игнорише" + +#, c-format +msgid "E415: unexpected equal sign: %s" +msgstr "E415: неочкиван знак једнакоÑти: %s" + +#, c-format +msgid "E416: missing equal sign: %s" +msgstr "E416: недоÑтаје знак једнакоÑти: %s" + +#, c-format +msgid "E417: missing argument: %s" +msgstr "E417: недоÑтаје аргумент: %s" + +#, c-format +msgid "E418: Illegal value: %s" +msgstr "E418: Ðеважећа вредноÑÑ‚: %s" + +msgid "E419: FG color unknown" +msgstr "E419: Ðепозната FG боја" + +msgid "E420: BG color unknown" +msgstr "E420: Ðепозната BG боја" + +#, c-format +msgid "E421: Color name or number not recognized: %s" +msgstr "E421: Име боје или број ниÑу препознати: %s" + +#, c-format +msgid "E422: terminal code too long: %s" +msgstr "E422: код терминала је предугачак: %s" + +#, c-format +msgid "E423: Illegal argument: %s" +msgstr "E423: Ðеважећи аргумент: %s" + +msgid "E424: Too many different highlighting attributes in use" +msgstr "E424: У употреби је превише различитих атрибута иÑтицања" + +msgid "E669: Unprintable character in group name" +msgstr "E669: У имену групе је карактер који не може да Ñе штампа" + +msgid "W18: Invalid character in group name" +msgstr "W18: Ðеважећи карактер у имену групе" + +msgid "E849: Too many highlight and syntax groups" +msgstr "E849: Превише ÑинтакÑних и група иÑтицања" + +msgid "E555: at bottom of tag stack" +msgstr "E555: на дну Ñтека ознака" + +msgid "E556: at top of tag stack" +msgstr "E556: на врху Ñтека ознака" + +msgid "E425: Cannot go before first matching tag" +msgstr "E425: Ðе може да Ñе иде иÑпред прве подударајуће ознаке" + +#, c-format +msgid "E426: tag not found: %s" +msgstr "E426: ознака није пронађена: %s" + +msgid " # pri kind tag" +msgstr " # ознака pri врÑте" + +msgid "file\n" +msgstr "датотека\n" + +msgid "E427: There is only one matching tag" +msgstr "E427: ПоÑтоји Ñамо једна подударајућа ознака" + +msgid "E428: Cannot go beyond last matching tag" +msgstr "E428: Ðе може да Ñе иде иза поÑледње подударајуће ознаке" + +#, c-format +msgid "File \"%s\" does not exist" +msgstr "Датотека \"%s\" не поÑтоји" + +#, c-format +msgid "tag %d of %d%s" +msgstr "ознака %d од %d%s" + +msgid " or more" +msgstr " или више" + +msgid " Using tag with different case!" +msgstr " КориÑти Ñе ознака за другом врÑтом Ñлова (мала/велика)!" + +#, c-format +msgid "E429: File \"%s\" does not exist" +msgstr "E429: Датотека \"%s\" не поÑтоји" + +msgid "" +"\n" +" # TO tag FROM line in file/text" +msgstr "" +"\n" +" # ÐРознака ОД линије у датот/текÑÑ‚" + +#, c-format +msgid "Searching tags file %s" +msgstr "Претраживање датотеке ознака %s" + +#, c-format +msgid "E430: Tag file path truncated for %s\n" +msgstr "E430: Путања датотеке ознака је прекинута за %s\n" + +msgid "Ignoring long line in tags file" +msgstr "Дугачка линија у датотеци ознака Ñе игнорише" + +#, c-format +msgid "E431: Format error in tags file \"%s\"" +msgstr "E431: Грешка формата у датотеци ознака \"%s\"" + +#, c-format +msgid "Before byte %ld" +msgstr "Пре бајта %ld" + +#, c-format +msgid "E432: Tags file not sorted: %s" +msgstr "E432: Датотека ознака није Ñортирана: %s" + +msgid "E433: No tags file" +msgstr "E433: Ðема датотеке ознака" + +msgid "E434: Can't find tag pattern" +msgstr "E434: Ðе може да Ñе пронађе шаблон ознаке" + +msgid "E435: Couldn't find tag, just guessing!" +msgstr "E435: Ознака није могла да Ñе пронађе, Ñамо нагађам!" + +#, c-format +msgid "Duplicate field name: %s" +msgstr "Дупло име поља: %s" + +msgid "' not known. Available builtin terminals are:" +msgstr "' није познат. ДоÑтупни уграђени терминали Ñу:" + +msgid "defaulting to '" +msgstr "подразумева Ñе '" + +msgid "E557: Cannot open termcap file" +msgstr "E557: termcap датотека не може да Ñе отвори" + +msgid "E558: Terminal entry not found in terminfo" +msgstr "E558: У terminfo није пронађена Ñтавка за терминал" + +msgid "E559: Terminal entry not found in termcap" +msgstr "E559: У termcap није пронађена Ñтавка терминала" + +#, c-format +msgid "E436: No \"%s\" entry in termcap" +msgstr "E436: Ðема \"%s\" Ñтавке у termcap" + +msgid "E437: terminal capability \"cm\" required" +msgstr "E437: потребна је могућноÑÑ‚ терминала \"cm\"" + +msgid "" +"\n" +"--- Terminal keys ---" +msgstr "" +"\n" +"--- ТаÑтери терминала ---" + +msgid "Cannot open $VIMRUNTIME/rgb.txt" +msgstr "Ðе може да Ñе отвори $VIMRUNTIME/rgb.txt" + +#, c-format +msgid "Kill job in \"%s\"?" +msgstr "Да ли да Ñе уништи задатак у \"%s\"?" + +msgid "Terminal" +msgstr "Терминал" + +msgid "Terminal-finished" +msgstr "Терминал-завршен" + +msgid "active" +msgstr "aktivan" + +msgid "running" +msgstr "ради" + +msgid "finished" +msgstr "завршен" + +#, c-format +msgid "E953: File exists: %s" +msgstr "E953: Датотека већ поÑтоји: %s" + +msgid "E955: Not a terminal buffer" +msgstr "E955: Ðије терминалÑки бафер" + +msgid "new shell started\n" +msgstr "покренуто ново командно окружење\n" + +msgid "Vim: Error reading input, exiting...\n" +msgstr "Vim: Грешка при читању улаза, излазак...\n" + +msgid "Used CUT_BUFFER0 instead of empty selection" +msgstr "УмеÑто празне Ñелекције корићен је CUT_BUFFER0" + +msgid "E881: Line count changed unexpectedly" +msgstr "E881: Број линија Ñе неочекивано променио" + +msgid "No undo possible; continue anyway" +msgstr "Ðије могућ опозив; ипак наÑтави" + +#, c-format +msgid "E828: Cannot open undo file for writing: %s" +msgstr "E828: Датотека опозива не може да Ñе отвори за упиÑ: %s" + +#, c-format +msgid "E825: Corrupted undo file (%s): %s" +msgstr "E825: ИÑкварена датотека за опозив (%s): %s" + +msgid "Cannot write undo file in any directory in 'undodir'" +msgstr "" +"Датотека за опозив не може да Ñе упише ни у један директоријум из 'undodir'" + +#, c-format +msgid "Will not overwrite with undo file, cannot read: %s" +msgstr "" +"Ðеће Ñе вршити препиÑивање Ñа датотеком опозива, читање није могуће: %s" + +#, c-format +msgid "Will not overwrite, this is not an undo file: %s" +msgstr "Ðеће Ñе цршити препиÑивање, ово није датотека за опозив: %s" + +msgid "Skipping undo file write, nothing to undo" +msgstr "ПреÑкакање упиÑа у датотеку за опозив, нема шта да Ñе опозове" + +#, c-format +msgid "Writing undo file: %s" +msgstr "Ð£Ð¿Ð¸Ñ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ за опозив: %s" + +#, c-format +msgid "E829: write error in undo file: %s" +msgstr "E829: грешка код упиÑа у датотеку за опозив: %s" + +#, c-format +msgid "Not reading undo file, owner differs: %s" +msgstr "Датотека за опозив Ñе не чита, влаÑник Ñе разликује: %s" + +#, c-format +msgid "Reading undo file: %s" +msgstr "Читање датотеке за опозив: %s" + +#, c-format +msgid "E822: Cannot open undo file for reading: %s" +msgstr "E822: Датотека за опозив не може да Ñе отвори за читање: %s" + +#, c-format +msgid "E823: Not an undo file: %s" +msgstr "E823: Ðије датотека за опозив: %s" + +#, c-format +msgid "E832: Non-encrypted file has encrypted undo file: %s" +msgstr "" +"E832: Датотека која није шифрована има шифровану датотеку за опозив: %s" + +#, c-format +msgid "E826: Undo file decryption failed: %s" +msgstr "E826: Дешифровање датотеке за опозив није уÑпело: %s" + +#, c-format +msgid "E827: Undo file is encrypted: %s" +msgstr "E827: Датотека за опозив је шифрована: %s" + +#, c-format +msgid "E824: Incompatible undo file: %s" +msgstr "E824: Ðекомпатибилна датотека за опозив: %s" + +msgid "File contents changed, cannot use undo info" +msgstr "" +"Садржај датотеке је промењен, информације за опозив не могу да Ñе кориÑте" + +#, c-format +msgid "Finished reading undo file %s" +msgstr "Тавршено је читање датотеке за опозив %s" + +msgid "Already at oldest change" +msgstr "Већ Ñте на најÑтаријој измени" + +msgid "Already at newest change" +msgstr "Већ Ñте на најновијој измени" + +#, c-format +msgid "E830: Undo number %ld not found" +msgstr "E830: Број опозива %ld није пронађен" + +msgid "E438: u_undo: line numbers wrong" +msgstr "E438: u_undo: погрешни бројеви линије" + +msgid "more line" +msgstr "линија више" + +msgid "more lines" +msgstr "линија више" + +msgid "line less" +msgstr "линија мање" + +msgid "fewer lines" +msgstr "линија мање" + +msgid "change" +msgstr "измена" + +msgid "changes" +msgstr "измена" + +#, c-format +msgid "%ld %s; %s #%ld %s" +msgstr "%ld %s; %s #%ld %s" + +msgid "before" +msgstr "пре" + +msgid "after" +msgstr "након" + +msgid "Nothing to undo" +msgstr "Ðишта за опозив" + +msgid "number changes when saved" +msgstr "број измене када Ñачувано" + +#, c-format +msgid "%ld seconds ago" +msgstr "пре %ld Ñекунди" + +msgid "E790: undojoin is not allowed after undo" +msgstr "E790: undojoin ије дозвољен након undo" + +msgid "E439: undo list corrupt" +msgstr "E439: лиÑта опозива је иÑкварена" + +msgid "E440: undo line missing" +msgstr "E440: недоÑтаје линија опозива" + +#, c-format +msgid "E122: Function %s already exists, add ! to replace it" +msgstr "E122: Функција %s већ поÑтоји, додајте ! да је замените" + +msgid "E717: Dictionary entry already exists" +msgstr "E717: Ð£Ð½Ð¾Ñ Ð²ÐµÑ› поÑтоји у речнику" + +msgid "E718: Funcref required" +msgstr "E718: Потребна funcref" + +#, c-format +msgid "E130: Unknown function: %s" +msgstr "E130: Ðепозната функција: %s" + +#, c-format +msgid "E125: Illegal argument: %s" +msgstr "E125: Ðеважећи аргумент: %s" + +#, c-format +msgid "E853: Duplicate argument name: %s" +msgstr "E853: Име аргумента је дуплирано: %s" + +#, c-format +msgid "E740: Too many arguments for function %s" +msgstr "E740: Превише аргумената за функцију %s" + +#, c-format +msgid "E116: Invalid arguments for function %s" +msgstr "E116: Ðеважећи аргументи за функцију %s" + +msgid "E132: Function call depth is higher than 'maxfuncdepth'" +msgstr "E132: Дубина позива функције је већа од 'maxfuncdepth'" + +#, c-format +msgid "calling %s" +msgstr "позива Ñе %s" + +#, c-format +msgid "%s aborted" +msgstr "%s је прекинута" + +#, c-format +msgid "%s returning #%ld" +msgstr "%s враћа #%ld" + +#, c-format +msgid "%s returning %s" +msgstr "%s враћа %s" + +msgid "E699: Too many arguments" +msgstr "E699: Сувише аргумената" + +#, c-format +msgid "E117: Unknown function: %s" +msgstr "E117: Ðепозната функција: %s" + +#, c-format +msgid "E933: Function was deleted: %s" +msgstr "E933: Функција је обриÑана: %s" + +#, c-format +msgid "E119: Not enough arguments for function: %s" +msgstr "E119: Ðема довољно аргумената за функцију: %s" + +#, c-format +msgid "E120: Using <SID> not in a script context: %s" +msgstr "E120: Коришћење <SID> ван Ñкрипт контекÑта: %s" + +#, c-format +msgid "E725: Calling dict function without Dictionary: %s" +msgstr "E725: Позивање dict функције без Речника: %s" + +msgid "E129: Function name required" +msgstr "E129: Потребно је име функције" + +#, c-format +msgid "E128: Function name must start with a capital or \"s:\": %s" +msgstr "E128: Име функције мора да почне великим Ñловом или \"s:\": %s" + +#, c-format +msgid "E884: Function name cannot contain a colon: %s" +msgstr "E884: Име функције не може да Ñадржи двотачку: %s" + +#, c-format +msgid "E123: Undefined function: %s" +msgstr "E123: ÐедефиниÑана функција: %s" + +#, c-format +msgid "E124: Missing '(': %s" +msgstr "E124: ÐедоÑтаје '(': %s" + +msgid "E862: Cannot use g: here" +msgstr "E862: g: не може овде да Ñе кориÑти" + +#, c-format +msgid "E932: Closure function should not be at top level: %s" +msgstr "E932: Затварајућа функција не би требало да буде на највишем нивоу: %s" + +msgid "E126: Missing :endfunction" +msgstr "E126: ÐедоÑтаје :endfunction" + +#, c-format +msgid "W22: Text found after :endfunction: %s" +msgstr "W22: Пронађен текÑÑ‚ након :endfunction: %s" + +#, c-format +msgid "E707: Function name conflicts with variable: %s" +msgstr "E707: Име функције је у конфликту Ñа променљивом: %s" + +#, c-format +msgid "E127: Cannot redefine function %s: It is in use" +msgstr "E127: Функција %s не може да Ñе редефинише: Тренутно Ñе кориÑти" + +#, c-format +msgid "E746: Function name does not match script file name: %s" +msgstr "E746: Име функције Ñе не поклапа Ñа именом Ñкрипт датотеке: %s" + +#, c-format +msgid "E131: Cannot delete function %s: It is in use" +msgstr "E131: Функција %s не може да Ñе обрише: Тренутно Ñе кориÑти" + +msgid "E133: :return not inside a function" +msgstr "E133: :return није унутар функције" + +#, c-format +msgid "E107: Missing parentheses: %s" +msgstr "E107: ÐедоÑтају заграде: %s" + +msgid "" +"\n" +"MS-Windows 64-bit GUI version" +msgstr "" +"\n" +"MS-Windows 64-битна GUI верзија" + +msgid "" +"\n" +"MS-Windows 32-bit GUI version" +msgstr "" +"\n" +"MS-Windows 32-битна GUI верзија" + +msgid " with OLE support" +msgstr " Ñа OLE подршком" + +msgid "" +"\n" +"MS-Windows 64-bit console version" +msgstr "" +"\n" +"MS-Windows 64-битна конзолна верзија" + +msgid "" +"\n" +"MS-Windows 32-bit console version" +msgstr "" +"\n" +"MS-Windows 32-битна конзолна верзија" + +msgid "" +"\n" +"macOS version" +msgstr "" +"\n" +"macOS верзија" + +msgid "" +"\n" +"macOS version w/o darwin feat." +msgstr "" +"\n" +"macOS верзија без darwin могућ." + +msgid "" +"\n" +"OpenVMS version" +msgstr "" +"\n" +"OpenVMS верзија" + +msgid "" +"\n" +"Included patches: " +msgstr "" +"\n" +"Укључене иÑправке: " + +msgid "" +"\n" +"Extra patches: " +msgstr "" +"\n" +"ЕкÑтра иÑправке: " + +msgid "Modified by " +msgstr "Модификовао " + +msgid "" +"\n" +"Compiled " +msgstr "" +"\n" +"Компајлирао" + +msgid "by " +msgstr " " + +msgid "" +"\n" +"Huge version " +msgstr "" +"\n" +"Огромна верзија " + +msgid "" +"\n" +"Big version " +msgstr "" +"\n" +"Велика верзија " + +msgid "" +"\n" +"Normal version " +msgstr "" +"\n" +"Ðормална верзија " + +msgid "" +"\n" +"Small version " +msgstr "" +"\n" +"Мала верзија " + +msgid "" +"\n" +"Tiny version " +msgstr "" +"\n" +"Сићушна верзија " + +msgid "without GUI." +msgstr "без GUI." + +msgid "with GTK3 GUI." +msgstr "Ñа GTK3 GUI." + +msgid "with GTK2-GNOME GUI." +msgstr "Ñа GTK2-GNOME GUI." + +msgid "with GTK2 GUI." +msgstr "Ñа GTK2 GUI." + +msgid "with X11-Motif GUI." +msgstr "Ñа X11-Motif GUI." + +msgid "with X11-neXtaw GUI." +msgstr "Ñа X11-neXtaw GUI." + +msgid "with X11-Athena GUI." +msgstr "Ñа X11-Athena GUI." + +msgid "with Photon GUI." +msgstr "Ñа Photon GUI." + +msgid "with GUI." +msgstr "Ñа GUI." + +msgid "with Carbon GUI." +msgstr "Ñа Carbon GUI." + +msgid "with Cocoa GUI." +msgstr "Ñа Cocoa GUI." + +msgid " Features included (+) or not (-):\n" +msgstr " МогућноÑти укључене (+) или не (-):\n" + +msgid " system vimrc file: \"" +msgstr " ÑиÑтемÑкa vimrc датотека: \"" + +msgid " user vimrc file: \"" +msgstr " кориÑничка vimrc датотека: \"" + +msgid " 2nd user vimrc file: \"" +msgstr " 2га кориÑничка vimrc датотека: \"" + +msgid " 3rd user vimrc file: \"" +msgstr " 3ћа кориÑничка vimrc датотека: \"" + +msgid " user exrc file: \"" +msgstr " кориÑничка exrc датотека: \"" + +msgid " 2nd user exrc file: \"" +msgstr " 2га кориÑничка exrc датотека: \"" + +msgid " system gvimrc file: \"" +msgstr " ÑиÑтемÑка gvimrc датотека: \"" + +msgid " user gvimrc file: \"" +msgstr " кориÑничка gvimrc датотека: \"" + +msgid "2nd user gvimrc file: \"" +msgstr "2га кориÑничка gvimrc датотека: \"" + +msgid "3rd user gvimrc file: \"" +msgstr "3ћа кориÑничка gvimrc датотека: \"" + +msgid " defaults file: \"" +msgstr " датотека Ñа подраз. опцијама: \"" + +msgid " system menu file: \"" +msgstr " ÑиÑтемÑка датотека менија: \"" + +msgid " fall-back for $VIM: \"" +msgstr " резервна вредноÑÑ‚ за $VIM: \"" + +msgid " f-b for $VIMRUNTIME: \"" +msgstr "резервна вредн. за $VIMRUNTIME: \"" + +msgid "Compilation: " +msgstr "Компилација: " + +msgid "Compiler: " +msgstr "Компајлер: " + +msgid "Linking: " +msgstr "Повезивање: " + +msgid " DEBUG BUILD" +msgstr " DEBUG ИЗДÐЊЕ" + +msgid "VIM - Vi IMproved" +msgstr "VIM - Vi IMproved" + +msgid "version " +msgstr "верзија " + +msgid "by Bram Moolenaar et al." +msgstr "напиÑали Bram Moolenaar et al." + +msgid "Vim is open source and freely distributable" +msgstr "Vim је отвореног кода и може Ñлободно да Ñе диÑтрибуира" + +msgid "Help poor children in Uganda!" +msgstr "Помозите Ñиромашној деци у Уганди!" + +msgid "type :help iccf<Enter> for information " +msgstr "откуцајте :help iccf<Enter> за информације " + +msgid "type :q<Enter> to exit " +msgstr "откуцајте :q<Enter> за излаз " + +msgid "type :help<Enter> or <F1> for on-line help" +msgstr "откуцајте :help<Enter> или <F1> за on-line помоћ " + +msgid "type :help version8<Enter> for version info" +msgstr "откуцајте :help version8<Enter> за инфо о верзији" + +msgid "Running in Vi compatible mode" +msgstr "Рад у Vi компатибилном режиму" + +msgid "type :set nocp<Enter> for Vim defaults" +msgstr "откуцајте :set nocp<Enter> за Vim подразумевано" + +msgid "type :help cp-default<Enter> for info on this" +msgstr "откуцајте :help cp-default<Enter> за инфо о овоме" + +msgid "menu Help->Orphans for information " +msgstr "мени Помоћ->Сирочићи за информације " + +msgid "Running modeless, typed text is inserted" +msgstr "БезрежимÑки рад, умеће Ñе откуцани текÑÑ‚" + +msgid "menu Edit->Global Settings->Toggle Insert Mode " +msgstr "мени Уређивање->Глобална подешавања->Преклапај режим Уметање " + +msgid " for two modes " +msgstr " за два режима " + +msgid "menu Edit->Global Settings->Toggle Vi Compatible" +msgstr "мени Уређивање->Глобална подешавања->Преклапај Vi Компатибилно" + +msgid " for Vim defaults " +msgstr " за Vim подразумевано " + +msgid "Sponsor Vim development!" +msgstr "Спонзоришите Vim развој!" + +msgid "Become a registered Vim user!" +msgstr "ПоÑтаните региÑтровани Vim кориÑник!" + +msgid "type :help sponsor<Enter> for information " +msgstr "откуцајте :help sponsor<Enter> за информације " + +msgid "type :help register<Enter> for information " +msgstr "откуцајте :help register<Enter> за информације " + +msgid "menu Help->Sponsor/Register for information " +msgstr "мени Помоћ->Спонзор/РегиÑтруј Ñе за информације " + +msgid "Already only one window" +msgstr "Већ поÑтоји Ñамо један прозор" + +msgid "E441: There is no preview window" +msgstr "E441: Ðема прозора за преглед" + +msgid "E442: Can't split topleft and botright at the same time" +msgstr "E442: topleft и botright не могу да Ñе поделе у иÑто време" + +msgid "E443: Cannot rotate when another window is split" +msgstr "E443: Ðе може да Ñе ротира када је подељен други прозор" + +msgid "E444: Cannot close last window" +msgstr "E444: ПоÑледњи прозор не може да Ñе затвори" + +msgid "E813: Cannot close autocmd window" +msgstr "E813: autocmd прозор не може да Ñе затвори" + +msgid "E814: Cannot close window, only autocmd window would remain" +msgstr "E814: Прозор не може да Ñе затвори, преоÑтао би једино autocmd прозор" + +msgid "E445: Other window contains changes" +msgstr "E445: Други прозори Ñадрже измене" + +msgid "E446: No file name under cursor" +msgstr "E446: Под курÑором Ñе не налази име датотеке" + +#, c-format +msgid "E447: Can't find file \"%s\" in path" +msgstr "E447: Датотека \"%s\" не може да Ñе пронађе у путањи" + +#, c-format +msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E799: Ðеважећи ИД: %ld (мора бити већи од или једнак 1)" + +#, c-format +msgid "E801: ID already taken: %ld" +msgstr "E801: ИД је већ заузет: %ld" + +msgid "List or number required" +msgstr "Захтева Ñе лиÑта или број" + +#, c-format +msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)" +msgstr "E802: Ðеважећи ИД: %ld (мора бити већи од или једнак 1)" + +#, c-format +msgid "E803: ID not found: %ld" +msgstr "E803: ИД није пронађен: %ld" + +msgid "Edit with &multiple Vims" +msgstr "Уређуј Ñа &више Vim-ова" + +msgid "Edit with single &Vim" +msgstr "Уређуј Ñа једним &Vim-ом" + +msgid "Diff with Vim" +msgstr "Diff Ñа Vim" + +msgid "Edit with &Vim" +msgstr "Уређуј Ñа &Vim-ом" + +msgid "Edit with existing Vim - " +msgstr "Уређуј Ñа поÑтојећим Vim - " + +msgid "Edits the selected file(s) with Vim" +msgstr "Уређује Ñелектовауе датотеку(е) Ñа Vim-ом" + +msgid "Error creating process: Check if gvim is in your path!" +msgstr "" +"Грешка приликом креирања процеÑа: Проверите да ли је gvim у вашој путањи!" + +msgid "gvimext.dll error" +msgstr "gvimext.dll грешка" + +msgid "Path length too long!" +msgstr "Путања је предугачка!" + +msgid "--No lines in buffer--" +msgstr "--У баферу нема линија--" + +msgid "E470: Command aborted" +msgstr "E470: Команда прекинута" + +msgid "E471: Argument required" +msgstr "E471: Потребан је аргумент" + +msgid "E10: \\ should be followed by /, ? or &" +msgstr "E10: Иза \\ треба да је /, ? или &" + +msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits" +msgstr "" +"E11: Ðеважеће у прозору командне линије; <CR> извршава, CTRL-C отказује" + +msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" +msgstr "" +"E12: ПоÑтоји забрана за команду у exrc/vimrc у текућој претрази " +"директоријума или ознаке" + +msgid "E171: Missing :endif" +msgstr "E171: ÐедоÑтаје :endif" + +msgid "E600: Missing :endtry" +msgstr "E600: ÐедоÑтаје :endtry" + +msgid "E170: Missing :endwhile" +msgstr "E170: ÐедоÑтаје :endwhile" + +msgid "E170: Missing :endfor" +msgstr "E170: ÐедоÑтаје :endfor" + +msgid "E588: :endwhile without :while" +msgstr "E588: :endwhile без :while" + +msgid "E588: :endfor without :for" +msgstr "E588: :endfor без :for" + +msgid "E13: File exists (add ! to override)" +msgstr "E13: Датотека поÑтоји (додајте ! за премошћавање)" + +msgid "E472: Command failed" +msgstr "E472: Команда није уÑпела" + +#, c-format +msgid "E234: Unknown fontset: %s" +msgstr "E234: Ðепознат fontset: %s" + +#, c-format +msgid "E235: Unknown font: %s" +msgstr "E235: Ðепознат фонт: %s" + +#, c-format +msgid "E236: Font \"%s\" is not fixed-width" +msgstr "E236: Фонт \"%s\" није фикÑне ширине" + +msgid "E473: Internal error" +msgstr "E473: Интерна грешка" + +#, c-format +msgid "E685: Internal error: %s" +msgstr "E685: Интерна грешка: %s" + +msgid "Interrupted" +msgstr "Прекинуто" + +msgid "E14: Invalid address" +msgstr "E14: Ðеважећа адреÑа" + +msgid "E474: Invalid argument" +msgstr "E474: Ðеважећи аргумент" + +#, c-format +msgid "E475: Invalid argument: %s" +msgstr "E475: Ðеважећи аргумент: %s" + +#, c-format +msgid "E475: Invalid value for argument %s" +msgstr "E475: Ðеважећa вредноÑÑ‚ за аргумент: %s" + +#, c-format +msgid "E475: Invalid value for argument %s: %s" +msgstr "E475: Ðеважећa вредноÑÑ‚ за аргумент %s: %s" + +#, c-format +msgid "E15: Invalid expression: %s" +msgstr "E15: Ðеважећи израз: %s" + +msgid "E16: Invalid range" +msgstr "E16: Ðеважећи опÑег" + +msgid "E476: Invalid command" +msgstr "E476: Ðеважећа команда" + +#, c-format +msgid "E17: \"%s\" is a directory" +msgstr "E17: \"%s\" је директоријум" + +#, c-format +msgid "E364: Library call failed for \"%s()\"" +msgstr "E364: Позив библиотеке није уÑпео за \"%s()\"" + +msgid "E667: Fsync failed" +msgstr "E667: Fsync није уÑпео" + +#, c-format +msgid "E448: Could not load library function %s" +msgstr "E448: Библиотечка функција %s није могла да Ñе учита" + +msgid "E19: Mark has invalid line number" +msgstr "E19: Маркер Ñадржи неиÑправан број линије" + +msgid "E20: Mark not set" +msgstr "E20: Маркер није поÑтављен" + +msgid "E21: Cannot make changes, 'modifiable' is off" +msgstr "E21: Измене не могу да Ñе учине, опција 'modifiable' је иÑкључена" + +msgid "E22: Scripts nested too deep" +msgstr "E22: Скрипте Ñу предубоко угњеждене" + +msgid "E23: No alternate file" +msgstr "E23: Ðема алтернативне датотеке" + +msgid "E24: No such abbreviation" +msgstr "E24: Таква Ñкраћеница не поÑтоји" + +msgid "E477: No ! allowed" +msgstr "E477: ! није дозвољен" + +msgid "E25: GUI cannot be used: Not enabled at compile time" +msgstr "E25: GUI не може да Ñе кориÑти: Ðије омогућен у време компилације" + +msgid "E26: Hebrew cannot be used: Not enabled at compile time\n" +msgstr "" +"E26: хебрејÑки не може да Ñе кориÑти: Ðије омогућен у време компилације\n" + +msgid "E27: Farsi cannot be used: Not enabled at compile time\n" +msgstr "E27: фарÑи не може да Ñе кориÑти: Ðије омогућен у време компилације\n" + +msgid "E800: Arabic cannot be used: Not enabled at compile time\n" +msgstr "" +"E800: арапÑки не може да Ñе кориÑти: Ðије омогућен у време компилације\n" + +#, c-format +msgid "E28: No such highlight group name: %s" +msgstr "E28: Ðема групе иÑтицања Ñа таквим именом: %s" + +msgid "E29: No inserted text yet" +msgstr "E29: ТекÑÑ‚ још није унет" + +msgid "E30: No previous command line" +msgstr "E30: Ðема претходне командне линије" + +msgid "E31: No such mapping" +msgstr "E31: Такво мапирање не поÑтоји" + +msgid "E479: No match" +msgstr "E479: Ðема подударања" + +#, c-format +msgid "E480: No match: %s" +msgstr "E480: Ðема подударања: %s" + +msgid "E32: No file name" +msgstr "E32: Ðема имена датотеке" + +msgid "E33: No previous substitute regular expression" +msgstr "E33: Ðема претходног регуларног израза за замену" + +msgid "E34: No previous command" +msgstr "E34: Ðема претходне команде" + +msgid "E35: No previous regular expression" +msgstr "E35: Ðема претходног регуларног израза" + +msgid "E481: No range allowed" +msgstr "E481: ОпÑег није дозвољен" + +msgid "E36: Not enough room" +msgstr "E36: Ðема довољно проÑтора" + +#, c-format +msgid "E247: no registered server named \"%s\"" +msgstr "E247: нема региÑтованог Ñервера под именом \"%s\"" + +#, c-format +msgid "E482: Can't create file %s" +msgstr "E482: Датотека %s не може да Ñе креира" + +msgid "E483: Can't get temp file name" +msgstr "E483: Име привремене датотке не може да Ñе добије" + +#, c-format +msgid "E484: Can't open file %s" +msgstr "E484: Датотека %s не може да Ñе отвори" + +#, c-format +msgid "E485: Can't read file %s" +msgstr "E485: Датотека %s не може да Ñе прочита" + +msgid "E38: Null argument" +msgstr "E38: Празан аргумент" + +msgid "E39: Number expected" +msgstr "E39: Очекује Ñе број" + +#, c-format +msgid "E40: Can't open errorfile %s" +msgstr "E40: Датотека грешке %s не може да Ñе отвори" + +msgid "E233: cannot open display" +msgstr "E233: проказ не може да Ñе отвори" + +msgid "E41: Out of memory!" +msgstr "E41: Ðема више меморије!" + +msgid "Pattern not found" +msgstr "Шаблон није пронађен" + +#, c-format +msgid "E486: Pattern not found: %s" +msgstr "E486: Шаблон није пронађен: %s" + +msgid "E487: Argument must be positive" +msgstr "E487: Ðргумент мора бити позитиван" + +msgid "E459: Cannot go back to previous directory" +msgstr "E459: Ðе може да Ñе оде назад на претходни директоријум" + +msgid "E42: No Errors" +msgstr "E42: Ðема грешака" + +msgid "E776: No location list" +msgstr "E776: Ðема лиÑте локација" + +msgid "E43: Damaged match string" +msgstr "E43: Оштећен Ñтринг за подударање" + +msgid "E44: Corrupted regexp program" +msgstr "E44: regexp програм је покварен" + +msgid "E45: 'readonly' option is set (add ! to override)" +msgstr "E45: ПоÑтављена је 'readonly' опција (додајте ! за премошћавање)" + +#, c-format +msgid "E46: Cannot change read-only variable \"%s\"" +msgstr "E46: Променљива Ñамо за читање \"%s\" не може да Ñе измени" + +#, c-format +msgid "E794: Cannot set variable in the sandbox: \"%s\"" +msgstr "E794: Ðе може да Ñе поÑтави променљива у sandbox-у: \"%s\"" + +msgid "E713: Cannot use empty key for Dictionary" +msgstr "E713: Ðе може да Ñе кориÑти празан кључ за Речник" + +msgid "E715: Dictionary required" +msgstr "E715: Потребан Речник" + +#, c-format +msgid "E684: list index out of range: %ld" +msgstr "E684: Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ñте је ван опÑега: %ld" + +#, c-format +msgid "E118: Too many arguments for function: %s" +msgstr "E118: Превише аргумената за функцију: %s" + +#, c-format +msgid "E716: Key not present in Dictionary: %s" +msgstr "E716: У Речнику нема кључа: %s" + +msgid "E714: List required" +msgstr "E714: Потребна ЛиÑта" + +#, c-format +msgid "E712: Argument of %s must be a List or Dictionary" +msgstr "E712: Ðргумент за %s мора бити ЛиÑта или Речник" + +msgid "E47: Error while reading errorfile" +msgstr "E47: Грешка приликом читаља датотеке грешке" + +msgid "E48: Not allowed in sandbox" +msgstr "E48: Ðије дозвољено у sandbox-у" + +msgid "E523: Not allowed here" +msgstr "E523: Ðије дозвољено овде" + +msgid "E359: Screen mode setting not supported" +msgstr "E359: Подешавање режима екрана није подржано" + +msgid "E49: Invalid scroll size" +msgstr "E49: Ðеважећа величина линије за Ñкроловање" + +msgid "E91: 'shell' option is empty" +msgstr "E91: Опција 'shell' је празна" + +msgid "E255: Couldn't read in sign data!" +msgstr "E255: Подаци за знак ниÑу могли да Ñе прочитају!" + +msgid "E72: Close error on swap file" +msgstr "E72: Грешка код затвањара swap датотеке" + +msgid "E73: tag stack empty" +msgstr "E73: Ñтек ознака је празан" + +msgid "E74: Command too complex" +msgstr "E74: Команда је Ñувише комплекÑна" + +msgid "E75: Name too long" +msgstr "E75: Име је предугачко" + +msgid "E76: Too many [" +msgstr "E76: Превише [" + +msgid "E77: Too many file names" +msgstr "E77: Превише имена датотека" + +msgid "E488: Trailing characters" +msgstr "E488: Карактери вишка на крају" + +msgid "E78: Unknown mark" +msgstr "E78: Ðепознат маркер" + +msgid "E79: Cannot expand wildcards" +msgstr "E79: Ðокери не могу да Ñе развију" + +msgid "E591: 'winheight' cannot be smaller than 'winminheight'" +msgstr "E591: 'winheight' не може да буде мање од 'winminheight'" + +msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'" +msgstr "E592: 'winwidth' не може да буде мање од 'winminwidth'" + +msgid "E80: Error while writing" +msgstr "E80: Грешка приликом упиÑа" + +msgid "E939: Positive count required" +msgstr "E939: Потребан је позитиван број" + +msgid "E81: Using <SID> not in a script context" +msgstr "E81: <SID> Ñе кориÑти ван Ñкрипт контекÑта" + +msgid "E449: Invalid expression received" +msgstr "E449: Примљен је неважећи израз" + +msgid "E463: Region is guarded, cannot modify" +msgstr "E463: Регион је чуван, измена није могућа" + +msgid "E744: NetBeans does not allow changes in read-only files" +msgstr "" +"E744: NetBeans не дозвољава измене датотека које Ñмеју Ñамо да Ñе читају" + +msgid "E363: pattern uses more memory than 'maxmempattern'" +msgstr "E363: шаблон кориÑти више меморије од 'maxmempattern'" + +msgid "E749: empty buffer" +msgstr "E749: празан бафер" + +#, c-format +msgid "E86: Buffer %ld does not exist" +msgstr "E86: Бафер %ld не поÑтоји" + +msgid "E682: Invalid search pattern or delimiter" +msgstr "E682: Ðеважећи шаблон претраге или раздвојни карактер" + +msgid "E139: File is loaded in another buffer" +msgstr "E139: Датотека је учитана у други бафер" + +#, c-format +msgid "E764: Option '%s' is not set" +msgstr "E764: Опција '%s' није поÑтављена" + +msgid "E850: Invalid register name" +msgstr "E850: Ðеважеће име региÑтра" + +#, c-format +msgid "E919: Directory not found in '%s': \"%s\"" +msgstr "E919: Ðије пронађен директоријум у '%s': \"%s\"" + +msgid "E952: Autocommand caused recursive behavior" +msgstr "E952: Ðутокомандa je изазвала рекурзивно понашање" + +msgid "search hit TOP, continuing at BOTTOM" +msgstr "претрага је доÑтигла ВРХ, наÑтавља Ñе на ДÐУ" + +msgid "search hit BOTTOM, continuing at TOP" +msgstr "претрага је доÑтигла ДÐО, наÑтавља Ñе на ВРХУ" + +#, c-format +msgid "Need encryption key for \"%s\"" +msgstr "Потребан је кључ за шифровање \"%s\"" + +msgid "empty keys are not allowed" +msgstr "празни кључеви ниÑу дозвољени" + +msgid "dictionary is locked" +msgstr "речник је закључан" + +msgid "list is locked" +msgstr "лиÑта је закључана" + +#, c-format +msgid "failed to add key '%s' to dictionary" +msgstr "кључ '%s' није могао да Ñе дода у речник" + +#, c-format +msgid "index must be int or slice, not %s" +msgstr "index мора бити типа int или slice, не %s" + +#, c-format +msgid "expected str() or unicode() instance, but got %s" +msgstr "очекивала Ñе инÑтанца str() или unicode(), али је добијена %s" + +#, c-format +msgid "expected bytes() or str() instance, but got %s" +msgstr "очекивала Ñе инÑтанца bytes() или str(), али је добијена %s" + +#, c-format +msgid "" +"expected int(), long() or something supporting coercing to long(), but got %s" +msgstr "" +"очекивало Ñе int(), long() или нешто што подржава Ñпајање Ñа long(), али је " +"добијено %s" + +#, c-format +msgid "expected int() or something supporting coercing to int(), but got %s" +msgstr "" +"очекивало Ñе int() или нешто што подржава Ñпајање Ñа int(), али је добијено %" +"s" + +msgid "value is too large to fit into C int type" +msgstr "вредноÑÑ‚ је Ñувише велика да Ñе ÑмеÑти у C int тип" + +msgid "value is too small to fit into C int type" +msgstr "вредноÑÑ‚ је Ñувише мала да Ñе ÑмеÑти у C int тип" + +msgid "number must be greater than zero" +msgstr "број мора бити већи од нуле" + +msgid "number must be greater or equal to zero" +msgstr "број мора бити већи од или једнак нули" + +msgid "can't delete OutputObject attributes" +msgstr "атрибути OutputObject не могу да Ñе обришу" + +#, c-format +msgid "invalid attribute: %s" +msgstr "неважећи атрибут: %s" + +msgid "E264: Python: Error initialising I/O objects" +msgstr "E264: Python: Грешка код иницијализације У/И објеката" + +msgid "failed to change directory" +msgstr "не може да Ñе промени директоријум" + +#, c-format +msgid "expected 3-tuple as imp.find_module() result, but got %s" +msgstr "Као резултат imp.find_module() очекује Ñе триплет, али је добијено %s" + +#, c-format +msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d" +msgstr "" +"Као резултат imp.find_module() очекује Ñе триплет, али је добијена н-торка " +"величине %d" + +msgid "internal error: imp.find_module returned tuple with NULL" +msgstr "интерна грешка: imp.find_module је вратио н-торку Ñа NULL" + +msgid "cannot delete vim.Dictionary attributes" +msgstr "vim.Dictionary атрибути не могу да Ñе обришу" + +msgid "cannot modify fixed dictionary" +msgstr "фикÑни речник не може да Ñе измени" + +#, c-format +msgid "cannot set attribute %s" +msgstr "атрибут %s не може да Ñе поÑтави" + +msgid "hashtab changed during iteration" +msgstr "hashtab је промењен током итерације" + +#, c-format +msgid "expected sequence element of size 2, but got sequence of size %d" +msgstr "" +"очекивао Ñе елемент Ñеквенце величине 2, али је добијена Ñеквенца " +"величине %d" + +msgid "list constructor does not accept keyword arguments" +msgstr "конÑтруктор лиÑте не прихвата кључне речи за аргументе" + +msgid "list index out of range" +msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ñте је ван опÑега" + +#, c-format +msgid "internal error: failed to get vim list item %d" +msgstr "интерна грешка: Ñтавка %d vim лиÑте није могла да Ñе добије" + +msgid "slice step cannot be zero" +msgstr "slice корак не може да буде нула" + +#, c-format +msgid "attempt to assign sequence of size greater than %d to extended slice" +msgstr "покушај доделе Ñеквенце величине веће од %d како би Ñе продужио slice" + +#, c-format +msgid "internal error: no vim list item %d" +msgstr "интерна грешка: нема Ñтавке %d у vim лиÑти" + +msgid "internal error: not enough list items" +msgstr "интерна грешка: нема довољно Ñтавки лиÑте" + +msgid "internal error: failed to add item to list" +msgstr "интерна грешка: Ñтавка није могла да Ñе дода лиÑти" + +#, c-format +msgid "attempt to assign sequence of size %d to extended slice of size %d" +msgstr "" +"покушај доделе Ñеквенце величине %d како би Ñе продужио slice величине %d" + +msgid "failed to add item to list" +msgstr "Ñтавка није могла да Ñе дода лиÑти" + +msgid "cannot delete vim.List attributes" +msgstr "vim.List атрибути не могу да Ñе обришу" + +msgid "cannot modify fixed list" +msgstr "фикÑна лиÑта не може да Ñе измени" + +#, c-format +msgid "unnamed function %s does not exist" +msgstr "неименована функција %s не поÑтоји" + +#, c-format +msgid "function %s does not exist" +msgstr "функција %s не поÑтоји" + +#, c-format +msgid "failed to run function %s" +msgstr "функција %s није могла да Ñе покрене" + +msgid "unable to get option value" +msgstr "вредноÑÑ‚ опције није могла да Ñе добије" + +msgid "internal error: unknown option type" +msgstr "интерна грешка: непознат тип опције" + +msgid "problem while switching windows" +msgstr "проблем код пребацивања прозора" + +#, c-format +msgid "unable to unset global option %s" +msgstr "глобална опција %s није могла да Ñе иÑкључи" + +#, c-format +msgid "unable to unset option %s which does not have global value" +msgstr "опција %s која нема глобалну вредноÑÑ‚ није могла да Ñе иÑкључи" + +msgid "attempt to refer to deleted tab page" +msgstr "покушај рефериÑања на обриÑану картицу" + +msgid "no such tab page" +msgstr "не поÑтоји таква картица" + +msgid "attempt to refer to deleted window" +msgstr "покушај рефериÑања на обриÑан прозор" + +msgid "readonly attribute: buffer" +msgstr "атрибут Ñамо за читање: бафер" + +msgid "cursor position outside buffer" +msgstr "позиција курÑора је ван бафера" + +msgid "no such window" +msgstr "нема таквог прозора" + +msgid "attempt to refer to deleted buffer" +msgstr "покушај рефериÑања на обриÑан бафер" + +msgid "failed to rename buffer" +msgstr "име бафера није могло да Ñе промени" + +msgid "mark name must be a single character" +msgstr "име маркера мора бити Ñамо један карактер" + +#, c-format +msgid "expected vim.Buffer object, but got %s" +msgstr "очекивао Ñе vim.Buffer објекат, али је добијен %s" + +#, c-format +msgid "failed to switch to buffer %d" +msgstr "прелазак на бафер %d није био могућ" + +#, c-format +msgid "expected vim.Window object, but got %s" +msgstr "очекивао Ñе vim.Window објекат, али је добијен %s" + +msgid "failed to find window in the current tab page" +msgstr "прозор није пронађен у текућој картици" + +msgid "did not switch to the specified window" +msgstr "није Ñе прешло у наведени прозор" + +#, c-format +msgid "expected vim.TabPage object, but got %s" +msgstr "очекивао Ñе vim.TabPage објекат, али је добијен %s" + +msgid "did not switch to the specified tab page" +msgstr "није Ñе прешло у наведену картицу" + +msgid "failed to run the code" +msgstr "кôд није могао да Ñе покрене" + +msgid "E858: Eval did not return a valid python object" +msgstr "E858: Eval није вратио важећи python објекат" + +msgid "E859: Failed to convert returned python object to vim value" +msgstr "E859: Конверзија враћеног python објекта у vim вредноÑÑ‚ није уÑпела" + +#, c-format +msgid "unable to convert %s to vim dictionary" +msgstr "%s не може да Ñе конвертује у vim речник" + +#, c-format +msgid "unable to convert %s to vim list" +msgstr "%s не може да Ñе конвертује у vim лиÑту" + +#, c-format +msgid "unable to convert %s to vim structure" +msgstr "%s не може да Ñе конвертује у vim Ñтруктуру" + +msgid "internal error: NULL reference passed" +msgstr "интерна грешка: проÑлеђена је NULL референца" + +msgid "internal error: invalid value type" +msgstr "интерна грешка: вредноÑÑ‚ неважећег типа" + +msgid "" +"Failed to set path hook: sys.path_hooks is not a list\n" +"You should now do the following:\n" +"- append vim.path_hook to sys.path_hooks\n" +"- append vim.VIM_SPECIAL_PATH to sys.path\n" +msgstr "" +"Кука за путању није могла да Ñе поÑтави: sys.path_hooks није у лиÑти\n" +"Сада би требало да урадите Ñледеће:\n" +"- додајте vim.path_hook на крај sys.path_hooks\n" +"- додајте vim.VIM_SPECIAL_PATH на крај sys.path\n" + +msgid "" +"Failed to set path: sys.path is not a list\n" +"You should now append vim.VIM_SPECIAL_PATH to sys.path" +msgstr "" +"Путања није могла да Ñе поÑтави: sys.path није у лиÑти\n" +"Сада би требало да додате vim.VIM_SPECIAL_PATH на крај sys.path" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*.*)\t*.*\n" +msgstr "" +"Vim макро датотеке (*.vim)\t*.vim\n" +"Све датотеке (*.*)\t*.*\n" + +msgid "All Files (*.*)\t*.*\n" +msgstr "Све датотеке (*.*)\t*.*\n" + +msgid "" +"All Files (*.*)\t*.*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB code (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"Све датотеке (*.*)\t*.*\n" +"C изворни код (*.c, *.h)\t*.c;*.h\n" +"C++ изворни код (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"VB код (*.bas, *.frm)\t*.bas;*.frm\n" +"Vim датотеке (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" + +msgid "" +"Vim macro files (*.vim)\t*.vim\n" +"All Files (*)\t*\n" +msgstr "" +"Vim макро датотеке (*.vim)\t*.vim\n" +"Све датотеке (*)\t*\n" + +msgid "All Files (*)\t*\n" +msgstr "Све датотеке (*)\t*\n" + +msgid "" +"All Files (*)\t*\n" +"C source (*.c, *.h)\t*.c;*.h\n" +"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" +msgstr "" +"Све датотеке (*)\t*\n" +"C изворни код (*.c, *.h)\t*.c;*.h\n" +"C++ изворни код (*.cpp, *.hpp)\t*.cpp;*.hpp\n" +"Vim датотеке (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n" diff --git a/src/nvim/po/sv.po b/src/nvim/po/sv.po index f27ffa0dd4..4770db15de 100644 --- a/src/nvim/po/sv.po +++ b/src/nvim/po/sv.po @@ -818,7 +818,7 @@ msgstr "E216: Ingen sådan grupp eller händelse: %s" #: ../fileio.c:5994 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Autokommandon ---" @@ -842,7 +842,7 @@ msgstr "E218: autokommando nästlad för djupt" #: ../fileio.c:7043 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s Autokommandon för \"%s\"" #: ../fileio.c:7049 @@ -3792,8 +3792,8 @@ msgstr "Varning: region %s stöds inte" #: ../spell.c:4362 #, c-format -msgid "Reading affix file %s ..." -msgstr "Läser affix-fil %s ..." +msgid "Reading affix file %s..." +msgstr "Läser affix-fil %s..." #: ../spell.c:4401 ../spell.c:5439 ../spell.c:5944 #, c-format @@ -3953,8 +3953,8 @@ msgstr "%s värde skiljer sig från vad som används i en annan .aff-fil." #: ../spell.c:5406 #, c-format -msgid "Reading dictionary file %s ..." -msgstr "Läser ordboksfil %s ..." +msgid "Reading dictionary file %s..." +msgstr "Läser ordboksfil %s..." #: ../spell.c:5415 #, c-format @@ -3988,8 +3988,8 @@ msgstr "Ignorerade %d ord med icke-ASCII tecken i %s" #: ../spell.c:5919 #, c-format -msgid "Reading word file %s ..." -msgstr "Läser ordfil %s ..." +msgid "Reading word file %s..." +msgstr "Läser ordfil %s..." #: ../spell.c:5959 #, c-format @@ -4058,8 +4058,8 @@ msgstr "Totalt antal ord: %d" #: ../spell.c:7458 #, c-format -msgid "Writing suggestion file %s ..." -msgstr "Skriver förslagsfil %s ..." +msgid "Writing suggestion file %s..." +msgstr "Skriver förslagsfil %s..." #: ../spell.c:7510 ../spell.c:7730 #, c-format @@ -4085,8 +4085,8 @@ msgstr "Varning: både sammansättning och NOBREAK specifierad" #: ../spell.c:7723 #, c-format -msgid "Writing spell file %s ..." -msgstr "Skriver stavningsfil %s ..." +msgid "Writing spell file %s..." +msgstr "Skriver stavningsfil %s..." #: ../spell.c:7728 msgid "Done!" @@ -5675,7 +5675,7 @@ msgstr "-q [felfil] redigera fil med första fel" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/po/uk.po b/src/nvim/po/uk.po index b2e572ab82..4c5d169ec9 100644 --- a/src/nvim/po/uk.po +++ b/src/nvim/po/uk.po @@ -4826,8 +4826,8 @@ msgid "E782: error while reading .sug file: %s" msgstr "E782: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ .sug: %s" #, c-format -msgid "Reading affix file %s ..." -msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» афікÑів %s ..." +msgid "Reading affix file %s..." +msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» афікÑів %s..." #, c-format msgid "Conversion failure for word in %s line %d: %s" @@ -4959,8 +4959,8 @@ msgid "%s value differs from what is used in another .aff file" msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s відрізнÑєтьÑÑ Ð²Ñ–Ð´ того, що вжито у іншому файлі .aff" #, c-format -msgid "Reading dictionary file %s ..." -msgstr "ЗчитуєтьÑÑ Ñловниковий файл %s ..." +msgid "Reading dictionary file %s..." +msgstr "ЗчитуєтьÑÑ Ñловниковий файл %s..." #, c-format msgid "E760: No word count in %s" @@ -4987,8 +4987,8 @@ msgid "Ignored %d word(s) with non-ASCII characters in %s" msgstr "Пропущено %d Ñлів(~) із не-ASCII Ñимволами у %s" #, c-format -msgid "Reading word file %s ..." -msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» Ñлів %s ..." +msgid "Reading word file %s..." +msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» Ñлів %s..." #, c-format msgid "Duplicate /encoding= line ignored in %s line %d: %s" @@ -5043,8 +5043,8 @@ msgid "Total number of words: %d" msgstr "Повна кількіÑть Ñлів: %d" #, c-format -msgid "Writing suggestion file %s ..." -msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» припущень %s ..." +msgid "Writing suggestion file %s..." +msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» припущень %s..." #, c-format msgid "Estimated runtime memory use: %d bytes" @@ -5064,8 +5064,8 @@ msgid "Warning: both compounding and NOBREAK specified" msgstr "ЗаÑтереженнÑ: зазначено обидва `Ñкладні Ñлова' Ñ– NOBREAK" #, c-format -msgid "Writing spell file %s ..." -msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» орфографії %s ..." +msgid "Writing spell file %s..." +msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» орфографії %s..." msgid "Done!" msgstr "Зроблено!" diff --git a/src/nvim/po/vi.po b/src/nvim/po/vi.po index 456e640a80..7dbf19c263 100644 --- a/src/nvim/po/vi.po +++ b/src/nvim/po/vi.po @@ -2500,7 +2500,7 @@ msgstr "E216: Nhóm hoặc sá»± kiện không có tháºt: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- Câu lệnh tá»± động ---" @@ -2524,7 +2524,7 @@ msgstr "E218: câu lệnh tá»± động xếp lồng và o nhau quá xâu" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s câu lệnh tá»± động cho \"%s\"" #: ../fileio.c:7149 @@ -3419,7 +3419,7 @@ msgstr "-q [táºp tin lá»—i] soạn thảo táºp tin vá»›i lá»—i đầu tiên" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/po/zh_CN.UTF-8.po b/src/nvim/po/zh_CN.UTF-8.po index 981719a2e7..76204a43a8 100644 --- a/src/nvim/po/zh_CN.UTF-8.po +++ b/src/nvim/po/zh_CN.UTF-8.po @@ -2461,7 +2461,7 @@ msgstr "E216: æ— æ¤ç»„或事件: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" "--- 自动命令 ---" @@ -2485,7 +2485,7 @@ msgstr "E218: 自动命令嵌套层数过深" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" +msgid "%s Autocommands for \"%s\"" msgstr "%s 自动命令 \"%s\"" #: ../fileio.c:7149 @@ -3367,7 +3367,7 @@ msgstr "-q [errorfile] 编辑第一个出错处的文件" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" @@ -5292,7 +5292,7 @@ msgstr "è¦å‘Š: 区域 %s 䏿”¯æŒ" #: ../spell.c:4550 #, c-format -msgid "Reading affix file %s ..." +msgid "Reading affix file %s..." msgstr "读å–é™„åŠ æ–‡ä»¶ %s ……" #: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140 @@ -5451,7 +5451,7 @@ msgstr "%s 的值与å¦ä¸€ä¸ª .aff 文件ä¸ä½¿ç”¨çš„值ä¸ç›¸åŒ" #: ../spell.c:5602 #, c-format -msgid "Reading dictionary file %s ..." +msgid "Reading dictionary file %s..." msgstr "读å–å—典文件 %s ……" #: ../spell.c:5611 @@ -5486,7 +5486,7 @@ msgstr "å¿½ç•¥äº†å«æœ‰éž ASCII å—符的 %d 个å•è¯ï¼Œåœ¨ %s ä¸" #: ../spell.c:6115 #, c-format -msgid "Reading word file %s ..." +msgid "Reading word file %s..." msgstr "读å–å•è¯æ–‡ä»¶ %s ……" #: ../spell.c:6155 @@ -5556,7 +5556,7 @@ msgstr "å•è¯æ€»æ•°: %d" #: ../spell.c:7655 #, c-format -msgid "Writing suggestion file %s ..." +msgid "Writing suggestion file %s..." msgstr "写入建议文件 %s ……" #: ../spell.c:7707 ../spell.c:7927 @@ -5583,7 +5583,7 @@ msgstr "è¦å‘Š: åŒæ—¶æŒ‡å®šäº† compounding å’Œ NOBREAK" #: ../spell.c:7920 #, c-format -msgid "Writing spell file %s ..." +msgid "Writing spell file %s..." msgstr "写入拼写文件 %s ……" #: ../spell.c:7925 diff --git a/src/nvim/po/zh_TW.UTF-8.po b/src/nvim/po/zh_TW.UTF-8.po index af8c3fff48..3c1dd463b7 100644 --- a/src/nvim/po/zh_TW.UTF-8.po +++ b/src/nvim/po/zh_TW.UTF-8.po @@ -2509,10 +2509,10 @@ msgstr "E216: ç„¡æ¤ç¾¤çµ„或事件: %s" #: ../fileio.c:6090 msgid "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" msgstr "" "\n" -"--- Auto-Commands ---" +"--- Autocommands ---" #: ../fileio.c:6293 #, fuzzy, c-format @@ -2533,8 +2533,8 @@ msgstr "E218: autocommand å±¤æ•¸éŽæ·±" #: ../fileio.c:7143 #, c-format -msgid "%s Auto commands for \"%s\"" -msgstr "%s Auto commands: \"%s\"" +msgid "%s Autocommands for \"%s\"" +msgstr "%s Autocommands: \"%s\"" #: ../fileio.c:7149 #, c-format @@ -3422,7 +3422,7 @@ msgstr "-q [errorfile] 編輯時載入第一個錯誤" msgid "" "\n" "\n" -"usage:" +"Usage:" msgstr "" "\n" "\n" diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 1182d3d902..68c8967b91 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -81,225 +81,230 @@ void pum_display(pumitem_T *array, int size, int selected, bool array_changed) pum_external = ui_is_external(kUIPopupmenu); } -redo: - // Mark the pum as visible already here, - // to avoid that must_redraw is set when 'cursorcolumn' is on. - pum_is_visible = true; - validate_cursor_col(); - above_row = 0; - below_row = cmdline_row; - - // anchor position: the start of the completed word - row = curwin->w_wrow + curwin->w_winrow; - if (curwin->w_p_rl) { - col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1; - } else { - col = curwin->w_wincol + curwin->w_wcol; - } - - if (pum_external) { - if (array_changed) { - Array arr = ARRAY_DICT_INIT; - for (i = 0; i < size; i++) { - Array item = ARRAY_DICT_INIT; - ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_text))); - ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_kind))); - ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_extra))); - ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info))); - ADD(arr, ARRAY_OBJ(item)); - } - ui_call_popupmenu_show(arr, selected, row, col); + do { + // Mark the pum as visible already here, + // to avoid that must_redraw is set when 'cursorcolumn' is on. + pum_is_visible = true; + validate_cursor_col(); + above_row = 0; + below_row = cmdline_row; + + // anchor position: the start of the completed word + row = curwin->w_wrow + curwin->w_winrow; + if (curwin->w_p_rl) { + col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1; } else { - ui_call_popupmenu_select(selected); + col = curwin->w_wincol + curwin->w_wcol; } - return; - } - - def_width = PUM_DEF_WIDTH; - max_width = 0; - kind_width = 0; - extra_width = 0; - - win_T *pvwin = NULL; - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_p_pvw) { - pvwin = wp; - break; - } - } - if (pvwin != NULL) { - if (pvwin->w_wrow < curwin->w_wrow) { - above_row = pvwin->w_wrow + pvwin->w_height; - } else if (pvwin->w_wrow > pvwin->w_wrow + curwin->w_height) { - below_row = pvwin->w_wrow; + if (pum_external) { + if (array_changed) { + Array arr = ARRAY_DICT_INIT; + for (i = 0; i < size; i++) { + Array item = ARRAY_DICT_INIT; + ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_text))); + ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_kind))); + ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_extra))); + ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info))); + ADD(arr, ARRAY_OBJ(item)); + } + ui_call_popupmenu_show(arr, selected, row, col); + } else { + ui_call_popupmenu_select(selected); + } + return; } - } - // Figure out the size and position of the pum. - if (size < PUM_DEF_HEIGHT) { - pum_height = size; - } else { - pum_height = PUM_DEF_HEIGHT; - } + def_width = PUM_DEF_WIDTH; + max_width = 0; + kind_width = 0; + extra_width = 0; - if ((p_ph > 0) && (pum_height > p_ph)) { - pum_height = (int)p_ph; - } - - // Put the pum below "row" if possible. If there are few lines decide on - // where there is more room. - if (row + 2 >= below_row - pum_height - && row - above_row > (below_row - above_row) / 2) { - // pum above "row" + win_T *pvwin = NULL; + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_p_pvw) { + pvwin = wp; + break; + } + } - // Leave two lines of context if possible - if (curwin->w_wrow - curwin->w_cline_row >= 2) { - context_lines = 2; - } else { - context_lines = curwin->w_wrow - curwin->w_cline_row; + if (pvwin != NULL) { + if (pvwin->w_winrow < curwin->w_winrow) { + above_row = pvwin->w_winrow + pvwin->w_height; + } else if (pvwin->w_winrow > curwin->w_winrow + curwin->w_height) { + below_row = pvwin->w_winrow; + } } - if (row >= size + context_lines) { - pum_row = row - size - context_lines; + // Figure out the size and position of the pum. + if (size < PUM_DEF_HEIGHT) { pum_height = size; } else { - pum_row = 0; - pum_height = row - context_lines; + pum_height = PUM_DEF_HEIGHT; } if ((p_ph > 0) && (pum_height > p_ph)) { - pum_row += pum_height - (int)p_ph; pum_height = (int)p_ph; } - } else { - // pum below "row" - // Leave two lines of context if possible - if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) { - context_lines = 3; - } else { - context_lines = curwin->w_cline_row - + curwin->w_cline_height - curwin->w_wrow; - } + // Put the pum below "row" if possible. If there are few lines decide on + // where there is more room. + if (row + 2 >= below_row - pum_height + && row - above_row > (below_row - above_row) / 2) { + // pum above "row" - pum_row = row + context_lines; - if (size > below_row - pum_row) { - pum_height = below_row - pum_row; - } else { - pum_height = size; - } + // Leave two lines of context if possible + if (curwin->w_wrow - curwin->w_cline_row >= 2) { + context_lines = 2; + } else { + context_lines = curwin->w_wrow - curwin->w_cline_row; + } - if ((p_ph > 0) && (pum_height > p_ph)) { - pum_height = (int)p_ph; - } - } + if (row >= size + context_lines) { + pum_row = row - size - context_lines; + pum_height = size; + } else { + pum_row = 0; + pum_height = row - context_lines; + } - // don't display when we only have room for one line - if ((pum_height < 1) || ((pum_height == 1) && (size > 1))) { - return; - } + if ((p_ph > 0) && (pum_height > p_ph)) { + pum_row += pum_height - (int)p_ph; + pum_height = (int)p_ph; + } + } else { + // pum below "row" - // If there is a preview window at the above avoid drawing over it. - if (pvwin != NULL && pum_row < above_row && pum_height > above_row) { - pum_row += above_row; - pum_height -= above_row; - } + // Leave two lines of context if possible + if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) { + context_lines = 3; + } else { + context_lines = curwin->w_cline_row + + curwin->w_cline_height - curwin->w_wrow; + } - // Compute the width of the widest match and the widest extra. - for (i = 0; i < size; ++i) { - w = vim_strsize(array[i].pum_text); + pum_row = row + context_lines; + if (size > below_row - pum_row) { + pum_height = below_row - pum_row; + } else { + pum_height = size; + } - if (max_width < w) { - max_width = w; + if ((p_ph > 0) && (pum_height > p_ph)) { + pum_height = (int)p_ph; + } } - if (array[i].pum_kind != NULL) { - w = vim_strsize(array[i].pum_kind) + 1; + // don't display when we only have room for one line + if ((pum_height < 1) || ((pum_height == 1) && (size > 1))) { + return; + } - if (kind_width < w) { - kind_width = w; + // If there is a preview window above, avoid drawing over it. + // Do keep at least 10 entries. + if (pvwin != NULL && pum_row < above_row && pum_height > 10) { + if (row - above_row < 10) { + pum_row = row - 10; + pum_height = 10; + } else { + pum_row = above_row; + pum_height = row - above_row; } } - if (array[i].pum_extra != NULL) { - w = vim_strsize(array[i].pum_extra) + 1; + // Compute the width of the widest match and the widest extra. + for (i = 0; i < size; i++) { + w = vim_strsize(array[i].pum_text); - if (extra_width < w) { - extra_width = w; + if (max_width < w) { + max_width = w; } - } - } - pum_base_width = max_width; - pum_kind_width = kind_width; - - // if there are more items than room we need a scrollbar - if (pum_height < size) { - pum_scrollbar = 1; - max_width++; - } else { - pum_scrollbar = 0; - } - if (def_width < max_width) { - def_width = max_width; - } + if (array[i].pum_kind != NULL) { + w = vim_strsize(array[i].pum_kind) + 1; - if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width)) - && !curwin->w_p_rl) - || (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) { - // align pum column with "col" - pum_col = col; - if (curwin->w_p_rl) { - pum_width = pum_col - pum_scrollbar + 1; - } else { - assert(Columns - pum_col - pum_scrollbar >= INT_MIN - && Columns - pum_col - pum_scrollbar <= INT_MAX); - pum_width = (int)(Columns - pum_col - pum_scrollbar); - } + if (kind_width < w) { + kind_width = w; + } + } - if ((pum_width > max_width + kind_width + extra_width + 1) - && (pum_width > PUM_DEF_WIDTH)) { - pum_width = max_width + kind_width + extra_width + 1; + if (array[i].pum_extra != NULL) { + w = vim_strsize(array[i].pum_extra) + 1; - if (pum_width < PUM_DEF_WIDTH) { - pum_width = PUM_DEF_WIDTH; + if (extra_width < w) { + extra_width = w; + } } } - } else if (Columns < def_width) { - // not enough room, will use what we have - if (curwin->w_p_rl) { - assert(Columns - 1 >= INT_MIN); - pum_col = (int)(Columns - 1); + pum_base_width = max_width; + pum_kind_width = kind_width; + + // if there are more items than room we need a scrollbar + if (pum_height < size) { + pum_scrollbar = 1; + max_width++; } else { - pum_col = 0; + pum_scrollbar = 0; } - assert(Columns - 1 >= INT_MIN); - pum_width = (int)(Columns - 1); - } else { - if (max_width > PUM_DEF_WIDTH) { - // truncate - max_width = PUM_DEF_WIDTH; + + if (def_width < max_width) { + def_width = max_width; } - if (curwin->w_p_rl) { - pum_col = max_width - 1; + if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width)) + && !curwin->w_p_rl) + || (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) { + // align pum column with "col" + pum_col = col; + if (curwin->w_p_rl) { + pum_width = pum_col - pum_scrollbar + 1; + } else { + assert(Columns - pum_col - pum_scrollbar >= INT_MIN + && Columns - pum_col - pum_scrollbar <= INT_MAX); + pum_width = (int)(Columns - pum_col - pum_scrollbar); + } + + if ((pum_width > max_width + kind_width + extra_width + 1) + && (pum_width > PUM_DEF_WIDTH)) { + pum_width = max_width + kind_width + extra_width + 1; + + if (pum_width < PUM_DEF_WIDTH) { + pum_width = PUM_DEF_WIDTH; + } + } + } else if (Columns < def_width) { + // not enough room, will use what we have + if (curwin->w_p_rl) { + assert(Columns - 1 >= INT_MIN); + pum_col = (int)(Columns - 1); + } else { + pum_col = 0; + } + assert(Columns - 1 >= INT_MIN); + pum_width = (int)(Columns - 1); } else { - assert(Columns - max_width >= INT_MIN && Columns - max_width <= INT_MAX); - pum_col = (int)(Columns - max_width); + if (max_width > PUM_DEF_WIDTH) { + // truncate + max_width = PUM_DEF_WIDTH; + } + + if (curwin->w_p_rl) { + pum_col = max_width - 1; + } else { + assert(Columns - max_width >= INT_MIN + && Columns - max_width <= INT_MAX); + pum_col = (int)(Columns - max_width); + } + pum_width = max_width - pum_scrollbar; } - pum_width = max_width - pum_scrollbar; - } - pum_array = array; - pum_size = size; + pum_array = array; + pum_size = size; - // Set selected item and redraw. If the window size changed need to redo - // the positioning. Limit this to two times, when there is not much - // room the window size will keep changing. - if (pum_set_selected(selected, redo_count) && (++redo_count <= 2)) { - goto redo; - } + // Set selected item and redraw. If the window size changed need to redo + // the positioning. Limit this to two times, when there is not much + // room the window size will keep changing. + } while (pum_set_selected(selected, redo_count) && (++redo_count <= 2)); } /// Redraw the popup menu, using "pum_first" and "pum_selected". @@ -341,6 +346,8 @@ void pum_redraw(void) idx = i + pum_first; attr = (idx == pum_selected) ? attr_select : attr_norm; + screen_puts_line_start(row); + // prepend a space if there is room if (curwin->w_p_rl) { if (pum_col < curwin->w_wincol + curwin->w_width - 1) { @@ -397,7 +404,7 @@ void pum_redraw(void) if (size > pum_width) { do { - size -= has_mbyte ? (*mb_ptr2cells)(rt) : 1; + size -= utf_ptr2cells(rt); MB_PTR_ADV(rt); } while (size > pum_width); @@ -488,6 +495,7 @@ void pum_redraw(void) ? attr_thumb : attr_scroll); } } + screen_puts_line_flush(false); row++; } } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 47760e1e70..51a7dd670f 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -82,6 +82,7 @@ struct qfline_S { /// created using setqflist()/setloclist() with a title and/or user context /// information and entries can be added later using setqflist()/setloclist(). typedef struct qf_list_S { + unsigned qf_id; ///< Unique identifier for this list qfline_T *qf_start; ///< pointer to the first error qfline_T *qf_last; ///< pointer to the last error qfline_T *qf_ptr; ///< pointer to the current error @@ -91,6 +92,14 @@ typedef struct qf_list_S { char_u *qf_title; ///< title derived from the command that created ///< the error list or set by setqflist typval_T *qf_ctx; ///< context set by setqflist/setloclist + + struct dir_stack_T *qf_dir_stack; + char_u *qf_directory; + struct dir_stack_T *qf_file_stack; + char_u *qf_currfile; + bool qf_multiline; + bool qf_multiignore; + bool qf_multiscan; } qf_list_T; /// Quickfix/Location list stack definition @@ -106,18 +115,10 @@ struct qf_info_S { int qf_listcount; /* current number of lists */ int qf_curlist; /* current error list */ qf_list_T qf_lists[LISTCOUNT]; - - int qf_dir_curlist; ///< error list for qf_dir_stack - struct dir_stack_T *qf_dir_stack; - char_u *qf_directory; - struct dir_stack_T *qf_file_stack; - char_u *qf_currfile; - bool qf_multiline; - bool qf_multiignore; - bool qf_multiscan; }; -static qf_info_T ql_info; /* global quickfix list */ +static qf_info_T ql_info; // global quickfix list +static unsigned last_qf_id = 0; // Last Used quickfix list id #define FMT_PATTERNS 10 /* maximum number of % recognized */ @@ -223,9 +224,8 @@ int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, qi = ll_get_or_alloc_list(wp); } - return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist, - (linenr_T)0, (linenr_T)0, - qf_title, enc); + return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, + newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); } // Maximum number of bytes allowed per line while reading an errorfile. @@ -712,8 +712,8 @@ static int qf_get_nextline(qfstate_T *state) /// Parse a line and get the quickfix fields. /// Return the QF_ status. -static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen, - efm_T *fmt_first, qffields_T *fields) +static int qf_parse_line(qf_info_T *qi, int qf_idx, char_u *linebuf, + size_t linelen, efm_T *fmt_first, qffields_T *fields) { efm_T *fmt_ptr; size_t len; @@ -721,7 +721,7 @@ static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen, int idx = 0; char_u *tail = NULL; regmatch_T regmatch; - + qf_list_T *qfl = &qi->qf_lists[qf_idx]; // Always ignore case when looking for a matching error. regmatch.rm_ic = true; @@ -740,12 +740,12 @@ static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen, restofline: for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) { idx = fmt_ptr->prefix; - if (qi->qf_multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL) { + if (qfl->qf_multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL) { continue; } fields->namebuf[0] = NUL; fields->pattern[0] = NUL; - if (!qi->qf_multiscan) { + if (!qfl->qf_multiscan) { fields->errmsg[0] = NUL; } fields->lnum = 0; @@ -759,7 +759,7 @@ restofline: int r = vim_regexec(®match, linebuf, (colnr_T)0); fmt_ptr->prog = regmatch.regprog; if (r) { - if ((idx == 'C' || idx == 'Z') && !qi->qf_multiline) { + if ((idx == 'C' || idx == 'Z') && !qfl->qf_multiline) { continue; } if (vim_strchr((char_u *)"EWI", idx) != NULL) { @@ -809,7 +809,7 @@ restofline: } fields->type = *regmatch.startp[i]; } - if (fmt_ptr->flags == '+' && !qi->qf_multiscan) { // %+ + if (fmt_ptr->flags == '+' && !qfl->qf_multiscan) { // %+ if (linelen >= fields->errmsglen) { // linelen + null terminator fields->errmsg = xrealloc(fields->errmsg, linelen + 1); @@ -877,7 +877,7 @@ restofline: break; } } - qi->qf_multiscan = false; + qfl->qf_multiscan = false; if (fmt_ptr == NULL || idx == 'D' || idx == 'X') { if (fmt_ptr != NULL) { @@ -886,13 +886,13 @@ restofline: EMSG(_("E379: Missing or empty directory name")); return QF_FAIL; } - qi->qf_directory = qf_push_dir(fields->namebuf, &qi->qf_dir_stack, - false); - if (qi->qf_directory == NULL) { + qfl->qf_directory = qf_push_dir(fields->namebuf, &qfl->qf_dir_stack, + false); + if (qfl->qf_directory == NULL) { return QF_FAIL; } } else if (idx == 'X') { // leave directory - qi->qf_directory = qf_pop_dir(&qi->qf_dir_stack); + qfl->qf_directory = qf_pop_dir(&qfl->qf_dir_stack); } } fields->namebuf[0] = NUL; // no match found, remove file name @@ -906,7 +906,7 @@ restofline: // copy whole line to error message STRLCPY(fields->errmsg, linebuf, linelen + 1); if (fmt_ptr == NULL) { - qi->qf_multiline = qi->qf_multiignore = false; + qfl->qf_multiline = qfl->qf_multiignore = false; } } else { // honor %> item @@ -915,12 +915,12 @@ restofline: } if (vim_strchr((char_u *)"AEWI", idx) != NULL) { - qi->qf_multiline = true; // start of a multi-line message - qi->qf_multiignore = false; // reset continuation + qfl->qf_multiline = true; // start of a multi-line message + qfl->qf_multiignore = false; // reset continuation } else if (vim_strchr((char_u *)"CZ", idx) != NULL) { // continuation of multi-line msg - if (!qi->qf_multiignore) { - qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last; + if (!qfl->qf_multiignore) { + qfline_T *qfprev = qfl->qf_last; if (qfprev == NULL) { return QF_FAIL; } @@ -945,15 +945,15 @@ restofline: } qfprev->qf_viscol = fields->use_viscol; if (!qfprev->qf_fnum) { - qfprev->qf_fnum = qf_get_fnum(qi, qi->qf_directory, - *fields->namebuf || qi->qf_directory + qfprev->qf_fnum = qf_get_fnum(qi, qf_idx, qfl->qf_directory, + *fields->namebuf || qfl->qf_directory ? fields->namebuf - : qi->qf_currfile && fields->valid - ? qi->qf_currfile : 0); + : qfl->qf_currfile && fields->valid + ? qfl->qf_currfile : 0); } } if (idx == 'Z') { - qi->qf_multiline = qi->qf_multiignore = false; + qfl->qf_multiline = qfl->qf_multiignore = false; } line_breakcheck(); @@ -963,23 +963,23 @@ restofline: fields->valid = false; if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) { if (*fields->namebuf && idx == 'P') { - qi->qf_currfile = qf_push_dir(fields->namebuf, &qi->qf_file_stack, - true); + qfl->qf_currfile = qf_push_dir(fields->namebuf, &qfl->qf_file_stack, + true); } else if (idx == 'Q') { - qi->qf_currfile = qf_pop_dir(&qi->qf_file_stack); + qfl->qf_currfile = qf_pop_dir(&qfl->qf_file_stack); } *fields->namebuf = NUL; if (tail && *tail) { STRMOVE(IObuff, skipwhite(tail)); - qi->qf_multiscan = true; + qfl->qf_multiscan = true; goto restofline; } } } if (fmt_ptr->flags == '-') { // generally exclude this line - if (qi->qf_multiline) { + if (qfl->qf_multiline) { // also exclude continuation lines - qi->qf_multiignore = true; + qfl->qf_multiignore = true; } return QF_IGNORE_LINE; } @@ -999,6 +999,7 @@ restofline: static int qf_init_ext( qf_info_T *qi, + int qf_idx, char_u *efile, buf_T *buf, typval_T *tv, @@ -1041,15 +1042,20 @@ qf_init_ext( goto qf_init_end; } - if (newlist || qi->qf_curlist == qi->qf_listcount) { + if (newlist || qf_idx == qi->qf_listcount) { // make place for a new list qf_new_list(qi, qf_title); - } else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) { + qf_idx = qi->qf_curlist; + } else { // Adding to existing list, use last entry. adding = true; - old_last = qi->qf_lists[qi->qf_curlist].qf_last; + if (qi->qf_lists[qf_idx].qf_count > 0) { + old_last = qi->qf_lists[qf_idx].qf_last; + } } + qf_list_T *qfl = &qi->qf_lists[qf_idx]; + // Use the local value of 'errorformat' if it's set. if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) { efm = buf->b_p_efm; @@ -1057,18 +1063,6 @@ qf_init_ext( efm = errorformat; } - // If we are not adding or adding to another list: clear the state. - if (newlist || qi->qf_curlist != qi->qf_dir_curlist) { - qi->qf_dir_curlist = qi->qf_curlist; - qf_clean_dir_stack(&qi->qf_dir_stack); - qi->qf_directory = NULL; - qf_clean_dir_stack(&qi->qf_file_stack); - qi->qf_currfile = NULL; - qi->qf_multiline = false; - qi->qf_multiignore = false; - qi->qf_multiscan = false; - } - // If the errorformat didn't change between calls, then reuse the previously // parsed values. if (last_efm == NULL || (STRCMP(last_efm, efm) != 0)) { @@ -1118,8 +1112,8 @@ qf_init_ext( break; } - status = qf_parse_line(qi, state.linebuf, state.linelen, fmt_first, - &fields); + status = qf_parse_line(qi, qf_idx, state.linebuf, state.linelen, + fmt_first, &fields); if (status == QF_FAIL) { goto error2; } @@ -1128,11 +1122,11 @@ qf_init_ext( } if (qf_add_entry(qi, - qi->qf_curlist, - qi->qf_directory, - (*fields.namebuf || qi->qf_directory) - ? fields.namebuf : ((qi->qf_currfile && fields.valid) - ? qi->qf_currfile : (char_u *)NULL), + qf_idx, + qfl->qf_directory, + (*fields.namebuf || qfl->qf_directory) + ? fields.namebuf : ((qfl->qf_currfile && fields.valid) + ? qfl->qf_currfile : (char_u *)NULL), 0, fields.errmsg, fields.lnum, @@ -1147,25 +1141,25 @@ qf_init_ext( line_breakcheck(); } if (state.fd == NULL || !ferror(state.fd)) { - if (qi->qf_lists[qi->qf_curlist].qf_index == 0) { - /* no valid entry found */ - qi->qf_lists[qi->qf_curlist].qf_ptr = - qi->qf_lists[qi->qf_curlist].qf_start; - qi->qf_lists[qi->qf_curlist].qf_index = 1; - qi->qf_lists[qi->qf_curlist].qf_nonevalid = TRUE; + if (qfl->qf_index == 0) { + // no valid entry found + qfl->qf_ptr = qfl->qf_start; + qfl->qf_index = 1; + qfl->qf_nonevalid = true; } else { - qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; - if (qi->qf_lists[qi->qf_curlist].qf_ptr == NULL) - qi->qf_lists[qi->qf_curlist].qf_ptr = - qi->qf_lists[qi->qf_curlist].qf_start; + qfl->qf_nonevalid = false; + if (qfl->qf_ptr == NULL) { + qfl->qf_ptr = qfl->qf_start; + } } - /* return number of matches */ - retval = qi->qf_lists[qi->qf_curlist].qf_count; + // return number of matches + retval = qfl->qf_count; goto qf_init_end; } EMSG(_(e_readerrf)); error2: if (!adding) { + // Error when creating a new list. Free the new list qf_free(qi, qi->qf_curlist); qi->qf_listcount--; if (qi->qf_curlist > 0) { @@ -1181,7 +1175,9 @@ qf_init_end: xfree(fields.pattern); xfree(state.growbuf); - qf_update_buffer(qi, old_last); + if (qf_idx == qi->qf_curlist) { + qf_update_buffer(qi, old_last); + } if (state.vc.vc_type != CONV_NONE) { convert_setup(&state.vc, NULL, NULL); @@ -1204,9 +1200,9 @@ static void qf_store_title(qf_info_T *qi, int qf_idx, char_u *title) } } -/* - * Prepare for adding a new quickfix list. - */ +// Prepare for adding a new quickfix list. If the current list is in the +// middle of the stack, then all the following lists are freed and then +// the new list is added. static void qf_new_list(qf_info_T *qi, char_u *qf_title) { int i; @@ -1230,6 +1226,7 @@ static void qf_new_list(qf_info_T *qi, char_u *qf_title) qi->qf_curlist = qi->qf_listcount++; memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); qf_store_title(qi, qi->qf_curlist, qf_title); + qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id; } /* @@ -1303,7 +1300,7 @@ static int qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY; } } else { - qfp->qf_fnum = qf_get_fnum(qi, dir, fname); + qfp->qf_fnum = qf_get_fnum(qi, qf_idx, dir, fname); } qfp->qf_text = vim_strsave(mesg); qfp->qf_lnum = lnum; @@ -1473,6 +1470,9 @@ void copy_loclist(win_T *from, win_T *to) to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */ + // Assign a new ID for the location list + to_qfl->qf_id = ++last_qf_id; + /* When no valid entries are present in the list, qf_ptr points to * the first item in the list */ if (to_qfl->qf_nonevalid) { @@ -1486,7 +1486,8 @@ void copy_loclist(win_T *from, win_T *to) // Get buffer number for file "directory/fname". // Also sets the b_has_qf_entry flag. -static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname) +static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *directory, + char_u *fname) { char_u *ptr = NULL; char_u *bufname; @@ -1509,7 +1510,7 @@ static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname) // directory change. if (!os_path_exists(ptr)) { xfree(ptr); - directory = qf_guess_filepath(qi, fname); + directory = qf_guess_filepath(qi, qf_idx, fname); if (directory) { ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, true); } else { @@ -1659,18 +1660,19 @@ static void qf_clean_dir_stack(struct dir_stack_T **stackptr) * Then qf_push_dir thinks we are in ./aa/bb, but we are in ./bb. * qf_guess_filepath will return NULL. */ -static char_u *qf_guess_filepath(qf_info_T *qi, char_u *filename) +static char_u *qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *filename) { struct dir_stack_T *ds_ptr; struct dir_stack_T *ds_tmp; char_u *fullname; + qf_list_T *qfl = &qi->qf_lists[qf_idx]; // no dirs on the stack - there's nothing we can do - if (qi->qf_dir_stack == NULL) { + if (qfl->qf_dir_stack == NULL) { return NULL; } - ds_ptr = qi->qf_dir_stack->next; + ds_ptr = qfl->qf_dir_stack->next; fullname = NULL; while (ds_ptr) { xfree(fullname); @@ -1686,9 +1688,9 @@ static char_u *qf_guess_filepath(qf_info_T *qi, char_u *filename) xfree(fullname); // clean up all dirs we already left - while (qi->qf_dir_stack->next != ds_ptr) { - ds_tmp = qi->qf_dir_stack->next; - qi->qf_dir_stack->next = qi->qf_dir_stack->next->next; + while (qfl->qf_dir_stack->next != ds_ptr) { + ds_tmp = qfl->qf_dir_stack->next; + qfl->qf_dir_stack->next = qfl->qf_dir_stack->next->next; xfree(ds_tmp->dirname); xfree(ds_tmp); } @@ -1757,7 +1759,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) win_T *oldwin = curwin; int print_message = TRUE; int len; - int old_KeyTyped = KeyTyped; /* getting file may reset it */ + const bool old_KeyTyped = KeyTyped; // getting file may reset it int ok = OK; bool usable_win; @@ -1843,12 +1845,12 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit) /* * For ":helpgrep" find a help window or open one. */ - if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) { + if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) { win_T *wp = NULL; if (cmdmod.tab == 0) { FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) { - if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) { + if (bt_help(wp2->w_buffer)) { wp = wp2; break; } @@ -2238,8 +2240,12 @@ void qf_list(exarg_T *eap) } } - if (qi->qf_lists[qi->qf_curlist].qf_nonevalid) - all = TRUE; + // Shorten all the file names, so that it is easy to read. + shorten_fnames(false); + + if (qi->qf_lists[qi->qf_curlist].qf_nonevalid) { + all = true; + } qfp = qi->qf_lists[qi->qf_curlist].qf_start; for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ) { if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2) { @@ -2413,11 +2419,12 @@ static void qf_free_items(qf_info_T *qi, int idx) qfline_T *qfp; qfline_T *qfpnext; bool stop = false; + qf_list_T *qfl = &qi->qf_lists[idx]; - while (qi->qf_lists[idx].qf_count && qi->qf_lists[idx].qf_start != NULL) { - qfp = qi->qf_lists[idx].qf_start; + while (qfl->qf_count && qfl->qf_start != NULL) { + qfp = qfl->qf_start; qfpnext = qfp->qf_next; - if (qi->qf_lists[idx].qf_title != NULL && !stop) { + if (!stop) { xfree(qfp->qf_text); stop = (qfp == qfpnext); xfree(qfp->qf_pattern); @@ -2426,40 +2433,42 @@ static void qf_free_items(qf_info_T *qi, int idx) // Somehow qf_count may have an incorrect value, set it to 1 // to avoid crashing when it's wrong. // TODO(vim): Avoid qf_count being incorrect. - qi->qf_lists[idx].qf_count = 1; + qfl->qf_count = 1; } } - qi->qf_lists[idx].qf_start = qfpnext; - qi->qf_lists[idx].qf_count--; - } - - qi->qf_lists[idx].qf_start = NULL; - qi->qf_lists[idx].qf_ptr = NULL; - qi->qf_lists[idx].qf_index = 0; - qi->qf_lists[idx].qf_start = NULL; - qi->qf_lists[idx].qf_last = NULL; - qi->qf_lists[idx].qf_ptr = NULL; - qi->qf_lists[idx].qf_nonevalid = true; - - qf_clean_dir_stack(&qi->qf_dir_stack); - qi->qf_directory = NULL; - qf_clean_dir_stack(&qi->qf_file_stack); - qi->qf_currfile = NULL; - qi->qf_multiline = false; - qi->qf_multiignore = false; - qi->qf_multiscan = false; + qfl->qf_start = qfpnext; + qfl->qf_count--; + } + + qfl->qf_start = NULL; + qfl->qf_ptr = NULL; + qfl->qf_index = 0; + qfl->qf_start = NULL; + qfl->qf_last = NULL; + qfl->qf_ptr = NULL; + qfl->qf_nonevalid = true; + + qf_clean_dir_stack(&qfl->qf_dir_stack); + qfl->qf_directory = NULL; + qf_clean_dir_stack(&qfl->qf_file_stack); + qfl->qf_currfile = NULL; + qfl->qf_multiline = false; + qfl->qf_multiignore = false; + qfl->qf_multiscan = false; } /// Free error list "idx". Frees all the entries in the quickfix list, /// associated context information and the title. static void qf_free(qf_info_T *qi, int idx) { + qf_list_T *qfl = &qi->qf_lists[idx]; qf_free_items(qi, idx); - xfree(qi->qf_lists[idx].qf_title); - qi->qf_lists[idx].qf_title = NULL; - tv_free(qi->qf_lists[idx].qf_ctx); - qi->qf_lists[idx].qf_ctx = NULL; + xfree(qfl->qf_title); + qfl->qf_title = NULL; + tv_free(qfl->qf_ctx); + qfl->qf_ctx = NULL; + qfl->qf_id = 0; } /* @@ -2599,8 +2608,9 @@ void ex_cclose(exarg_T *eap) /* Find existing quickfix window and close it. */ win = qf_find_win(qi); - if (win != NULL) - win_close(win, FALSE); + if (win != NULL) { + win_close(win, false); + } } /* @@ -2885,6 +2895,7 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last) qf_update_win_titlevar(qi); qf_fill_buffer(qi, buf, old_last); + buf_inc_changedtick(buf); if (old_last == NULL) { (void)qf_win_pos_update(qi, 0); @@ -2921,7 +2932,7 @@ static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) qfline_T *qfp; buf_T *errbuf; int len; - int old_KeyTyped = KeyTyped; + const bool old_KeyTyped = KeyTyped; if (old_last == NULL) { if (buf != curbuf) { @@ -2937,6 +2948,10 @@ static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) /* Check if there is anything to display */ if (qi->qf_curlist < qi->qf_listcount) { + char_u dirname[MAXPATHL]; + + *dirname = NUL; + // Add one line for each error if (old_last == NULL) { qfp = qi->qf_lists[qi->qf_curlist].qf_start; @@ -2952,6 +2967,14 @@ static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) if (qfp->qf_type == 1) { // :helpgrep STRLCPY(IObuff, path_tail(errbuf->b_fname), sizeof(IObuff)); } else { + // shorten the file name if not done already + if (errbuf->b_sfname == NULL + || path_is_absolute(errbuf->b_sfname)) { + if (*dirname == NUL) { + os_dirname(dirname, MAXPATHL); + } + shorten_buf_fname(errbuf, dirname, false); + } STRLCPY(IObuff, errbuf->b_fname, sizeof(IObuff)); } len = (int)STRLEN(IObuff); @@ -3603,15 +3626,16 @@ void ex_vimgrep(exarg_T *eap) goto theend; } - if (s != NULL && *s == NUL) { - /* Pattern is empty, use last search pattern. */ + if (s == NULL || *s == NUL) { + // Pattern is empty, use last search pattern. if (last_search_pat() == NULL) { EMSG(_(e_noprevre)); goto theend; } regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC); - } else + } else { regmatch.regprog = vim_regcomp(s, RE_MAGIC); + } if (regmatch.regprog == NULL) goto theend; @@ -4030,18 +4054,22 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start) /// Add each quickfix error to list "list" as a dictionary. /// If qf_idx is -1, use the current list. Otherwise, use the specified list. -int get_errorlist(win_T *wp, int qf_idx, list_T *list) +int get_errorlist(const qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) { - qf_info_T *qi = &ql_info; + const qf_info_T *qi = qi_arg; char_u buf[2]; qfline_T *qfp; int i; int bufnum; - if (wp != NULL) { - qi = GET_LOC_LIST(wp); - if (qi == NULL) - return FAIL; + if (qi == NULL) { + qi = &ql_info; + if (wp != NULL) { + qi = GET_LOC_LIST(wp); + if (qi == NULL) { + return FAIL; + } + } } if (qf_idx == -1) { @@ -4105,9 +4133,48 @@ enum { QF_GETLIST_NR = 0x4, QF_GETLIST_WINID = 0x8, QF_GETLIST_CONTEXT = 0x10, + QF_GETLIST_ID = 0x20, QF_GETLIST_ALL = 0xFF }; +// Parse text from 'di' and return the quickfix list items +static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict) +{ + int status = FAIL; + char_u *errorformat = p_efm; + dictitem_T *efm_di; + + // Only a List value is supported + if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { + // If errorformat is supplied then use it, otherwise use the 'efm' + // option setting + if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) { + if (efm_di->di_tv.v_type != VAR_STRING + || efm_di->di_tv.vval.v_string == NULL) { + return FAIL; + } + errorformat = efm_di->di_tv.vval.v_string; + } + + list_T *l = tv_list_alloc(kListLenMayKnow); + qf_info_T *qi = xmalloc(sizeof(*qi)); + memset(qi, 0, sizeof(*qi)); + qi->qf_refcount++; + + if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, + true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { + (void)get_errorlist(qi, NULL, 0, l); + qf_free(qi, 0); + } + xfree(qi); + + tv_dict_add_list(retdict, S_LEN("items"), l); + status = OK; + } + + return status; +} + /// Return quickfix/location list details (title) as a /// dictionary. 'what' contains the details to return. If 'list_idx' is -1, /// then current list is used. Otherwise the specified list is used. @@ -4116,17 +4183,22 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) qf_info_T *qi = &ql_info; dictitem_T *di; + if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) { + return qf_get_list_from_lines(what, di, retdict); + } + if (wp != NULL) { qi = GET_LOC_LIST(wp); - if (qi == NULL) { - // If querying for the size of the location list, return 0 - if (((di = tv_dict_find(what, S_LEN("nr"))) != NULL) - && (di->di_tv.v_type == VAR_STRING) - && strequal((const char *)di->di_tv.vval.v_string, "$")) { - return tv_dict_add_nr(retdict, S_LEN("nr"), 0); - } - return FAIL; + } + // List is not present or is empty + if (qi == NULL || qi->qf_listcount == 0) { + // If querying for the size of the list, return 0 + if (((di = tv_dict_find(what, S_LEN("nr"))) != NULL) + && (di->di_tv.v_type == VAR_STRING) + && (STRCMP(di->di_tv.vval.v_string, "$") == 0)) { + return tv_dict_add_nr(retdict, S_LEN("nr"), 0); } + return FAIL; } int status = OK; @@ -4142,44 +4214,51 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) if (qf_idx < 0 || qf_idx >= qi->qf_listcount) { return FAIL; } - } else if (qi->qf_listcount == 0) { // stack is empty - return FAIL; } - flags |= QF_GETLIST_NR; } else if (di->di_tv.v_type == VAR_STRING && strequal((const char *)di->di_tv.vval.v_string, "$")) { // Get the last quickfix list number - if (qi->qf_listcount > 0) { - qf_idx = qi->qf_listcount - 1; - } else { - qf_idx = -1; // Quickfix stack is empty - } - flags |= QF_GETLIST_NR; + qf_idx = qi->qf_listcount - 1; } else { return FAIL; } + flags |= QF_GETLIST_NR; } - if (qf_idx != -1) { - if (tv_dict_find(what, S_LEN("all")) != NULL) { - flags |= QF_GETLIST_ALL; - } - - if (tv_dict_find(what, S_LEN("title")) != NULL) { - flags |= QF_GETLIST_TITLE; - } - - if (tv_dict_find(what, S_LEN("winid")) != NULL) { - flags |= QF_GETLIST_WINID; - } - - if (tv_dict_find(what, S_LEN("context")) != NULL) { - flags |= QF_GETLIST_CONTEXT; + if ((di = tv_dict_find(what, S_LEN("id"))) != NULL) { + // Look for a list with the specified id + if (di->di_tv.v_type == VAR_NUMBER) { + // For zero, use the current list or the list specifed by 'nr' + if (di->di_tv.vval.v_number != 0) { + for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) { + if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number) { + break; + } + } + if (qf_idx == qi->qf_listcount) { + return FAIL; // List not found + } + } + flags |= QF_GETLIST_ID; + } else { + return FAIL; } + } - if (tv_dict_find(what, S_LEN("items")) != NULL) { - flags |= QF_GETLIST_ITEMS; - } + if (tv_dict_find(what, S_LEN("all")) != NULL) { + flags |= QF_GETLIST_ALL; + } + if (tv_dict_find(what, S_LEN("title")) != NULL) { + flags |= QF_GETLIST_TITLE; + } + if (tv_dict_find(what, S_LEN("winid")) != NULL) { + flags |= QF_GETLIST_WINID; + } + if (tv_dict_find(what, S_LEN("context")) != NULL) { + flags |= QF_GETLIST_CONTEXT; + } + if (tv_dict_find(what, S_LEN("items")) != NULL) { + flags |= QF_GETLIST_ITEMS; } if (flags & QF_GETLIST_TITLE) { @@ -4200,7 +4279,7 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) } if ((status == OK) && (flags & QF_GETLIST_ITEMS)) { list_T *l = tv_list_alloc(kListLenMayKnow); - (void)get_errorlist(wp, qf_idx, l); + (void)get_errorlist(qi, NULL, qf_idx, l); tv_dict_add_list(retdict, S_LEN("items"), l); } @@ -4208,7 +4287,8 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) if (qi->qf_lists[qf_idx].qf_ctx != NULL) { di = tv_dict_item_alloc_len(S_LEN("context")); tv_copy(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv); - if (tv_dict_add(retdict, di) == FAIL) { + status = tv_dict_add(retdict, di); + if (status == FAIL) { tv_dict_item_free(di); } } else { @@ -4216,6 +4296,10 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict) } } + if ((status == OK) && (flags & QF_GETLIST_ID)) { + status = tv_dict_add_nr(retdict, S_LEN("id"), qi->qf_lists[qf_idx].qf_id); + } + return status; } @@ -4328,11 +4412,13 @@ static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, return retval; } -static int qf_set_properties(qf_info_T *qi, dict_T *what, int action) +static int qf_set_properties(qf_info_T *qi, dict_T *what, int action, + char_u *title) { dictitem_T *di; int retval = FAIL; int newlist = false; + char_u *errorformat = p_efm; if (action == ' ' || qi->qf_curlist == qi->qf_listcount) { newlist = true; @@ -4348,25 +4434,48 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action) if ((action == ' ' || action == 'a') && qf_idx == qi->qf_listcount) { // When creating a new list, accept qf_idx pointing to the next - // non-available list + // non-available list and add the new list at the end of the + // stack. newlist = true; + qf_idx = qi->qf_listcount - 1; } else if (qf_idx < 0 || qf_idx >= qi->qf_listcount) { return FAIL; - } else { + } else if (action != ' ') { newlist = false; // use the specified list } } else if (di->di_tv.v_type == VAR_STRING - && strequal((const char *)di->di_tv.vval.v_string, "$") - && qi->qf_listcount > 0) { - qf_idx = qi->qf_listcount - 1; - newlist = false; + && strequal((const char *)di->di_tv.vval.v_string, "$")) { + if (qi->qf_listcount > 0) { + qf_idx = qi->qf_listcount - 1; + } else if (newlist) { + qf_idx = 0; + } else { + return FAIL; + } + } else { + return FAIL; + } + } + + if (!newlist && (di = tv_dict_find(what, S_LEN("id"))) != NULL) { + // Use the quickfix/location list with the specified id + if (di->di_tv.v_type == VAR_NUMBER) { + for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) { + if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number) { + break; + } + } + if (qf_idx == qi->qf_listcount) { + return FAIL; // List not found + } } else { return FAIL; } } if (newlist) { - qf_new_list(qi, NULL); + qi->qf_curlist = qf_idx; + qf_new_list(qi, title); qf_idx = qi->qf_curlist; } @@ -4383,6 +4492,7 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action) } if ((di = tv_dict_find(what, S_LEN("items"))) != NULL) { if (di->di_tv.v_type == VAR_LIST) { + assert(qi->qf_lists[qf_idx].qf_title != NULL); char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title); retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list, @@ -4391,12 +4501,35 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action) } } + if ((di = tv_dict_find(what, S_LEN("efm"))) != NULL) { + if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL) { + return FAIL; + } + errorformat = di->di_tv.vval.v_string; + } + + if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) { + // Only a List value is supported + if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) { + if (action == 'r') { + qf_free_items(qi, qf_idx); + } + if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat, + false, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { + retval = OK; + } + } else { + return FAIL; + } + } + if ((di = tv_dict_find(what, S_LEN("context"))) != NULL) { tv_free(qi->qf_lists[qf_idx].qf_ctx); typval_T *ctx = xcalloc(1, sizeof(typval_T)); tv_copy(&di->di_tv, ctx); qi->qf_lists[qf_idx].qf_ctx = ctx; + retval = OK; } return retval; @@ -4477,7 +4610,7 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, // Free the entire quickfix or location list stack qf_free_stack(wp, qi); } else if (what != NULL) { - retval = qf_set_properties(qi, what, action); + retval = qf_set_properties(qi, what, action, title); } else { retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); } @@ -4535,11 +4668,6 @@ void ex_cbuffer(exarg_T *eap) qf_info_T *qi = &ql_info; const char *au_name = NULL; - if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer - || eap->cmdidx == CMD_laddbuffer) { - qi = ll_get_or_alloc_list(curwin); - } - switch (eap->cmdidx) { case CMD_cbuffer: au_name = "cbuffer"; @@ -4570,6 +4698,13 @@ void ex_cbuffer(exarg_T *eap) } } + // Must come after autocommands. + if (eap->cmdidx == CMD_lbuffer + || eap->cmdidx == CMD_lgetbuffer + || eap->cmdidx == CMD_laddbuffer) { + qi = ll_get_or_alloc_list(curwin); + } + if (*eap->arg == NUL) buf = curbuf; else if (*skipwhite(skipdigits(eap->arg)) == NUL) @@ -4595,7 +4730,7 @@ void ex_cbuffer(exarg_T *eap) qf_title = IObuff; } - if (qf_init_ext(qi, NULL, buf, NULL, p_efm, + if (qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm, (eap->cmdidx != CMD_caddbuffer && eap->cmdidx != CMD_laddbuffer), eap->line1, eap->line2, qf_title, NULL) > 0) { @@ -4660,7 +4795,7 @@ void ex_cexpr(exarg_T *eap) if (eval0(eap->arg, &tv, NULL, true) != FAIL) { if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL) || tv.v_type == VAR_LIST) { - if (qf_init_ext(qi, NULL, NULL, &tv, p_efm, + if (qf_init_ext(qi, qi->qf_curlist, NULL, NULL, &tv, p_efm, (eap->cmdidx != CMD_caddexpr && eap->cmdidx != CMD_laddexpr), (linenr_T)0, (linenr_T)0, *eap->cmdlinep, NULL) > 0) { @@ -4717,16 +4852,26 @@ void ex_helpgrep(exarg_T *eap) p_cpo = empty_option; if (eap->cmdidx == CMD_lhelpgrep) { - qi = NULL; + win_T *wp = NULL; - /* Find an existing help window */ - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_buffer != NULL && wp->w_buffer->b_help) { - qi = wp->w_llist; + // If the current window is a help window, then use it + if (bt_help(curwin->w_buffer)) { + wp = curwin; + } else { + // Find an existing help window + FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) { + if (bt_help(wp2->w_buffer)) { + wp = wp2; + break; + } } } - /* Help window not found */ + if (wp == NULL) { // Help window not found + qi = NULL; + } else { + qi = wp->w_llist; + } if (qi == NULL) { /* Allocate a new location list for help text matches */ qi = ll_new_list(); @@ -4847,11 +4992,13 @@ void ex_helpgrep(exarg_T *eap) if (eap->cmdidx == CMD_lhelpgrep) { /* If the help window is not opened or if it already points to the * correct location list, then free the new location list. */ - if (!curwin->w_buffer->b_help || curwin->w_llist == qi) { - if (new_qi) + if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi) { + if (new_qi) { ll_free_all(&qi); - } else if (curwin->w_llist == NULL) + } + } else if (curwin->w_llist == NULL) { curwin->w_llist = qi; + } } } diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index d76da62c6d..15a701f022 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -772,13 +772,9 @@ static int get_equi_class(char_u **pp) char_u *p = *pp; if (p[1] == '=') { - if (has_mbyte) - l = (*mb_ptr2len)(p + 2); + l = (*mb_ptr2len)(p + 2); if (p[l + 2] == '=' && p[l + 3] == ']') { - if (has_mbyte) - c = mb_ptr2char(p + 2); - else - c = p[2]; + c = utf_ptr2char(p + 2); *pp += l + 4; return c; } @@ -1107,13 +1103,9 @@ static int get_coll_element(char_u **pp) char_u *p = *pp; if (p[0] != NUL && p[1] == '.') { - if (has_mbyte) - l = (*mb_ptr2len)(p + 2); + l = utfc_ptr2len(p + 2); if (p[l + 2] == '.' && p[l + 3] == ']') { - if (has_mbyte) - c = mb_ptr2char(p + 2); - else - c = p[2]; + c = utf_ptr2char(p + 2); *pp += l + 4; return c; } @@ -1299,10 +1291,7 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags) } if (OP(scan) == EXACTLY) { - if (has_mbyte) - r->regstart = (*mb_ptr2char)(OPERAND(scan)); - else - r->regstart = *OPERAND(scan); + r->regstart = utf_ptr2char(OPERAND(scan)); } else if (OP(scan) == BOW || OP(scan) == EOW || OP(scan) == NOTHING @@ -1310,10 +1299,7 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags) || OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE) { char_u *regnext_scan = regnext(scan); if (OP(regnext_scan) == EXACTLY) { - if (has_mbyte) - r->regstart = (*mb_ptr2char)(OPERAND(regnext_scan)); - else - r->regstart = *OPERAND(regnext_scan); + r->regstart = utf_ptr2char(OPERAND(regnext_scan)); } } @@ -1678,9 +1664,8 @@ static char_u *regpiece(int *flagp) case Magic('@'): { int lop = END; - int nr; + int64_t nr = getdecchrs(); - nr = getdecchrs(); switch (no_Magic(getchr())) { case '=': lop = MATCH; break; /* \@= */ case '!': lop = NOMATCH; break; /* \@! */ @@ -1820,8 +1805,8 @@ static char_u *regatom(int *flagp) if (c == '[') goto collection; - /* "\_x" is character class plus newline */ - /*FALLTHROUGH*/ + // "\_x" is character class plus newline + FALLTHROUGH; /* * Character classes. @@ -2101,7 +2086,7 @@ static char_u *regatom(int *flagp) case 'u': /* %uabcd hex 4 */ case 'U': /* %U1234abcd hex 8 */ { - int i; + int64_t i; switch (c) { case 'd': i = getdecchrs(); break; @@ -2412,20 +2397,16 @@ collection: break; } } else { - if (has_mbyte) { - int len; - - /* produce a multibyte character, including any - * following composing characters */ - startc = mb_ptr2char(regparse); - len = (*mb_ptr2len)(regparse); - if (enc_utf8 && utf_char2len(startc) != len) - startc = -1; /* composing chars */ - while (--len >= 0) - regc(*regparse++); - } else { - startc = *regparse++; - regc(startc); + // produce a multibyte character, including any + // following composing characters. + startc = utf_ptr2char(regparse); + int len = utfc_ptr2len(regparse); + if (utf_char2len(startc) != len) { + // composing chars + startc = -1; + } + while (--len >= 0) { + regc(*regparse++); } } } @@ -2439,7 +2420,7 @@ collection: } else if (reg_strict) EMSG2_RET_NULL(_(e_missingbracket), reg_magic > MAGIC_OFF); } - /* FALLTHROUGH */ + FALLTHROUGH; default: { @@ -2557,12 +2538,11 @@ static void regc(int b) */ static void regmbc(int c) { - if (!has_mbyte && c > 0xff) - return; - if (regcode == JUST_CALC_SIZE) - regsize += (*mb_char2len)(c); - else - regcode += (*mb_char2bytes)(c, regcode); + if (regcode == JUST_CALC_SIZE) { + regsize += utf_char2len(c); + } else { + regcode += utf_char2bytes(c, regcode); + } } /* @@ -2906,17 +2886,13 @@ static int peekchr(void) * Next character can never be (made) magic? * Then backslashing it won't do anything. */ - if (has_mbyte) - curchr = (*mb_ptr2char)(regparse + 1); - else - curchr = c; + curchr = utf_ptr2char(regparse + 1); } break; } default: - if (has_mbyte) - curchr = (*mb_ptr2char)(regparse); + curchr = utf_ptr2char(regparse); } return curchr; @@ -2998,9 +2974,9 @@ static void ungetchr(void) * The parameter controls the maximum number of input characters. This will be * 2 when reading a \%x20 sequence and 4 when reading a \%u20AC sequence. */ -static int gethexchrs(int maxinputlen) +static int64_t gethexchrs(int maxinputlen) { - int nr = 0; + int64_t nr = 0; int c; int i; @@ -3022,9 +2998,9 @@ static int gethexchrs(int maxinputlen) * Get and return the value of the decimal string immediately after the * current position. Return -1 for invalid. Consumes all digits. */ -static int getdecchrs(void) +static int64_t getdecchrs(void) { - int nr = 0; + int64_t nr = 0; int c; int i; @@ -3051,9 +3027,9 @@ static int getdecchrs(void) * blahblah\%o210asdf * before-^ ^-after */ -static int getoctchrs(void) +static int64_t getoctchrs(void) { - int nr = 0; + int64_t nr = 0; int c; int i; @@ -3077,7 +3053,7 @@ static int getoctchrs(void) */ static int coll_get_char(void) { - int nr = -1; + int64_t nr = -1; switch (*regparse++) { case 'd': nr = getdecchrs(); break; @@ -3466,12 +3442,7 @@ static long bt_regexec_both(char_u *line, /* If there is a "must appear" string, look for it. */ if (prog->regmust != NULL) { - int c; - - if (has_mbyte) - c = (*mb_ptr2char)(prog->regmust); - else - c = *prog->regmust; + int c = utf_ptr2char(prog->regmust); s = line + col; // This is used very often, esp. for ":global". Use two versions of @@ -3502,16 +3473,11 @@ static long bt_regexec_both(char_u *line, /* Simplest case: Anchored match need be tried only once. */ if (prog->reganch) { - int c; - - if (has_mbyte) - c = (*mb_ptr2char)(regline + col); - else - c = regline[col]; + int c = utf_ptr2char(regline + col); if (prog->regstart == NUL || prog->regstart == c || (rex.reg_ic - && (((enc_utf8 && utf_fold(prog->regstart) == utf_fold(c))) + && (utf_fold(prog->regstart) == utf_fold(c) || (c < 255 && prog->regstart < 255 && mb_tolower(prog->regstart) == mb_tolower(c))))) { retval = regtry(prog, col); @@ -3686,8 +3652,7 @@ static long regtry(bt_regprog_T *prog, colnr_T col) static int reg_prev_class(void) { if (reginput > regline) { - return mb_get_class_tab(reginput - 1 - (*mb_head_off)(regline, - reginput - 1), + return mb_get_class_tab(reginput - 1 - utf_head_off(regline, reginput - 1), rex.reg_buf->b_chartab); } return -1; @@ -3858,12 +3823,10 @@ regmatch ( } else if (rex.reg_line_lbr && WITH_NL(op) && *reginput == '\n') { ADVANCE_REGINPUT(); } else { - if (WITH_NL(op)) + if (WITH_NL(op)) { op -= ADD_NL; - if (has_mbyte) - c = (*mb_ptr2char)(reginput); - else - c = *reginput; + } + c = utf_ptr2char(reginput); switch (op) { case BOL: if (reginput != regline) @@ -4956,13 +4919,13 @@ regmatch ( (colnr_T)STRLEN(regline); } } else { - if (has_mbyte) { - rp->rs_un.regsave.rs_u.pos.col -= - (*mb_head_off)(regline, regline - + rp->rs_un.regsave.rs_u.pos.col - 1) + 1; - } else { - rp->rs_un.regsave.rs_u.pos.col--; - } + const char_u *const line = + reg_getline(behind_pos.rs_u.pos.lnum); + + rp->rs_un.regsave.rs_u.pos.col -= + utf_head_off(line, + line + rp->rs_un.regsave.rs_u.pos.col - 1) + + 1; } } else { if (rp->rs_un.regsave.rs_u.ptr == regline) { @@ -5191,8 +5154,8 @@ regrepeat ( case IDENT: case IDENT + ADD_NL: - testval = TRUE; - /*FALLTHROUGH*/ + testval = 1; + FALLTHROUGH; case SIDENT: case SIDENT + ADD_NL: while (count < maxcount) { @@ -5218,8 +5181,8 @@ regrepeat ( case KWORD: case KWORD + ADD_NL: - testval = TRUE; - /*FALLTHROUGH*/ + testval = 1; + FALLTHROUGH; case SKWORD: case SKWORD + ADD_NL: while (count < maxcount) { @@ -5247,8 +5210,8 @@ regrepeat ( case FNAME: case FNAME + ADD_NL: - testval = TRUE; - /*FALLTHROUGH*/ + testval = 1; + FALLTHROUGH; case SFNAME: case SFNAME + ADD_NL: while (count < maxcount) { @@ -5275,8 +5238,8 @@ regrepeat ( case PRINT: case PRINT + ADD_NL: - testval = TRUE; - /*FALLTHROUGH*/ + testval = 1; + FALLTHROUGH; case SPRINT: case SPRINT + ADD_NL: while (count < maxcount) { @@ -5454,8 +5417,8 @@ do_class: case ANYOF: case ANYOF + ADD_NL: - testval = TRUE; - /*FALLTHROUGH*/ + testval = 1; + FALLTHROUGH; case ANYBUT: case ANYBUT + ADD_NL: @@ -5473,8 +5436,8 @@ do_class: } } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) { scan++; - } else if (has_mbyte && (len = (*mb_ptr2len)(scan)) > 1) { - if ((cstrchr(opnd, (*mb_ptr2char)(scan)) == NULL) == testval) { + } else if ((len = utfc_ptr2len(scan)) > 1) { + if ((cstrchr(opnd, utf_ptr2char(scan)) == NULL) == testval) { break; } scan += len; @@ -6782,40 +6745,36 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, } c = *src++; } - } else if (has_mbyte) - c = mb_ptr2char(src - 1); - - /* Write to buffer, if copy is set. */ - if (func_one != (fptr_T)NULL) - /* Turbo C complains without the typecast */ + } else { + c = utf_ptr2char(src - 1); + } + // Write to buffer, if copy is set. + if (func_one != NULL) { func_one = (fptr_T)(func_one(&cc, c)); - else if (func_all != (fptr_T)NULL) - /* Turbo C complains without the typecast */ + } else if (func_all != NULL) { func_all = (fptr_T)(func_all(&cc, c)); - else /* just copy */ + } else { + // just copy cc = c; + } - if (has_mbyte) { - int totlen = mb_ptr2len(src - 1); + int totlen = utfc_ptr2len(src - 1); - if (copy) - mb_char2bytes(cc, dst); - dst += mb_char2len(cc) - 1; - if (enc_utf8) { - int clen = utf_ptr2len(src - 1); + if (copy) { + utf_char2bytes(cc, dst); + } + dst += utf_char2len(cc) - 1; + int clen = utf_ptr2len(src - 1); - /* If the character length is shorter than "totlen", there - * are composing characters; copy them as-is. */ - if (clen < totlen) { - if (copy) - memmove(dst + 1, src - 1 + clen, - (size_t)(totlen - clen)); - dst += totlen - clen; - } + // If the character length is shorter than "totlen", there + // are composing characters; copy them as-is. + if (clen < totlen) { + if (copy) { + memmove(dst + 1, src - 1 + clen, (size_t)(totlen - clen)); } - src += totlen - 1; - } else if (copy) - *dst = cc; + dst += totlen - clen; + } + src += totlen - 1; dst++; } else { if (REG_MULTI) { @@ -6878,10 +6837,7 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, } dst += 2; } else { - if (has_mbyte) - c = mb_ptr2char(s); - else - c = *s; + c = utf_ptr2char(s); if (func_one != (fptr_T)NULL) /* Turbo C complains without the typecast */ @@ -6895,20 +6851,19 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, if (has_mbyte) { int l; - /* Copy composing characters separately, one - * at a time. */ - if (enc_utf8) - l = utf_ptr2len(s) - 1; - else - l = mb_ptr2len(s) - 1; + // Copy composing characters separately, one + // at a time. + l = utf_ptr2len(s) - 1; s += l; len -= l; - if (copy) - mb_char2bytes(cc, dst); - dst += mb_char2len(cc) - 1; - } else if (copy) + if (copy) { + utf_char2bytes(cc, dst); + } + dst += utf_char2len(cc) - 1; + } else if (copy) { *dst = cc; + } dst++; } diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 2eb0ca9313..fe18cb4389 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -563,10 +563,7 @@ static char_u *nfa_get_match_text(nfa_state_T *start) p = start->out->out; /* skip first char, it goes into regstart */ s = ret; while (p->c > 0) { - if (has_mbyte) - s += (*mb_char2bytes)(p->c, s); - else - *s++ = p->c; + s += utf_char2bytes(p->c, s); p = p->out; } *s = NUL; @@ -1223,8 +1220,8 @@ static int nfa_regatom(void) if (c == '[') goto collection; - /* "\_x" is character class plus newline */ - /*FALLTHROUGH*/ + // "\_x" is character class plus newline + FALLTHROUGH; /* * Character classes. @@ -1387,8 +1384,8 @@ static int nfa_regatom(void) re_has_z = REX_SET; break; default: - EMSGN(_("E867: (NFA) Unknown operator '\\z%c'"), - no_Magic(c)); + emsgf(_("E867: (NFA) Unknown operator '\\z%c'"), + no_Magic(c)); return FAIL; } break; @@ -1409,7 +1406,7 @@ static int nfa_regatom(void) case 'u': /* %uabcd hex 4 */ case 'U': /* %U1234abcd hex 8 */ { - int nr; + int64_t nr; switch (c) { case 'd': nr = getdecchrs(); break; @@ -1485,7 +1482,7 @@ static int nfa_regatom(void) default: { - int n = 0; + long n = 0; int cmp = c; if (c == '<' || c == '>') @@ -1511,7 +1508,13 @@ static int nfa_regatom(void) EMIT(cmp == '<' ? NFA_VCOL_LT : cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); } - EMIT(n); +#if SIZEOF_INT < SIZEOF_LONG + if (n > INT_MAX) { + EMSG(_("E951: \\% value too large")); + return FAIL; + } +#endif + EMIT((int)n); break; } else if (c == '\'' && n == 0) { /* \%'m \%<'m \%>'m */ @@ -1521,8 +1524,8 @@ static int nfa_regatom(void) break; } } - EMSGN(_("E867: (NFA) Unknown operator '\\%%%c'"), - no_Magic(c)); + emsgf(_("E867: (NFA) Unknown operator '\\%%%c'"), + no_Magic(c)); return FAIL; } break; @@ -1798,7 +1801,7 @@ collection: if (reg_strict) EMSG_RET_FAIL(_(e_missingbracket)); - /* FALLTHROUGH */ + FALLTHROUGH; default: { @@ -1859,7 +1862,7 @@ static int nfa_regpiece(void) int greedy = TRUE; /* Braces are prefixed with '-' ? */ parse_state_T old_state; parse_state_T new_state; - int c2; + int64_t c2; int old_post_pos; int my_post_start; int quest; @@ -1934,7 +1937,7 @@ static int nfa_regpiece(void) break; } if (i == 0) { - EMSGN(_("E869: (NFA) Unknown operator '\\@%c'"), op); + emsgf(_("E869: (NFA) Unknown operator '\\@%c'"), op); return FAIL; } EMIT(i); @@ -2032,9 +2035,10 @@ static int nfa_regpiece(void) break; } /* end switch */ - if (re_multi_type(peekchr()) != NOT_MULTI) - /* Can't have a multi follow a multi. */ - EMSG_RET_FAIL(_("E871: (NFA regexp) Can't have a multi follow a multi !")); + if (re_multi_type(peekchr()) != NOT_MULTI) { + // Can't have a multi follow a multi. + EMSG_RET_FAIL(_("E871: (NFA regexp) Can't have a multi follow a multi")); + } return OK; } @@ -2124,7 +2128,6 @@ static int nfa_regconcat(void) */ static int nfa_regbranch(void) { - int ch; int old_post_pos; old_post_pos = (int)(post_ptr - post_start); @@ -2133,10 +2136,13 @@ static int nfa_regbranch(void) if (nfa_regconcat() == FAIL) return FAIL; - ch = peekchr(); - /* Try next concats */ - while (ch == Magic('&')) { + // Try next concats + while (peekchr() == Magic('&')) { skipchr(); + // if concat is empty do emit a node + if (old_post_pos == (int)(post_ptr - post_start)) { + EMIT(NFA_EMPTY); + } EMIT(NFA_NOPEN); EMIT(NFA_PREV_ATOM_NO_WIDTH); old_post_pos = (int)(post_ptr - post_start); @@ -2146,7 +2152,6 @@ static int nfa_regbranch(void) if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); EMIT(NFA_CONCAT); - ch = peekchr(); } /* if a branch is empty, emit one node for it */ @@ -2447,6 +2452,8 @@ static void nfa_set_code(int c) } static FILE *log_fd; +static char_u e_log_open_failed[] = N_( + "Could not open temporary log file for writing, displaying on stderr... "); /* * Print the postfix notation of the current regexp. @@ -2459,10 +2466,11 @@ static void nfa_postfix_dump(char_u *expr, int retval) f = fopen(NFA_REGEXP_DUMP_LOG, "a"); if (f != NULL) { fprintf(f, "\n-------------------------\n"); - if (retval == FAIL) - fprintf(f, ">>> NFA engine failed ... \n"); - else if (retval == OK) + if (retval == FAIL) { + fprintf(f, ">>> NFA engine failed... \n"); + } else if (retval == OK) { fprintf(f, ">>> NFA engine succeeded !\n"); + } fprintf(f, "Regexp: \"%s\"\nPostfix notation (char): \"", expr); for (p = post_start; *p && p < post_ptr; p++) { nfa_set_code(*p); @@ -2716,7 +2724,7 @@ static void st_error(int *postfix, int *end, int *p) fclose(df); } #endif - EMSG(_("E874: (NFA) Could not pop the stack !")); + EMSG(_("E874: (NFA) Could not pop the stack!")); } /* @@ -3224,7 +3232,13 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size) if (pattern) { /* NFA_ZEND -> NFA_END_PATTERN -> NFA_SKIP -> what follows. */ skip = alloc_state(NFA_SKIP, NULL, NULL); + if (skip == NULL) { + goto theend; + } zend = alloc_state(NFA_ZEND, s1, NULL); + if (zend == NULL) { + goto theend; + } s1->out= skip; patch(e.out, zend); PUSH(frag(s, list1(&skip->out))); @@ -3242,8 +3256,8 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size) break; } - case NFA_COMPOSING: /* char with composing char */ - /* FALLTHROUGH */ + case NFA_COMPOSING: // char with composing char + FALLTHROUGH; case NFA_MOPEN: /* \( \) Submatch */ case NFA_MOPEN1: @@ -3972,7 +3986,7 @@ addstate ( || !REG_MULTI || reglnum == nfa_endp->se_u.pos.lnum)) goto skip_add; - /* FALLTHROUGH */ + FALLTHROUGH; case NFA_MOPEN1: case NFA_MOPEN2: @@ -4195,7 +4209,7 @@ skip_add: subs = addstate(l, state->out, subs, pim, off_arg); break; } - // fallthrough + FALLTHROUGH; case NFA_MCLOSE1: case NFA_MCLOSE2: case NFA_MCLOSE3: @@ -4622,10 +4636,10 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T } if ((int)(reginput - regline) >= state->val) { reginput -= state->val; - if (has_mbyte) - reginput -= mb_head_off(regline, reginput); - } else + reginput -= utf_head_off(regline, reginput); + } else { reginput = regline; + } } } @@ -4685,8 +4699,7 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T fprintf(log_fd, "MATCH = %s\n", !result ? "FALSE" : "OK"); fprintf(log_fd, "****************************\n"); } else { - EMSG(_( - "Could not open temporary log file for writing, displaying on stderr ... ")); + EMSG(_(e_log_open_failed)); log_fd = stderr; } #endif @@ -4952,7 +4965,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, FILE *debug = fopen(NFA_REGEXP_DEBUG_LOG, "a"); if (debug == NULL) { - EMSG2(_("(NFA) COULD NOT OPEN %s !"), NFA_REGEXP_DEBUG_LOG); + EMSG2("(NFA) COULD NOT OPEN %s!", NFA_REGEXP_DEBUG_LOG); return false; } #endif @@ -4990,8 +5003,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, abs(start->id), code); fprintf(log_fd, "**********************************\n"); } else { - EMSG(_( - "Could not open temporary log file for writing, displaying on stderr ... ")); + EMSG(_(e_log_open_failed)); log_fd = stderr; } #endif @@ -5030,16 +5042,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, * Run for each character. */ for (;; ) { - int curc; - int clen; - - if (has_mbyte) { - curc = (*mb_ptr2char)(reginput); - clen = (*mb_ptr2len)(reginput); - } else { - curc = *reginput; - clen = 1; - } + int curc = utf_ptr2char(reginput); + int clen = utfc_ptr2len(reginput); if (curc == NUL) { clen = 0; go_to_nextline = false; @@ -5064,8 +5068,9 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, fprintf(log_fd, "------------------------------------------\n"); fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput); fprintf(log_fd, - ">>> Advanced one character ... Current char is %c (code %d) \n", curc, - (int)curc); + ">>> Advanced one character... Current char is %c (code %d) \n", + curc, + (int)curc); fprintf(log_fd, ">>> Thislist has %d states available: ", thislist->n); { int i; @@ -5097,16 +5102,17 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, { int col; - if (t->subs.norm.in_use <= 0) + if (t->subs.norm.in_use <= 0) { col = -1; - else if (REG_MULTI) + } else if (REG_MULTI) { col = t->subs.norm.list.multi[0].start_col; - else + } else { col = (int)(t->subs.norm.list.line[0].start - regline); + } nfa_set_code(t->state->c); - fprintf(log_fd, "(%d) char %d %s (start col %d)%s ... \n", - abs(t->state->id), (int)t->state->c, code, col, - pim_info(&t->pim)); + fprintf(log_fd, "(%d) char %d %s (start col %d)%s... \n", + abs(t->state->id), (int)t->state->c, code, col, + pim_info(&t->pim)); } #endif @@ -5501,7 +5507,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, // We don't care about the order of composing characters. // Get them into cchars[] first. while (len < clen) { - mc = mb_ptr2char(reginput + len); + mc = utf_ptr2char(reginput + len); cchars[ccount++] = mc; len += mb_char2len(mc); if (ccount == MAX_MCO) @@ -6260,8 +6266,9 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm) nfa_print_state(f, start); fprintf(f, "\n\n"); fclose(f); - } else - EMSG(_("Could not open temporary log file for writing ")); + } else { + EMSG("Could not open temporary log file for writing"); + } #endif clear_sub(&subs.norm); @@ -6487,10 +6494,10 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags) FILE *f = fopen(NFA_REGEXP_RUN_LOG, "a"); if (f != NULL) { - fprintf( - f, - "\n*****************************\n\n\n\n\tCompiling regexp \"%s\" ... hold on !\n", - expr); + fprintf(f, + "\n*****************************\n\n\n\n\t" + "Compiling regexp \"%s\"... hold on !\n", + expr); fclose(f); } } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 49aeaff3a6..d1453b56d2 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -85,6 +85,7 @@ #include "nvim/fold.h" #include "nvim/indent.h" #include "nvim/getchar.h" +#include "nvim/highlight.h" #include "nvim/main.h" #include "nvim/mark.h" #include "nvim/mbyte.h" @@ -131,6 +132,15 @@ static schar_T *current_ScreenLine; StlClickDefinition *tab_page_click_defs = NULL; long tab_page_click_defs_size = 0; +// for line_putchar. Contains the state that needs to be remembered from +// putting one character to the next. +typedef struct { + const char_u *p; + int prev_c; // previous Arabic character + int prev_c1; // first composing char for prev_c +} LineState; +#define LINE_STATE(p) { p, 0, 0 } + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.c.generated.h" #endif @@ -148,7 +158,7 @@ void redraw_later(int type) void redraw_win_later(win_T *wp, int type) { - if (wp->w_redr_type < type) { + if (!exiting && wp->w_redr_type < type) { wp->w_redr_type = type; if (type >= NOT_VALID) wp->w_lines_valid = 0; @@ -158,15 +168,6 @@ void redraw_win_later(win_T *wp, int type) } /* - * Force a complete redraw later. Also resets the highlighting. To be used - * after executing a shell command that messes up the screen. - */ -void redraw_later_clear(void) -{ - redraw_all_later(CLEAR); -} - -/* * Mark all windows to be redrawn later. */ void redraw_all_later(int type) @@ -202,24 +203,28 @@ void redraw_buf_later(buf_T *buf, int type) * may become invalid and the whole window will have to be redrawn. */ void -redrawWinline ( +redrawWinline( + win_T *wp, linenr_T lnum, int invalid /* window line height is invalid now */ ) { int i; - if (curwin->w_redraw_top == 0 || curwin->w_redraw_top > lnum) - curwin->w_redraw_top = lnum; - if (curwin->w_redraw_bot == 0 || curwin->w_redraw_bot < lnum) - curwin->w_redraw_bot = lnum; - redraw_later(VALID); + if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) { + wp->w_redraw_top = lnum; + } + if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) { + wp->w_redraw_bot = lnum; + } + redraw_win_later(wp, VALID); if (invalid) { - /* A w_lines[] entry for this lnum has become invalid. */ - i = find_wl_entry(curwin, lnum); - if (i >= 0) - curwin->w_lines[i].wl_valid = FALSE; + // A w_lines[] entry for this lnum has become invalid. + i = find_wl_entry(wp, lnum); + if (i >= 0) { + wp->w_lines[i].wl_valid = false; + } } } @@ -282,8 +287,11 @@ void update_screen(int type) if (msg_scrolled) { clear_cmdline = true; if (dy_flags & DY_MSGSEP) { + int valid = MAX(Rows - msg_scrollsize(), 0); + if (valid == 0) { + redraw_tabline = true; + } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - int valid = Rows - msg_scrollsize(); if (wp->w_winrow + wp->w_height > valid) { wp->w_redr_type = NOT_VALID; wp->w_lines_valid = 0; @@ -291,15 +299,13 @@ void update_screen(int type) if (wp->w_winrow + wp->w_height + wp->w_status_height > valid) { wp->w_redr_status = true; } - if (valid == 0) { - redraw_tabline = true; - } } } else if (msg_scrolled > Rows - 5) { // clearing is faster type = CLEAR; } else if (type != CLEAR) { check_for_delay(false); - if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL) { + if (screen_ins_lines(0, msg_scrolled, (int)Rows, 0, (int)Columns) + == FAIL) { type = CLEAR; } FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { @@ -421,7 +427,7 @@ void update_screen(int type) /* redraw status line after the window to minimize cursor movement */ if (wp->w_redr_status) { - win_redr_status(wp); + win_redr_status(wp, true); // any popup menu will be redrawn below } } end_search_hl(); @@ -476,7 +482,7 @@ int conceal_cursor_line(win_T *wp) /* * Check if the cursor line needs to be redrawn because of 'concealcursor'. */ -void conceal_check_cursur_line(void) +void conceal_check_cursor_line(void) { if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) { need_cursor_line_redraw = TRUE; @@ -505,7 +511,8 @@ void update_single_line(win_T *wp, linenr_T lnum) init_search_hl(wp); start_search_hl(); prepare_search_hl(wp, lnum); - win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, false); + update_window_hl(wp, false); + win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, false, false); end_search_hl(); break; } @@ -540,51 +547,57 @@ static void update_finish(void) updating_screen = FALSE; } -void update_debug_sign(buf_T *buf, linenr_T lnum) +void update_debug_sign(const buf_T *const buf, const linenr_T lnum) { - int doit = FALSE; - win_foldinfo.fi_level = 0; - - /* update/delete a specific mark */ - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (buf != NULL && lnum > 0) { - if (wp->w_buffer == buf && lnum >= wp->w_topline - && lnum < wp->w_botline) { - if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) { - wp->w_redraw_top = lnum; - } - if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) { - wp->w_redraw_bot = lnum; - } - redraw_win_later(wp, VALID); + bool doit = false; + win_foldinfo.fi_level = 0; + + // update/delete a specific mark + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (buf != NULL && lnum > 0) { + if (wp->w_buffer == buf && lnum >= wp->w_topline + && lnum < wp->w_botline) { + if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) { + wp->w_redraw_top = lnum; + } + if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) { + wp->w_redraw_bot = lnum; } - } else { redraw_win_later(wp, VALID); } - if (wp->w_redr_type != 0) { - doit = TRUE; - } + } else { + redraw_win_later(wp, VALID); } - - /* Return when there is nothing to do, screen updating is already - * happening (recursive call) or still starting up. */ - if (!doit || updating_screen || starting) { - return; + if (wp->w_redr_type != 0) { + doit = true; } + } - /* update all windows that need updating */ - update_prepare(); + // Return when there is nothing to do, screen updating is already + // happening (recursive call), messages on the screen or still starting up. + if (!doit + || updating_screen + || State == ASKMORE + || State == HITRETURN + || msg_scrolled + || starting) { + return; + } - FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_redr_type != 0) { - win_update(wp); - } - if (wp->w_redr_status) { - win_redr_status(wp); - } + // update all windows that need updating + update_prepare(); + + FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { + if (wp->w_redr_type != 0) { + update_window_hl(wp, wp->w_redr_type >= NOT_VALID); + win_update(wp); + } + if (wp->w_redr_status) { + win_redr_status(wp, false); } + } - update_finish(); + update_finish(); } /* @@ -774,16 +787,18 @@ static void win_update(win_T *wp) } } - (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, TRUE, NULL); - if (mod_top > lnumt) + (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, true, NULL); + if (mod_top > lnumt) { mod_top = lnumt; + } - /* Now do the same for the bottom line (one above mod_bot). */ - --mod_bot; - (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, TRUE, NULL); - ++mod_bot; - if (mod_bot < lnumb) + // Now do the same for the bottom line (one above mod_bot). + mod_bot--; + (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, true, NULL); + mod_bot++; + if (mod_bot < lnumb) { mod_bot = lnumb; + } } /* When a change starts above w_topline and the end is below @@ -824,13 +839,6 @@ static void win_update(win_T *wp) type = VALID; } - /* Trick: we want to avoid clearing the screen twice. screenclear() will - * set "screen_cleared" to TRUE. The special value MAYBE (which is still - * non-zero and thus not FALSE) will indicate that screenclear() was not - * called. */ - if (screen_cleared) - screen_cleared = MAYBE; - /* * If there are no changes on the screen that require a complete redraw, * handle three cases: @@ -866,7 +874,7 @@ static void win_update(win_T *wp) ++j; if (j >= wp->w_height - 2) break; - (void)hasFoldingWin(wp, ln, NULL, &ln, TRUE, NULL); + (void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL); } } else j = wp->w_lines[0].wl_lnum - wp->w_topline; @@ -876,15 +884,11 @@ static void win_update(win_T *wp) if (wp->w_lines[0].wl_lnum != wp->w_topline) i += diff_check_fill(wp, wp->w_lines[0].wl_lnum) - wp->w_old_topfill; - if (i < wp->w_height - 2) { /* less than a screen off */ - /* - * Try to insert the correct number of lines. - * If not the last window, delete the lines at the bottom. - * win_ins_lines may fail when the terminal can't do it. - */ - if (i > 0) - check_for_delay(FALSE); - if (win_ins_lines(wp, 0, i, FALSE, wp == firstwin) == OK) { + if (i < wp->w_height - 2) { // less than a screen off + // Try to insert the correct number of lines. + // If not the last window, delete the lines at the bottom. + // win_ins_lines may fail when the terminal can't do it. + if (win_ins_lines(wp, 0, i) == OK) { if (wp->w_lines_valid != 0) { /* Need to update rows that are new, stop at the * first one that scrolled down. */ @@ -942,11 +946,11 @@ static void win_update(win_T *wp) /* ... but don't delete new filler lines. */ row -= wp->w_topfill; if (row > 0) { - check_for_delay(FALSE); - if (win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK) + if (win_del_lines(wp, 0, row) == OK) { bot_start = wp->w_height - row; - else - mid_start = 0; /* redraw all lines */ + } else { + mid_start = 0; // redraw all lines + } } if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) { /* @@ -978,35 +982,16 @@ static void win_update(win_T *wp) * when it won't get updated below. */ if (wp->w_p_diff && bot_start > 0) wp->w_lines[0].wl_size = - plines_win_nofill(wp, wp->w_topline, TRUE) + plines_win_nofill(wp, wp->w_topline, true) + wp->w_topfill; } } } - /* When starting redraw in the first line, redraw all lines. When - * there is only one window it's probably faster to clear the screen - * first. */ + // When starting redraw in the first line, redraw all lines. if (mid_start == 0) { mid_end = wp->w_height; - if (ONE_WINDOW) { - /* Clear the screen when it was not done by win_del_lines() or - * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE - * then. */ - if (screen_cleared != TRUE) - screenclear(); - /* The screen was cleared, redraw the tab pages line. */ - if (redraw_tabline) - draw_tabline(); - } - } - - /* When win_del_lines() or win_ins_lines() caused the screen to be - * cleared (only happens for the first window) or when screenclear() - * was called directly above, "must_redraw" will have been set to - * NOT_VALID, need to reset it here to avoid redrawing twice. */ - if (screen_cleared == TRUE) - must_redraw = 0; + } } else { /* Not VALID or INVERTED: redraw all lines. */ mid_start = 0; @@ -1217,15 +1202,13 @@ static void win_update(win_T *wp) * with. It is used further down when the line doesn't fit. */ srow = row; - /* - * Update a line when it is in an area that needs updating, when it - * has changes or w_lines[idx] is invalid. - * bot_start may be halfway through a wrapped line after using - * win_del_lines(), check if the current line includes it. - * When syntax folding is being used, the saved syntax states will - * already have been updated, we can't see where the syntax state is - * the same again, just update until the end of the window. - */ + // Update a line when it is in an area that needs updating, when it + // has changes or w_lines[idx] is invalid. + // "bot_start" may be halfway a wrapped line after using + // win_del_lines(), check if the current line includes it. + // When syntax folding is being used, the saved syntax states will + // already have been updated, we can't see where the syntax state is + // the same again, just update until the end of the window. if (row < top_end || (row >= mid_start && row < mid_end) || top_to_mod @@ -1294,15 +1277,15 @@ static void win_update(win_T *wp) /* Able to count old number of rows: Count new window * rows, and may insert/delete lines */ j = idx; - for (l = lnum; l < mod_bot; ++l) { - if (hasFoldingWin(wp, l, NULL, &l, TRUE, NULL)) - ++new_rows; - else if (l == wp->w_topline) - new_rows += plines_win_nofill(wp, l, TRUE) - + wp->w_topfill; - else - new_rows += plines_win(wp, l, TRUE); - ++j; + for (l = lnum; l < mod_bot; l++) { + if (hasFoldingWin(wp, l, NULL, &l, true, NULL)) { + new_rows++; + } else if (l == wp->w_topline) { + new_rows += plines_win_nofill(wp, l, true) + wp->w_topfill; + } else { + new_rows += plines_win(wp, l, true); + } + j++; if (new_rows > wp->w_height - row - 2) { /* it's getting too much, must redraw the rest */ new_rows = 9999; @@ -1315,31 +1298,29 @@ static void win_update(win_T *wp) * remaining text or scrolling fails, must redraw the * rest. If scrolling works, must redraw the text * below the scrolled text. */ - if (row - xtra_rows >= wp->w_height - 2) + if (row - xtra_rows >= wp->w_height - 2) { mod_bot = MAXLNUM; - else { - check_for_delay(FALSE); - if (win_del_lines(wp, row, - -xtra_rows, FALSE, FALSE) == FAIL) + } else { + if (win_del_lines(wp, row, -xtra_rows) == FAIL) { mod_bot = MAXLNUM; - else - bot_start = wp->w_height + xtra_rows; + } else { + bot_start = wp->w_height + xtra_rows; + } } } else if (xtra_rows > 0) { /* May scroll text down. If there is not enough * remaining text of scrolling fails, must redraw the * rest. */ - if (row + xtra_rows >= wp->w_height - 2) + if (row + xtra_rows >= wp->w_height - 2) { mod_bot = MAXLNUM; - else { - check_for_delay(FALSE); - if (win_ins_lines(wp, row + old_rows, - xtra_rows, FALSE, FALSE) == FAIL) + } else { + if (win_ins_lines(wp, row + old_rows, xtra_rows) == FAIL) { mod_bot = MAXLNUM; - else if (top_end > row + old_rows) - /* Scrolled the part at the top that requires - * updating down. */ + } else if (top_end > row + old_rows) { + // Scrolled the part at the top that requires + // updating down. top_end += xtra_rows; + } } } @@ -1423,7 +1404,7 @@ static void win_update(win_T *wp) /* * Display one line. */ - row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0); + row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0, false); wp->w_lines[idx].wl_folded = FALSE; wp->w_lines[idx].wl_lastlnum = lnum; @@ -1432,12 +1413,17 @@ static void win_update(win_T *wp) } wp->w_lines[idx].wl_lnum = lnum; - wp->w_lines[idx].wl_valid = TRUE; - if (row > wp->w_height) { /* past end of screen */ - /* we may need the size of that too long line later on */ - if (dollar_vcol == -1) - wp->w_lines[idx].wl_size = plines_win(wp, lnum, TRUE); - ++idx; + wp->w_lines[idx].wl_valid = true; + + // Past end of the window or end of the screen. Note that after + // resizing wp->w_height may be end up too big. That's a problem + // elsewhere, but prevent a crash here. + if (row > wp->w_height || row + wp->w_winrow >= Rows) { + // we may need the size of that too long line later on + if (dollar_vcol == -1) { + wp->w_lines[idx].wl_size = plines_win(wp, lnum, true); + } + idx++; break; } if (dollar_vcol == -1) @@ -1445,7 +1431,13 @@ static void win_update(win_T *wp) ++idx; lnum += fold_count + 1; } else { - /* This line does not need updating, advance to the next one */ + if (wp->w_p_rnu) { + // 'relativenumber' set: The text doesn't need to be drawn, but + // the number column nearly always does. + (void)win_line(wp, lnum, srow, wp->w_height, true, true); + } + + // This line does not need to be drawn, advance to the next one. row += wp->w_lines[idx++].wl_size; if (row > wp->w_height) /* past end of screen */ break; @@ -1479,6 +1471,8 @@ static void win_update(win_T *wp) wp->w_empty_rows = 0; wp->w_filler_rows = 0; if (!eof && !didline) { + int at_attr = hl_combine_attr(wp->w_hl_attr_normal, + win_hl_attr(wp, HLF_AT)); if (lnum == wp->w_topline) { /* * Single line that does not fit! @@ -1493,12 +1487,11 @@ static void win_update(win_T *wp) int scr_row = wp->w_winrow + wp->w_height - 1; // Last line isn't finished: Display "@@@" in the last screen line. - screen_puts_len((char_u *)"@@", 2, scr_row, wp->w_wincol, - win_hl_attr(wp, HLF_AT)); + screen_puts_len((char_u *)"@@", 2, scr_row, wp->w_wincol, at_attr); screen_fill(scr_row, scr_row + 1, (int)wp->w_wincol + 2, (int)W_ENDCOL(wp), - '@', ' ', win_hl_attr(wp, HLF_AT)); + '@', ' ', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; } else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline" @@ -1506,7 +1499,7 @@ static void win_update(win_T *wp) screen_fill(wp->w_winrow + wp->w_height - 1, wp->w_winrow + wp->w_height, W_ENDCOL(wp) - 3, W_ENDCOL(wp), - '@', '@', win_hl_attr(wp, HLF_AT)); + '@', '@', at_attr); set_empty_rows(wp, srow); wp->w_botline = lnum; } else { @@ -1514,8 +1507,7 @@ static void win_update(win_T *wp) wp->w_botline = lnum; } } else { - draw_vsep_win(wp, row); - if (eof) { /* we hit the end of the file */ + if (eof) { // we hit the end of the file wp->w_botline = buf->b_ml.ml_line_count + 1; j = diff_check_fill(wp, wp->w_botline); if (j > 0 && !wp->w_botfill) { @@ -1539,6 +1531,10 @@ static void win_update(win_T *wp) win_draw_end(wp, fill_eob, ' ', row, wp->w_height, HLF_EOB); } + if (wp->w_redr_type >= REDRAW_TOP) { + draw_vsep_win(wp, 0); + } + /* Reset the type of redrawing required, the window has been updated. */ wp->w_redr_type = 0; wp->w_old_topfill = wp->w_topfill; @@ -1604,7 +1600,7 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h # define FDC_OFF n int fdc = compute_foldcolumn(wp, 0); - int attr = win_hl_attr(wp, hl); + int attr = hl_combine_attr(wp->w_hl_attr_normal, win_hl_attr(wp, hl)); if (wp->w_p_rl) { // No check for cmdline window: should never be right-left. @@ -1705,6 +1701,56 @@ static int compute_foldcolumn(win_T *wp, int col) return fdc; } +/// Put a single char from an UTF-8 buffer into a line buffer. +/// +/// Handles composing chars and arabic shaping state. +static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl) +{ + const char_u *p = s->p; + int cells = utf_ptr2cells(p); + int c_len = utfc_ptr2len(p); + int u8c, u8cc[MAX_MCO]; + if (cells > maxcells) { + return -1; + } + u8c = utfc_ptr2char(p, u8cc); + if (*p < 0x80 && u8cc[0] == 0) { + schar_from_ascii(dest[0], *p); + s->prev_c = u8c; + } else { + if (p_arshape && !p_tbidi && arabic_char(u8c)) { + // Do Arabic shaping. + int pc, pc1, nc; + int pcc[MAX_MCO]; + int firstbyte = *p; + + // The idea of what is the previous and next + // character depends on 'rightleft'. + if (rl) { + pc = s->prev_c; + pc1 = s->prev_c1; + nc = utf_ptr2char(p + c_len); + s->prev_c1 = u8cc[0]; + } else { + pc = utfc_ptr2char(p + c_len, pcc); + nc = s->prev_c; + pc1 = pcc[0]; + } + s->prev_c = u8c; + + u8c = arabic_shape(u8c, &firstbyte, &u8cc[0], pc, pc1, nc); + } else { + s->prev_c = u8c; + } + schar_from_cc(dest[0], u8c, u8cc); + } + if (cells > 1) { + dest[1][0] = 0; + } + s->p += c_len; + return cells; +} + /* * Display one folded line. */ @@ -1837,13 +1883,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T * Right-left text is put in columns 0 - number-col, normal text is put * in columns number-col - window-width. */ - int cells; - int u8c, u8cc[MAX_MCO]; int idx; - int c_len; - char_u *p; - int prev_c = 0; // previous Arabic character - int prev_c1 = 0; // first composing char for prev_c if (wp->w_p_rl) { idx = off; @@ -1851,50 +1891,20 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T idx = off + col; } - // Store multibyte characters in ScreenLines[] et al. correctly. - for (p = text; *p != NUL; ) { - cells = (*mb_ptr2cells)(p); - c_len = (*mb_ptr2len)(p); - if (col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { - break; - } - u8c = utfc_ptr2char(p, u8cc); - if (*p < 0x80 && u8cc[0] == 0) { - schar_from_ascii(ScreenLines[idx], *p); - prev_c = u8c; - } else { - if (p_arshape && !p_tbidi && arabic_char(u8c)) { - // Do Arabic shaping. - int pc, pc1, nc; - int pcc[MAX_MCO]; - int firstbyte = *p; - - // The idea of what is the previous and next - // character depends on 'rightleft'. - if (wp->w_p_rl) { - pc = prev_c; - pc1 = prev_c1; - nc = utf_ptr2char(p + c_len); - prev_c1 = u8cc[0]; - } else { - pc = utfc_ptr2char(p + c_len, pcc); - nc = prev_c; - pc1 = pcc[0]; - } - prev_c = u8c; + LineState s = LINE_STATE(text); - u8c = arabic_shape(u8c, &firstbyte, &u8cc[0], pc, pc1, nc); - } else { - prev_c = u8c; - } - schar_from_cc(ScreenLines[idx], u8c, u8cc); - } - if (cells > 1) { - ScreenLines[idx + 1][0] = 0; + while (*s.p != NUL) { + // TODO(bfredl): cargo-culted from the old Vim code: + // if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; } + // This is obvious wrong. If Vim ever fixes this, solve for "cells" again + // in the correct condition. + int maxcells = wp->w_width - col - (wp->w_p_rl ? col : 0); + int cells = line_putchar(&s, &ScreenLines[idx], maxcells, wp->w_p_rl); + if (cells == -1) { + break; } col += cells; idx += cells; - p += c_len; } /* Fill the rest of the line with the fold filler */ @@ -1991,7 +2001,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T } screen_line(row + wp->w_winrow, wp->w_wincol, wp->w_width, - wp->w_width, false, wp, 0); + wp->w_width, false, wp, wp->w_hl_attr_normal, false); /* * Update w_cline_height and w_cline_folded if the cursor line was @@ -2088,7 +2098,8 @@ win_line ( linenr_T lnum, int startrow, int endrow, - bool nochange /* not updating for changed text */ + bool nochange, // not updating for changed text + bool number_only // only update the number column ) { unsigned off; // offset in ScreenLines/ScreenAttrs @@ -2125,11 +2136,11 @@ win_line ( int n_skip = 0; /* nr of chars to skip for 'nowrap' */ - int fromcol, tocol; /* start/end of inverting */ - int fromcol_prev = -2; /* start of inverting after cursor */ - int noinvcur = FALSE; /* don't invert the cursor */ - pos_T *top, *bot; - int lnum_in_visual_area = FALSE; + int fromcol = 0, tocol = 0; // start/end of inverting + int fromcol_prev = -2; // start of inverting after cursor + int noinvcur = false; // don't invert the cursor + pos_T *top, *bot; + int lnum_in_visual_area = false; pos_T pos; long v; @@ -2180,17 +2191,16 @@ win_line ( match_T *shl; // points to search_hl or a match int shl_flag; // flag to indicate whether search_hl // has been processed or not - int prevcol_hl_flag; // flag to indicate whether prevcol + bool prevcol_hl_flag; // flag to indicate whether prevcol // equals startcol of search_hl or one // of the matches int prev_c = 0; // previous Arabic character int prev_c1 = 0; // first composing char for prev_c - int did_line_attr = 0; bool search_attr_from_match = false; // if search_attr is from :match - bool has_bufhl = false; // this buffer has highlight matches - int bufhl_attr = 0; // attributes desired by bufhl BufhlLineInfo bufhl_info; // bufhl data for this line + bool has_bufhl = false; // this buffer has highlight matches + bool do_virttext = false; // draw virtual text for this line /* draw_state: items that are drawn in sequence: */ #define WL_START 0 /* nothing done yet */ @@ -2232,156 +2242,165 @@ win_line ( row = startrow; screen_row = row + wp->w_winrow; - /* - * To speed up the loop below, set extra_check when there is linebreak, - * trailing white space and/or syntax processing to be done. - */ - extra_check = wp->w_p_lbr; - if (syntax_present(wp) && !wp->w_s->b_syn_error) { - /* Prepare for syntax highlighting in this line. When there is an - * error, stop syntax highlighting. */ - save_did_emsg = did_emsg; - did_emsg = FALSE; - syntax_start(wp, lnum); - if (did_emsg) - wp->w_s->b_syn_error = TRUE; - else { - did_emsg = save_did_emsg; - has_syntax = TRUE; - extra_check = TRUE; - } - } - - if (bufhl_start_line(wp->w_buffer, lnum, &bufhl_info)) { - has_bufhl = true; - extra_check = true; - } + if (!number_only) { + // To speed up the loop below, set extra_check when there is linebreak, + // trailing white space and/or syntax processing to be done. + extra_check = wp->w_p_lbr; + if (syntax_present(wp) && !wp->w_s->b_syn_error) { + // Prepare for syntax highlighting in this line. When there is an + // error, stop syntax highlighting. + save_did_emsg = did_emsg; + did_emsg = false; + syntax_start(wp, lnum); + if (did_emsg) { + wp->w_s->b_syn_error = true; + } else { + did_emsg = save_did_emsg; + has_syntax = true; + extra_check = true; + } + } - /* Check for columns to display for 'colorcolumn'. */ - color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols; - if (color_cols != NULL) - draw_color_col = advance_color_col(VCOL_HLC, &color_cols); - - if (wp->w_p_spell - && *wp->w_s->b_p_spl != NUL - && !GA_EMPTY(&wp->w_s->b_langp) - && *(char **)(wp->w_s->b_langp.ga_data) != NULL) { - /* Prepare for spell checking. */ - has_spell = true; - extra_check = TRUE; - - /* Get the start of the next line, so that words that wrap to the next - * line are found too: "et<line-break>al.". - * Trick: skip a few chars for C/shell/Vim comments */ - nextline[SPWORDLEN] = NUL; - if (lnum < wp->w_buffer->b_ml.ml_line_count) { - line = ml_get_buf(wp->w_buffer, lnum + 1, FALSE); - spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN); - } - - /* When a word wrapped from the previous line the start of the current - * line is valid. */ - if (lnum == checked_lnum) - cur_checked_col = checked_col; - checked_lnum = 0; - - /* When there was a sentence end in the previous line may require a - * word starting with capital in this line. In line 1 always check - * the first word. */ - if (lnum != capcol_lnum) - cap_col = -1; - if (lnum == 1) - cap_col = 0; - capcol_lnum = 0; - } + if (bufhl_start_line(wp->w_buffer, lnum, &bufhl_info)) { + if (kv_size(bufhl_info.line->items)) { + has_bufhl = true; + extra_check = true; + } + if (kv_size(bufhl_info.line->virt_text)) { + do_virttext = true; + } + } - /* - * handle visual active in this window - */ - fromcol = -10; - tocol = MAXCOL; - if (VIsual_active && wp->w_buffer == curwin->w_buffer) { - /* Visual is after curwin->w_cursor */ - if (ltoreq(curwin->w_cursor, VIsual)) { - top = &curwin->w_cursor; - bot = &VIsual; - } else { /* Visual is before curwin->w_cursor */ - top = &VIsual; - bot = &curwin->w_cursor; + // Check for columns to display for 'colorcolumn'. + color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols; + if (color_cols != NULL) { + draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } - lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum); - if (VIsual_mode == Ctrl_V) { /* block mode */ - if (lnum_in_visual_area) { - fromcol = wp->w_old_cursor_fcol; - tocol = wp->w_old_cursor_lcol; - } - } else { /* non-block mode */ - if (lnum > top->lnum && lnum <= bot->lnum) - fromcol = 0; - else if (lnum == top->lnum) { - if (VIsual_mode == 'V') /* linewise */ + + if (wp->w_p_spell + && *wp->w_s->b_p_spl != NUL + && !GA_EMPTY(&wp->w_s->b_langp) + && *(char **)(wp->w_s->b_langp.ga_data) != NULL) { + // Prepare for spell checking. + has_spell = true; + extra_check = true; + + // Get the start of the next line, so that words that wrap to the next + // line are found too: "et<line-break>al.". + // Trick: skip a few chars for C/shell/Vim comments + nextline[SPWORDLEN] = NUL; + if (lnum < wp->w_buffer->b_ml.ml_line_count) { + line = ml_get_buf(wp->w_buffer, lnum + 1, false); + spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN); + } + + // When a word wrapped from the previous line the start of the current + // line is valid. + if (lnum == checked_lnum) { + cur_checked_col = checked_col; + } + checked_lnum = 0; + + // When there was a sentence end in the previous line may require a + // word starting with capital in this line. In line 1 always check + // the first word. + if (lnum != capcol_lnum) { + cap_col = -1; + } + if (lnum == 1) { + cap_col = 0; + } + capcol_lnum = 0; + } + + // + // handle visual active in this window + // + fromcol = -10; + tocol = MAXCOL; + if (VIsual_active && wp->w_buffer == curwin->w_buffer) { + // Visual is after curwin->w_cursor + if (ltoreq(curwin->w_cursor, VIsual)) { + top = &curwin->w_cursor; + bot = &VIsual; + } else { // Visual is before curwin->w_cursor + top = &VIsual; + bot = &curwin->w_cursor; + } + lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum); + if (VIsual_mode == Ctrl_V) { // block mode + if (lnum_in_visual_area) { + fromcol = wp->w_old_cursor_fcol; + tocol = wp->w_old_cursor_lcol; + } + } else { // non-block mode + if (lnum > top->lnum && lnum <= bot->lnum) { fromcol = 0; - else { - getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL); - if (gchar_pos(top) == NUL) - tocol = fromcol + 1; + } else if (lnum == top->lnum) { + if (VIsual_mode == 'V') { // linewise + fromcol = 0; + } else { + getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL); + if (gchar_pos(top) == NUL) { + tocol = fromcol + 1; + } + } } - } - if (VIsual_mode != 'V' && lnum == bot->lnum) { - if (*p_sel == 'e' && bot->col == 0 - && bot->coladd == 0 - ) { - fromcol = -10; - tocol = MAXCOL; - } else if (bot->col == MAXCOL) - tocol = MAXCOL; - else { - pos = *bot; - if (*p_sel == 'e') - getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL); - else { - getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol); - ++tocol; + if (VIsual_mode != 'V' && lnum == bot->lnum) { + if (*p_sel == 'e' && bot->col == 0 + && bot->coladd == 0) { + fromcol = -10; + tocol = MAXCOL; + } else if (bot->col == MAXCOL) { + tocol = MAXCOL; + } else { + pos = *bot; + if (*p_sel == 'e') { + getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL); + } else { + getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol); + tocol++; + } } } } - } - /* Check if the character under the cursor should not be inverted */ - if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin - ) - noinvcur = TRUE; + // Check if the character under the cursor should not be inverted + if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin) { + noinvcur = true; + } - /* if inverting in this line set area_highlighting */ - if (fromcol >= 0) { + // if inverting in this line set area_highlighting + if (fromcol >= 0) { + area_highlighting = true; + attr = win_hl_attr(wp, HLF_V); + } + // handle 'incsearch' and ":s///c" highlighting + } else if (highlight_match + && wp == curwin + && lnum >= curwin->w_cursor.lnum + && lnum <= curwin->w_cursor.lnum + search_match_lines) { + if (lnum == curwin->w_cursor.lnum) { + getvcol(curwin, &(curwin->w_cursor), + (colnr_T *)&fromcol, NULL, NULL); + } else { + fromcol = 0; + } + if (lnum == curwin->w_cursor.lnum + search_match_lines) { + pos.lnum = lnum; + pos.col = search_match_endcol; + getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL); + } else { + tocol = MAXCOL; + } + // do at least one character; happens when past end of line + if (fromcol == tocol) { + tocol = fromcol + 1; + } area_highlighting = true; - attr = win_hl_attr(wp, HLF_V); + attr = win_hl_attr(wp, HLF_I); } } - /* - * handle 'incsearch' and ":s///c" highlighting - */ - else if (highlight_match - && wp == curwin - && lnum >= curwin->w_cursor.lnum - && lnum <= curwin->w_cursor.lnum + search_match_lines) { - if (lnum == curwin->w_cursor.lnum) - getvcol(curwin, &(curwin->w_cursor), - (colnr_T *)&fromcol, NULL, NULL); - else - fromcol = 0; - if (lnum == curwin->w_cursor.lnum + search_match_lines) { - pos.lnum = lnum; - pos.col = search_match_endcol; - getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL); - } else - tocol = MAXCOL; - /* do at least one character; happens when past end of line */ - if (fromcol == tocol) - tocol = fromcol + 1; - area_highlighting = true; - attr = win_hl_attr(wp, HLF_I); - } filler_lines = diff_check(wp, lnum); if (filler_lines < 0) { @@ -2407,15 +2426,15 @@ win_line ( if (wp->w_p_cul && lnum == wp->w_cursor.lnum && !(wp == curwin && VIsual_active)) { int cul_attr = win_hl_attr(wp, HLF_CUL); - HlAttrs *aep = syn_cterm_attr2entry(cul_attr); + HlAttrs ae = syn_attr2entry(cul_attr); // We make a compromise here (#7383): // * low-priority CursorLine if fg is not set // * high-priority ("same as Vim" priority) CursorLine if fg is set - if (aep->rgb_fg_color == -1 && aep->cterm_fg_color == 0) { + if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) { line_attr_lowprio = cul_attr; } else { - if (line_attr != 0 && !(State & INSERT) && bt_quickfix(wp->w_buffer) + if (!(State & INSERT) && bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) { line_attr = hl_combine_attr(cul_attr, line_attr); } else { @@ -2427,7 +2446,7 @@ win_line ( // If this line has a sign with line highlighting set line_attr. v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL); if (v != 0) { - line_attr = sign_get_attr((int)v, true); + line_attr = sign_get_attr((int)v, SIGN_LINEHL); } // Highlight the current line in the quickfix window. @@ -2442,10 +2461,11 @@ win_line ( line = ml_get_buf(wp->w_buffer, lnum, FALSE); ptr = line; - if (has_spell) { - /* For checking first word with a capital skip white space. */ - if (cap_col == 0) - cap_col = (int)(skipwhite(line) - line); + if (has_spell && !number_only) { + // For checking first word with a capital skip white space. + if (cap_col == 0) { + cap_col = (int)getwhitecols(line); + } /* To be able to spell-check over line boundaries copy the end of the * current line into nextline[]. Above the start of the next line was @@ -2494,7 +2514,7 @@ win_line ( v = wp->w_skipcol; else v = wp->w_leftcol; - if (v > 0) { + if (v > 0 && !number_only) { char_u *prev_ptr = ptr; while (vcol < v && *ptr != NUL) { c = win_lbr_chartabsize(wp, line, ptr, (colnr_T)vcol, NULL); @@ -2603,7 +2623,7 @@ win_line ( */ cur = wp->w_match_head; shl_flag = false; - while (cur != NULL || !shl_flag) { + while ((cur != NULL || !shl_flag) && !number_only) { if (!shl_flag) { shl = &search_hl; shl_flag = true; @@ -2734,7 +2754,7 @@ win_line ( p_extra = extra; p_extra[n_extra] = NUL; } - char_attr = sign_get_attr(text_sign, FALSE); + char_attr = sign_get_attr(text_sign, SIGN_TEXT); } } } @@ -2781,12 +2801,17 @@ win_line ( c_extra = ' '; n_extra = number_width(wp) + 1; char_attr = win_hl_attr(wp, HLF_N); - // When 'cursorline' is set highlight the line number of - // the current line differently. - // TODO(vim): Can we use CursorLine instead of CursorLineNr - // when CursorLineNr isn't set? - if ((wp->w_p_cul || wp->w_p_rnu) - && lnum == wp->w_cursor.lnum) { + + int num_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_NUMHL); + if (num_sign != 0) { + // :sign defined with "numhl" highlight. + char_attr = sign_get_attr(num_sign, SIGN_NUMHL); + } else if ((wp->w_p_cul || wp->w_p_rnu) + && lnum == wp->w_cursor.lnum) { + // When 'cursorline' is set highlight the line number of + // the current line differently. + // TODO(vim): Can we use CursorLine instead of CursorLineNr + // when CursorLineNr isn't set? char_attr = win_hl_attr(wp, HLF_CLN); } } @@ -2807,7 +2832,7 @@ win_line ( // if need_showbreak is set, breakindent also applies if (wp->w_p_bri && (row != startrow || need_showbreak) && filler_lines == 0) { - char_attr = wp->w_hl_attr_normal; + char_attr = 0; if (diff_hlf != (hlf_T)0) { char_attr = win_hl_attr(wp, diff_hlf); @@ -2867,18 +2892,18 @@ win_line ( p_extra = saved_p_extra; char_attr = saved_char_attr; } else { - char_attr = wp->w_hl_attr_normal; + char_attr = 0; } } } - /* When still displaying '$' of change command, stop at cursor */ - if (dollar_vcol >= 0 && wp == curwin - && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol - && filler_todo <= 0 - ) { + // When still displaying '$' of change command, stop at cursor + if ((dollar_vcol >= 0 && wp == curwin + && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol + && filler_todo <= 0) + || (number_only && draw_state > WL_NR)) { screen_line(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl, wp, - wp->w_hl_attr_normal); + wp->w_hl_attr_normal, false); // Pretend we have finished updating the window. Except when // 'cursorcolumn' is set. if (wp->w_p_cuc) { @@ -2892,16 +2917,17 @@ win_line ( if (draw_state == WL_LINE && area_highlighting) { /* handle Visual or match highlighting in this line */ if (vcol == fromcol - || (has_mbyte && vcol + 1 == fromcol && n_extra == 0 - && (*mb_ptr2cells)(ptr) > 1) + || (vcol + 1 == fromcol && n_extra == 0 + && utf_ptr2cells(ptr) > 1) || ((int)vcol_prev == fromcol_prev - && vcol_prev < vcol /* not at margin */ - && vcol < tocol)) - area_attr = attr; /* start highlighting */ - else if (area_attr != 0 - && (vcol == tocol - || (noinvcur && (colnr_T)vcol == wp->w_virtcol))) - area_attr = 0; /* stop highlighting */ + && vcol_prev < vcol // not at margin + && vcol < tocol)) { + area_attr = attr; // start highlighting + } else if (area_attr != 0 && (vcol == tocol + || (noinvcur + && (colnr_T)vcol == wp->w_virtcol))) { + area_attr = 0; // stop highlighting + } if (!n_extra) { /* @@ -3009,6 +3035,11 @@ win_line ( if (shl != &search_hl && cur != NULL) cur = cur->next; } + // Only highlight one character after the last column. + if (*ptr == NUL + && (wp->w_p_list && lcs_eol_one == -1)) { + search_attr = 0; + } } if (diff_hlf != (hlf_T)0) { @@ -3045,7 +3076,7 @@ win_line ( if (has_syntax) { char_attr = syntax_attr; } else { - char_attr = wp->w_hl_attr_normal; + char_attr = 0; } } } @@ -3284,8 +3315,7 @@ win_line ( did_emsg = FALSE; syntax_attr = get_syntax_attr((colnr_T)v - 1, - has_spell ? &can_spell : - NULL, FALSE); + has_spell ? &can_spell : NULL, false); if (did_emsg) { wp->w_s->b_syn_error = TRUE; @@ -3309,7 +3339,7 @@ win_line ( else syntax_flags = get_syntax_info(&syntax_seqnr); } else if (!attr_pri) { - char_attr = wp->w_hl_attr_normal; + char_attr = 0; } /* Check spelling (unless at the end of the line). @@ -3391,7 +3421,7 @@ win_line ( } if (has_bufhl && v > 0) { - bufhl_attr = bufhl_get_attr(&bufhl_info, (colnr_T)v); + int bufhl_attr = bufhl_get_attr(&bufhl_info, (colnr_T)v); if (bufhl_attr != 0) { if (!attr_pri) { char_attr = hl_combine_attr(char_attr, bufhl_attr); @@ -3408,7 +3438,7 @@ win_line ( // Found last space before word: check for line break. if (wp->w_p_lbr && c0 == c && vim_isbreak(c) && !vim_isbreak((int)(*ptr))) { - int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0; + int mb_off = utf_head_off(line, ptr - 1); char_u *p = ptr - (mb_off + 1); // TODO: is passing p for start of the line OK? n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1; @@ -3511,7 +3541,7 @@ win_line ( xfree(p_extra_free); p_extra_free = p; for (i = 0; i < tab_len; i++) { - mb_char2bytes(lcs_tab2, p); + utf_char2bytes(lcs_tab2, p); p += mb_char2len(lcs_tab2); n_extra += mb_char2len(lcs_tab2) - (saved_nextra > 0 ? 1: 0); } @@ -3645,32 +3675,6 @@ win_line ( (col < wp->w_width))) { c = ' '; ptr--; // put it back at the NUL - } else if ((diff_hlf != (hlf_T)0 || line_attr_lowprio || line_attr) - && (wp->w_p_rl - ? (col >= 0) - : (col - boguscols < wp->w_width))) { - // Highlight until the right side of the window - c = ' '; - ptr--; // put it back at the NUL - - // Remember we do the char for line highlighting. - did_line_attr++; - - // don't do search HL for the rest of the line - if ((line_attr_lowprio || line_attr) - && char_attr == search_attr && col > 0) { - char_attr = line_attr; - } - if (diff_hlf == HLF_TXD) { - diff_hlf = HLF_CHD; - if (attr == 0 || char_attr != attr) { - char_attr = win_hl_attr(wp, diff_hlf); - if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { - char_attr = hl_combine_attr(char_attr, - win_hl_attr(wp, HLF_CUL)); - } - } - } } } @@ -3787,7 +3791,7 @@ win_line ( /* * At end of the text line or just after the last character. */ - if (c == NUL || did_line_attr == 1) { + if (c == NUL) { long prevcol = (long)(ptr - line) - (c == NUL); /* we're not really at that column when skipping some text */ @@ -3817,9 +3821,8 @@ win_line ( || lnum == VIsual.lnum || lnum == curwin->w_cursor.lnum) && c == NUL) - /* highlight 'hlsearch' match at end of line */ - || (prevcol_hl_flag == TRUE && did_line_attr <= 1) - )) { + // highlight 'hlsearch' match at end of line + || prevcol_hl_flag)) { int n = 0; if (wp->w_p_rl) { @@ -3863,10 +3866,11 @@ win_line ( } } - if (wp->w_hl_attr_normal != 0) { - char_attr = hl_combine_attr(wp->w_hl_attr_normal, char_attr); + int eol_attr = char_attr; + if (wp->w_p_cul && lnum == wp->w_cursor.lnum) { + eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr); } - ScreenAttrs[off] = char_attr; + ScreenAttrs[off] = eol_attr; if (wp->w_p_rl) { --col; --off; @@ -3877,25 +3881,12 @@ win_line ( ++vcol; eol_hl_off = 1; } - } - - /* - * At end of the text line. - */ - if (c == NUL) { - if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol - && lnum == wp->w_cursor.lnum) { - /* highlight last char after line */ - --col; - --off; - --vcol; - } - - /* Highlight 'cursorcolumn' & 'colorcolumn' past end of the line. */ - if (wp->w_p_wrap) + // Highlight 'cursorcolumn' & 'colorcolumn' past end of the line. + if (wp->w_p_wrap) { v = wp->w_skipcol; - else + } else { v = wp->w_leftcol; + } /* check if line ends before left margin */ if (vcol < v + col - win_col_off(wp)) @@ -3913,40 +3904,105 @@ win_line ( && (int)wp->w_virtcol < wp->w_width * (row - startrow + 1) + v && lnum != wp->w_cursor.lnum) - || draw_color_col) - && !wp->w_p_rl - ) { + || draw_color_col || line_attr_lowprio || line_attr + || diff_hlf != (hlf_T)0 || do_virttext)) { int rightmost_vcol = 0; int i; - if (wp->w_p_cuc) + VirtText virt_text = do_virttext ? bufhl_info.line->virt_text + : (VirtText)KV_INITIAL_VALUE; + size_t virt_pos = 0; + LineState s = LINE_STATE((char_u *)""); + int virt_attr = 0; + + // Make sure alignment is the same regardless + // if listchars=eol:X is used or not. + bool delay_virttext = lcs_eol == lcs_eol_one && eol_hl_off == 0; + + if (wp->w_p_cuc) { rightmost_vcol = wp->w_virtcol; - if (draw_color_col) - /* determine rightmost colorcolumn to possibly draw */ - for (i = 0; color_cols[i] >= 0; ++i) - if (rightmost_vcol < color_cols[i]) + } + + if (draw_color_col) { + // determine rightmost colorcolumn to possibly draw + for (i = 0; color_cols[i] >= 0; i++) { + if (rightmost_vcol < color_cols[i]) { rightmost_vcol = color_cols[i]; + } + } + } int cuc_attr = win_hl_attr(wp, HLF_CUC); int mc_attr = win_hl_attr(wp, HLF_MC); - while (col < wp->w_width) { - schar_from_ascii(ScreenLines[off], ' '); - col++; + int diff_attr = 0; + if (diff_hlf == HLF_TXD) { + diff_hlf = HLF_CHD; + } + if (diff_hlf != 0) { + diff_attr = win_hl_attr(wp, diff_hlf); + } + + int base_attr = hl_combine_attr(line_attr_lowprio, diff_attr); + if (base_attr || line_attr) { + rightmost_vcol = INT_MAX; + } + + int col_stride = wp->w_p_rl ? -1 : 1; + + while (wp->w_p_rl ? col >= 0 : col < wp->w_width) { + int cells = -1; + if (do_virttext && !delay_virttext) { + if (*s.p == NUL) { + if (virt_pos < virt_text.size) { + s.p = (char_u *)kv_A(virt_text, virt_pos).text; + int hl_id = kv_A(virt_text, virt_pos).hl_id; + virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0; + virt_pos++; + } else { + do_virttext = false; + } + } + if (*s.p != NUL) { + cells = line_putchar(&s, &ScreenLines[off], wp->w_width - col, + false); + } + } + delay_virttext = false; + + if (cells == -1) { + schar_from_ascii(ScreenLines[off], ' '); + cells = 1; + } + col += cells * col_stride; if (draw_color_col) { draw_color_col = advance_color_col(VCOL_HLC, &color_cols); } + int attr = base_attr; + if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) { - ScreenAttrs[off++] = cuc_attr; + attr = cuc_attr; } else if (draw_color_col && VCOL_HLC == *color_cols) { - ScreenAttrs[off++] = mc_attr; - } else { - ScreenAttrs[off++] = wp->w_hl_attr_normal; + attr = mc_attr; + } + + if (do_virttext) { + attr = hl_combine_attr(attr, virt_attr); } - if (VCOL_HLC >= rightmost_vcol) + attr = hl_combine_attr(attr, line_attr); + + ScreenAttrs[off] = attr; + if (cells == 2) { + ScreenAttrs[off+1] = attr; + } + off += cells * col_stride; + + if (VCOL_HLC >= rightmost_vcol && *s.p == NUL + && virt_pos >= virt_text.size) { break; + } ++vcol; } @@ -3963,7 +4019,7 @@ win_line ( } } screen_line(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl, wp, - wp->w_hl_attr_normal); + wp->w_hl_attr_normal, false); row++; /* @@ -4171,8 +4227,22 @@ win_line ( || (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str) || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL))) ) { + bool wrap = wp->w_p_wrap // Wrapping enabled. + && filler_todo <= 0 // Not drawing diff filler lines. + && lcs_eol_one != -1 // Haven't printed the lcs_eol character. + && row != endrow - 1 // Not the last line being displayed. + && wp->w_width == Columns // Window spans the width of the screen. + && !wp->w_p_rl; // Not right-to-left. screen_line(screen_row, wp->w_wincol, col - boguscols, - wp->w_width, wp->w_p_rl, wp, wp->w_hl_attr_normal); + wp->w_width, wp->w_p_rl, wp, wp->w_hl_attr_normal, wrap); + if (wrap) { + // Force a redraw of the first column of the next line. + ScreenAttrs[LineOffset[screen_row + 1]] = -1; + + // Remember that the line wraps, used for modeless copy. + LineWraps[screen_row] = true; + } + boguscols = 0; ++row; ++screen_row; @@ -4189,7 +4259,6 @@ win_line ( && filler_todo <= 0 ) { win_draw_end(wp, '@', ' ', row, wp->w_height, HLF_AT); - draw_vsep_win(wp, row); row = endrow; } @@ -4199,53 +4268,6 @@ win_line ( break; } - if (ui_current_row() == screen_row - 1 - && filler_todo <= 0 - && wp->w_width == Columns) { - /* Remember that the line wraps, used for modeless copy. */ - LineWraps[screen_row - 1] = TRUE; - - /* - * Special trick to make copy/paste of wrapped lines work with - * xterm/screen: write an extra character beyond the end of - * the line. This will work with all terminal types - * (regardless of the xn,am settings). - * Only do this if the cursor is on the current line - * (something has been written in it). - * Don't do this for double-width characters. - * Don't do this for a window not at the right screen border. - */ - if (!(has_mbyte - && ((*mb_off2cells)(LineOffset[screen_row], - LineOffset[screen_row] + screen_Columns) - == 2 - || (*mb_off2cells)(LineOffset[screen_row - 1] - + (int)Columns - 2, - LineOffset[screen_row] + screen_Columns) - == 2)) - ) { - /* First make sure we are at the end of the screen line, - * then output the same character again to let the - * terminal know about the wrap. If the terminal doesn't - * auto-wrap, we overwrite the character. */ - if (ui_current_col() != wp->w_width) - screen_char(LineOffset[screen_row - 1] - + (unsigned)Columns - 1, - screen_row - 1, (int)(Columns - 1)); - - /* When there is a multi-byte character, just output a - * space to keep it simple. */ - if (ScreenLines[LineOffset[screen_row - 1] - + (Columns - 1)][1] != 0) { - ui_putc(' '); - } else { - ui_puts(ScreenLines[LineOffset[screen_row - 1] + (Columns - 1)]); - } - /* force a redraw of the first char on the next line */ - ScreenAttrs[LineOffset[screen_row]] = (sattr_T)-1; - } - } - col = 0; off = (unsigned)(current_ScreenLine - ScreenLines); if (wp->w_p_rl) { @@ -4295,7 +4317,7 @@ static int char_needs_redraw(int off_from, int off_to, int cols) return (cols > 0 && ((schar_cmp(ScreenLines[off_from], ScreenLines[off_to]) || ScreenAttrs[off_from] != ScreenAttrs[off_to] - || ((*mb_off2cells)(off_from, off_from + cols) > 1 + || (utf_off2cells(off_from, off_from + cols) > 1 && schar_cmp(ScreenLines[off_from + 1], ScreenLines[off_to + 1]))) || p_wd < 0)); @@ -4311,24 +4333,23 @@ static int char_needs_redraw(int off_from, int off_to, int cols) * "rlflag" is TRUE in a rightleft window: * When TRUE and "clear_width" > 0, clear columns 0 to "endcol" * When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width" + * If "wrap" is true, then hint to the UI that "row" contains a line + * which has wrapped into the next row. */ -static void screen_line(int row, int coloff, int endcol, - int clear_width, int rlflag, win_T *wp, int bg_attr) +static void screen_line(int row, int coloff, int endcol, int clear_width, + int rlflag, win_T *wp, int bg_attr, bool wrap) { unsigned off_from; unsigned off_to; unsigned max_off_from; unsigned max_off_to; int col = 0; - int hl; - int force = FALSE; /* force update rest of the line */ - int redraw_this /* bool: does character need redraw? */ - ; - int redraw_next; /* redraw_this for next character */ - int clear_next = FALSE; - int char_cells; /* 1: normal char */ - /* 2: occupies two display cells */ -# define CHAR_CELLS char_cells + bool redraw_this; // Does character need redraw? + bool redraw_next; // redraw_this for next character + bool clear_next = false; + int char_cells; // 1: normal char + // 2: occupies two display cells + int start_dirty = -1, end_dirty = 0; /* Check for illegal row and col, just in case. */ if (row >= Rows) @@ -4336,7 +4357,6 @@ static void screen_line(int row, int coloff, int endcol, if (endcol > Columns) endcol = Columns; - off_from = (unsigned)(current_ScreenLine - ScreenLines); off_to = LineOffset[row] + coloff; max_off_from = off_from + screen_Columns; @@ -4373,28 +4393,31 @@ static void screen_line(int row, int coloff, int endcol, redraw_next = char_needs_redraw(off_from, off_to, endcol - col); while (col < endcol) { - if (has_mbyte && (col + 1 < endcol)) - char_cells = (*mb_off2cells)(off_from, max_off_from); - else - char_cells = 1; - + char_cells = 1; + if (col + 1 < endcol) { + char_cells = utf_off2cells(off_from, max_off_from); + } redraw_this = redraw_next; - redraw_next = force || char_needs_redraw(off_from + CHAR_CELLS, - off_to + CHAR_CELLS, endcol - col - CHAR_CELLS); - + redraw_next = char_needs_redraw(off_from + char_cells, + off_to + char_cells, + endcol - col - char_cells); if (redraw_this) { + if (start_dirty == -1) { + start_dirty = col; + } + end_dirty = col + char_cells; // When writing a single-width character over a double-width // character and at the end of the redrawn text, need to clear out // the right halve of the old character. // Also required when writing the right halve of a double-width // char over the left halve of an existing one - if (has_mbyte && col + char_cells == endcol + if (col + char_cells == endcol && ((char_cells == 1 - && (*mb_off2cells)(off_to, max_off_to) > 1) + && utf_off2cells(off_to, max_off_to) > 1) || (char_cells == 2 - && (*mb_off2cells)(off_to, max_off_to) == 1 - && (*mb_off2cells)(off_to + 1, max_off_to) > 1))) { + && utf_off2cells(off_to, max_off_to) == 1 + && utf_off2cells(off_to + 1, max_off_to) > 1))) { clear_next = true; } @@ -4404,58 +4427,63 @@ static void screen_line(int row, int coloff, int endcol, } ScreenAttrs[off_to] = ScreenAttrs[off_from]; - /* For simplicity set the attributes of second half of a - * double-wide character equal to the first half. */ - if (char_cells == 2) + // For simplicity set the attributes of second half of a + // double-wide character equal to the first half. + if (char_cells == 2) { ScreenAttrs[off_to + 1] = ScreenAttrs[off_from]; - - screen_char(off_to, row, col + coloff); + } } - off_to += CHAR_CELLS; - off_from += CHAR_CELLS; - col += CHAR_CELLS; + off_to += char_cells; + off_from += char_cells; + col += char_cells; } if (clear_next) { /* Clear the second half of a double-wide character of which the left * half was overwritten with a single-wide character. */ schar_from_ascii(ScreenLines[off_to], ' '); - screen_char(off_to, row, col + coloff); + end_dirty++; } + int clear_end = -1; if (clear_width > 0 && !rlflag) { // blank out the rest of the line - while (col < clear_width && ScreenLines[off_to][0] == ' ' - && ScreenLines[off_to][1] == NUL - && ScreenAttrs[off_to] == bg_attr - ) { - ++off_to; - ++col; - } - if (col < clear_width) { - screen_fill(row, row + 1, col + coloff, clear_width + coloff, ' ', ' ', - bg_attr); - off_to += clear_width - col; - col = clear_width; - } - } - - if (clear_width > 0) { - // For a window that's left of another, draw the separator char. - if (col + coloff < Columns && wp->w_vsep_width > 0) { - int c = fillchar_vsep(wp, &hl); - schar_T sc; - schar_from_char(sc, c); - - if (schar_cmp(ScreenLines[off_to], sc) - || ScreenAttrs[off_to] != hl) { - schar_copy(ScreenLines[off_to], sc); - ScreenAttrs[off_to] = hl; - screen_char(off_to, row, col + coloff); - } - } else - LineWraps[row] = FALSE; + // TODO(bfredl): we could cache winline widths + while (col < clear_width) { + if (ScreenLines[off_to][0] != ' ' || ScreenLines[off_to][1] != NUL + || ScreenAttrs[off_to] != bg_attr) { + ScreenLines[off_to][0] = ' '; + ScreenLines[off_to][1] = NUL; + ScreenAttrs[off_to] = bg_attr; + if (start_dirty == -1) { + start_dirty = col; + end_dirty = col; + } else if (clear_end == -1) { + end_dirty = endcol; + } + clear_end = col+1; + } + col++; + off_to++; + } + } + + if (clear_width > 0 || wp->w_width != Columns) { + // If we cleared after the end of the line, it did not wrap. + // For vsplit, line wrapping is not possible. + LineWraps[row] = false; + } + + if (clear_end < end_dirty) { + clear_end = end_dirty; + } + if (start_dirty == -1) { + start_dirty = end_dirty; + } + if (clear_end > start_dirty) { + ui_line(row, coloff+start_dirty, coloff+end_dirty, coloff+clear_end, + bg_attr, wrap); } } @@ -4489,14 +4517,18 @@ void status_redraw_all(void) } } -/* - * mark all status lines of the current buffer for redraw - */ +/// Marks all status lines of the current buffer for redraw. void status_redraw_curbuf(void) { + status_redraw_buf(curbuf); +} + +/// Marks all status lines of the specified buffer for redraw. +void status_redraw_buf(buf_T *buf) +{ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - if (wp->w_status_height != 0 && wp->w_buffer == curbuf) { - wp->w_redr_status = TRUE; + if (wp->w_status_height != 0 && wp->w_buffer == buf) { + wp->w_redr_status = true; redraw_later(VALID); } } @@ -4509,7 +4541,7 @@ void redraw_statuslines(void) { FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_redr_status) { - win_redr_status(wp); + win_redr_status(wp, false); } } if (redraw_tabline) @@ -4738,11 +4770,11 @@ win_redr_status_matches ( /* Put the wildmenu just above the command line. If there is * no room, scroll the screen one line up. */ if (cmdline_row == Rows - 1) { - screen_del_lines(0, 0, 1, (int)Rows, NULL); - ++msg_scrolled; + screen_del_lines(0, 1, (int)Rows, 0, (int)Columns); + msg_scrolled++; } else { - ++cmdline_row; - ++row; + cmdline_row++; + row++; } wild_menu_showing = WM_SCROLLED; } else { @@ -4776,7 +4808,9 @@ win_redr_status_matches ( /// Redraw the status line of window `wp`. /// /// If inversion is possible we use it. Else '=' characters are used. -static void win_redr_status(win_T *wp) +/// If "ignore_pum" is true, also redraw statusline when the popup menu is +/// displayed. +static void win_redr_status(win_T *wp, int ignore_pum) { int row; char_u *p; @@ -4799,7 +4833,7 @@ static void win_redr_status(win_T *wp) if (wp->w_status_height == 0) { // no status line, can only be last window redraw_cmdline = true; - } else if (!redrawing() || pum_drawn()) { + } else if (!redrawing() || (!ignore_pum && pum_drawn())) { // Don't redraw right now, do it later. Don't update status line when // popup menu is visible and may be drawn over it wp->w_redr_status = true; @@ -4851,8 +4885,8 @@ static void win_redr_status(win_T *wp) // Find first character that will fit. // Going from start to end is much faster for DBCS. for (i = 0; p[i] != NUL && clen >= this_ru_col - 1; - i += (*mb_ptr2len)(p + i)) { - clen -= (*mb_ptr2cells)(p + i); + i += utfc_ptr2len(p + i)) { + clen -= utf_ptr2cells(p + i); } len = clen; if (i > 0) { @@ -5098,14 +5132,16 @@ win_redr_custom ( /* fill up with "fillchar" */ while (width < maxwidth && len < (int)sizeof(buf) - 1) { - len += (*mb_char2bytes)(fillchar, buf + len); - ++width; + len += utf_char2bytes(fillchar, buf + len); + width++; } buf[len] = NUL; /* * Draw each snippet with the specified highlighting. */ + screen_puts_line_start(row); + curattr = attr; p = buf; for (n = 0; hltab[n].start != NULL; n++) { @@ -5126,6 +5162,8 @@ win_redr_custom ( // Make sure to use an empty string instead of p, if p is beyond buf + len. screen_puts(p >= buf + len ? (char_u *)"" : p, row, col, curattr); + screen_puts_line_flush(false); + if (wp == NULL) { // Fill the tab_page_click_defs array for clicking in the tab pages line. col = 0; @@ -5203,7 +5241,7 @@ void screen_putchar(int c, int row, int col, int attr) { char_u buf[MB_MAXBYTES + 1]; - buf[(*mb_char2bytes)(c, buf)] = NUL; + buf[utf_char2bytes(c, buf)] = NUL; screen_puts(buf, row, col, attr); } @@ -5223,7 +5261,6 @@ void screen_getbytes(int row, int col, char_u *bytes, int *attrp) } } - /* * Put string '*text' on the screen at position 'row' and 'col', with * attributes 'attr', and update ScreenLines[] and ScreenAttrs[]. @@ -5235,6 +5272,20 @@ void screen_puts(char_u *text, int row, int col, int attr) screen_puts_len(text, -1, row, col, attr); } +static int put_dirty_row = -1; +static int put_dirty_first = -1; +static int put_dirty_last = 0; + +/// Start a group of screen_puts_len calls that builds a single screen line. +/// +/// Must be matched with a screen_puts_line_flush call before moving to +/// another line. +void screen_puts_line_start(int row) +{ + assert(put_dirty_row == -1); + put_dirty_row = row; +} + /* * Like screen_puts(), but output "text[len]". When "len" is -1 output up to * a NUL. @@ -5258,6 +5309,16 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) int force_redraw_next = FALSE; int need_redraw; + bool do_flush = false; + if (put_dirty_row == -1) { + screen_puts_line_start(row); + do_flush = true; + } else { + if (row != put_dirty_row) { + abort(); + } + } + if (ScreenLines == NULL || row >= screen_Rows) /* safety check */ return; off = LineOffset[row] + col; @@ -5268,9 +5329,12 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) schar_from_ascii(ScreenLines[off - 1], ' '); ScreenAttrs[off - 1] = 0; // redraw the previous cell, make it empty - screen_char(off - 1, row, col - 1); - /* force the cell at "col" to be redrawn */ - force_redraw_next = TRUE; + if (put_dirty_first == -1) { + put_dirty_first = col-1; + } + put_dirty_last = col+1; + // force the cell at "col" to be redrawn + force_redraw_next = true; } max_off = LineOffset[row] + screen_Columns; @@ -5331,15 +5395,15 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) // character with a one-cell character, need to clear the next // cell. Also when overwriting the left halve of a two-cell char // with the right halve of a two-cell char. Do this only once - // (mb_off2cells() may return 2 on the right halve). + // (utf8_off2cells() may return 2 on the right halve). if (clear_next_cell) { clear_next_cell = false; } else if ((len < 0 ? ptr[mbyte_blen] == NUL : ptr + mbyte_blen >= text + len) - && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1) + && ((mbyte_cells == 1 && utf_off2cells(off, max_off) > 1) || (mbyte_cells == 2 - && (*mb_off2cells)(off, max_off) == 1 - && (*mb_off2cells)(off + 1, max_off) > 1))) { + && utf_off2cells(off, max_off) == 1 + && utf_off2cells(off + 1, max_off) > 1))) { clear_next_cell = true; } @@ -5349,8 +5413,12 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) ScreenLines[off + 1][0] = 0; ScreenAttrs[off + 1] = attr; } - screen_char(off, row, col); + if (put_dirty_first == -1) { + put_dirty_first = col; + } + put_dirty_last = col+mbyte_cells; } + off += mbyte_cells; col += mbyte_cells; ptr += mbyte_blen; @@ -5361,13 +5429,32 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr) } } - /* If we detected the next character needs to be redrawn, but the text - * doesn't extend up to there, update the character here. */ - if (force_redraw_next && col < screen_Columns) { - screen_char(off, row, col); + if (do_flush) { + screen_puts_line_flush(true); } } +/// End a group of screen_puts_len calls and send the screen buffer to the UI +/// layer. +/// +/// @param set_cursor Move the visible cursor to the end of the changed region. +/// This is a workaround for not yet refactored code paths +/// and shouldn't be used in new code. +void screen_puts_line_flush(bool set_cursor) +{ + assert(put_dirty_row != -1); + if (put_dirty_first != -1) { + if (set_cursor) { + ui_cursor_goto(put_dirty_row, put_dirty_last); + } + ui_line(put_dirty_row, put_dirty_first, put_dirty_last, put_dirty_last, 0, + false); + put_dirty_first = -1; + put_dirty_last = 0; + } + put_dirty_row = -1; +} + /* * Prepare for 'hlsearch' highlighting. */ @@ -5391,41 +5478,6 @@ static void end_search_hl(void) } } -static void update_window_hl(win_T *wp, bool invalid) -{ - if (!wp->w_hl_needs_update && !invalid) { - return; - } - wp->w_hl_needs_update = false; - - // determine window specific background set in 'winhighlight' - if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) { - wp->w_hl_attr_normal = syn_id2attr(wp->w_hl_ids[HLF_INACTIVE]); - } else if (wp->w_hl_id_normal > 0) { - wp->w_hl_attr_normal = syn_id2attr(wp->w_hl_id_normal); - } else { - wp->w_hl_attr_normal = 0; - } - if (wp != curwin) { - wp->w_hl_attr_normal = hl_combine_attr(HL_ATTR(HLF_INACTIVE), - wp->w_hl_attr_normal); - } - - for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { - int attr; - if (wp->w_hl_ids[hlf] > 0) { - attr = syn_id2attr(wp->w_hl_ids[hlf]); - } else { - attr = HL_ATTR(hlf); - } - if (wp->w_hl_attr_normal != 0) { - attr = hl_combine_attr(wp->w_hl_attr_normal, attr); - } - wp->w_hl_attrs[hlf] = attr; - } -} - - /* * Init for calling prepare_search_hl(). @@ -5488,10 +5540,12 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum) && re_multiline(shl->rm.regprog)) { if (shl->first_lnum == 0) { for (shl->first_lnum = lnum; - shl->first_lnum > wp->w_topline; --shl->first_lnum) - if (hasFoldingWin(wp, shl->first_lnum - 1, - NULL, NULL, TRUE, NULL)) + shl->first_lnum > wp->w_topline; + shl->first_lnum--) { + if (hasFoldingWin(wp, shl->first_lnum - 1, NULL, NULL, true, NULL)) { break; + } + } } if (cur != NULL) { cur->pos.cur = 0; @@ -5692,32 +5746,6 @@ next_search_hl_pos( return 0; } -/* - * Put character ScreenLines["off"] on the screen at position "row" and "col", - * using the attributes from ScreenAttrs["off"]. - */ -static void screen_char(unsigned off, int row, int col) -{ - // Check for illegal values, just in case (could happen just after resizing). - if (row >= screen_Rows || col >= screen_Columns) { - return; - } - - // Outputting the last character on the screen may scrollup the screen. - // Don't to it! Mark the character invalid (update it when scrolled up) - // FIXME: The premise here is not actually true (cf. deferred wrap). - if (row == screen_Rows - 1 && col == screen_Columns - 1 - // account for first command-line character in rightleft mode - && !cmdmsg_rl) { - ScreenAttrs[off] = (sattr_T)-1; - return; - } - - ui_cursor_goto(row, col); - ui_set_highlight(ScreenAttrs[off]); - - ui_puts(ScreenLines[off]); -} /* * Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col' @@ -5726,12 +5754,6 @@ static void screen_char(unsigned off, int row, int col) */ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr) { - int row; - int col; - int off; - int end_off; - int did_delete; - int c; schar_T sc; if (end_row > screen_Rows) /* safety check */ @@ -5743,8 +5765,7 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, || start_col >= end_col) /* nothing to do */ return; - /* it's a "normal" terminal when not in a GUI or cterm */ - for (row = start_row; row < end_row; ++row) { + for (int row = start_row; row < end_row; row++) { if (has_mbyte) { // When drawing over the right halve of a double-wide char clear // out the left halve. When drawing over the left halve of a @@ -5757,71 +5778,53 @@ void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, screen_puts_len((char_u *)" ", 1, row, end_col, 0); } } - /* - * Try to use delete-line termcap code, when no attributes or in a - * "normal" terminal, where a bold/italic space is just a - * space. - */ - did_delete = FALSE; - if (c2 == ' ' - && end_col == Columns - && attr == 0) { - /* - * check if we really need to clear something - */ - col = start_col; - if (c1 != ' ') /* don't clear first char */ - ++col; - - off = LineOffset[row] + col; - end_off = LineOffset[row] + end_col; - // skip blanks (used often, keep it fast!) - while (off < end_off && ScreenLines[off][0] == ' ' - && ScreenLines[off][1] == 0 && ScreenAttrs[off] == 0) { - off++; - } - if (off < end_off) { // something to be cleared - col = off - LineOffset[row]; - ui_clear_highlight(); - ui_cursor_goto(row, col); // clear rest of this screen line - ui_call_eol_clear(); - col = end_col - col; - while (col--) { // clear chars in ScreenLines - schar_from_ascii(ScreenLines[off], ' '); - ScreenAttrs[off] = 0; - ++off; - } - } - did_delete = TRUE; /* the chars are cleared now */ - } - - off = LineOffset[row] + start_col; - c = c1; - schar_from_char(sc, c); + int dirty_first = INT_MAX; + int dirty_last = 0; + int col = start_col; + schar_from_char(sc, c1); + int lineoff = LineOffset[row]; for (col = start_col; col < end_col; col++) { + int off = lineoff + col; if (schar_cmp(ScreenLines[off], sc) || ScreenAttrs[off] != attr) { schar_copy(ScreenLines[off], sc); ScreenAttrs[off] = attr; - if (!did_delete || c != ' ') - screen_char(off, row, col); + if (dirty_first == INT_MAX) { + dirty_first = col; + } + dirty_last = col+1; } - ++off; if (col == start_col) { - if (did_delete) - break; - c = c2; - schar_from_char(sc, c); + schar_from_char(sc, c2); } } - if (end_col == Columns) - LineWraps[row] = FALSE; - if (row == Rows - 1) { /* overwritten the command line */ - redraw_cmdline = TRUE; - if (c1 == ' ' && c2 == ' ') - clear_cmdline = FALSE; /* command line has been cleared */ - if (start_col == 0) - mode_displayed = FALSE; /* mode cleared or overwritten */ + if (dirty_last > dirty_first) { + // TODO(bfredl): support a cleared suffix even with a batched line? + if (put_dirty_row == row) { + if (put_dirty_first == -1) { + put_dirty_first = dirty_first; + } + put_dirty_last = MAX(put_dirty_last, dirty_last); + } else { + int last = c2 != ' ' ? dirty_last : dirty_first + (c1 != ' '); + ui_line(row, dirty_first, last, dirty_last, attr, false); + } + } + + if (end_col == Columns) { + LineWraps[row] = false; + } + + // TODO(bfredl): The relevant caller should do this + if (row == Rows - 1) { // overwritten the command line + redraw_cmdline = true; + if (start_col == 0 && end_col == Columns + && c1 == ' ' && c2 == ' ' && attr == 0) { + clear_cmdline = false; // command line has been cleared + } + if (start_col == 0) { + mode_displayed = false; // mode cleared or overwritten + } } } } @@ -5870,7 +5873,6 @@ void screenalloc(bool doclear) int new_row, old_row; int len; static bool entered = false; // avoid recursiveness - static bool done_outofmem_msg = false; int retry_count = 0; retry: @@ -5940,67 +5942,39 @@ retry: win_alloc_lines(aucmd_win); } - if (new_ScreenLines == NULL - || new_ScreenAttrs == NULL - || new_LineOffset == NULL - || new_LineWraps == NULL - || new_tab_page_click_defs == NULL) { - if (ScreenLines != NULL || !done_outofmem_msg) { - // Guess the size. - do_outofmem_msg((Rows + 1) * Columns); - - // Remember we did this to avoid getting outofmem messages over - // and over again. - done_outofmem_msg = true; - } - xfree(new_ScreenLines); - new_ScreenLines = NULL; - xfree(new_ScreenAttrs); - new_ScreenAttrs = NULL; - xfree(new_LineOffset); - new_LineOffset = NULL; - xfree(new_LineWraps); - new_LineWraps = NULL; - xfree(new_tab_page_click_defs); - new_tab_page_click_defs = NULL; - } else { - done_outofmem_msg = FALSE; - - for (new_row = 0; new_row < Rows; ++new_row) { - new_LineOffset[new_row] = new_row * Columns; - new_LineWraps[new_row] = FALSE; - - /* - * If the screen is not going to be cleared, copy as much as - * possible from the old screen to the new one and clear the rest - * (used when resizing the window at the "--more--" prompt or when - * executing an external command, for the GUI). - */ - if (!doclear) { - for (int col = 0; col < Columns; col++) { - schar_from_ascii(new_ScreenLines[new_row * Columns + col], ' '); - } - memset(new_ScreenAttrs + new_row * Columns, - 0, (size_t)Columns * sizeof(*new_ScreenAttrs)); - old_row = new_row + (screen_Rows - Rows); - if (old_row >= 0 && ScreenLines != NULL) { - if (screen_Columns < Columns) - len = screen_Columns; - else - len = Columns; - - memmove(new_ScreenLines + new_LineOffset[new_row], - ScreenLines + LineOffset[old_row], - (size_t)len * sizeof(schar_T)); - memmove(new_ScreenAttrs + new_LineOffset[new_row], - ScreenAttrs + LineOffset[old_row], - (size_t)len * sizeof(new_ScreenAttrs[0])); + for (new_row = 0; new_row < Rows; new_row++) { + new_LineOffset[new_row] = new_row * Columns; + new_LineWraps[new_row] = false; + + // If the screen is not going to be cleared, copy as much as + // possible from the old screen to the new one and clear the rest + // (used when resizing the window at the "--more--" prompt or when + // executing an external command, for the GUI). + if (!doclear) { + for (int col = 0; col < Columns; col++) { + schar_from_ascii(new_ScreenLines[new_row * Columns + col], ' '); + } + memset(new_ScreenAttrs + new_row * Columns, + 0, (size_t)Columns * sizeof(*new_ScreenAttrs)); + old_row = new_row + (screen_Rows - Rows); + if (old_row >= 0 && ScreenLines != NULL) { + if (screen_Columns < Columns) { + len = screen_Columns; + } else { + len = Columns; } + + memmove(new_ScreenLines + new_LineOffset[new_row], + ScreenLines + LineOffset[old_row], + (size_t)len * sizeof(schar_T)); + memmove(new_ScreenAttrs + new_LineOffset[new_row], + ScreenAttrs + LineOffset[old_row], + (size_t)len * sizeof(new_ScreenAttrs[0])); } } - /* Use the last line of the screen for the current line. */ - current_ScreenLine = new_ScreenLines + Rows * Columns; } + // Use the last line of the screen for the current line. + current_ScreenLine = new_ScreenLines + Rows * Columns; free_screenlines(); @@ -6078,55 +6052,52 @@ static void screenclear2(void) return; } - ui_clear_highlight(); // don't want highlighting here - - /* blank out ScreenLines */ - for (i = 0; i < Rows; ++i) { - lineclear(LineOffset[i], (int)Columns); - LineWraps[i] = FALSE; + // blank out ScreenLines + for (i = 0; i < Rows; i++) { + lineclear(LineOffset[i], (int)Columns, true); + LineWraps[i] = false; } - ui_call_clear(); // clear the display + ui_call_grid_clear(1); // clear the display clear_cmdline = false; mode_displayed = false; - screen_cleared = true; // can use contents of ScreenLines now - win_rest_invalid(firstwin); - redraw_cmdline = TRUE; - redraw_tabline = TRUE; - if (must_redraw == CLEAR) /* no need to clear again */ - must_redraw = NOT_VALID; + redraw_all_later(NOT_VALID); + redraw_cmdline = true; + redraw_tabline = true; + if (must_redraw == CLEAR) { + must_redraw = NOT_VALID; // no need to clear again + } compute_cmdrow(); - msg_row = cmdline_row; /* put cursor on last line for messages */ + msg_row = cmdline_row; // put cursor on last line for messages msg_col = 0; - msg_scrolled = 0; /* can't scroll back */ - msg_didany = FALSE; - msg_didout = FALSE; + msg_scrolled = 0; // can't scroll back + msg_didany = false; + msg_didout = false; } /* * Clear one line in ScreenLines. */ -static void lineclear(unsigned off, int width) +static void lineclear(unsigned off, int width, bool valid) { for (int col = 0; col < width; col++) { schar_from_ascii(ScreenLines[off + col], ' '); } - (void)memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T)); + int fill = valid ? 0 : -1; + (void)memset(ScreenAttrs + off, fill, (size_t)width * sizeof(sattr_T)); } -/* - * Copy part of a Screenline for vertically split window "wp". - */ -static void linecopy(int to, int from, win_T *wp) +/// Copy part of a Screenline for vertically split window. +static void linecopy(int to, int from, int col, int width) { - const unsigned off_to = LineOffset[to] + wp->w_wincol; - const unsigned off_from = LineOffset[from] + wp->w_wincol; + unsigned off_to = LineOffset[to] + col; + unsigned off_from = LineOffset[from] + col; memmove(ScreenLines + off_to, ScreenLines + off_from, - wp->w_width * sizeof(schar_T)); + width * sizeof(schar_T)); memmove(ScreenAttrs + off_to, ScreenAttrs + off_from, - wp->w_width * sizeof(ScreenAttrs[0])); + width * sizeof(sattr_T)); } /* @@ -6136,100 +6107,65 @@ void setcursor(void) { if (redrawing()) { validate_cursor(); + int left_offset = curwin->w_wcol; + if (curwin->w_p_rl) { + // With 'rightleft' set and the cursor on a double-wide character, + // position it on the leftmost column. + left_offset = curwin->w_width - curwin->w_wcol + - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2 + && vim_isprintc(gchar_cursor())) ? 2 : 1); + } ui_cursor_goto(curwin->w_winrow + curwin->w_wrow, - curwin->w_wincol + ( - /* With 'rightleft' set and the cursor on a double-wide - * character, position it on the leftmost column. */ - curwin->w_p_rl ? (curwin->w_width - curwin->w_wcol - ( - (has_mbyte - && (*mb_ptr2cells)(get_cursor_pos_ptr()) == 2 - && vim_isprintc(gchar_cursor())) ? 2 : - 1)) : - curwin->w_wcol)); + curwin->w_wincol + left_offset); } } /// Insert 'line_count' lines at 'row' in window 'wp'. -/// If 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated. -/// If 'mayclear' is TRUE the screen will be cleared if it is faster than -/// scrolling. /// Returns FAIL if the lines are not inserted, OK for success. -int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear) +int win_ins_lines(win_T *wp, int row, int line_count) { - if (wp->w_height < 5) { - return FAIL; - } - - return win_do_lines(wp, row, line_count, invalid, mayclear, false); + return win_do_lines(wp, row, line_count, false); } /// Delete "line_count" window lines at "row" in window "wp". -/// If "invalid" is TRUE curwin->w_lines[] is invalidated. -/// If "mayclear" is TRUE the screen will be cleared if it is faster than -/// scrolling /// Return OK for success, FAIL if the lines are not deleted. -int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear) +int win_del_lines(win_T *wp, int row, int line_count) { - return win_do_lines(wp, row, line_count, invalid, mayclear, true); + return win_do_lines(wp, row, line_count, true); } // Common code for win_ins_lines() and win_del_lines(). // Returns OK or FAIL when the work has been done. -static int win_do_lines(win_T *wp, int row, int line_count, - int invalid, int mayclear, int del) +static int win_do_lines(win_T *wp, int row, int line_count, int del) { - if (invalid) { - wp->w_lines_valid = 0; - } - if (!redrawing() || line_count <= 0) { return FAIL; } - // only a few lines left: redraw is faster - if (mayclear && Rows - line_count < 5 && wp->w_width == Columns) { - screenclear(); /* will set wp->w_lines_valid to 0 */ - return FAIL; - } - - // Delete all remaining lines + // No lines are being moved, just draw over the entire area if (row + line_count >= wp->w_height) { - screen_fill(wp->w_winrow + row, wp->w_winrow + wp->w_height, - wp->w_wincol, W_ENDCOL(wp), - ' ', ' ', 0); return OK; } // when scrolling, the message on the command line should be cleared, // otherwise it will stay there forever. - clear_cmdline = TRUE; + check_for_delay(false); + clear_cmdline = true; int retval; - ui_set_scroll_region(wp, row); + if (del) { - retval = screen_del_lines(wp->w_winrow + row, 0, line_count, - wp->w_height - row, wp); + retval = screen_del_lines(wp->w_winrow + row, line_count, + wp->w_winrow + wp->w_height, + wp->w_wincol, wp->w_width); } else { - retval = screen_ins_lines(wp->w_winrow + row, 0, line_count, - wp->w_height - row, wp); + retval = screen_ins_lines(wp->w_winrow + row, line_count, + wp->w_winrow + wp->w_height, + wp->w_wincol, wp->w_width); } - ui_reset_scroll_region(); return retval; } /* - * window 'wp' and everything after it is messed up, mark it for redraw - */ -static void win_rest_invalid(win_T *wp) -{ - while (wp != NULL) { - redraw_win_later(wp, NOT_VALID); - wp->w_redr_status = TRUE; - wp = wp->w_next; - } - redraw_cmdline = TRUE; -} - -/* * The rest of the routines in this file perform screen manipulations. The * given operation is performed physically on the screen. The corresponding * change is also made to the internal screen image. In this way, the editor @@ -6240,19 +6176,13 @@ static void win_rest_invalid(win_T *wp) */ -// insert lines on the screen and update ScreenLines[] -// 'end' is the line after the scrolled part. Normally it is Rows. -// When scrolling region used 'off' is the offset from the top for the region. -// 'row' and 'end' are relative to the start of the region. -// -// return FAIL for failure, OK for success. -int screen_ins_lines ( - int off, - int row, - int line_count, - int end, - win_T *wp /* NULL or window to use width from */ -) +/// insert lines on the screen and update ScreenLines[] +/// 'end' is the line after the scrolled part. Normally it is Rows. +/// When scrolling region used 'off' is the offset from the top for the region. +/// 'row' and 'end' are relative to the start of the region. +/// +/// @return FAIL for failure, OK for success. +int screen_ins_lines(int row, int line_count, int end, int col, int width) { int i; int j; @@ -6264,18 +6194,16 @@ int screen_ins_lines ( // Shift LineOffset[] line_count down to reflect the inserted lines. // Clear the inserted lines in ScreenLines[]. - row += off; - end += off; - for (i = 0; i < line_count; ++i) { - if (wp != NULL && wp->w_width != Columns) { + for (i = 0; i < line_count; i++) { + if (width != Columns) { // need to copy part of a line j = end - 1 - i; while ((j -= line_count) >= row) { - linecopy(j + line_count, j, wp); + linecopy(j + line_count, j, col, width); } j += line_count; - lineclear(LineOffset[j] + wp->w_wincol, wp->w_width); - LineWraps[j] = FALSE; + lineclear(LineOffset[j] + col, width, false); + LineWraps[j] = false; } else { j = end - 1 - i; temp = LineOffset[j]; @@ -6284,29 +6212,23 @@ int screen_ins_lines ( LineWraps[j + line_count] = LineWraps[j]; } LineOffset[j + line_count] = temp; - LineWraps[j + line_count] = FALSE; - lineclear(temp, (int)Columns); + LineWraps[j + line_count] = false; + lineclear(temp, (int)Columns, false); } } - ui_call_scroll(-line_count); + ui_call_grid_scroll(1, row, end, col, col+width, -line_count, 0); return OK; } -// delete lines on the screen and update ScreenLines[] -// 'end' is the line after the scrolled part. Normally it is Rows. -// When scrolling region used 'off' is the offset from the top for the region. -// 'row' and 'end' are relative to the start of the region. -// -// Return OK for success, FAIL if the lines are not deleted. -int screen_del_lines ( - int off, - int row, - int line_count, - int end, - win_T *wp /* NULL or window to use width from */ -) +/// delete lines on the screen and update ScreenLines[] +/// 'end' is the line after the scrolled part. Normally it is Rows. +/// When scrolling region used 'off' is the offset from the top for the region. +/// 'row' and 'end' are relative to the start of the region. +/// +/// Return OK for success, FAIL if the lines are not deleted. +int screen_del_lines(int row, int line_count, int end, int col, int width) { int j; int i; @@ -6318,18 +6240,16 @@ int screen_del_lines ( // Now shift LineOffset[] line_count up to reflect the deleted lines. // Clear the inserted lines in ScreenLines[]. - row += off; - end += off; - for (i = 0; i < line_count; ++i) { - if (wp != NULL && wp->w_width != Columns) { + for (i = 0; i < line_count; i++) { + if (width != Columns) { // need to copy part of a line j = row + i; while ((j += line_count) <= end - 1) { - linecopy(j - line_count, j, wp); + linecopy(j - line_count, j, col, width); } j -= line_count; - lineclear(LineOffset[j] + wp->w_wincol, wp->w_width); - LineWraps[j] = FALSE; + lineclear(LineOffset[j] + col, width, false); + LineWraps[j] = false; } else { // whole width, moving the line pointers is faster j = row + i; @@ -6339,16 +6259,17 @@ int screen_del_lines ( LineWraps[j - line_count] = LineWraps[j]; } LineOffset[j - line_count] = temp; - LineWraps[j - line_count] = FALSE; - lineclear(temp, (int)Columns); + LineWraps[j - line_count] = false; + lineclear(temp, (int)Columns, false); } } - ui_call_scroll(line_count); + ui_call_grid_scroll(1, row, end, col, col+width, line_count, 0); return OK; } + /* * show the current mode and ruler * @@ -6982,26 +6903,20 @@ static void win_redr_ruler(win_T *wp, int always) if (this_ru_col + o < width) { // Need at least 3 chars left for get_rel_pos() + NUL. while (this_ru_col + o < width && RULER_BUF_LEN > i + 4) { - if (has_mbyte) - i += (*mb_char2bytes)(fillchar, buffer + i); - else - buffer[i++] = fillchar; - ++o; + i += utf_char2bytes(fillchar, buffer + i); + o++; } get_rel_pos(wp, buffer + i, RULER_BUF_LEN - i); } - /* Truncate at window boundary. */ - if (has_mbyte) { - o = 0; - for (i = 0; buffer[i] != NUL; i += (*mb_ptr2len)(buffer + i)) { - o += (*mb_ptr2cells)(buffer + i); - if (this_ru_col + o > width) { - buffer[i] = NUL; - break; - } + // Truncate at window boundary. + o = 0; + for (i = 0; buffer[i] != NUL; i += utfc_ptr2len(buffer + i)) { + o += utf_ptr2cells(buffer + i); + if (this_ru_col + o > width) { + buffer[i] = NUL; + break; } - } else if (this_ru_col + (int)STRLEN(buffer) > width) - buffer[width - this_ru_col] = NUL; + } screen_puts(buffer, row, this_ru_col + off, attr); i = redraw_cmdline; @@ -7128,11 +7043,12 @@ void screen_resize(int width, int height) update_topline(); if (pum_drawn()) { redraw_later(NOT_VALID); - ins_compl_show_pum(); /* This includes the redraw. */ - } else - update_screen(NOT_VALID); - if (redrawing()) + ins_compl_show_pum(); + } + update_screen(NOT_VALID); + if (redrawing()) { setcursor(); + } } } } diff --git a/src/nvim/search.c b/src/nvim/search.c index 578d1fd35a..f31ec7170b 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -521,7 +521,7 @@ int searchit( buffer without a window! */ buf_T *buf, pos_T *pos, - int dir, + Direction dir, char_u *pat, long count, int options, @@ -570,8 +570,12 @@ int searchit( && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count && pos->col < MAXCOL - 2) { // Watch out for the "col" being MAXCOL - 2, used in a closed fold. - ptr = ml_get_buf(buf, pos->lnum, false) + pos->col; - start_char_len = *ptr == NUL ? 1 : (*mb_ptr2len)(ptr); + ptr = ml_get_buf(buf, pos->lnum, false); + if ((int)STRLEN(ptr) <= pos->col) { + start_char_len = 1; + } else { + start_char_len = utfc_ptr2len(ptr + pos->col); + } } else { start_char_len = 1; } @@ -817,11 +821,10 @@ int searchit( pos->lnum, FALSE)); } } else { - --pos->col; - if (has_mbyte - && pos->lnum <= buf->b_ml.ml_line_count) { - ptr = ml_get_buf(buf, pos->lnum, FALSE); - pos->col -= (*mb_head_off)(ptr, ptr + pos->col); + pos->col--; + if (pos->lnum <= buf->b_ml.ml_line_count) { + ptr = ml_get_buf(buf, pos->lnum, false); + pos->col -= utf_head_off(ptr, ptr + pos->col); } } } else { @@ -1120,8 +1123,8 @@ int do_search( msgbuf = xmalloc(STRLEN(p) + 40); { msgbuf[0] = dirc; - if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) { - /* Use a space to draw the composing char on. */ + if (utf_iscomposing(utf_ptr2char(p))) { + // Use a space to draw the composing char on. msgbuf[1] = ' '; STRCPY(msgbuf + 2, p); } else @@ -1373,11 +1376,14 @@ int searchc(cmdarg_T *cap, int t_cmd) *lastc = c; set_csearch_direction(dir); set_csearch_until(t_cmd); - lastc_bytelen = (*mb_char2bytes)(c, lastc_bytes); + lastc_bytelen = utf_char2bytes(c, lastc_bytes); if (cap->ncharC1 != 0) { - lastc_bytelen += (*mb_char2bytes)(cap->ncharC1, lastc_bytes + lastc_bytelen); - if (cap->ncharC2 != 0) - lastc_bytelen += (*mb_char2bytes)(cap->ncharC2, lastc_bytes + lastc_bytelen); + lastc_bytelen += utf_char2bytes(cap->ncharC1, + lastc_bytes + lastc_bytelen); + if (cap->ncharC2 != 0) { + lastc_bytelen += utf_char2bytes(cap->ncharC2, + lastc_bytes + lastc_bytelen); + } } } } else { // repeat previous search @@ -1419,7 +1425,7 @@ int searchc(cmdarg_T *cap, int t_cmd) } else { if (col == 0) return FAIL; - col -= (*mb_head_off)(p, p + col - 1) + 1; + col -= utf_head_off(p, p + col - 1) + 1; } if (lastc_bytelen == 1) { if (p[col] == c && stop) { @@ -1442,15 +1448,14 @@ int searchc(cmdarg_T *cap, int t_cmd) } if (t_cmd) { - /* backup to before the character (possibly double-byte) */ + // Backup to before the character (possibly double-byte). col -= dir; - if (has_mbyte) { - if (dir < 0) - /* Landed on the search char which is lastc_bytelen long */ - col += lastc_bytelen - 1; - else - /* To previous char, which may be multi-byte. */ - col -= (*mb_head_off)(p, p + col); + if (dir < 0) { + // Landed on the search char which is lastc_bytelen long. + col += lastc_bytelen - 1; + } else { + // To previous char, which may be multi-byte. + col -= utf_head_off(p, p + col); } } curwin->w_cursor.col = col; @@ -1472,21 +1477,21 @@ pos_T *findmatch(oparg_T *oap, int initc) return findmatchlimit(oap, initc, 0, 0); } -/* - * Return TRUE if the character before "linep[col]" equals "ch". - * Return FALSE if "col" is zero. - * Update "*prevcol" to the column of the previous character, unless "prevcol" - * is NULL. - * Handles multibyte string correctly. - */ -static int check_prevcol(char_u *linep, int col, int ch, int *prevcol) +// Return true if the character before "linep[col]" equals "ch". +// Return false if "col" is zero. +// Update "*prevcol" to the column of the previous character, unless "prevcol" +// is NULL. +// Handles multibyte string correctly. +static bool check_prevcol(char_u *linep, int col, int ch, int *prevcol) { - --col; - if (col > 0 && has_mbyte) - col -= (*mb_head_off)(linep, linep + col); - if (prevcol) + col--; + if (col > 0) { + col -= utf_head_off(linep, linep + col); + } + if (prevcol) { *prevcol = col; - return (col >= 0 && linep[col] == ch) ? TRUE : FALSE; + } + return (col >= 0 && linep[col] == ch) ? true : false; } /* @@ -1549,37 +1554,31 @@ static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos) pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) { - static pos_T pos; /* current search position */ - int findc = 0; /* matching brace */ - int c; - int count = 0; /* cumulative number of braces */ - int backwards = false; /* init for gcc */ - int raw_string = false; /* search for raw string */ - int inquote = false; /* true when inside quotes */ - char_u *linep; /* pointer to current line */ + static pos_T pos; // current search position + int findc = 0; // matching brace + int count = 0; // cumulative number of braces + int backwards = false; // init for gcc + bool raw_string = false; // search for raw string + bool inquote = false; // true when inside quotes char_u *ptr; - int do_quotes; /* check for quotes in current line */ - int at_start; /* do_quotes value at start position */ - int hash_dir = 0; /* Direction searched for # things */ - int comment_dir = 0; /* Direction searched for comments */ - pos_T match_pos; /* Where last slash-star was found */ - int start_in_quotes; /* start position is in quotes */ - int traveled = 0; /* how far we've searched so far */ - int ignore_cend = FALSE; /* ignore comment end */ - int cpo_match; /* vi compatible matching */ - int cpo_bsl; /* don't recognize backslashes */ - int match_escaped = 0; /* search for escaped match */ - int dir; /* Direction to search */ - int comment_col = MAXCOL; /* start of / / comment */ - int lispcomm = FALSE; /* inside of Lisp-style comment */ - int lisp = curbuf->b_p_lisp; /* engage Lisp-specific hacks ;) */ + int hash_dir = 0; // Direction searched for # things + int comment_dir = 0; // Direction searched for comments + int traveled = 0; // how far we've searched so far + bool ignore_cend = false; // ignore comment end + int match_escaped = 0; // search for escaped match + int dir; // Direction to search + int comment_col = MAXCOL; // start of / / comment + bool lispcomm = false; // inside of Lisp-style comment + bool lisp = curbuf->b_p_lisp; // engage Lisp-specific hacks ;) pos = curwin->w_cursor; pos.coladd = 0; - linep = ml_get(pos.lnum); + char_u *linep = ml_get(pos.lnum); // pointer to current line - cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); - cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL); + // vi compatible matching + bool cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); + // don't recognize backslashes + bool cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL); /* Direction to search when initc is '/', '*' or '#' */ if (flags & FM_BACKWARD) @@ -1748,13 +1747,16 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } - /* This is just guessing: when 'rightleft' is set, search for a matching - * paren/brace in the other direction. */ - if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) + // This is just guessing: when 'rightleft' is set, search for a matching + // paren/brace in the other direction. + if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) { backwards = !backwards; + } - do_quotes = -1; - start_in_quotes = MAYBE; + int do_quotes = -1; // check for quotes in current line + int at_start; // do_quotes value at start position + TriState start_in_quotes = kNone; // start position is in quotes + pos_T match_pos; // Where last slash-star was found clearpos(&match_pos); /* backward search: Check if this line contains a single-line comment */ @@ -1762,8 +1764,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) || lisp ) comment_col = check_linecomment(linep); - if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) - lispcomm = TRUE; /* find match inside this comment */ + if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) { + lispcomm = true; // find match inside this comment + } while (!got_int) { /* * Go to the next position, forward or backward. We could use @@ -1795,9 +1798,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) if (lisp && comment_col != MAXCOL) pos.col = comment_col; } else { - --pos.col; - if (has_mbyte) - pos.col -= (*mb_head_off)(linep, linep + pos.col); + pos.col--; + pos.col -= utf_head_off(linep, linep + pos.col); } } else { /* forward search */ if (linep[pos.col] == NUL @@ -1851,7 +1853,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } else { /* Searching backwards */ /* * A comment may contain / * or / /, it may also start or end - * with / * /. Ignore a / * after / /. + * with / * /. Ignore a / * after / / and after *. */ if (pos.col == 0) continue; @@ -1876,6 +1878,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } else if ( linep[pos.col - 1] == '/' && linep[pos.col] == '*' + && (pos.col == 1 || linep[pos.col - 2] != '*') && (int)pos.col < comment_col) { count++; match_pos = pos; @@ -1925,26 +1928,29 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) * one for a '\' at the end. */ if (!do_quotes) { - inquote = FALSE; + inquote = false; if (ptr[-1] == '\\') { do_quotes = 1; - if (start_in_quotes == MAYBE) { - /* Do we need to use at_start here? */ - inquote = TRUE; - start_in_quotes = TRUE; - } else if (backwards) - inquote = TRUE; + if (start_in_quotes == kNone) { + // Do we need to use at_start here? + inquote = true; + start_in_quotes = kTrue; + } else if (backwards) { + inquote = true; + } } if (pos.lnum > 1) { ptr = ml_get(pos.lnum - 1); if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\') { do_quotes = 1; - if (start_in_quotes == MAYBE) { + if (start_in_quotes == kNone) { inquote = at_start; - if (inquote) - start_in_quotes = TRUE; - } else if (!backwards) - inquote = TRUE; + if (inquote) { + start_in_quotes = kTrue; + } + } else if (!backwards) { + inquote = true; + } } /* ml_get() only keeps one line, need to get linep again */ @@ -1952,8 +1958,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } } - if (start_in_quotes == MAYBE) - start_in_quotes = FALSE; + if (start_in_quotes == kNone) { + start_in_quotes = kFalse; + } /* * If 'smartmatch' is set: @@ -1966,13 +1973,13 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) * inquote if the number of quotes in a line is even, unless this * line or the previous one ends in a '\'. Complicated, isn't it? */ - c = PTR2CHAR(linep + pos.col); + const int c = PTR2CHAR(linep + pos.col); switch (c) { case NUL: /* at end of line without trailing backslash, reset inquote */ if (pos.col == 0 || linep[pos.col - 1] != '\\') { - inquote = FALSE; - start_in_quotes = FALSE; + inquote = false; + start_in_quotes = kFalse; } break; @@ -1987,7 +1994,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) break; if ((((int)pos.col - 1 - col) & 1) == 0) { inquote = !inquote; - start_in_quotes = FALSE; + start_in_quotes = kFalse; } } break; @@ -2023,7 +2030,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } } - /* FALLTHROUGH */ + FALLTHROUGH; default: /* @@ -2039,7 +2046,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) /* Check for match outside of quotes, and inside of * quotes when the start is also inside of quotes. */ - if ((!inquote || start_in_quotes == TRUE) + if ((!inquote || start_in_quotes == kTrue) && (c == initc || c == findc)) { int col, bslcnt = 0; @@ -2204,21 +2211,17 @@ showmatch( } } -/* - * findsent(dir, count) - Find the start of the next sentence in direction - * "dir" Sentences are supposed to end in ".", "!" or "?" followed by white - * space or a line break. Also stop at an empty line. - * Return OK if the next sentence was found. - */ -int findsent(int dir, long count) +// Find the start of the next sentence, searching in the direction specified +// by the "dir" argument. The cursor is positioned on the start of the next +// sentence when found. If the next sentence is found, return OK. Return FAIL +// otherwise. See ":h sentence" for the precise definition of a "sentence" +// text object. +int findsent(Direction dir, long count) { pos_T pos, tpos; int c; int (*func)(pos_T *); - int startlnum; - int noskip = FALSE; /* do not skip blanks */ - int cpo_J; - int found_dot; + bool noskip = false; // do not skip blanks pos = curwin->w_cursor; if (dir == FORWARD) @@ -2252,30 +2255,30 @@ int findsent(int dir, long count) decl(&pos); } - // go back to the previous non-blank char - found_dot = false; - while ((c = gchar_pos(&pos)) == ' ' || c == '\t' - || (dir == BACKWARD - && vim_strchr((char_u *)".!?)]\"'", c) != NULL)) { - if (vim_strchr((char_u *)".!?", c) != NULL) { - /* Only skip over a '.', '!' and '?' once. */ - if (found_dot) - break; - found_dot = TRUE; + // go back to the previous non-white non-punctuation character + bool found_dot = false; + while (c = gchar_pos(&pos), ascii_iswhite(c) + || vim_strchr((char_u *)".!?)]\"'", c) != NULL) { + tpos = pos; + if (decl(&tpos) == -1 || (LINEEMPTY(tpos.lnum) && dir == FORWARD)) { + break; } - if (decl(&pos) == -1) { + if (found_dot) { break; } - // when going forward: Stop in front of empty line - if (LINEEMPTY(pos.lnum) && dir == FORWARD) { - incl(&pos); - goto found; + if (vim_strchr((char_u *) ".!?", c) != NULL) { + found_dot = true; + } + if (vim_strchr((char_u *) ")]\"'", c) != NULL + && vim_strchr((char_u *) ".!?)]\"'", gchar_pos(&tpos)) == NULL) { + break; } + decl(&pos); } - /* remember the line where the search started */ - startlnum = pos.lnum; - cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL; + // remember the line where the search started + const int startlnum = pos.lnum; + const bool cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL; for (;; ) { /* find end of sentence */ c = gchar_pos(&pos); @@ -2303,7 +2306,7 @@ int findsent(int dir, long count) if ((*func)(&pos) == -1) { if (count) return FAIL; - noskip = TRUE; + noskip = true; break; } } @@ -2383,8 +2386,7 @@ findpar ( // motion inclusive. if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0) { curwin->w_cursor.col--; - curwin->w_cursor.col -= - (*mb_head_off)(line, line + curwin->w_cursor.col); + curwin->w_cursor.col -= utf_head_off(line, line + curwin->w_cursor.col); *pincl = true; } } else @@ -3298,7 +3300,7 @@ int current_tagblock( oparg_T *oap, long count_arg, - int include /* TRUE == include white space */ + bool include // true == include white space ) { long count = count_arg; @@ -3312,7 +3314,7 @@ current_tagblock( char_u *cp; int len; int r; - int do_include = include; + bool do_include = include; bool save_p_ws = p_ws; int retval = FAIL; int is_inclusive = true; @@ -3438,10 +3440,12 @@ again: } curwin->w_cursor = end_pos; - /* If we now have the same text as before reset "do_include" and try - * again. */ - if (equalpos(start_pos, old_start) && equalpos(end_pos, old_end)) { - do_include = TRUE; + // If we are in Visual mode and now have the same text as before set + // "do_include" and try again. + if (VIsual_active + && equalpos(start_pos, old_start) + && equalpos(end_pos, old_end)) { + do_include = true; curwin->w_cursor = old_start; count = count_arg; goto again; @@ -3689,8 +3693,8 @@ find_prev_quote( int n; while (col_start > 0) { - --col_start; - col_start -= (*mb_head_off)(line, line + col_start); + col_start--; + col_start -= utf_head_off(line, line + col_start); n = 0; if (escape != NULL) while (col_start - n > 0 && vim_strchr(escape, @@ -3950,8 +3954,10 @@ current_search( if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) dec_cursor(); - pos_T orig_pos; /* position of the cursor at beginning */ - pos_T pos; /* position after the pattern */ + pos_T orig_pos; // position of the cursor at beginning + pos_T first_match; // position of first match + pos_T pos; // position after the pattern + int result; // result of various function calls if (VIsual_active) { orig_pos = pos = curwin->w_cursor; @@ -3966,8 +3972,9 @@ current_search( orig_pos = pos = curwin->w_cursor; } - // Is the pattern is zero-width? - int one_char = is_one_char(spats[last_idx].pat, true, &curwin->w_cursor); + // Is the pattern is zero-width?, this time, don't care about the direction + int one_char = is_one_char(spats[last_idx].pat, true, &curwin->w_cursor, + FORWARD); if (one_char == -1) { p_ws = old_p_ws; return FAIL; /* pattern not found */ @@ -3985,9 +3992,9 @@ current_search( if (!dir && !one_char) flags = SEARCH_END; - int result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), - spats[last_idx].pat, i ? count : 1, - SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); + result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), + spats[last_idx].pat, i ? count : 1, + SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); /* First search may fail, but then start searching from the * beginning of the file (cursor might be on the search match) @@ -4009,15 +4016,19 @@ current_search( ml_get(curwin->w_buffer->b_ml.ml_line_count)); } } + if (i == 0) { + first_match = pos; + } p_ws = old_p_ws; } - int flags = forward ? SEARCH_END : 0; + const int flags = forward ? SEARCH_END : SEARCH_START; pos_T start_pos = pos; + const Direction direction = forward ? FORWARD : BACKWARD; // Check again from the current cursor position, // since the next match might actually be only one char wide - one_char = is_one_char(spats[last_idx].pat, false, &pos); + one_char = is_one_char(spats[last_idx].pat, false, &pos, direction); if (one_char < 0) { // search failed, abort return FAIL; @@ -4025,9 +4036,26 @@ current_search( /* move to match, except for zero-width matches, in which case, we are * already on the next match */ - if (!one_char) - searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), - spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); + if (!one_char) { + p_ws = false; + for (int i = 0; i < 2; i++) { + result = searchit(curwin, curbuf, &pos, direction, + spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, + 0, NULL); + // Search successfull, break out from the loop + if (result) { + break; + } + // search failed, try again from the last search position match + pos = first_match; + } + } + + p_ws = old_p_ws; + // not found + if (!result) { + return FAIL; + } if (!VIsual_active) VIsual = start_pos; @@ -4061,8 +4089,10 @@ current_search( /// Check if the pattern is one character long or zero-width. /// If move is true, check from the beginning of the buffer, /// else from position "cur". +/// "direction" is FORWARD or BACKWARD. /// Returns TRUE, FALSE or -1 for failure. -static int is_one_char(char_u *pattern, bool move, pos_T *cur) +static int is_one_char(char_u *pattern, bool move, pos_T *cur, + Direction direction) { regmmatch_T regmatch; int nmatched = 0; @@ -4089,7 +4119,7 @@ static int is_one_char(char_u *pattern, bool move, pos_T *cur) // accept a match at the cursor position flag = SEARCH_START; } - if (searchit(curwin, curbuf, &pos, FORWARD, pattern, 1, + if (searchit(curwin, curbuf, &pos, direction, pattern, 1, SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL) { // Zero-width pattern should match somewhere, then we can check if // start and end are in the same position. @@ -4101,7 +4131,9 @@ static int is_one_char(char_u *pattern, bool move, pos_T *cur) if (!nmatched) { break; } - } while (regmatch.startpos[0].col < pos.col); + } while (direction == FORWARD + ? regmatch.startpos[0].col < pos.col + : regmatch.startpos[0].col > pos.col); if (!called_emsg) { result = (nmatched != 0 @@ -4601,7 +4633,7 @@ search_line: if (depth == -1) { // match in current file if (l_g_do_tagpreview != 0) { - if (!GETFILE_SUCCESS(getfile(0, curwin_save->w_buffer->b_fname, + if (!GETFILE_SUCCESS(getfile(curwin_save->w_buffer->b_fnum, NULL, NULL, true, lnum, false))) { break; // failed to jump to file } @@ -4609,6 +4641,7 @@ search_line: setpcmark(); } curwin->w_cursor.lnum = lnum; + check_cursor(); } else { if (!GETFILE_SUCCESS(getfile(0, files[depth].name, NULL, true, files[depth].lnum, false))) { diff --git a/src/nvim/search.h b/src/nvim/search.h index cb50742990..cb094aab8c 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -4,7 +4,7 @@ #include <stdbool.h> #include <stdint.h> -#include "nvim/types.h" +#include "nvim/vim.h" #include "nvim/buffer_defs.h" #include "nvim/eval/typval.h" #include "nvim/normal.h" diff --git a/src/nvim/shada.c b/src/nvim/shada.c index f4454504a4..11da7195bf 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -884,7 +884,7 @@ static int shada_read_file(const char *const file, const int flags) if (p_verbose > 0) { verbose_enter(); - smsg(_("Reading ShaDa file \"%s\"%s%s%s"), + smsg(_("Reading ShaDa file \"%s\"%s%s%s%s"), fname, (flags & kShaDaWantInfo) ? _(" info") : "", (flags & kShaDaWantMarks) ? _(" marks") : "", @@ -2033,7 +2033,7 @@ static const char *shada_format_entry(const ShadaEntry entry) { static char ret[1024]; ret[0] = 0; - vim_snprintf(S_LEN(ret), "[ ] ts=%" PRIu64 " "); + vim_snprintf(S_LEN(ret), "%s", "[ ] ts=%" PRIu64 " "); // ^ Space for `can_free_entry` switch (entry.type) { case kSDItemMissing: { @@ -2091,7 +2091,7 @@ static const char *shada_format_entry(const ShadaEntry entry) entry.data.filemark.mark.lnum, \ entry.data.filemark.mark.col, \ entry.data.filemark.mark.coladd, \ - entry.data.filemark.additional_data, \ + (void *)entry.data.filemark.additional_data, \ ad_len, \ ad); \ } while (0) diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 3778f4287e..4443fd8a2e 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -9,17 +9,20 @@ typedef struct signlist signlist_T; struct signlist { - int id; /* unique identifier for each placed sign */ - linenr_T lnum; /* line number which has this sign */ - int typenr; /* typenr of sign */ - signlist_T *next; /* next signlist entry */ + int id; // unique identifier for each placed sign + linenr_T lnum; // line number which has this sign + int typenr; // typenr of sign + signlist_T *next; // next signlist entry }; -/* type argument for buf_getsigntype() */ -#define SIGN_ANY 0 -#define SIGN_LINEHL 1 -#define SIGN_ICON 2 -#define SIGN_TEXT 3 +// type argument for buf_getsigntype() and sign_get_attr() +typedef enum { + SIGN_ANY, + SIGN_LINEHL, + SIGN_ICON, + SIGN_TEXT, + SIGN_NUMHL, +} SignType; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 0714eb3137..518bd0922e 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -688,8 +688,9 @@ static void find_word(matchinf_T *mip, int mode) arridx = endidx[endidxcnt]; wlen = endlen[endidxcnt]; - if ((*mb_head_off)(ptr, ptr + wlen) > 0) + if (utf_head_off(ptr, ptr + wlen) > 0) { continue; // not at first byte of character + } if (spell_iswordp(ptr + wlen, mip->mi_win)) { if (slang->sl_compprog == NULL && !slang->sl_nobreak) continue; // next char is a word character @@ -1398,13 +1399,14 @@ spell_move_to ( capcol = 0; // For checking first word with a capital skip white space. - if (capcol == 0) - capcol = (int)(skipwhite(line) - line); - else if (curline && wp == curwin) { + if (capcol == 0) { + capcol = (int)getwhitecols(line); + } else if (curline && wp == curwin) { // For spellbadword(): check if first word needs a capital. - col = (int)(skipwhite(line) - line); - if (check_need_cap(lnum, col)) + col = (int)getwhitecols(line); + if (check_need_cap(lnum, col)) { capcol = col; + } // Need to get the line again, may have looked at the previous // one. @@ -1956,7 +1958,7 @@ static int count_syllables(slang_T *slang, char_u *word) skip = false; } else { // No recognized syllable item, at least a syllable char then? - c = mb_ptr2char(p); + c = utf_ptr2char(p); len = (*mb_ptr2len)(p); if (vim_strchr(slang->sl_syllable, c) == NULL) skip = false; // No, search for next syllable @@ -2043,9 +2045,11 @@ char_u *did_set_spelllang(win_T *wp) dont_use_region = true; // Check if we loaded this language before. - for (slang = first_lang; slang != NULL; slang = slang->sl_next) - if (path_full_compare(lang, slang->sl_fname, FALSE) == kEqualFiles) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) { + if (path_full_compare(lang, slang->sl_fname, false) == kEqualFiles) { break; + } + } } else { filename = false; if (len > 3 && lang[len - 3] == '_') { @@ -2085,8 +2089,9 @@ char_u *did_set_spelllang(win_T *wp) } // Loop over the languages, there can be several files for "lang". - for (slang = first_lang; slang != NULL; slang = slang->sl_next) - if (filename ? path_full_compare(lang, slang->sl_fname, FALSE) == kEqualFiles + for (slang = first_lang; slang != NULL; slang = slang->sl_next) { + if (filename + ? path_full_compare(lang, slang->sl_fname, false) == kEqualFiles : STRICMP(lang, slang->sl_name) == 0) { region_mask = REGION_ALL; if (!filename && region != NULL) { @@ -2116,6 +2121,7 @@ char_u *did_set_spelllang(win_T *wp) nobreak = true; } } + } } // round 0: load int_wordlist, if possible. @@ -2137,17 +2143,21 @@ char_u *did_set_spelllang(win_T *wp) // If it was already found above then skip it. for (c = 0; c < ga.ga_len; ++c) { p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname; - if (p != NULL && path_full_compare(spf_name, p, FALSE) == kEqualFiles) + if (p != NULL + && path_full_compare(spf_name, p, false) == kEqualFiles) { break; + } } if (c < ga.ga_len) continue; } // Check if it was loaded already. - for (slang = first_lang; slang != NULL; slang = slang->sl_next) - if (path_full_compare(spf_name, slang->sl_fname, FALSE) == kEqualFiles) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) { + if (path_full_compare(spf_name, slang->sl_fname, false) == kEqualFiles) { break; + } + } if (slang == NULL) { // Not loaded, try loading it now. The language name includes the // region name, the region is ignored otherwise. for int_wordlist @@ -2263,7 +2273,7 @@ static void use_midword(slang_T *lp, win_T *wp) int c, l, n; char_u *bp; - c = mb_ptr2char(p); + c = utf_ptr2char(p); l = (*mb_ptr2len)(p); if (c < 256 && l <= 2) wp->w_s->b_spell_ismw[c] = true; @@ -2589,16 +2599,18 @@ static bool spell_iswordp(char_u *p, win_T *wp) if (wp->w_s->b_spell_ismw[*p]) s = p + 1; // skip a mid-word character } else { - c = mb_ptr2char(p); + c = utf_ptr2char(p); if (c < 256 ? wp->w_s->b_spell_ismw[c] : (wp->w_s->b_spell_ismw_mb != NULL - && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL)) + && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL)) { s = p + l; + } } - c = mb_ptr2char(s); - if (c > 255) + c = utf_ptr2char(s); + if (c > 255) { return spell_mb_isword_class(mb_get_class(s), wp); + } return spelltab.st_isw[c]; } @@ -2609,16 +2621,11 @@ static bool spell_iswordp(char_u *p, win_T *wp) // Unlike spell_iswordp() this doesn't check for "midword" characters. bool spell_iswordp_nmw(const char_u *p, win_T *wp) { - int c; - - if (has_mbyte) { - c = mb_ptr2char(p); - if (c > 255) { - return spell_mb_isword_class(mb_get_class(p), wp); - } - return spelltab.st_isw[c]; + int c = utf_ptr2char(p); + if (c > 255) { + return spell_mb_isword_class(mb_get_class(p), wp); } - return spelltab.st_isw[*p]; + return spelltab.st_isw[c]; } // Returns true if word class indicates a word character. @@ -2677,7 +2684,7 @@ int spell_casefold(char_u *str, int len, char_u *buf, int buflen) return FAIL; } c = mb_cptr2char_adv((const char_u **)&p); - outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi); + outi += utf_char2bytes(SPELL_TOFOLD(c), buf + outi); } buf[outi] = NUL; } else { @@ -2936,7 +2943,7 @@ void spell_suggest(int count) memmove(p, line, c); STRCPY(p + c, stp->st_word); STRCAT(p, sug.su_badptr + stp->st_orglen); - ml_replace(curwin->w_cursor.lnum, p, FALSE); + ml_replace(curwin->w_cursor.lnum, p, false); curwin->w_cursor.col = c; // For redo we use a change-word command. @@ -2971,7 +2978,7 @@ static bool check_need_cap(linenr_T lnum, colnr_T col) line = get_cursor_line_ptr(); endcol = 0; - if ((int)(skipwhite(line) - line) >= (int)col) { + if (getwhitecols(line) >= (int)col) { // At start of line, check if previous line is empty or sentence // ends there. if (lnum == 1) @@ -3054,7 +3061,7 @@ void ex_spellrepall(exarg_T *eap) memmove(p, line, curwin->w_cursor.col); STRCPY(p + curwin->w_cursor.col, repl_to); STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from)); - ml_replace(curwin->w_cursor.lnum, p, FALSE); + ml_replace(curwin->w_cursor.lnum, p, false); changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); if (curwin->w_cursor.lnum != prev_lnum) { @@ -3426,12 +3433,7 @@ void onecap_copy(char_u *word, char_u *wcopy, bool upper) } else { c = SPELL_TOFOLD(c); } - if (has_mbyte) { - l = mb_char2bytes(c, wcopy); - } else { - l = 1; - wcopy[0] = c; - } + l = utf_char2bytes(c, wcopy); STRLCPY(wcopy + l, p, MAXWLEN - l); } @@ -3459,15 +3461,10 @@ static void allcap_copy(char_u *word, char_u *wcopy) } else c = SPELL_TOUPPER(c); - if (has_mbyte) { - if (d - wcopy >= MAXWLEN - MB_MAXBYTES) - break; - d += mb_char2bytes(c, d); - } else { - if (d - wcopy >= MAXWLEN - 1) - break; - *d++ = c; + if (d - wcopy >= MAXWLEN - MB_MAXBYTES) { + break; } + d += utf_char2bytes(c, d); } *d = NUL; } @@ -4207,7 +4204,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } PROF_STORE(sp->ts_state) sp->ts_state = STATE_PLAIN; - // FALLTHROUGH + FALLTHROUGH; case STATE_PLAIN: // Go over all possible bytes at this node, add each to tword[] @@ -4292,14 +4289,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so && utf_iscomposing(utf_ptr2char(fword + sp->ts_fcharstart))) { sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP; - } else if (!soundfold - && slang->sl_has_map - && similar_chars(slang, - mb_ptr2char(tword - + sp->ts_twordlen - - sp->ts_tcharlen), - mb_ptr2char(fword - + sp->ts_fcharstart))) { + } else if ( + !soundfold + && slang->sl_has_map + && similar_chars( + slang, + utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen), + utf_ptr2char(fword + sp->ts_fcharstart))) { // For a similar character adjust score from // SCORE_SUBST to SCORE_SIMILAR. sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR; @@ -4307,8 +4303,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } else if (sp->ts_isdiff == DIFF_INSERT && sp->ts_twordlen > sp->ts_tcharlen) { p = tword + sp->ts_twordlen - sp->ts_tcharlen; - c = mb_ptr2char(p); - if (enc_utf8 && utf_iscomposing(c)) { + c = utf_ptr2char(p); + if (utf_iscomposing(c)) { // Inserting a composing char doesn't // count that much. sp->ts_score -= SCORE_INS - SCORE_INSCOMP; @@ -4319,7 +4315,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // tree (might seem illogical but does // give better scores). MB_PTR_BACK(tword, p); - if (c == mb_ptr2char(p)) { + if (c == utf_ptr2char(p)) { sp->ts_score -= SCORE_INS - SCORE_INSDUP; } } @@ -4380,22 +4376,17 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // score if the same character is following "nn" -> "n". It's // a bit illogical for soundfold tree but it does give better // results. - if (has_mbyte) { - c = mb_ptr2char(fword + sp->ts_fidx); - stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx); - if (enc_utf8 && utf_iscomposing(c)) { - stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP; - } else if (c == mb_ptr2char(fword + stack[depth].ts_fidx)) { - stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP; - } - } else { - ++stack[depth].ts_fidx; - if (fword[sp->ts_fidx] == fword[sp->ts_fidx + 1]) - stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP; + c = utf_ptr2char(fword + sp->ts_fidx); + stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx); + if (utf_iscomposing(c)) { + stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP; + } else if (c == utf_ptr2char(fword + stack[depth].ts_fidx)) { + stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP; } + break; } - // FALLTHROUGH + FALLTHROUGH; case STATE_INS_PREP: if (sp->ts_flags & TSF_DIDDEL) { @@ -4425,7 +4416,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } break; - // FALLTHROUGH + FALLTHROUGH; case STATE_INS: // Insert one byte. Repeat this for each possible byte at this @@ -4507,22 +4498,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so break; } - if (has_mbyte) { - n = MB_CPTR2LEN(p); - c = mb_ptr2char(p); - if (p[n] == NUL) - c2 = NUL; - else if (!soundfold && !spell_iswordp(p + n, curwin)) - c2 = c; // don't swap non-word char - else - c2 = mb_ptr2char(p + n); + n = MB_CPTR2LEN(p); + c = utf_ptr2char(p); + if (p[n] == NUL) { + c2 = NUL; + } else if (!soundfold && !spell_iswordp(p + n, curwin)) { + c2 = c; // don't swap non-word char } else { - if (p[1] == NUL) - c2 = NUL; - else if (!soundfold && !spell_iswordp(p + 1, curwin)) - c2 = c; // don't swap non-word char - else - c2 = p[1]; + c2 = utf_ptr2char(p + n); } // When the second character is NUL we can't swap. @@ -4542,64 +4525,47 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (c2 != NUL && TRY_DEEPER(su, stack, depth, SCORE_SWAP)) { go_deeper(stack, depth, SCORE_SWAP); #ifdef DEBUG_TRIEWALK - sprintf(changename[depth], "%.*s-%s: swap %c and %c", - sp->ts_twordlen, tword, fword + sp->ts_fidx, - c, c2); + snprintf(changename[depth], sizeof(changename[0]), + "%.*s-%s: swap %c and %c", + sp->ts_twordlen, tword, fword + sp->ts_fidx, + c, c2); #endif PROF_STORE(sp->ts_state) sp->ts_state = STATE_UNSWAP; - ++depth; - if (has_mbyte) { - fl = mb_char2len(c2); - memmove(p, p + n, fl); - mb_char2bytes(c, p + fl); - stack[depth].ts_fidxtry = sp->ts_fidx + n + fl; - } else { - p[0] = c2; - p[1] = c; - stack[depth].ts_fidxtry = sp->ts_fidx + 2; - } - } else + depth++; + fl = mb_char2len(c2); + memmove(p, p + n, fl); + utf_char2bytes(c, p + fl); + stack[depth].ts_fidxtry = sp->ts_fidx + n + fl; + } else { // If this swap doesn't work then SWAP3 won't either. PROF_STORE(sp->ts_state) sp->ts_state = STATE_REP_INI; + } break; case STATE_UNSWAP: // Undo the STATE_SWAP swap: "21" -> "12". p = fword + sp->ts_fidx; - if (has_mbyte) { - n = MB_PTR2LEN(p); - c = mb_ptr2char(p + n); - memmove(p + MB_PTR2LEN(p + n), p, n); - mb_char2bytes(c, p); - } else { - c = *p; - *p = p[1]; - p[1] = c; - } - // FALLTHROUGH + n = MB_PTR2LEN(p); + c = utf_ptr2char(p + n); + memmove(p + MB_PTR2LEN(p + n), p, n); + utf_char2bytes(c, p); + + FALLTHROUGH; case STATE_SWAP3: // Swap two bytes, skipping one: "123" -> "321". We change // "fword" here, it's changed back afterwards at STATE_UNSWAP3. p = fword + sp->ts_fidx; - if (has_mbyte) { - n = MB_CPTR2LEN(p); - c = mb_ptr2char(p); - fl = MB_CPTR2LEN(p + n); - c2 = mb_ptr2char(p + n); - if (!soundfold && !spell_iswordp(p + n + fl, curwin)) - c3 = c; // don't swap non-word char - else - c3 = mb_ptr2char(p + n + fl); + n = MB_CPTR2LEN(p); + c = utf_ptr2char(p); + fl = MB_CPTR2LEN(p + n); + c2 = utf_ptr2char(p + n); + if (!soundfold && !spell_iswordp(p + n + fl, curwin)) { + c3 = c; // don't swap non-word char } else { - c = *p; - c2 = p[1]; - if (!soundfold && !spell_iswordp(p + 2, curwin)) - c3 = c; // don't swap non-word char - else - c3 = p[2]; + c3 = utf_ptr2char(p + n + fl); } // When characters are identical: "121" then SWAP3 result is @@ -4622,18 +4588,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so #endif PROF_STORE(sp->ts_state) sp->ts_state = STATE_UNSWAP3; - ++depth; - if (has_mbyte) { - tl = mb_char2len(c3); - memmove(p, p + n + fl, tl); - mb_char2bytes(c2, p + tl); - mb_char2bytes(c, p + fl + tl); - stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl; - } else { - p[0] = p[2]; - p[2] = c; - stack[depth].ts_fidxtry = sp->ts_fidx + 3; - } + depth++; + tl = mb_char2len(c3); + memmove(p, p + n + fl, tl); + utf_char2bytes(c2, p + tl); + utf_char2bytes(c, p + fl + tl); + stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl; } else { PROF_STORE(sp->ts_state) sp->ts_state = STATE_REP_INI; @@ -4643,22 +4603,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNSWAP3: // Undo STATE_SWAP3: "321" -> "123" p = fword + sp->ts_fidx; - if (has_mbyte) { - n = MB_PTR2LEN(p); - c2 = mb_ptr2char(p + n); - fl = MB_PTR2LEN(p + n); - c = mb_ptr2char(p + n + fl); - tl = MB_PTR2LEN(p + n + fl); - memmove(p + fl + tl, p, n); - mb_char2bytes(c, p); - mb_char2bytes(c2, p + tl); - p = p + tl; - } else { - c = *p; - *p = p[2]; - p[2] = c; - ++p; - } + n = MB_PTR2LEN(p); + c2 = utf_ptr2char(p + n); + fl = MB_PTR2LEN(p + n); + c = utf_ptr2char(p + n + fl); + tl = MB_PTR2LEN(p + n + fl); + memmove(p + fl + tl, p, n); + utf_char2bytes(c, p); + utf_char2bytes(c2, p + tl); + p = p + tl; if (!soundfold && !spell_iswordp(p, curwin)) { // Middle char is not a word char, skip the rotate. First and @@ -4682,21 +4635,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp->ts_state = STATE_UNROT3L; ++depth; p = fword + sp->ts_fidx; - if (has_mbyte) { - n = MB_CPTR2LEN(p); - c = mb_ptr2char(p); - fl = MB_CPTR2LEN(p + n); - fl += MB_CPTR2LEN(p + n + fl); - memmove(p, p + n, fl); - mb_char2bytes(c, p + fl); - stack[depth].ts_fidxtry = sp->ts_fidx + n + fl; - } else { - c = *p; - *p = p[1]; - p[1] = p[2]; - p[2] = c; - stack[depth].ts_fidxtry = sp->ts_fidx + 3; - } + n = MB_CPTR2LEN(p); + c = utf_ptr2char(p); + fl = MB_CPTR2LEN(p + n); + fl += MB_CPTR2LEN(p + n + fl); + memmove(p, p + n, fl); + utf_char2bytes(c, p + fl); + stack[depth].ts_fidxtry = sp->ts_fidx + n + fl; } else { PROF_STORE(sp->ts_state) sp->ts_state = STATE_REP_INI; @@ -4706,19 +4651,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNROT3L: // Undo ROT3L: "231" -> "123" p = fword + sp->ts_fidx; - if (has_mbyte) { - n = MB_PTR2LEN(p); - n += MB_PTR2LEN(p + n); - c = mb_ptr2char(p + n); - tl = MB_PTR2LEN(p + n); - memmove(p + tl, p, n); - mb_char2bytes(c, p); - } else { - c = p[2]; - p[2] = p[1]; - p[1] = *p; - *p = c; - } + n = MB_PTR2LEN(p); + n += MB_PTR2LEN(p + n); + c = utf_ptr2char(p + n); + tl = MB_PTR2LEN(p + n); + memmove(p + tl, p, n); + utf_char2bytes(c, p); // Rotate three bytes right: "123" -> "312". We change "fword" // here, it's changed back afterwards at STATE_UNROT3R. @@ -4734,21 +4672,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp->ts_state = STATE_UNROT3R; ++depth; p = fword + sp->ts_fidx; - if (has_mbyte) { - n = MB_CPTR2LEN(p); - n += MB_CPTR2LEN(p + n); - c = mb_ptr2char(p + n); - tl = MB_CPTR2LEN(p + n); - memmove(p + tl, p, n); - mb_char2bytes(c, p); - stack[depth].ts_fidxtry = sp->ts_fidx + n + tl; - } else { - c = p[2]; - p[2] = p[1]; - p[1] = *p; - *p = c; - stack[depth].ts_fidxtry = sp->ts_fidx + 3; - } + n = MB_CPTR2LEN(p); + n += MB_CPTR2LEN(p + n); + c = utf_ptr2char(p + n); + tl = MB_CPTR2LEN(p + n); + memmove(p + tl, p, n); + utf_char2bytes(c, p); + stack[depth].ts_fidxtry = sp->ts_fidx + n + tl; } else { PROF_STORE(sp->ts_state) sp->ts_state = STATE_REP_INI; @@ -4758,20 +4688,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNROT3R: // Undo ROT3R: "312" -> "123" p = fword + sp->ts_fidx; - if (has_mbyte) { - c = mb_ptr2char(p); - tl = MB_PTR2LEN(p); - n = MB_PTR2LEN(p + tl); - n += MB_PTR2LEN(p + tl + n); - memmove(p, p + tl, n); - mb_char2bytes(c, p + n); - } else { - c = *p; - *p = p[1]; - p[1] = p[2]; - p[2] = c; - } - // FALLTHROUGH + c = utf_ptr2char(p); + tl = MB_PTR2LEN(p); + n = MB_PTR2LEN(p + tl); + n += MB_PTR2LEN(p + tl + n); + memmove(p, p + tl, n); + utf_char2bytes(c, p + n); + + FALLTHROUGH; case STATE_REP_INI: // Check if matching with REP items from the .aff file would work. @@ -4802,7 +4726,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so PROF_STORE(sp->ts_state) sp->ts_state = STATE_REP; - // FALLTHROUGH + FALLTHROUGH; case STATE_REP: // Try matching with REP items from the .aff file. For each match @@ -5594,27 +5518,31 @@ static bool similar_chars(slang_T *slang, int c1, int c2) hashitem_T *hi; if (c1 >= 256) { - buf[mb_char2bytes(c1, buf)] = 0; + buf[utf_char2bytes(c1, buf)] = 0; hi = hash_find(&slang->sl_map_hash, buf); - if (HASHITEM_EMPTY(hi)) + if (HASHITEM_EMPTY(hi)) { m1 = 0; - else - m1 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1); - } else + } else { + m1 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1); + } + } else { m1 = slang->sl_map_array[c1]; - if (m1 == 0) + } + if (m1 == 0) { return false; - + } if (c2 >= 256) { - buf[mb_char2bytes(c2, buf)] = 0; + buf[utf_char2bytes(c2, buf)] = 0; hi = hash_find(&slang->sl_map_hash, buf); - if (HASHITEM_EMPTY(hi)) + if (HASHITEM_EMPTY(hi)) { m2 = 0; - else - m2 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1); - } else + } else { + m2 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1); + } + } else { m2 = slang->sl_map_array[c2]; + } return m1 == m2; } @@ -5651,11 +5579,9 @@ add_suggestion ( break; MB_PTR_BACK(goodword, pgood); MB_PTR_BACK(su->su_badptr, pbad); - if (has_mbyte) { - if (mb_ptr2char(pgood) != mb_ptr2char(pbad)) - break; - } else if (*pgood != *pbad) + if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) { break; + } } if (badlen == 0 && goodlen == 0) @@ -5970,9 +5896,10 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res) } if (c != NUL && c != prevc) { - ri += mb_char2bytes(c, res + ri); - if (ri + MB_MAXBYTES > MAXWLEN) + ri += utf_char2bytes(c, res + ri); + if (ri + MB_MAXBYTES > MAXWLEN) { break; + } prevc = c; } } @@ -6492,10 +6419,11 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // Convert wide characters in "wres" to a multi-byte string in "res". l = 0; - for (n = 0; n < reslen; ++n) { - l += mb_char2bytes(wres[n], res + l); - if (l + MB_MAXBYTES > MAXWLEN) + for (n = 0; n < reslen; n++) { + l += utf_char2bytes(wres[n], res + l); + if (l + MB_MAXBYTES > MAXWLEN) { break; + } } res[l] = NUL; } @@ -7600,5 +7528,3 @@ int expand_spelling(linenr_T lnum, char_u *pat, char_u ***matchp) *matchp = ga.ga_data; return ga.ga_len; } - - diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h index ddd54c724e..e83b21b219 100644 --- a/src/nvim/spell_defs.h +++ b/src/nvim/spell_defs.h @@ -13,6 +13,9 @@ // Some places assume a word length fits in a // byte, thus it can't be above 255. +// Number of regions supported. +#define MAXREGIONS 8 + // Type used for indexes in the word tree need to be at least 4 bytes. If int // is 8 bytes we could use something smaller, but what? typedef int idx_T; @@ -124,7 +127,8 @@ struct slang_S { char_u *sl_info; // infotext string or NULL - char_u sl_regions[17]; // table with up to 8 region names plus NUL + char_u sl_regions[MAXREGIONS * 2 + 1]; + // table with up to 8 region names plus NUL char_u *sl_midword; // MIDWORD string or NULL diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 69fa95107e..8be8d24b9f 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -45,7 +45,8 @@ // website, etc) // // sectionID == SN_REGION: <regionname> ... -// <regionname> 2 bytes Up to 8 region names: ca, au, etc. Lower case. +// <regionname> 2 bytes Up to MAXREGIONS region names: ca, au, etc. +// Lower case. // First <regionname> is region 1. // // sectionID == SN_CHARFLAGS: <charflagslen> <charflags> @@ -460,7 +461,8 @@ typedef struct spellinfo_S { char_u *si_info; // info text chars or NULL int si_region_count; // number of regions supported (1 when there // are no regions) - char_u si_region_name[17]; // region names; used only if + char_u si_region_name[MAXREGIONS * 2 + 1]; + // region names; used only if // si_region_count > 1) garray_T si_rep; // list of fromto_T entries from REP lines @@ -878,9 +880,10 @@ void suggest_load_files(void) // don't try again and again. slang->sl_sugloaded = true; - dotp = vim_strrchr(slang->sl_fname, '.'); - if (dotp == NULL || fnamecmp(dotp, ".spl") != 0) + dotp = STRRCHR(slang->sl_fname, '.'); + if (dotp == NULL || fnamecmp(dotp, ".spl") != 0) { continue; + } STRCPY(dotp, ".sug"); fd = mch_fopen((char *)slang->sl_fname, "r"); if (fd == NULL) @@ -1003,7 +1006,7 @@ static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp) // Return SP_*ERROR flags. static int read_region_section(FILE *fd, slang_T *lp, int len) { - if (len > 16) { + if (len > MAXREGIONS * 2) { return SP_FORMERROR; } SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd, ;); @@ -1199,7 +1202,6 @@ static int read_sal_section(FILE *fd, slang_T *slang) SPELL_READ_NONNUL_BYTES( // <salfrom> (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead)); p += (ccnt - i); - i = ccnt; } *p++ = NUL; @@ -1455,12 +1457,10 @@ static int read_compound(FILE *fd, slang_T *slang, int len) *pp++ = '|'; atstart = 1; } else { // normal char, "[abc]" and '*' are copied as-is - if (c == '?' || c == '+' || c == '~') + if (c == '?' || c == '+' || c == '~') { *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+" - if (enc_utf8) - pp += mb_char2bytes(c, pp); - else - *pp++ = c; + } + pp += utf_char2bytes(c, pp); } } @@ -1786,7 +1786,7 @@ spell_reload_one ( bool didit = false; for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(fname, slang->sl_fname, FALSE) == kEqualFiles) { + if (path_full_compare(fname, slang->sl_fname, false) == kEqualFiles) { slang_clear(slang); if (spell_load_file(fname, NULL, slang, false) == NULL) // reloading failed, clear the language @@ -1990,7 +1990,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname) return NULL; } - vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s ..."), fname); + vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s..."), fname); spell_message(spin, IObuff); // Only do REP lines when not done in another .aff file already. @@ -3029,7 +3029,7 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) hash_init(&ht); vim_snprintf((char *)IObuff, IOSIZE, - _("Reading dictionary file %s ..."), fname); + _("Reading dictionary file %s..."), fname); spell_message(spin, IObuff); // start with a message for the first line @@ -3096,8 +3096,8 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) if (spin->si_verbose && spin->si_msg_count > 10000) { spin->si_msg_count = 0; vim_snprintf((char *)message, sizeof(message), - _("line %6d, word %6d - %s"), - lnum, spin->si_foldwcount + spin->si_keepwcount, w); + _("line %6d, word %6ld - %s"), + lnum, spin->si_foldwcount + spin->si_keepwcount, w); msg_start(); msg_puts_long_attr(message, 0); msg_clr_eos(); @@ -3545,7 +3545,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) return FAIL; } - vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s ..."), fname); + vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s..."), fname); spell_message(spin, IObuff); // Read all the lines in the file one by one. @@ -3570,7 +3570,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) if (spin->si_conv.vc_type != CONV_NONE) { pc = string_convert(&spin->si_conv, rline, NULL); if (pc == NULL) { - smsg(_("Conversion failure for word in %s line %d: %s"), + smsg(_("Conversion failure for word in %s line %ld: %s"), fname, lnum, rline); continue; } @@ -3583,13 +3583,13 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) if (*line == '/') { ++line; if (STRNCMP(line, "encoding=", 9) == 0) { - if (spin->si_conv.vc_type != CONV_NONE) - smsg(_("Duplicate /encoding= line ignored in %s line %d: %s"), + if (spin->si_conv.vc_type != CONV_NONE) { + smsg(_("Duplicate /encoding= line ignored in %s line %ld: %s"), fname, lnum, line - 1); - else if (did_word) - smsg(_("/encoding= line after word ignored in %s line %d: %s"), + } else if (did_word) { + smsg(_("/encoding= line after word ignored in %s line %ld: %s"), fname, lnum, line - 1); - else { + } else { char_u *enc; // Setup for conversion to 'encoding'. @@ -3607,15 +3607,15 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) } if (STRNCMP(line, "regions=", 8) == 0) { - if (spin->si_region_count > 1) - smsg(_("Duplicate /regions= line ignored in %s line %d: %s"), + if (spin->si_region_count > 1) { + smsg(_("Duplicate /regions= line ignored in %s line %ld: %s"), fname, lnum, line); - else { + } else { line += 8; - if (STRLEN(line) > 16) - smsg(_("Too many regions in %s line %d: %s"), + if (STRLEN(line) > MAXREGIONS * 2) { + smsg(_("Too many regions in %s line %ld: %s"), fname, lnum, line); - else { + } else { spin->si_region_count = (int)STRLEN(line) / 2; STRCPY(spin->si_region_name, line); @@ -3626,7 +3626,7 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) continue; } - smsg(_("/ line ignored in %s line %d: %s"), + smsg(_("/ line ignored in %s line %ld: %s"), fname, lnum, line - 1); continue; } @@ -3652,13 +3652,13 @@ static int spell_read_wordfile(spellinfo_T *spin, char_u *fname) l = *p - '0'; if (l == 0 || l > spin->si_region_count) { - smsg(_("Invalid region nr in %s line %d: %s"), + smsg(_("Invalid region nr in %s line %ld: %s"), fname, lnum, p); break; } regionmask |= 1 << (l - 1); } else { - smsg(_("Unrecognized flags in %s line %d: %s"), + smsg(_("Unrecognized flags in %s line %ld: %s"), fname, lnum, p); break; } @@ -4242,11 +4242,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // Form the <folchars> string first, we need to know its length. size_t l = 0; - for (size_t i = 128; i < 256; ++i) { - if (has_mbyte) - l += (size_t)mb_char2bytes(spelltab.st_fold[i], folchars + l); - else - folchars[l++] = spelltab.st_fold[i]; + for (size_t i = 128; i < 256; i++) { + l += (size_t)utf_char2bytes(spelltab.st_fold[i], folchars + l); } put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen> @@ -4714,9 +4711,11 @@ static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname) // pointer-linked version of the trie. And it avoids having two versions // of the code for the soundfolding stuff. // It might have been done already by spell_reload_one(). - for (slang = first_lang; slang != NULL; slang = slang->sl_next) - if (path_full_compare(wfname, slang->sl_fname, FALSE) == kEqualFiles) + for (slang = first_lang; slang != NULL; slang = slang->sl_next) { + if (path_full_compare(wfname, slang->sl_fname, false) == kEqualFiles) { break; + } + } if (slang == NULL) { spell_message(spin, (char_u *)_("Reading back spell file...")); slang = spell_load_file(wfname, NULL, NULL, false); @@ -4993,7 +4992,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname) } vim_snprintf((char *)IObuff, IOSIZE, - _("Writing suggestion file %s ..."), fname); + _("Writing suggestion file %s..."), fname); spell_message(spin, IObuff); // <SUGHEADER>: <fileID> <versionnr> <timestamp> @@ -5075,7 +5074,7 @@ mkspell ( char_u *wfname; char_u **innames; int incount; - afffile_T *(afile[8]); + afffile_T *(afile[MAXREGIONS]); int i; int len; bool error = false; @@ -5132,13 +5131,13 @@ mkspell ( spin.si_add = true; } - if (incount <= 0) + if (incount <= 0) { EMSG(_(e_invarg)); // need at least output and input names - else if (vim_strchr(path_tail(wfname), '_') != NULL) + } else if (vim_strchr(path_tail(wfname), '_') != NULL) { EMSG(_("E751: Output file name must not have region name")); - else if (incount > 8) - EMSG(_("E754: Only up to 8 regions supported")); - else { + } else if (incount > MAXREGIONS) { + emsgf(_("E754: Only up to %d regions supported"), MAXREGIONS); + } else { // Check for overwriting before doing things that may take a lot of // time. if (!over_write && os_path_exists(wfname)) { @@ -5229,7 +5228,7 @@ mkspell ( if (!error && !got_int) { // Write the info in the spell file. vim_snprintf((char *)IObuff, IOSIZE, - _("Writing spell file %s ..."), wfname); + _("Writing spell file %s..."), wfname); spell_message(&spin, IObuff); error = write_vim_spell(&spin, wfname) == FAIL; @@ -5706,9 +5705,9 @@ static void set_map_str(slang_T *lp, char_u *map) hashitem_T *hi; b = xmalloc(cl + headcl + 2); - mb_char2bytes(c, b); + utf_char2bytes(c, b); b[cl] = NUL; - mb_char2bytes(headc, b + cl + 1); + utf_char2bytes(headc, b + cl + 1); b[cl + 1 + headcl] = NUL; hash = hash_hash(b); hi = hash_lookup(&lp->sl_map_hash, (const char *)b, STRLEN(b), hash); diff --git a/src/nvim/state.c b/src/nvim/state.c index a4b394c9e4..d75f4038ae 100644 --- a/src/nvim/state.c +++ b/src/nvim/state.c @@ -64,6 +64,12 @@ getkey: may_sync_undo(); } +#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL + char *keyname = key == K_EVENT + ? "K_EVENT" : (char *)get_special_key_name(key, mod_mask); + DLOG("input: %s", keyname); +#endif + int execute_result = s->execute(s, key); if (!execute_result) { break; @@ -73,13 +79,13 @@ getkey: } } -/// Return TRUE if in the current mode we need to use virtual. -int virtual_active(void) +/// Return true if in the current mode we need to use virtual. +bool virtual_active(void) { // While an operator is being executed we return "virtual_op", because // VIsual_active has already been reset, thus we can't check for "block" // being used. - if (virtual_op != MAYBE) { + if (virtual_op != kNone) { return virtual_op; } return ve_flags == VE_ALL diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 3f31914c03..3b0a950ff2 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -344,14 +344,17 @@ char *strcase_save(const char *const orig, bool upper) char *p = res; while (*p != NUL) { - int l; - int c = utf_ptr2char((const char_u *)p); + int l = utf_ptr2len((const char_u *)p); + if (c == 0) { + // overlong sequence, use only the first byte + c = *p; + l = 1; + } int uc = upper ? mb_toupper(c) : mb_tolower(c); // Reallocate string when byte count changes. This is rare, // thus it's OK to do another malloc()/free(). - l = utf_ptr2len((const char_u *)p); int newl = utf_char2len(uc); if (newl != l) { // TODO(philix): use xrealloc() in strup_save() @@ -456,25 +459,6 @@ char_u *vim_strchr(const char_u *const string, const int c) } /* - * Search for last occurrence of "c" in "string". - * Return NULL if not found. - * Does not handle multi-byte char for "c"! - */ -char_u *vim_strrchr(const char_u *string, int c) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE -{ - const char_u *retval = NULL; - const char_u *p = string; - - while (*p) { - if (*p == c) - retval = p; - MB_PTR_ADV(p); - } - return (char_u *) retval; -} - -/* * Sort an array of strings. */ @@ -709,6 +693,7 @@ static float_T tv_float(typval_T *const tvs, int *const idxp) /// /// @see vim_vsnprintf(). int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...) + FUNC_ATTR_PRINTF(3, 4) { const size_t len = strlen(str); size_t space; @@ -734,6 +719,7 @@ int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...) /// @return Number of bytes excluding NUL byte that would be written to the /// string if str_m was greater or equal to the return value. int vim_snprintf(char *str, size_t str_m, const char *fmt, ...) + FUNC_ATTR_PRINTF(3, 4) { va_list ap; va_start(ap, fmt); @@ -1233,6 +1219,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, str_arg_l = 3; zero_padding = 0; } else { + // Regular float number format[0] = '%'; size_t l = 1; if (force_sign) { @@ -1257,7 +1244,6 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec); format[l + 1] = NUL; - // Regular float number str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f); assert(str_arg_l < sizeof(tmp)); diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 98e457db18..22eabc75c1 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -16,12 +16,14 @@ #include "nvim/ascii.h" #include "nvim/syntax.h" #include "nvim/charset.h" +#include "nvim/cursor_shape.h" #include "nvim/eval.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/hashtab.h" +#include "nvim/highlight.h" #include "nvim/indent_c.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -42,7 +44,6 @@ #include "nvim/ui.h" #include "nvim/os/os.h" #include "nvim/os/time.h" -#include "nvim/api/private/helpers.h" #include "nvim/buffer.h" static bool did_syntax_onoff = false; @@ -53,7 +54,7 @@ static bool did_syntax_onoff = false; struct hl_group { char_u *sg_name; ///< highlight group name char_u *sg_name_u; ///< uppercase of sg_name - int sg_cleared; ///< "hi clear" was used + bool sg_cleared; ///< "hi clear" was used int sg_attr; ///< Screen attr @see ATTR_ENTRY int sg_link; ///< link to this highlight group ID int sg_set; ///< combination of flags in \ref SG_SET @@ -62,7 +63,7 @@ struct hl_group { int sg_cterm; ///< "cterm=" highlighting attr int sg_cterm_fg; ///< terminal fg color number + 1 int sg_cterm_bg; ///< terminal bg color number + 1 - int sg_cterm_bold; ///< bold attr was set for light color + bool sg_cterm_bold; ///< bold attr was set for light color // for RGB UIs int sg_gui; ///< "gui=" highlighting attributes ///< (combination of \ref HlAttrFlags) @@ -115,42 +116,42 @@ static int hl_attr_table[] = {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, 0}; -/* - * The patterns that are being searched for are stored in a syn_pattern. - * A match item consists of one pattern. - * A start/end item consists of n start patterns and m end patterns. - * A start/skip/end item consists of n start patterns, one skip pattern and m - * end patterns. - * For the latter two, the patterns are always consecutive: start-skip-end. - * - * A character offset can be given for the matched text (_m_start and _m_end) - * and for the actually highlighted text (_h_start and _h_end). - */ +// The patterns that are being searched for are stored in a syn_pattern. +// A match item consists of one pattern. +// A start/end item consists of n start patterns and m end patterns. +// A start/skip/end item consists of n start patterns, one skip pattern and m +// end patterns. +// For the latter two, the patterns are always consecutive: start-skip-end. +// +// A character offset can be given for the matched text (_m_start and _m_end) +// and for the actually highlighted text (_h_start and _h_end). +// +// Note that ordering of members is optimized to reduce padding. typedef struct syn_pattern { - char sp_type; /* see SPTYPE_ defines below */ - char sp_syncing; /* this item used for syncing */ - int sp_flags; /* see HL_ defines below */ - int sp_cchar; /* conceal substitute character */ - struct sp_syn sp_syn; /* struct passed to in_id_list() */ - short sp_syn_match_id; /* highlight group ID of pattern */ - char_u *sp_pattern; /* regexp to match, pattern */ - regprog_T *sp_prog; /* regexp to match, program */ + char sp_type; // see SPTYPE_ defines below + bool sp_syncing; // this item used for syncing + int16_t sp_syn_match_id; // highlight group ID of pattern + int16_t sp_off_flags; // see below + int sp_offsets[SPO_COUNT]; // offsets + int sp_flags; // see HL_ defines below + int sp_cchar; // conceal substitute character + int sp_ic; // ignore-case flag for sp_prog + int sp_sync_idx; // sync item index (syncing only) + int sp_line_id; // ID of last line where tried + int sp_startcol; // next match in sp_line_id line + int16_t *sp_cont_list; // cont. group IDs, if non-zero + int16_t *sp_next_list; // next group IDs, if non-zero + struct sp_syn sp_syn; // struct passed to in_id_list() + char_u *sp_pattern; // regexp to match, pattern + regprog_T *sp_prog; // regexp to match, program syn_time_T sp_time; - int sp_ic; /* ignore-case flag for sp_prog */ - short sp_off_flags; /* see below */ - int sp_offsets[SPO_COUNT]; /* offsets */ - short *sp_cont_list; /* cont. group IDs, if non-zero */ - short *sp_next_list; /* next group IDs, if non-zero */ - int sp_sync_idx; /* sync item index (syncing only) */ - int sp_line_id; /* ID of last line where tried */ - int sp_startcol; /* next match in sp_line_id line */ } synpat_T; typedef struct syn_cluster_S { - char_u *scl_name; /* syntax cluster name */ - char_u *scl_name_u; /* uppercase of scl_name */ - short *scl_list; /* IDs in this syntax cluster */ + char_u *scl_name; // syntax cluster name + char_u *scl_name_u; // uppercase of scl_name + int16_t *scl_list; // IDs in this syntax cluster } syn_cluster_T; /* @@ -159,27 +160,27 @@ typedef struct syn_cluster_S { * (The end positions have the column number of the next char) */ typedef struct state_item { - int si_idx; /* index of syntax pattern or - KEYWORD_IDX */ - int si_id; /* highlight group ID for keywords */ - int si_trans_id; /* idem, transparency removed */ - int si_m_lnum; /* lnum of the match */ - int si_m_startcol; /* starting column of the match */ - lpos_T si_m_endpos; /* just after end posn of the match */ - lpos_T si_h_startpos; /* start position of the highlighting */ - lpos_T si_h_endpos; /* end position of the highlighting */ - lpos_T si_eoe_pos; /* end position of end pattern */ - int si_end_idx; /* group ID for end pattern or zero */ - int si_ends; /* if match ends before si_m_endpos */ - int si_attr; /* attributes in this state */ - long si_flags; /* HL_HAS_EOL flag in this state, and - * HL_SKIP* for si_next_list */ - int si_seqnr; /* sequence number */ - int si_cchar; /* substitution character for conceal */ - short *si_cont_list; /* list of contained groups */ - short *si_next_list; /* nextgroup IDs after this item ends */ - reg_extmatch_T *si_extmatch; /* \z(...\) matches from start - * pattern */ + int si_idx; // index of syntax pattern or + // KEYWORD_IDX + int si_id; // highlight group ID for keywords + int si_trans_id; // idem, transparency removed + int si_m_lnum; // lnum of the match + int si_m_startcol; // starting column of the match + lpos_T si_m_endpos; // just after end posn of the match + lpos_T si_h_startpos; // start position of the highlighting + lpos_T si_h_endpos; // end position of the highlighting + lpos_T si_eoe_pos; // end position of end pattern + int si_end_idx; // group ID for end pattern or zero + int si_ends; // if match ends before si_m_endpos + int si_attr; // attributes in this state + long si_flags; // HL_HAS_EOL flag in this state, and + // HL_SKIP* for si_next_list + int si_seqnr; // sequence number + int si_cchar; // substitution character for conceal + int16_t *si_cont_list; // list of contained groups + int16_t *si_next_list; // nextgroup IDs after this item ends + reg_extmatch_T *si_extmatch; // \z(...\) matches from start + // pattern } stateitem_T; /* @@ -187,14 +188,14 @@ typedef struct state_item { * very often. */ typedef struct { - int flags; /* flags for contained and transparent */ - int keyword; /* TRUE for ":syn keyword" */ - int *sync_idx; /* syntax item for "grouphere" argument, NULL - if not allowed */ - char has_cont_list; /* TRUE if "cont_list" can be used */ - short *cont_list; /* group IDs for "contains" argument */ - short *cont_in_list; /* group IDs for "containedin" argument */ - short *next_list; /* group IDs for "nextgroup" argument */ + int flags; // flags for contained and transparent + bool keyword; // true for ":syn keyword" + int *sync_idx; // syntax item for "grouphere" argument, NULL + // if not allowed + bool has_cont_list; // true if "cont_list" can be used + int16_t *cont_list; // group IDs for "contains" argument + int16_t *cont_in_list; // group IDs for "containedin" argument + int16_t *next_list; // group IDs for "nextgroup" argument } syn_opt_arg_T; typedef struct { @@ -216,12 +217,6 @@ struct name_list { # include "syntax.c.generated.h" #endif -/* - * An attribute number is the index in attr_table plus ATTR_OFF. - */ -#define ATTR_OFF 1 - - static char *(spo_name_tab[SPO_COUNT]) = {"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="}; @@ -324,9 +319,10 @@ static int keepend_level = -1; static char msg_no_items[] = N_("No Syntax items defined for this buffer"); -#define KEYWORD_IDX -1 /* value of si_idx for keywords */ -#define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all - but contained groups */ +// value of si_idx for keywords +#define KEYWORD_IDX -1 +// valid of si_cont_list for containing all but contained groups +#define ID_LIST_ALL (int16_t *)-1 static int next_seqnr = 1; /* value to use for si_seqnr */ @@ -369,9 +365,9 @@ static int current_state_stored = 0; /* TRUE if stored current state static int current_finished = 0; /* current line has been finished */ static garray_T current_state /* current stack of state_items */ = GA_EMPTY_INIT_VALUE; -static short *current_next_list = NULL; /* when non-zero, nextgroup list */ -static int current_next_flags = 0; /* flags for current_next_list */ -static int current_line_id = 0; /* unique number for current line */ +static int16_t *current_next_list = NULL; // when non-zero, nextgroup list +static int current_next_flags = 0; // flags for current_next_list +static int current_line_id = 0; // unique number for current line #define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx] @@ -1531,32 +1527,26 @@ int syntax_check_changed(linenr_T lnum) */ static bool syn_finish_line( - bool syncing // called for syncing + const bool syncing // called for syncing ) { - stateitem_T *cur_si; - colnr_T prev_current_col; - while (!current_finished) { - (void)syn_current_attr(syncing, FALSE, NULL, FALSE); - /* - * When syncing, and found some item, need to check the item. - */ + (void)syn_current_attr(syncing, false, NULL, false); + + // When syncing, and found some item, need to check the item. if (syncing && current_state.ga_len) { - /* - * Check for match with sync item. - */ - cur_si = &CUR_STATE(current_state.ga_len - 1); + // Check for match with sync item. + const stateitem_T *const cur_si = &CUR_STATE(current_state.ga_len - 1); if (cur_si->si_idx >= 0 && (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE))) { return true; } - /* syn_current_attr() will have skipped the check for an item - * that ends here, need to do that now. Be careful not to go - * past the NUL. */ - prev_current_col = current_col; + // syn_current_attr() will have skipped the check for an item + // that ends here, need to do that now. Be careful not to go + // past the NUL. + const colnr_T prev_current_col = current_col; if (syn_getcurline()[current_col] != NUL) { current_col++; } @@ -1579,9 +1569,9 @@ syn_finish_line( */ int get_syntax_attr( - colnr_T col, - bool *can_spell, - int keep_state /* keep state of char at "col" */ + const colnr_T col, + bool *const can_spell, + const bool keep_state // keep state of char at "col" ) { int attr = 0; @@ -1615,9 +1605,9 @@ get_syntax_attr( * Skip from the current column to "col", get the attributes for "col". */ while (current_col <= col) { - attr = syn_current_attr(FALSE, TRUE, can_spell, - current_col == col ? keep_state : FALSE); - ++current_col; + attr = syn_current_attr(false, true, can_spell, + current_col == col ? keep_state : false); + current_col++; } return attr; @@ -1626,42 +1616,37 @@ get_syntax_attr( /* * Get syntax attributes for current_lnum, current_col. */ -static int -syn_current_attr( - int syncing, // When 1: called for syncing - int displaying, // result will be displayed - bool *can_spell, // return: do spell checking - int keep_state // keep syntax stack afterwards +static int syn_current_attr( + const bool syncing, // When true: called for syncing + const bool displaying, // result will be displayed + bool *const can_spell, // return: do spell checking + const bool keep_state // keep syntax stack afterwards ) { - int syn_id; - lpos_T endpos; /* was: char_u *endp; */ - lpos_T hl_startpos; /* was: int hl_startcol; */ + lpos_T endpos; // was: char_u *endp; + lpos_T hl_startpos; // was: int hl_startcol; lpos_T hl_endpos; - lpos_T eos_pos; /* end-of-start match (start region) */ - lpos_T eoe_pos; /* end-of-end pattern */ - int end_idx; /* group ID for end pattern */ - synpat_T *spp; + lpos_T eos_pos; // end-of-start match (start region) + lpos_T eoe_pos; // end-of-end pattern + int end_idx; // group ID for end pattern stateitem_T *cur_si, *sip = NULL; int startcol; int endcol; long flags; int cchar; - short *next_list; - int found_match; /* found usable match */ - static int try_next_column = FALSE; /* must try in next col */ - int do_keywords; + int16_t *next_list; + bool found_match; // found usable match + static bool try_next_column = false; // must try in next col regmmatch_T regmatch; lpos_T pos; - int lc_col; reg_extmatch_T *cur_extmatch = NULL; char_u buf_chartab[32]; // chartab array for syn iskeyword char_u *line; // current line. NOTE: becomes invalid after // looking for a pattern match! - /* variables for zero-width matches that have a "nextgroup" argument */ - int keep_next_list; - int zero_width_next_list = FALSE; + // variables for zero-width matches that have a "nextgroup" argument + bool keep_next_list; + bool zero_width_next_list = false; garray_T zero_width_next_ga; /* @@ -1696,13 +1681,13 @@ syn_current_attr( */ if (try_next_column) { next_match_idx = -1; - try_next_column = FALSE; + try_next_column = false; } - /* Only check for keywords when not syncing and there are some. */ - do_keywords = !syncing - && (syn_block->b_keywtab.ht_used > 0 - || syn_block->b_keywtab_ic.ht_used > 0); + // Only check for keywords when not syncing and there are some. + const bool do_keywords = !syncing + && (syn_block->b_keywtab.ht_used > 0 + || syn_block->b_keywtab_ic.ht_used > 0); /* Init the list of zero-width matches with a nextlist. This is used to * avoid matching the same item in the same position twice. */ @@ -1717,9 +1702,9 @@ syn_current_attr( * column. */ do { - found_match = FALSE; - keep_next_list = FALSE; - syn_id = 0; + found_match = false; + keep_next_list = false; + int syn_id = 0; /* * 1. Check for a current state. @@ -1741,16 +1726,12 @@ syn_current_attr( */ if (do_keywords) { line = syn_getcurline(); - if (vim_iswordp_buf(line + current_col, syn_buf) - && (current_col == 0 - || !vim_iswordp_buf(line + current_col - 1 - - (has_mbyte - ? (*mb_head_off)(line, line + current_col - 1) - : 0) - , syn_buf))) { - syn_id = check_keyword_id(line, (int)current_col, - &endcol, &flags, &next_list, cur_si, - &cchar); + const char_u *cur_pos = line + current_col; + if (vim_iswordp_buf(cur_pos, syn_buf) + && (current_col == 0 || !vim_iswordp_buf( + cur_pos - 1 - utf_head_off(line, cur_pos - 1), syn_buf))) { + syn_id = check_keyword_id(line, (int)current_col, &endcol, &flags, + &next_list, cur_si, &cchar); if (syn_id != 0) { push_current_state(KEYWORD_IDX); { @@ -1812,7 +1793,7 @@ syn_current_attr( next_match_idx = 0; /* no match in this line yet */ next_match_col = MAXCOL; for (int idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) { - spp = &(SYN_ITEMS(syn_block)[idx]); + synpat_T *const spp = &(SYN_ITEMS(syn_block)[idx]); if ( spp->sp_syncing == syncing && (displaying || !(spp->sp_flags & HL_DISPLAY)) && (spp->sp_type == SPTYPE_MATCH @@ -1833,13 +1814,14 @@ syn_current_attr( continue; spp->sp_line_id = current_line_id; - lc_col = current_col - spp->sp_offsets[SPO_LC_OFF]; - if (lc_col < 0) + colnr_T lc_col = current_col - spp->sp_offsets[SPO_LC_OFF]; + if (lc_col < 0) { lc_col = 0; + } regmatch.rmm_ic = spp->sp_ic; regmatch.regprog = spp->sp_prog; - int r = syn_regexec(®match, current_lnum, (colnr_T)lc_col, + int r = syn_regexec(®match, current_lnum, lc_col, IF_SYN_TIME(&spp->sp_time)); spp->sp_prog = regmatch.regprog; if (!r) { @@ -1878,7 +1860,7 @@ syn_current_attr( * column, because it may match from there. */ if (did_match_already(idx, &zero_width_next_ga)) { - try_next_column = TRUE; + try_next_column = true; continue; } @@ -1940,9 +1922,9 @@ syn_current_attr( * If an empty string is matched, may need * to try matching again at next column. */ - if (regmatch.startpos[0].col - == regmatch.endpos[0].col) - try_next_column = TRUE; + if (regmatch.startpos[0].col == regmatch.endpos[0].col) { + try_next_column = true; + } continue; } } @@ -1987,8 +1969,8 @@ syn_current_attr( && lspp->sp_next_list != NULL) { current_next_list = lspp->sp_next_list; current_next_flags = lspp->sp_flags; - keep_next_list = TRUE; - zero_width_next_list = TRUE; + keep_next_list = true; + zero_width_next_list = true; /* Add the index to a list, so that we can check * later that we don't match it again (and cause an @@ -2031,8 +2013,9 @@ syn_current_attr( */ current_next_list = NULL; next_match_idx = -1; - if (!zero_width_next_list) - found_match = TRUE; + if (!zero_width_next_list) { + found_match = true; + } } } while (found_match); @@ -2937,39 +2920,35 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T * The caller must check if a keyword can start at startcol. * Return its ID if found, 0 otherwise. */ -static int -check_keyword_id( - char_u *line, - int startcol, /* position in line to check for keyword */ - int *endcolp, /* return: character after found keyword */ - long *flagsp, /* return: flags of matching keyword */ - short **next_listp, /* return: next_list of matching keyword */ - stateitem_T *cur_si, /* item at the top of the stack */ - int *ccharp /* conceal substitution char */ +static int check_keyword_id( + char_u *const line, + const int startcol, // position in line to check for keyword + int *const endcolp, // return: character after found keyword + long *const flagsp, // return: flags of matching keyword + int16_t **const next_listp, // return: next_list of matching keyword + stateitem_T *const cur_si, // item at the top of the stack + int *const ccharp // conceal substitution char ) { - char_u *kwp; - int kwlen; - char_u keyword[MAXKEYWLEN + 1]; /* assume max. keyword len is 80 */ - - /* Find first character after the keyword. First character was already - * checked. */ - kwp = line + startcol; - kwlen = 0; + // Find first character after the keyword. First character was already + // checked. + char_u *const kwp = line + startcol; + int kwlen = 0; do { - if (has_mbyte) + if (has_mbyte) { kwlen += (*mb_ptr2len)(kwp + kwlen); - else - ++kwlen; + } else { + kwlen++; + } } while (vim_iswordp_buf(kwp + kwlen, syn_buf)); - if (kwlen > MAXKEYWLEN) + if (kwlen > MAXKEYWLEN) { return 0; + } - /* - * Must make a copy of the keyword, so we can add a NUL and make it - * lowercase. - */ + // Must make a copy of the keyword, so we can add a NUL and make it + // lowercase. + char_u keyword[MAXKEYWLEN + 1]; // assume max. keyword len is 80 STRLCPY(keyword, kwp, kwlen + 1); keyentry_T *kp = NULL; @@ -3327,12 +3306,10 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) EMSG2(_("E391: No such syntax cluster: %s"), arg); break; } else { - /* - * We can't physically delete a cluster without changing - * the IDs of other clusters, so we do the next best thing - * and make it empty. - */ - short scl_id = id - SYNID_CLUSTER; + // We can't physically delete a cluster without changing + // the IDs of other clusters, so we do the next best thing + // and make it empty. + int scl_id = id - SYNID_CLUSTER; xfree(SYN_CLSTR(curwin->w_s)[scl_id].scl_list); SYN_CLSTR(curwin->w_s)[scl_id].scl_list = NULL; @@ -3355,7 +3332,7 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) /* * Clear one syntax group for the current buffer. */ -static void syn_clear_one(int id, int syncing) +static void syn_clear_one(const int id, const bool syncing) { synpat_T *spp; @@ -3425,9 +3402,9 @@ static void syn_cmd_off(exarg_T *eap, int syncing) static void syn_cmd_onoff(exarg_T *eap, char *name) FUNC_ATTR_NONNULL_ALL { - did_syntax_onoff = true; eap->nextcmd = check_nextcmd(eap->arg); if (!eap->skip) { + did_syntax_onoff = true; char buf[100]; memcpy(buf, "so ", 4); vim_snprintf(buf + 3, sizeof(buf) - 3, SYNTAX_FNAME, name); @@ -3497,8 +3474,8 @@ syn_cmd_list( /* * No argument: List all group IDs and all syntax clusters. */ - for (int id = 1; id <= highlight_ga.ga_len && !got_int; ++id) { - syn_list_one(id, syncing, FALSE); + for (int id = 1; id <= highlight_ga.ga_len && !got_int; id++) { + syn_list_one(id, syncing, false); } for (int id = 0; id < curwin->w_s->b_syn_clusters.ga_len && !got_int; ++id) { syn_list_cluster(id); @@ -3517,10 +3494,11 @@ syn_cmd_list( syn_list_cluster(id - SYNID_CLUSTER); } else { int id = syn_namen2id(arg, (int)(arg_end - arg)); - if (id == 0) + if (id == 0) { EMSG2(_(e_nogroup), arg); - else - syn_list_one(id, syncing, TRUE); + } else { + syn_list_one(id, syncing, true); + } } arg = skipwhite(arg_end); } @@ -3564,14 +3542,12 @@ static int last_matchgroup; */ static void syn_list_one( - int id, - int syncing, /* when TRUE: list syncing items */ - int link_only /* when TRUE; list link-only too */ + const int id, + const bool syncing, // when true: list syncing items + const bool link_only // when true; list link-only too ) { - int attr; - int did_header = FALSE; - synpat_T *spp; + bool did_header = false; static struct name_list namelist1[] = { {HL_DISPLAY, "display"}, @@ -3594,23 +3570,26 @@ syn_list_one( {0, NULL} }; - attr = HL_ATTR(HLF_D); // highlight like directories + const int attr = HL_ATTR(HLF_D); // highlight like directories - /* list the keywords for "id" */ + // list the keywords for "id" if (!syncing) { - did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, FALSE, attr); + did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, false, attr); did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab_ic, - did_header, attr); + did_header, attr); } - /* list the patterns for "id" */ - for (int idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; ++idx) { - spp = &(SYN_ITEMS(curwin->w_s)[idx]); - if (spp->sp_syn.id != id || spp->sp_syncing != syncing) + // list the patterns for "id" + for (int idx = 0; + idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; + idx++) { + const synpat_T *const spp = &(SYN_ITEMS(curwin->w_s)[idx]); + if (spp->sp_syn.id != id || spp->sp_syncing != syncing) { continue; + } (void)syn_list_header(did_header, 999, id); - did_header = TRUE; + did_header = true; last_matchgroup = 0; if (spp->sp_type == SPTYPE_MATCH) { put_pattern("match", ' ', spp, attr); @@ -3701,15 +3680,13 @@ static void syn_list_cluster(int id) } } -static void put_id_list(const char *name, - short *list, // NOLINT(runtime/int) - int attr) +static void put_id_list(const char *const name, + const int16_t *const list, + const int attr) { - short *p; - msg_puts_attr(name, attr); msg_putchar('='); - for (p = list; *p; ++p) { + for (const int16_t *p = list; *p; p++) { if (*p >= SYNID_ALLBUT && *p < SYNID_TOP) { if (p[1]) { msg_puts("ALLBUT"); @@ -3721,7 +3698,7 @@ static void put_id_list(const char *name, } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) { msg_puts("CONTAINED"); } else if (*p >= SYNID_CLUSTER) { - short scl_id = *p - SYNID_CLUSTER; + int scl_id = *p - SYNID_CLUSTER; msg_putchar('@'); msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name); @@ -3733,12 +3710,10 @@ static void put_id_list(const char *name, msg_putchar(' '); } -static void put_pattern(char *s, int c, synpat_T *spp, int attr) +static void put_pattern(const char *const s, const int c, + const synpat_T *const spp, const int attr) { - long n; - int mask; - int first; - static char *sepchars = "/+=-#@\"|'^&"; + static const char *const sepchars = "/+=-#@\"|'^&"; int i; /* May have to write "matchgroup=group" */ @@ -3767,10 +3742,10 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr) msg_outtrans(spp->sp_pattern); msg_putchar(sepchars[i]); - /* output any pattern options */ - first = TRUE; - for (i = 0; i < SPO_COUNT; ++i) { - mask = (1 << i); + // output any pattern options + bool first = true; + for (i = 0; i < SPO_COUNT; i++) { + const int mask = (1 << i); if (!(spp->sp_off_flags & (mask + (mask << SPO_COUNT)))) { continue; } @@ -3778,7 +3753,7 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr) msg_putchar(','); // Separate with commas. } msg_puts(spo_name_tab[i]); - n = spp->sp_offsets[i]; + const long n = spp->sp_offsets[i]; if (i != SPO_LC_OFF) { if (spp->sp_off_flags & mask) msg_putchar('s'); @@ -3787,47 +3762,40 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr) if (n > 0) msg_putchar('+'); } - if (n || i == SPO_LC_OFF) + if (n || i == SPO_LC_OFF) { msg_outnum(n); - first = FALSE; + } + first = false; } msg_putchar(' '); } -/* - * List or clear the keywords for one syntax group. - * Return TRUE if the header has been printed. - */ -static int -syn_list_keywords( - int id, - hashtab_T *ht, - int did_header, /* header has already been printed */ - int attr +// List or clear the keywords for one syntax group. +// Return true if the header has been printed. +static bool syn_list_keywords( + const int id, + const hashtab_T *const ht, + bool did_header, // header has already been printed + const int attr ) { int outlen; - hashitem_T *hi; - keyentry_T *kp; - int todo; int prev_contained = 0; - short *prev_next_list = NULL; - short *prev_cont_in_list = NULL; + const int16_t *prev_next_list = NULL; + const int16_t *prev_cont_in_list = NULL; int prev_skipnl = 0; int prev_skipwhite = 0; int prev_skipempty = 0; - /* - * Unfortunately, this list of keywords is not sorted on alphabet but on - * hash value... - */ - todo = (int)ht->ht_used; - for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) { + // Unfortunately, this list of keywords is not sorted on alphabet but on + // hash value... + size_t todo = ht->ht_used; + for (const hashitem_T *hi = ht->ht_array; todo > 0 && !got_int; hi++) { if (HASHITEM_EMPTY(hi)) { continue; } - --todo; - for (kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) { + todo--; + for (keyentry_T *kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) { if (kp->k_syn.id == id) { if (prev_contained != (kp->flags & HL_CONTAINED) || prev_skipnl != (kp->flags & HL_SKIPNL) @@ -3847,7 +3815,7 @@ syn_list_keywords( prev_skipwhite = 0; prev_skipempty = 0; } - did_header = TRUE; + did_header = true; if (prev_contained != (kp->flags & HL_CONTAINED)) { msg_puts_attr("contained", attr); msg_putchar(' '); @@ -3958,19 +3926,19 @@ static void clear_keywtab(hashtab_T *ht) /// @param flags flags for this keyword /// @param cont_in_list containedin for this keyword /// @param next_list nextgroup for this keyword -static void add_keyword(char_u *name, - int id, - int flags, - short *cont_in_list, - short *next_list, - int conceal_char) +static void add_keyword(char_u *const name, + const int id, + const int flags, + int16_t *const cont_in_list, + int16_t *const next_list, + const int conceal_char) { char_u name_folded[MAXKEYWLEN + 1]; - char_u *name_ic = (curwin->w_s->b_syn_ic) - ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded)) - : name; + const char_u *const name_ic = (curwin->w_s->b_syn_ic) + ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded)) + : name; - keyentry_T *kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic)); + keyentry_T *const kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic)); STRCPY(kp->keyword, name_ic); kp->k_syn.id = id; kp->k_syn.inc_tag = current_syn_inc_tag; @@ -3982,11 +3950,12 @@ static void add_keyword(char_u *name, } kp->next_list = copy_id_list(next_list); - hash_T hash = hash_hash(kp->keyword); - hashtab_T *ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic - : &curwin->w_s->b_keywtab; - hashitem_T *hi = hash_lookup(ht, (const char *)kp->keyword, - STRLEN(kp->keyword), hash); + const hash_T hash = hash_hash(kp->keyword); + hashtab_T *const ht = (curwin->w_s->b_syn_ic) + ? &curwin->w_s->b_keywtab_ic + : &curwin->w_s->b_keywtab; + hashitem_T *const hi = hash_lookup(ht, (const char *)kp->keyword, + STRLEN(kp->keyword), hash); // even though it looks like only the kp->keyword member is // being used here, vim uses some pointer trickery to get the orignal @@ -4129,13 +4098,9 @@ get_syn_options( return NULL; } } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') { - /* cchar=? */ - if (has_mbyte) { - *conceal_char = mb_ptr2char(arg + 6); - arg += mb_ptr2len(arg + 6) - 1; - } else { - *conceal_char = arg[6]; - } + // cchar=? + *conceal_char = utf_ptr2char(arg + 6); + arg += mb_ptr2len(arg + 6) - 1; if (!vim_isprintc_strict(*conceal_char)) { EMSG(_("E844: invalid cchar value")); return NULL; @@ -4197,8 +4162,8 @@ static void syn_incl_toplevel(int id, int *flagsp) return; *flagsp |= HL_CONTAINED; if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) { - /* We have to alloc this, because syn_combine_list() will free it. */ - short *grp_list = xmalloc(2 * sizeof(short)); + // We have to alloc this, because syn_combine_list() will free it. + int16_t *grp_list = xmalloc(2 * sizeof(*grp_list)); int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER; grp_list[0] = id; @@ -4413,9 +4378,9 @@ syn_cmd_match( /* Get options before the pattern */ syn_opt_arg.flags = 0; - syn_opt_arg.keyword = FALSE; + syn_opt_arg.keyword = false; syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL; - syn_opt_arg.has_cont_list = TRUE; + syn_opt_arg.has_cont_list = true; syn_opt_arg.cont_list = NULL; syn_opt_arg.cont_in_list = NULL; syn_opt_arg.next_list = NULL; @@ -4535,9 +4500,9 @@ syn_cmd_region( init_syn_patterns(); syn_opt_arg.flags = 0; - syn_opt_arg.keyword = FALSE; + syn_opt_arg.keyword = false; syn_opt_arg.sync_idx = NULL; - syn_opt_arg.has_cont_list = TRUE; + syn_opt_arg.has_cont_list = true; syn_opt_arg.cont_list = NULL; syn_opt_arg.cont_in_list = NULL; syn_opt_arg.next_list = NULL; @@ -4715,30 +4680,25 @@ syn_cmd_region( } } -/* - * A simple syntax group ID comparison function suitable for use in qsort() - */ -static int syn_compare_stub(const void *v1, const void *v2) +// A simple syntax group ID comparison function suitable for use in qsort() +static int syn_compare_stub(const void *const v1, const void *const v2) { - const short *s1 = v1; - const short *s2 = v2; + const int16_t *const s1 = v1; + const int16_t *const s2 = v2; return *s1 > *s2 ? 1 : *s1 < *s2 ? -1 : 0; } -/* - * Combines lists of syntax clusters. - * *clstr1 and *clstr2 must both be allocated memory; they will be consumed. - */ -static void syn_combine_list(short **clstr1, short **clstr2, int list_op) +// Combines lists of syntax clusters. +// *clstr1 and *clstr2 must both be allocated memory; they will be consumed. +static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, + const int list_op) { - int count1 = 0; - int count2 = 0; - short *g1; - short *g2; - short *clstr = NULL; - int count; - int round; + size_t count1 = 0; + size_t count2 = 0; + const int16_t *g1; + const int16_t *g2; + int16_t *clstr = NULL; /* * Handle degenerate cases. @@ -4755,27 +4715,25 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op) return; } - for (g1 = *clstr1; *g1; g1++) - ++count1; - for (g2 = *clstr2; *g2; g2++) - ++count2; + for (g1 = *clstr1; *g1; g1++) { + count1++; + } + for (g2 = *clstr2; *g2; g2++) { + count2++; + } - /* - * For speed purposes, sort both lists. - */ - qsort(*clstr1, (size_t)count1, sizeof(short), syn_compare_stub); - qsort(*clstr2, (size_t)count2, sizeof(short), syn_compare_stub); + // For speed purposes, sort both lists. + qsort(*clstr1, count1, sizeof(**clstr1), syn_compare_stub); + qsort(*clstr2, count2, sizeof(**clstr2), syn_compare_stub); - /* - * We proceed in two passes; in round 1, we count the elements to place - * in the new list, and in round 2, we allocate and populate the new - * list. For speed, we use a mergesort-like method, adding the smaller - * of the current elements in each list to the new list. - */ - for (round = 1; round <= 2; round++) { + // We proceed in two passes; in round 1, we count the elements to place + // in the new list, and in round 2, we allocate and populate the new + // list. For speed, we use a mergesort-like method, adding the smaller + // of the current elements in each list to the new list. + for (int round = 1; round <= 2; round++) { g1 = *clstr1; g2 = *clstr2; - count = 0; + int count = 0; /* * First, loop through the lists until one of them is empty. @@ -4827,7 +4785,7 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op) clstr = NULL; break; } - clstr = xmalloc((count + 1) * sizeof(short)); + clstr = xmalloc((count + 1) * sizeof(*clstr)); clstr[count] = 0; } } @@ -4932,9 +4890,7 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing) char_u *arg = eap->arg; char_u *group_name_end; char_u *rest; - int scl_id; - short *clstr_list; - int got_clstr = FALSE; + bool got_clstr = false; int opt_len; int list_op; @@ -4945,9 +4901,10 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing) rest = get_group_name(arg, &group_name_end); if (rest != NULL) { - scl_id = syn_check_cluster(arg, (int)(group_name_end - arg)); - if (scl_id == 0) + int scl_id = syn_check_cluster(arg, (int)(group_name_end - arg)); + if (scl_id == 0) { return; + } scl_id -= SYNID_CLUSTER; for (;; ) { @@ -4966,7 +4923,7 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing) } else break; - clstr_list = NULL; + int16_t *clstr_list = NULL; if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL) { EMSG2(_(e_invarg2), rest); break; @@ -5224,35 +5181,28 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) */ static int get_id_list( - char_u **arg, - int keylen, // length of keyword - int16_t **list, // where to store the resulting list, if not - // NULL, the list is silently skipped! - int skip + char_u **const arg, + const int keylen, // length of keyword + int16_t **const list, // where to store the resulting list, if not + // NULL, the list is silently skipped! + const bool skip ) { char_u *p = NULL; char_u *end; - int round; - int count; int total_count = 0; - short *retval = NULL; - char_u *name; + int16_t *retval = NULL; regmatch_T regmatch; int id; - int failed = FALSE; - - /* - * We parse the list twice: - * round == 1: count the number of items, allocate the array. - * round == 2: fill the array with the items. - * In round 1 new groups may be added, causing the number of items to - * grow when a regexp is used. In that case round 1 is done once again. - */ - for (round = 1; round <= 2; ++round) { - /* - * skip "contains" - */ + bool failed = false; + + // We parse the list twice: + // round == 1: count the number of items, allocate the array. + // round == 2: fill the array with the items. + // In round 1 new groups may be added, causing the number of items to + // grow when a regexp is used. In that case round 1 is done once again. + for (int round = 1; round <= 2; round++) { + // skip "contains" p = skipwhite(*arg + keylen); if (*p != '=') { EMSG2(_("E405: Missing equal sign: %s"), *arg); @@ -5264,14 +5214,12 @@ get_id_list( break; } - /* - * parse the arguments after "contains" - */ - count = 0; + // parse the arguments after "contains" + int count = 0; do { - for (end = p; *end && !ascii_iswhite(*end) && *end != ','; ++end) - ; - name = xmalloc((int)(end - p + 3)); /* leave room for "^$" */ + for (end = p; *end && !ascii_iswhite(*end) && *end != ','; end++) { + } + char_u *const name = xmalloc((int)(end - p + 3)); // leave room for "^$" STRLCPY(name + 1, p, end - p + 1); if ( STRCMP(name + 1, "ALLBUT") == 0 || STRCMP(name + 1, "ALL") == 0 @@ -5279,7 +5227,7 @@ get_id_list( || STRCMP(name + 1, "CONTAINED") == 0) { if (TOUPPER_ASC(**arg) != 'C') { EMSG2(_("E407: %s not allowed here"), name + 1); - failed = TRUE; + failed = true; xfree(name); break; } @@ -5315,7 +5263,7 @@ get_id_list( STRCAT(name, "$"); regmatch.regprog = vim_regcomp(name, RE_MAGIC); if (regmatch.regprog == NULL) { - failed = TRUE; + failed = true; xfree(name); break; } @@ -5346,7 +5294,7 @@ get_id_list( xfree(name); if (id == 0) { EMSG2(_("E409: Unknown group name: %s"), p); - failed = TRUE; + failed = true; break; } if (id > 0) { @@ -5369,8 +5317,8 @@ get_id_list( if (failed) break; if (round == 1) { - retval = xmalloc((count + 1) * sizeof(short)); - retval[count] = 0; /* zero means end of the list */ + retval = xmalloc((count + 1) * sizeof(*retval)); + retval[count] = 0; // zero means end of the list total_count = count; } } @@ -5392,20 +5340,18 @@ get_id_list( /* * Make a copy of an ID list. */ -static short *copy_id_list(short *list) +static int16_t *copy_id_list(const int16_t *const list) { - int len; - int count; - short *retval; - - if (list == NULL) + if (list == NULL) { return NULL; + } - for (count = 0; list[count]; ++count) - ; - len = (count + 1) * sizeof(short); - retval = xmalloc(len); - memmove(retval, list, (size_t)len); + int count; + for (count = 0; list[count]; count++) { + } + const size_t len = (count + 1) * sizeof(int16_t); + int16_t *const retval = xmalloc(len); + memmove(retval, list, len); return retval; } @@ -6380,17 +6326,101 @@ int load_colors(char_u *name) recursive = true; size_t buflen = STRLEN(name) + 12; buf = xmalloc(buflen); + apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf); snprintf((char *)buf, buflen, "colors/%s.vim", name); retval = source_runtime(buf, DIP_START + DIP_OPT); xfree(buf); apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); recursive = false; - ui_refresh(); return retval; } +static char *(color_names[28]) = { + "Black", "DarkBlue", "DarkGreen", "DarkCyan", + "DarkRed", "DarkMagenta", "Brown", "DarkYellow", + "Gray", "Grey", "LightGray", "LightGrey", + "DarkGray", "DarkGrey", + "Blue", "LightBlue", "Green", "LightGreen", + "Cyan", "LightCyan", "Red", "LightRed", "Magenta", + "LightMagenta", "Yellow", "LightYellow", "White", "NONE" }; + // indices: + // 0, 1, 2, 3, + // 4, 5, 6, 7, + // 8, 9, 10, 11, + // 12, 13, + // 14, 15, 16, 17, + // 18, 19, 20, 21, 22, + // 23, 24, 25, 26, 27 +static int color_numbers_16[28] = { 0, 1, 2, 3, + 4, 5, 6, 6, + 7, 7, 7, 7, + 8, 8, + 9, 9, 10, 10, + 11, 11, 12, 12, 13, + 13, 14, 14, 15, -1 }; +// for xterm with 88 colors... +static int color_numbers_88[28] = { 0, 4, 2, 6, + 1, 5, 32, 72, + 84, 84, 7, 7, + 82, 82, + 12, 43, 10, 61, + 14, 63, 9, 74, 13, + 75, 11, 78, 15, -1 }; +// for xterm with 256 colors... +static int color_numbers_256[28] = { 0, 4, 2, 6, + 1, 5, 130, 130, + 248, 248, 7, 7, + 242, 242, + 12, 81, 10, 121, + 14, 159, 9, 224, 13, + 225, 11, 229, 15, -1 }; +// for terminals with less than 16 colors... +static int color_numbers_8[28] = { 0, 4, 2, 6, + 1, 5, 3, 3, + 7, 7, 7, 7, + 0+8, 0+8, + 4+8, 4+8, 2+8, 2+8, + 6+8, 6+8, 1+8, 1+8, 5+8, + 5+8, 3+8, 3+8, 7+8, -1 }; + +// Lookup the "cterm" value to be used for color with index "idx" in +// color_names[]. +// "boldp" will be set to TRUE or FALSE for a foreground color when using 8 +// colors, otherwise it will be unchanged. +int lookup_color(const int idx, const bool foreground, TriState *const boldp) +{ + int color = color_numbers_16[idx]; + + // Use the _16 table to check if it's a valid color name. + if (color < 0) { + return -1; + } + + if (t_colors == 8) { + // t_Co is 8: use the 8 colors table + color = color_numbers_8[idx]; + if (foreground) { + // set/reset bold attribute to get light foreground + // colors (on some terminals, e.g. "linux") + if (color & 8) { + *boldp = kTrue; + } else { + *boldp = kFalse; + } + } + color &= 7; // truncate to 8 colors + } else if (t_colors == 16) { + color = color_numbers_8[idx]; + } else if (t_colors == 88) { + color = color_numbers_88[idx]; + } else if (t_colors >= 256) { + color = color_numbers_256[idx]; + } + return color; +} + /// Handle ":highlight" command /// @@ -6414,12 +6444,14 @@ void do_highlight(const char *line, const bool forceit, const bool init) int attr; int id; int idx; - int dodefault = FALSE; - int doclear = FALSE; - int dolink = FALSE; - int error = FALSE; + struct hl_group item_before; + bool dodefault = false; + bool doclear = false; + bool dolink = false; + bool error = false; int color; bool is_normal_group = false; // "Normal" group + bool did_highlight_changed = false; // If no argument, list current highlighting. if (ends_excmd((uint8_t)(*line))) { @@ -6502,19 +6534,22 @@ void do_highlight(const char *line, const bool forceit, const bool init) if (sourcing_name == NULL && !dodefault) { EMSG(_("E414: group has settings, highlight link ignored")); } - } else { - if (!init) + } else if (HL_TABLE()[from_id - 1].sg_link != to_id + || HL_TABLE()[from_id - 1].sg_scriptID != current_SID + || HL_TABLE()[from_id - 1].sg_cleared) { + if (!init) { HL_TABLE()[from_id - 1].sg_set |= SG_LINK; + } HL_TABLE()[from_id - 1].sg_link = to_id; HL_TABLE()[from_id - 1].sg_scriptID = current_SID; HL_TABLE()[from_id - 1].sg_cleared = false; redraw_all_later(SOME_VALID); + + // Only call highlight changed() once after multiple changes + need_highlight_changed = true; } } - // Only call highlight_changed() once, after sourcing a syntax file. - need_highlight_changed = true; - return; } @@ -6531,7 +6566,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } init_highlight(true, true); highlight_changed(); - redraw_later_clear(); + redraw_all_later(NOT_VALID); return; } name_end = (const char *)skiptowhite((const char_u *)line); @@ -6550,13 +6585,16 @@ void do_highlight(const char *line, const bool forceit, const bool init) return; } + // Make a copy so we can check if any attribute actually changed + item_before = HL_TABLE()[idx]; is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0); // Clear the highlighting for ":hi clear {group}" and ":hi clear". if (doclear || (forceit && init)) { highlight_clear(idx); - if (!doclear) + if (!doclear) { HL_TABLE()[idx].sg_set = 0; + } } char *key = NULL; @@ -6657,7 +6695,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) HL_TABLE()[idx].sg_set |= SG_CTERM; } HL_TABLE()[idx].sg_cterm = attr; - HL_TABLE()[idx].sg_cterm_bold = FALSE; + HL_TABLE()[idx].sg_cterm_bold = false; } } else if (*key == 'G') { if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { @@ -6679,7 +6717,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) * flag was set for a light color, reset it now */ if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) { HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; - HL_TABLE()[idx].sg_cterm_bold = FALSE; + HL_TABLE()[idx].sg_cterm_bold = false; } if (ascii_isdigit(*arg)) { @@ -6701,60 +6739,6 @@ void do_highlight(const char *line, const bool forceit, const bool init) break; } } else { - static const char *color_names[] = { - "Black", "DarkBlue", "DarkGreen", "DarkCyan", - "DarkRed", "DarkMagenta", "Brown", "DarkYellow", - "Gray", "Grey", - "LightGray", "LightGrey", "DarkGray", "DarkGrey", - "Blue", "LightBlue", "Green", "LightGreen", - "Cyan", "LightCyan", "Red", "LightRed", "Magenta", - "LightMagenta", "Yellow", "LightYellow", "White", - "NONE" - }; - static const int color_numbers_16[] = { - 0, 1, 2, 3, - 4, 5, 6, 6, - 7, 7, - 7, 7, 8, 8, - 9, 9, 10, 10, - 11, 11, 12, 12, 13, - 13, 14, 14, 15, - -1 - }; - // For xterm with 88 colors: - static int color_numbers_88[] = { - 0, 4, 2, 6, - 1, 5, 32, 72, - 84, 84, - 7, 7, 82, 82, - 12, 43, 10, 61, - 14, 63, 9, 74, 13, - 75, 11, 78, 15, - -1 - }; - // For xterm with 256 colors: - static int color_numbers_256[] = { - 0, 4, 2, 6, - 1, 5, 130, 130, - 248, 248, - 7, 7, 242, 242, - 12, 81, 10, 121, - 14, 159, 9, 224, 13, - 225, 11, 229, 15, - -1 - }; - // For terminals with less than 16 colors: - static int color_numbers_8[28] = { - 0, 4, 2, 6, - 1, 5, 3, 3, - 7, 7, - 7, 7, 0+8, 0+8, - 4+8, 4+8, 2+8, 2+8, - 6+8, 6+8, 1+8, 1+8, 5+8, - 5+8, 3+8, 3+8, 7+8, - -1 - }; - // Reduce calls to STRICMP a bit, it can be slow. off = TOUPPER_ASC(*arg); for (i = ARRAY_SIZE(color_names); --i >= 0; ) { @@ -6770,32 +6754,16 @@ void do_highlight(const char *line, const bool forceit, const bool init) break; } - // Use the _16 table to check if it's a valid color name. - color = color_numbers_16[i]; - if (color >= 0) { - if (t_colors == 8) { - // t_Co is 8: use the 8 colors table. - color = color_numbers_8[i]; - if (key[5] == 'F') { - /* set/reset bold attribute to get light foreground - * colors (on some terminals, e.g. "linux") */ - if (color & 8) { - HL_TABLE()[idx].sg_cterm |= HL_BOLD; - HL_TABLE()[idx].sg_cterm_bold = true; - } else { - HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; - } - } - color &= 7; // truncate to 8 colors - } else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) { - if (t_colors == 88) { - color = color_numbers_88[i]; - } else if (t_colors >= 256) { - color = color_numbers_256[i]; - } else { - color = color_numbers_8[i]; - } - } + TriState bold = kNone; + color = lookup_color(i, key[5] == 'F', &bold); + + // set/reset bold attribute to get light foreground + // colors (on some terminals, e.g. "linux") + if (bold == kTrue) { + HL_TABLE()[idx].sg_cterm |= HL_BOLD; + HL_TABLE()[idx].sg_cterm_bold = true; + } else if (bold == kFalse) { + HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; } } // Add one to the argument, to avoid zero. Zero is used for @@ -6804,14 +6772,12 @@ void do_highlight(const char *line, const bool forceit, const bool init) HL_TABLE()[idx].sg_cterm_fg = color + 1; if (is_normal_group) { cterm_normal_fg_color = color + 1; - must_redraw = CLEAR; } } else { HL_TABLE()[idx].sg_cterm_bg = color + 1; if (is_normal_group) { cterm_normal_bg_color = color + 1; if (!ui_rgb_attached()) { - must_redraw = CLEAR; if (color >= 0) { int dark = -1; @@ -6836,8 +6802,9 @@ void do_highlight(const char *line, const bool forceit, const bool init) } } else if (strcmp(key, "GUIFG") == 0) { if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { - if (!init) + if (!init) { HL_TABLE()[idx].sg_set |= SG_GUI; + } xfree(HL_TABLE()[idx].sg_rgb_fg_name); if (strcmp(arg, "NONE")) { @@ -6854,8 +6821,9 @@ void do_highlight(const char *line, const bool forceit, const bool init) } } else if (STRCMP(key, "GUIBG") == 0) { if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { - if (!init) + if (!init) { HL_TABLE()[idx].sg_set |= SG_GUI; + } xfree(HL_TABLE()[idx].sg_rgb_bg_name); if (STRCMP(arg, "NONE") != 0) { @@ -6872,8 +6840,9 @@ void do_highlight(const char *line, const bool forceit, const bool init) } } else if (strcmp(key, "GUISP") == 0) { if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { - if (!init) + if (!init) { HL_TABLE()[idx].sg_set |= SG_GUI; + } xfree(HL_TABLE()[idx].sg_rgb_sp_name); if (strcmp(arg, "NONE") != 0) { @@ -6915,19 +6884,33 @@ void do_highlight(const char *line, const bool forceit, const bool init) // Need to update all groups, because they might be using "bg" and/or // "fg", which have been changed now. highlight_attr_set_all(); - // If the normal group has changed, it is simpler to refresh every UI - ui_refresh(); + + if (!ui_is_external(kUILinegrid) && starting == 0) { + // Older UIs assume that we clear the screen after normal group is + // changed + ui_refresh(); + } else { + // TUI and newer UIs will repaint the screen themselves. NOT_VALID + // redraw below will still handle usages of guibg=fg etc. + ui_default_colors_set(); + } + did_highlight_changed = true; + redraw_all_later(NOT_VALID); } else { set_hl_attr(idx); } HL_TABLE()[idx].sg_scriptID = current_SID; - redraw_all_later(NOT_VALID); } xfree(key); xfree(arg); - // Only call highlight_changed() once, after sourcing a syntax file - need_highlight_changed = true; + // Only call highlight_changed() once, after a sequence of highlight + // commands, and only if an attribute actually changed + if (memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0 + && !did_highlight_changed) { + redraw_all_later(NOT_VALID); + need_highlight_changed = true; + } } #if defined(EXITFREE) @@ -6980,7 +6963,7 @@ static void highlight_clear(int idx) HL_TABLE()[idx].sg_attr = 0; HL_TABLE()[idx].sg_cterm = 0; - HL_TABLE()[idx].sg_cterm_bold = FALSE; + HL_TABLE()[idx].sg_cterm_bold = false; HL_TABLE()[idx].sg_cterm_fg = 0; HL_TABLE()[idx].sg_cterm_bg = 0; HL_TABLE()[idx].sg_gui = 0; @@ -7001,161 +6984,6 @@ static void highlight_clear(int idx) } -/// Table with the specifications for an attribute number. -/// Note that this table is used by ALL buffers. This is required because the -/// GUI can redraw at any time for any buffer. -static garray_T attr_table = GA_EMPTY_INIT_VALUE; - -static inline HlAttrs * ATTR_ENTRY(int idx) -{ - return &((HlAttrs *)attr_table.ga_data)[idx]; -} - - -/// Return the attr number for a set of colors and font. -/// Add a new entry to the term_attr_table, attr_table or gui_attr_table -/// if the combination is new. -/// @return 0 for error. -int get_attr_entry(HlAttrs *aep) -{ - garray_T *table = &attr_table; - HlAttrs *taep; - static int recursive = false; - - /* - * Init the table, in case it wasn't done yet. - */ - table->ga_itemsize = sizeof(HlAttrs); - ga_set_growsize(table, 7); - - // Try to find an entry with the same specifications. - for (int i = 0; i < table->ga_len; i++) { - taep = &(((HlAttrs *)table->ga_data)[i]); - if (aep->cterm_ae_attr == taep->cterm_ae_attr - && aep->cterm_fg_color == taep->cterm_fg_color - && aep->cterm_bg_color == taep->cterm_bg_color - && aep->rgb_ae_attr == taep->rgb_ae_attr - && aep->rgb_fg_color == taep->rgb_fg_color - && aep->rgb_bg_color == taep->rgb_bg_color - && aep->rgb_sp_color == taep->rgb_sp_color) { - return i + ATTR_OFF; - } - } - - if (table->ga_len + ATTR_OFF > MAX_TYPENR) { - /* - * Running out of attribute entries! remove all attributes, and - * compute new ones for all groups. - * When called recursively, we are really out of numbers. - */ - if (recursive) { - EMSG(_("E424: Too many different highlighting attributes in use")); - return 0; - } - recursive = TRUE; - - clear_hl_tables(); - - must_redraw = CLEAR; - - for (int i = 0; i < highlight_ga.ga_len; ++i) { - set_hl_attr(i); - } - - recursive = FALSE; - } - - - // This is a new combination of colors and font, add an entry. - taep = GA_APPEND_VIA_PTR(HlAttrs, table); - memset(taep, 0, sizeof(*taep)); - taep->cterm_ae_attr = aep->cterm_ae_attr; - taep->cterm_fg_color = aep->cterm_fg_color; - taep->cterm_bg_color = aep->cterm_bg_color; - taep->rgb_ae_attr = aep->rgb_ae_attr; - taep->rgb_fg_color = aep->rgb_fg_color; - taep->rgb_bg_color = aep->rgb_bg_color; - taep->rgb_sp_color = aep->rgb_sp_color; - - return table->ga_len - 1 + ATTR_OFF; -} - -// Clear all highlight tables. -void clear_hl_tables(void) -{ - ga_clear(&attr_table); -} - -// Combine special attributes (e.g., for spelling) with other attributes -// (e.g., for syntax highlighting). -// "prim_attr" overrules "char_attr". -// This creates a new group when required. -// Since we expect there to be few spelling mistakes we don't cache the -// result. -// Return the resulting attributes. -int hl_combine_attr(int char_attr, int prim_attr) -{ - HlAttrs *char_aep = NULL; - HlAttrs *spell_aep; - HlAttrs new_en = HLATTRS_INIT; - - if (char_attr == 0) { - return prim_attr; - } - - if (prim_attr == 0) { - return char_attr; - } - - // Find the entry for char_attr - char_aep = syn_cterm_attr2entry(char_attr); - - if (char_aep != NULL) { - // Copy all attributes from char_aep to the new entry - new_en = *char_aep; - } - - spell_aep = syn_cterm_attr2entry(prim_attr); - if (spell_aep != NULL) { - new_en.cterm_ae_attr |= spell_aep->cterm_ae_attr; - new_en.rgb_ae_attr |= spell_aep->rgb_ae_attr; - - if (spell_aep->cterm_fg_color > 0) { - new_en.cterm_fg_color = spell_aep->cterm_fg_color; - } - - if (spell_aep->cterm_bg_color > 0) { - new_en.cterm_bg_color = spell_aep->cterm_bg_color; - } - - if (spell_aep->rgb_fg_color >= 0) { - new_en.rgb_fg_color = spell_aep->rgb_fg_color; - } - - if (spell_aep->rgb_bg_color >= 0) { - new_en.rgb_bg_color = spell_aep->rgb_bg_color; - } - - if (spell_aep->rgb_sp_color >= 0) { - new_en.rgb_sp_color = spell_aep->rgb_sp_color; - } - } - return get_attr_entry(&new_en); -} - -/// \note this function does not apply exclusively to cterm attr contrary -/// to what its name implies -/// \warn don't call it with attr 0 (i.e., the null attribute) -HlAttrs *syn_cterm_attr2entry(int attr) -{ - attr -= ATTR_OFF; - if (attr >= attr_table.ga_len) { - // did ":syntax clear" - return NULL; - } - return ATTR_ENTRY(attr); -} - /// \addtogroup LIST_XXX /// @{ #define LIST_ATTR 1 @@ -7163,12 +6991,10 @@ HlAttrs *syn_cterm_attr2entry(int attr) #define LIST_INT 3 /// @} -static void highlight_list_one(int id) +static void highlight_list_one(const int id) { - struct hl_group *sgp; - int didh = FALSE; - - sgp = &HL_TABLE()[id - 1]; /* index is ID minus one */ + struct hl_group *const sgp = &HL_TABLE()[id - 1]; // index is ID minus one + bool didh = false; didh = highlight_list_arg(id, didh, LIST_ATTR, sgp->sg_cterm, NULL, "cterm"); @@ -7205,24 +7031,24 @@ static void highlight_list_one(int id) /// @param type one of \ref LIST_XXX /// @param iarg integer argument used if \p type == LIST_INT /// @param sarg string used if \p type == LIST_STRING -static int highlight_list_arg(int id, int didh, int type, int iarg, - char_u *sarg, const char *name) +static bool highlight_list_arg( + const int id, bool didh, const int type, int iarg, + char_u *const sarg, const char *const name) { char_u buf[100]; - char_u *ts; - int i; - if (got_int) - return FALSE; + if (got_int) { + return false; + } if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) { - ts = buf; - if (type == LIST_INT) - sprintf((char *)buf, "%d", iarg - 1); - else if (type == LIST_STRING) + char_u *ts = buf; + if (type == LIST_INT) { + snprintf((char *)buf, sizeof(buf), "%d", iarg - 1); + } else if (type == LIST_STRING) { ts = sarg; - else { /* type == LIST_ATTR */ + } else { // type == LIST_ATTR buf[0] = NUL; - for (i = 0; hl_attr_table[i] != 0; ++i) { + for (int i = 0; hl_attr_table[i] != 0; i++) { if (iarg & hl_attr_table[i]) { if (buf[0] != NUL) xstrlcat((char *)buf, ",", 100); @@ -7232,9 +7058,8 @@ static int highlight_list_arg(int id, int didh, int type, int iarg, } } - (void)syn_list_header(didh, - (int)(vim_strsize(ts) + STRLEN(name) + 1), id); - didh = TRUE; + (void)syn_list_header(didh, (int)(vim_strsize(ts) + STRLEN(name) + 1), id); + didh = true; if (!got_int) { if (*name != NUL) { MSG_PUTS_ATTR(name, HL_ATTR(HLF_D)); @@ -7352,11 +7177,11 @@ const char *highlight_color(const int id, const char *const what, /// @param outlen length of string that comes /// @param id highlight group id /// @return true when started a new line. -static int -syn_list_header(int did_header, int outlen, int id) +static bool syn_list_header(const bool did_header, const int outlen, + const int id) { int endcol = 19; - int newline = TRUE; + bool newline = true; if (!did_header) { msg_putchar('\n'); @@ -7367,11 +7192,13 @@ syn_list_header(int did_header, int outlen, int id) endcol = 15; } else if (msg_col + outlen + 1 >= Columns) { msg_putchar('\n'); - if (got_int) - return TRUE; + if (got_int) { + return true; + } } else { - if (msg_col >= endcol) /* wrap around is like starting a new line */ - newline = FALSE; + if (msg_col >= endcol) { // wrap around is like starting a new line + newline = false; + } } if (msg_col >= endcol) /* output at least one space */ @@ -7398,7 +7225,6 @@ static void set_hl_attr(int idx) HlAttrs at_en = HLATTRS_INIT; struct hl_group *sgp = HL_TABLE() + idx; - at_en.cterm_ae_attr = sgp->sg_cterm; at_en.cterm_fg_color = sgp->sg_cterm_fg; at_en.cterm_bg_color = sgp->sg_cterm_bg; @@ -7410,14 +7236,11 @@ static void set_hl_attr(int idx) at_en.rgb_bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1; at_en.rgb_sp_color = sgp->sg_rgb_sp_name ? sgp->sg_rgb_sp : -1; - if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0 - || at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1 - || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0 - || at_en.rgb_ae_attr != 0) { - sgp->sg_attr = get_attr_entry(&at_en); - } else { - // If all the fields are cleared, clear the attr field back to default value - sgp->sg_attr = 0; + sgp->sg_attr = hl_get_syn_attr(idx+1, at_en); + + // a cursor style uses this syn_id, make sure its atribute is updated. + if (cursor_mode_uses_syn_id(idx+1)) { + ui_mode_info_set(); } } @@ -7553,7 +7376,7 @@ static void syn_unadd_group(void) /// Translate a group ID to highlight attributes. -/// @see syn_cterm_attr2entry +/// @see syn_attr2entry int syn_id2attr(int hl_id) { struct hl_group *sgp; @@ -7590,7 +7413,7 @@ int syn_get_final_id(int hl_id) } /// Refresh the color attributes of all highlight groups. -static void highlight_attr_set_all(void) +void highlight_attr_set_all(void) { for (int idx = 0; idx < highlight_ga.ga_len; idx++) { struct hl_group *sgp = &HL_TABLE()[idx]; @@ -7613,7 +7436,6 @@ static void highlight_attr_set_all(void) /// screen redraw after any :highlight command. void highlight_changed(void) { - int attr; int id; char_u userhl[10]; int id_SNC = -1; @@ -7628,13 +7450,15 @@ void highlight_changed(void) if (id == 0) { abort(); } - attr = syn_id2attr(id); + int final_id = syn_get_final_id(id); if (hlf == (int)HLF_SNC) { - id_SNC = syn_get_final_id(id); + id_SNC = final_id; } else if (hlf == (int)HLF_S) { - id_S = syn_get_final_id(id); + id_S = final_id; } - highlight_attr[hlf] = attr; + + highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id, + hlf == (int)HLF_INACTIVE); } /* Setup the user highlights @@ -8522,26 +8346,6 @@ RgbValue name_to_color(const char_u *name) return -1; } -/// Gets highlight description for id `attr_id` as a map. -Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err) -{ - HlAttrs *aep = NULL; - Dictionary dic = ARRAY_DICT_INIT; - - if (attr_id == 0) { - return dic; - } - - aep = syn_cterm_attr2entry((int)attr_id); - if (!aep) { - api_set_error(err, kErrorTypeException, - "Invalid attribute id: %" PRId64, attr_id); - return dic; - } - - return hlattrs2dict(aep, rgb); -} - /************************************** * End of Highlighting stuff * diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h index f8282955a6..9fbad74f64 100644 --- a/src/nvim/syntax.h +++ b/src/nvim/syntax.h @@ -3,6 +3,7 @@ #include <stdbool.h> +#include "nvim/globals.h" #include "nvim/buffer_defs.h" #include "nvim/ex_cmds_defs.h" diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h index 63089a62af..5ee0611d58 100644 --- a/src/nvim/syntax_defs.h +++ b/src/nvim/syntax_defs.h @@ -14,13 +14,11 @@ typedef struct syn_state synstate_T; #include "nvim/buffer_defs.h" #include "nvim/regexp_defs.h" -typedef unsigned short disptick_T; /* display tick type */ - /* struct passed to in_id_list() */ struct sp_syn { - int inc_tag; /* ":syn include" unique tag */ - short id; /* highlight group ID of item */ - short *cont_in_list; /* cont.in group IDs, if non-zero */ + int inc_tag; // ":syn include" unique tag + int16_t id; // highlight group ID of item + int16_t *cont_in_list; // cont.in group IDs, if non-zero }; /* @@ -29,12 +27,12 @@ struct sp_syn { typedef struct keyentry keyentry_T; struct keyentry { - keyentry_T *ke_next; /* next entry with identical "keyword[]" */ - struct sp_syn k_syn; /* struct passed to in_id_list() */ - short *next_list; /* ID list for next match (if non-zero) */ + keyentry_T *ke_next; // next entry with identical "keyword[]" + struct sp_syn k_syn; // struct passed to in_id_list() + int16_t *next_list; // ID list for next match (if non-zero) int flags; - int k_char; /* conceal substitute character */ - char_u keyword[1]; /* actually longer */ + int k_char; // conceal substitute character + char_u keyword[1]; // actually longer }; /* @@ -59,13 +57,13 @@ struct syn_state { bufstate_T sst_stack[SST_FIX_STATES]; /* short state stack */ garray_T sst_ga; /* growarray for long state stack */ } sst_union; - int sst_next_flags; /* flags for sst_next_list */ - int sst_stacksize; /* number of states on the stack */ - short *sst_next_list; /* "nextgroup" list in this state - * (this is a copy, don't free it! */ - disptick_T sst_tick; /* tick when last displayed */ - linenr_T sst_change_lnum; /* when non-zero, change in this line - * may have made the state invalid */ + int sst_next_flags; // flags for sst_next_list + int sst_stacksize; // number of states on the stack + int16_t *sst_next_list; // "nextgroup" list in this state + // (this is a copy, don't free it! + disptick_T sst_tick; // tick when last displayed + linenr_T sst_change_lnum; // when non-zero, change in this line + // may have made the state invalid }; #endif // NVIM_SYNTAX_DEFS_H diff --git a/src/nvim/tag.c b/src/nvim/tag.c index beff89d191..50397d40e6 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -266,8 +266,8 @@ do_tag ( goto end_do_tag; } - if (type == DT_POP) { /* go to older position */ - int old_KeyTyped = KeyTyped; + if (type == DT_POP) { // go to older position + const bool old_KeyTyped = KeyTyped; if ((tagstackidx -= count) < 0) { EMSG(_(bottommsg)); if (tagstackidx + count == 0) { @@ -952,12 +952,12 @@ void do_tags(exarg_T *eap) continue; msg_putchar('\n'); - sprintf((char *)IObuff, "%c%2d %2d %-15s %5ld ", - i == tagstackidx ? '>' : ' ', - i + 1, - tagstack[i].cur_match + 1, - tagstack[i].tagname, - tagstack[i].fmark.mark.lnum); + vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld ", + i == tagstackidx ? '>' : ' ', + i + 1, + tagstack[i].cur_match + 1, + tagstack[i].tagname, + tagstack[i].fmark.mark.lnum); msg_outtrans(IObuff); msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum ? HL_ATTR(HLF_D) : 0); @@ -2217,6 +2217,16 @@ static bool test_for_static(tagptrs_T *tagp) return FALSE; } +// Returns the length of a matching tag line. +static size_t matching_line_len(const char_u *const lbuf) +{ + const char_u *p = lbuf + 1; + + // does the same thing as parse_match() + p += STRLEN(p) + 1; + return (p - lbuf) + STRLEN(p); +} + /* * Parse a line from a matching tag. Does not change the line itself. * @@ -2289,7 +2299,7 @@ static char_u *tag_full_fname(tagptrs_T *tagp) { int c = *tagp->fname_end; *tagp->fname_end = NUL; - char_u *fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE); + char_u *fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, false); *tagp->fname_end = c; return fullname; @@ -2300,11 +2310,10 @@ static char_u *tag_full_fname(tagptrs_T *tagp) * * returns OK for success, NOTAGFILE when file not found, FAIL otherwise. */ -static int -jumpto_tag ( - char_u *lbuf, /* line from the tags file for this tag */ - int forceit, /* :ta with ! */ - int keep_help /* keep help flag (FALSE for cscope) */ +static int jumpto_tag( + const char_u *lbuf_arg, // line from the tags file for this tag + int forceit, // :ta with ! + int keep_help // keep help flag (FALSE for cscope) ) { int save_secure; @@ -2312,7 +2321,6 @@ jumpto_tag ( bool save_p_ws; int save_p_scs, save_p_ic; linenr_T save_lnum; - int csave = 0; char_u *str; char_u *pbuf; /* search pattern buffer */ char_u *pbuf_end; @@ -2325,8 +2333,11 @@ jumpto_tag ( int save_no_hlsearch; win_T *curwin_save = NULL; char_u *full_fname = NULL; - int old_KeyTyped = KeyTyped; /* getting the file may reset it */ + const bool old_KeyTyped = KeyTyped; // getting the file may reset it const int l_g_do_tagpreview = g_do_tagpreview; + const size_t len = matching_line_len(lbuf_arg) + 1; + char_u *lbuf = xmalloc(len); + memmove(lbuf, lbuf_arg, len); pbuf = xmalloc(LSIZE); @@ -2336,8 +2347,7 @@ jumpto_tag ( goto erret; } - /* truncate the file name, so it can be used as a string */ - csave = *tagp.fname_end; + // truncate the file name, so it can be used as a string *tagp.fname_end = NUL; fname = tagp.fname; @@ -2363,8 +2373,8 @@ jumpto_tag ( * Expand file name, when needed (for environment variables). * If 'tagrelative' option set, may change file name. */ - fname = expand_tag_fname(fname, tagp.tag_fname, TRUE); - tofree_fname = fname; /* free() it later */ + fname = expand_tag_fname(fname, tagp.tag_fname, true); + tofree_fname = fname; // free() it later /* * Check if the file with the tag exists before abandoning the current @@ -2447,7 +2457,10 @@ jumpto_tag ( else keep_help_flag = curbuf->b_help; } + if (getfile_result == GETFILE_UNUSED) { + // Careful: getfile() may trigger autocommands and call jumpto_tag() + // recursively. getfile_result = getfile(0, fname, NULL, true, (linenr_T)0, forceit); } keep_help_flag = false; @@ -2595,19 +2608,18 @@ jumpto_tag ( win_enter(curwin_save, true); } - --RedrawingDisabled; + RedrawingDisabled--; } else { - --RedrawingDisabled; - if (postponed_split) { /* close the window */ - win_close(curwin, FALSE); + RedrawingDisabled--; + if (postponed_split) { // close the window + win_close(curwin, false); postponed_split = 0; } } erret: - g_do_tagpreview = 0; /* For next time */ - if (tagp.fname_end != NULL) - *tagp.fname_end = csave; + g_do_tagpreview = 0; // For next time + xfree(lbuf); xfree(pbuf); xfree(tofree_fname); xfree(full_fname); @@ -2615,13 +2627,12 @@ erret: return retval; } -/* - * If "expand" is TRUE, expand wildcards in fname. - * If 'tagrelative' option set, change fname (name of file containing tag) - * according to tag_fname (name of tag file containing fname). - * Returns a pointer to allocated memory. - */ -static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand) +// If "expand" is true, expand wildcards in fname. +// If 'tagrelative' option set, change fname (name of file containing tag) +// according to tag_fname (name of tag file containing fname). +// Returns a pointer to allocated memory. +static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname, + const bool expand) { char_u *p; char_u *expanded_fname = NULL; @@ -2676,8 +2687,8 @@ static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname, c = *fname_end; *fname_end = NUL; } - fullname = expand_tag_fname(fname, tag_fname, TRUE); - retval = (path_full_compare(fullname, buf_ffname, TRUE) & kEqualFiles); + fullname = expand_tag_fname(fname, tag_fname, true); + retval = (path_full_compare(fullname, buf_ffname, true) & kEqualFiles); xfree(fullname); *fname_end = c; } diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 6907529726..d831979022 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -49,6 +49,7 @@ #include "nvim/message.h" #include "nvim/memory.h" #include "nvim/option.h" +#include "nvim/highlight.h" #include "nvim/macros.h" #include "nvim/mbyte.h" #include "nvim/buffer.h" @@ -476,7 +477,7 @@ static int terminal_execute(VimState *state, int key) if (s->got_bsl) { return 0; } - // FALLTHROUGH + FALLTHROUGH; default: if (key == Ctrl_BSL && !s->got_bsl) { @@ -602,7 +603,7 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr, int attr_id = 0; if (hl_attrs || vt_fg != -1 || vt_bg != -1) { - attr_id = get_attr_entry(&(HlAttrs) { + attr_id = get_term_attr_entry(&(HlAttrs) { .cterm_ae_attr = (int16_t)hl_attrs, .cterm_fg_color = vt_fg_idx, .cterm_bg_color = vt_bg_idx, @@ -667,6 +668,7 @@ static void buf_set_term_title(buf_T *buf, char *title) false, &err); api_clear_error(&err); + status_redraw_buf(buf); } static int term_settermprop(VTermProp prop, VTermValue *val, void *data) @@ -840,20 +842,20 @@ static VTermKey convert_key(int key, VTermModifier *statep) switch (key) { case K_BS: return VTERM_KEY_BACKSPACE; - case K_S_TAB: // FALLTHROUGH + case K_S_TAB: FALLTHROUGH; case TAB: return VTERM_KEY_TAB; case Ctrl_M: return VTERM_KEY_ENTER; case ESC: return VTERM_KEY_ESCAPE; - case K_S_UP: // FALLTHROUGH + case K_S_UP: FALLTHROUGH; case K_UP: return VTERM_KEY_UP; - case K_S_DOWN: // FALLTHROUGH + case K_S_DOWN: FALLTHROUGH; case K_DOWN: return VTERM_KEY_DOWN; - case K_S_LEFT: // FALLTHROUGH - case K_C_LEFT: // FALLTHROUGH + case K_S_LEFT: FALLTHROUGH; + case K_C_LEFT: FALLTHROUGH; case K_LEFT: return VTERM_KEY_LEFT; - case K_S_RIGHT: // FALLTHROUGH - case K_C_RIGHT: // FALLTHROUGH + case K_S_RIGHT: FALLTHROUGH; + case K_C_RIGHT: FALLTHROUGH; case K_RIGHT: return VTERM_KEY_RIGHT; case K_INS: return VTERM_KEY_INS; @@ -863,22 +865,22 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_PAGEUP: return VTERM_KEY_PAGEUP; case K_PAGEDOWN: return VTERM_KEY_PAGEDOWN; - case K_K0: // FALLTHROUGH + case K_K0: FALLTHROUGH; case K_KINS: return VTERM_KEY_KP_0; - case K_K1: // FALLTHROUGH + case K_K1: FALLTHROUGH; case K_KEND: return VTERM_KEY_KP_1; case K_K2: return VTERM_KEY_KP_2; - case K_K3: // FALLTHROUGH + case K_K3: FALLTHROUGH; case K_KPAGEDOWN: return VTERM_KEY_KP_3; case K_K4: return VTERM_KEY_KP_4; case K_K5: return VTERM_KEY_KP_5; case K_K6: return VTERM_KEY_KP_6; - case K_K7: // FALLTHROUGH + case K_K7: FALLTHROUGH; case K_KHOME: return VTERM_KEY_KP_7; case K_K8: return VTERM_KEY_KP_8; - case K_K9: // FALLTHROUGH + case K_K9: FALLTHROUGH; case K_KPAGEUP: return VTERM_KEY_KP_9; - case K_KDEL: // FALLTHROUGH + case K_KDEL: FALLTHROUGH; case K_KPOINT: return VTERM_KEY_KP_PERIOD; case K_KENTER: return VTERM_KEY_KP_ENTER; case K_KPLUS: return VTERM_KEY_KP_PLUS; @@ -886,29 +888,29 @@ static VTermKey convert_key(int key, VTermModifier *statep) case K_KMULTIPLY: return VTERM_KEY_KP_MULT; case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; - case K_S_F1: // FALLTHROUGH + case K_S_F1: FALLTHROUGH; case K_F1: return VTERM_KEY_FUNCTION(1); - case K_S_F2: // FALLTHROUGH + case K_S_F2: FALLTHROUGH; case K_F2: return VTERM_KEY_FUNCTION(2); - case K_S_F3: // FALLTHROUGH + case K_S_F3: FALLTHROUGH; case K_F3: return VTERM_KEY_FUNCTION(3); - case K_S_F4: // FALLTHROUGH + case K_S_F4: FALLTHROUGH; case K_F4: return VTERM_KEY_FUNCTION(4); - case K_S_F5: // FALLTHROUGH + case K_S_F5: FALLTHROUGH; case K_F5: return VTERM_KEY_FUNCTION(5); - case K_S_F6: // FALLTHROUGH + case K_S_F6: FALLTHROUGH; case K_F6: return VTERM_KEY_FUNCTION(6); - case K_S_F7: // FALLTHROUGH + case K_S_F7: FALLTHROUGH; case K_F7: return VTERM_KEY_FUNCTION(7); - case K_S_F8: // FALLTHROUGH + case K_S_F8: FALLTHROUGH; case K_F8: return VTERM_KEY_FUNCTION(8); - case K_S_F9: // FALLTHROUGH + case K_S_F9: FALLTHROUGH; case K_F9: return VTERM_KEY_FUNCTION(9); - case K_S_F10: // FALLTHROUGH + case K_S_F10: FALLTHROUGH; case K_F10: return VTERM_KEY_FUNCTION(10); - case K_S_F11: // FALLTHROUGH + case K_S_F11: FALLTHROUGH; case K_F11: return VTERM_KEY_FUNCTION(11); - case K_S_F12: // FALLTHROUGH + case K_S_F12: FALLTHROUGH; case K_F12: return VTERM_KEY_FUNCTION(12); case K_F13: return VTERM_KEY_FUNCTION(13); @@ -974,11 +976,11 @@ static bool send_mouse_event(Terminal *term, int c) bool drag = false; switch (c) { - case K_LEFTDRAG: drag = true; // FALLTHROUGH + case K_LEFTDRAG: drag = true; FALLTHROUGH; case K_LEFTMOUSE: button = 1; break; - case K_MIDDLEDRAG: drag = true; // FALLTHROUGH + case K_MIDDLEDRAG: drag = true; FALLTHROUGH; case K_MIDDLEMOUSE: button = 2; break; - case K_RIGHTDRAG: drag = true; // FALLTHROUGH + case K_RIGHTDRAG: drag = true; FALLTHROUGH; case K_RIGHTMOUSE: button = 3; break; case K_MOUSEDOWN: button = 4; break; case K_MOUSEUP: button = 5; break; diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index e3b717989e..fac27aa346 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -14,112 +14,41 @@ export NVIM_PRG := $(NVIM_PRG) export TMPDIR := $(abspath ../../../Xtest-tmpdir) SCRIPTS_DEFAULT = \ - test14.out \ - test24.out \ - test37.out \ - test42.out \ - test48.out \ - test52.out \ - test64.out \ + test14.out \ + test37.out \ + test42.out \ + test48.out \ + test52.out \ + test64.out \ ifneq ($(OS),Windows_NT) SCRIPTS_DEFAULTS := $(SCRIPTS_DEFAULT) \ - test17.out \ - test49.out \ + test17.out \ + test49.out \ endif SCRIPTS ?= $(SCRIPTS_DEFAULT) # Tests using runtest.vim. -# Keep test_alot*.res as the last one, sort the others. -NEW_TESTS ?= \ - test_arabic.res \ - test_autocmd.res \ - test_bufwintabinfo.res \ - test_changedtick.res \ - test_charsearch.res \ - test_cindent.res \ - test_clientserver.res \ - test_close_count.res \ - test_cmdline.res \ - test_command_count.res \ - test_cscope.res \ - test_curswant.res \ - test_digraph.res \ - test_edit.res \ - test_erasebackword.res \ - test_exists.res \ - test_diffmode.res \ - test_farsi.res \ - test_file_size.res \ - test_filter_map.res \ - test_find_complete.res \ - test_fixeol.res \ - test_findfile.res \ - test_fnameescape.res \ - test_fold.res \ - test_ga.res \ - test_glob2regpat.res \ - test_gf.res \ - test_gn.res \ - test_hardcopy.res \ - test_help_tagjump.res \ - test_hide.res \ - test_history.res \ - test_hlsearch.res \ - test_increment.res \ - test_increment_dbcs.res \ - test_ins_complete.res \ - test_lambda.res \ - test_langmap.res \ - test_let.res \ - test_lineending.res \ - test_listdict.res \ - test_listchars.res \ - test_makeencoding.res \ - test_marks.res \ - test_match.res \ - test_matchadd_conceal.res \ - test_mksession.res \ - test_nested_function.res \ - test_normal.res \ - test_number.res \ - test_options.res \ - test_profile.res \ - test_put.res \ - test_python2.res \ - test_python3.res \ - test_quickfix.res \ - test_quotestar.res \ - test_recover.res \ - test_retab.res \ - test_scrollbind.res \ - test_search.res \ - test_signs.res \ - test_smartindent.res \ - test_spell.res \ - test_stat.res \ - test_startup.res \ - test_substitute.res \ - test_swap.res \ - test_syntax.res \ - test_system.res \ - test_tab.res \ - test_tabpage.res \ - test_textobjects.res \ - test_timers.res \ - test_undo.res \ - test_usercommands.res \ - test_vimscript.res \ - test_visual.res \ - test_winbuf_close.res \ - test_window_id.res \ - test_wordcount.res \ - test_writefile.res \ - test_alot_latin.res \ - test_alot_utf8.res \ - test_alot.res +NEW_TESTS_ALOT := test_alot_utf8 test_alot +NEW_TESTS_IN_ALOT := $(shell sed '/^source/ s/^source //;s/\.vim$$//' test_alot*.vim) +# Ignored tests. +# test_alot_latin: Nvim does not allow setting encoding. +# test_arglist: ported to Lua, but kept for easier merging. +# test_autochdir: ported to Lua, but kept for easier merging. +# test_eval_func: used as include in old-style test (test_eval.in). +# test_listlbr: Nvim does not allow setting encoding. +# test_largefile: uses too much resources to run on CI. +NEW_TESTS_IGNORE := $(NEW_TESTS_IN_ALOT) $(NEW_TESTS_ALOT) \ + test_alot_latin \ + test_arglist \ + test_autochdir \ + test_eval_func \ + test_listlbr \ + test_largefile \ + +NEW_TESTS ?= $(addsuffix .res,$(sort $(filter-out $(NEW_TESTS_IGNORE),$(basename $(notdir $(wildcard test_*.vim))))) $(NEW_TESTS_ALOT)) SCRIPTS_GUI := test16.out @@ -213,6 +142,7 @@ test1.out: .gdbinit test1.in @/bin/sh runnvim.sh --oldesttest $(ROOT) $(NVIM_PRG) $* $(RUN_VIM) $*.in @rm -rf X* test.ok viminfo +# Explicit dependencies. test49.out: test49.vim nolog: @@ -223,7 +153,7 @@ nolog: # New style of tests uses Vim script with assert calls. These are easier # to write and a lot easier to read and debug. # Limitation: Only works with the +eval feature. -RUN_VIMTEST = $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE --headless --noplugin +RUN_VIMTEST = $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --headless --noplugin newtests: newtestssilent @/bin/sh -c "if test -f messages && grep -q 'FAILED' messages; then \ diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index f2cd84f556..99b2b940d7 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -67,7 +67,7 @@ lang mess C let v:testing = 1 " Support function: get the alloc ID by name. -function GetAllocId(name) +func GetAllocId(name) exe 'split ' . s:srcdir . '/alloc.h' let top = search('typedef enum') if top == 0 @@ -81,6 +81,11 @@ function GetAllocId(name) return lnum - top - 1 endfunc +func CanRunVimInTerminal() + " Nvim: always false, we use Lua screen-tests instead. + return 0 +endfunc + func RunTheTest(test) echo 'Executing ' . a:test @@ -173,6 +178,9 @@ func FinishTesting() " Don't write viminfo on exit. set viminfo= + " Clean up files created by setup.vim + call delete('XfakeHOME', 'rf') + if s:fail == 0 " Success, create the .res file so that make knows it's done. exe 'split ' . fnamemodify(g:testname, ':r') . '.res' @@ -240,6 +248,7 @@ let s:flaky = [ \ 'Test_quoteplus()', \ 'Test_quotestar()', \ 'Test_reltime()', + \ 'Test_repeat_three()', \ 'Test_terminal_composing_unicode()', \ 'Test_terminal_redir_file()', \ 'Test_terminal_tmap()', diff --git a/src/nvim/testdir/sautest/autoload/foo.vim b/src/nvim/testdir/sautest/autoload/foo.vim new file mode 100644 index 0000000000..d7dcd5ce3d --- /dev/null +++ b/src/nvim/testdir/sautest/autoload/foo.vim @@ -0,0 +1,7 @@ +let g:loaded_foo_vim += 1 + +let foo#bar = {} + +func foo#bar.echo() + let g:called_foo_bar_echo += 1 +endfunc diff --git a/src/nvim/testdir/sautest/autoload/globone.vim b/src/nvim/testdir/sautest/autoload/globone.vim new file mode 100644 index 0000000000..98c9a10582 --- /dev/null +++ b/src/nvim/testdir/sautest/autoload/globone.vim @@ -0,0 +1 @@ +" used by Test_globpath() diff --git a/src/nvim/testdir/sautest/autoload/globtwo.vim b/src/nvim/testdir/sautest/autoload/globtwo.vim new file mode 100644 index 0000000000..98c9a10582 --- /dev/null +++ b/src/nvim/testdir/sautest/autoload/globtwo.vim @@ -0,0 +1 @@ +" used by Test_globpath() diff --git a/src/nvim/testdir/sautest/autoload/sourced.vim b/src/nvim/testdir/sautest/autoload/sourced.vim new file mode 100644 index 0000000000..f69f00cb53 --- /dev/null +++ b/src/nvim/testdir/sautest/autoload/sourced.vim @@ -0,0 +1,3 @@ +let g:loaded_sourced_vim += 1 +func! sourced#something() +endfunc diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index aac9fefef4..c7c3b378cc 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -1,12 +1,21 @@ " Common preparations for running tests. +" Only load this once. +if exists('s:did_load') + finish +endif +let s:did_load = 1 + " Align Nvim defaults to Vim. set sidescroll=0 set directory^=. +set undodir^=. set backspace= +set nrformats+=octal set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd set listchars=eol:$ set fillchars=vert:\|,fold:- +set shortmess-=F " Prevent Nvim log from writing to stderr. let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log' @@ -16,7 +25,10 @@ set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after let &packpath = &rtp " Make sure $HOME does not get read or written. -let $HOME = '/does/not/exist' +let $HOME = expand(getcwd() . '/XfakeHOME') +if !isdirectory($HOME) + call mkdir($HOME) +endif " Use default shell on Windows to avoid segfault, caused by TUI if has('win32') @@ -24,4 +36,5 @@ if has('win32') let $TERM = '' let &shell = empty($COMSPEC) ? exepath('cmd.exe') : $COMSPEC set shellcmdflag=/s/c shellxquote=\" shellredir=>%s\ 2>&1 + let &shellpipe = &shellredir endif diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim index 4925b04a82..b1f1d8fe66 100644 --- a/src/nvim/testdir/shared.vim +++ b/src/nvim/testdir/shared.vim @@ -1,5 +1,10 @@ " Functions shared by several tests. +" Only load this script once. +if exists('*WaitFor') + finish +endif + " {Nvim} " Filepath captured from output may be truncated, like this: " /home/va...estdir/Xtest-tmpdir/nvimxbXN4i/10 @@ -232,3 +237,14 @@ func RunVimPiped(before, after, arguments, pipecmd) endif return 1 endfunc + +" Get line "lnum" as displayed on the screen. +" Trailing white space is trimmed. +func! Screenline(lnum) + let chars = [] + for c in range(1, winwidth(0)) + call add(chars, nr2char(screenchar(a:lnum, c))) + endfor + let line = join(chars, '') + return matchstr(line, '^.\{-}\ze\s*$') +endfunc diff --git a/src/nvim/testdir/test24.in b/src/nvim/testdir/test24.in Binary files differdeleted file mode 100644 index 292f403048..0000000000 --- a/src/nvim/testdir/test24.in +++ /dev/null diff --git a/src/nvim/testdir/test24.ok b/src/nvim/testdir/test24.ok deleted file mode 100644 index cd61210968..0000000000 --- a/src/nvim/testdir/test24.ok +++ /dev/null @@ -1,32 +0,0 @@ -start -test text test text -test text test text -test text test text -test text test text -test text test text -test text test text -test text test text x61 -test text test text x60-x64 -test text test text x78 5 -test text test text o143 -test text test text o140-o144 -test text test text o41 7 -test text test text \%x42 -test text test text \%o103 -test text test text [\x00] -test text test text [\x00-\x10] -test text test text [\x-z] -test text test text [\u-z] -xx xx a -xx aaaaa xx a -xx aaaaa xx a -xx Aaa xx -xx Aaaa xx -xx Aaa xx -xx foobar xA xx -xx an A xx -XX 9; -YY 77; - xyz - bcd - BB diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 1a70ac152f..0602ff6a45 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -2,7 +2,10 @@ " This makes testing go faster, since Vim doesn't need to restart. source test_assign.vim +source test_behave.vim +source test_cd.vim source test_changedtick.vim +source test_compiler.vim source test_cursor_func.vim source test_ex_undo.vim source test_ex_z.vim @@ -17,6 +20,7 @@ source test_functions.vim source test_ga.vim source test_global.vim source test_goto.vim +source test_join.vim source test_jumps.vim source test_fileformat.vim source test_filetype.vim @@ -24,6 +28,7 @@ source test_lambda.vim source test_mapping.vim source test_menu.vim source test_messages.vim +source test_move.vim source test_partial.vim source test_popup.vim source test_put.vim @@ -34,6 +39,7 @@ source test_sort.vim source test_source_utf8.vim source test_sha256.vim source test_statusline.vim +source test_suspend.vim source test_syn_attr.vim source test_tabline.vim " source test_tabpage.vim diff --git a/src/nvim/testdir/test_arabic.vim b/src/nvim/testdir/test_arabic.vim index e62b022632..17e925ee7f 100644 --- a/src/nvim/testdir/test_arabic.vim +++ b/src/nvim/testdir/test_arabic.vim @@ -16,9 +16,9 @@ func s:get_chars(lnum) let numchars = strchars(getline('.'), 1) for i in range(1, numchars) exe 'norm ' i . '|' - let c=execute('ascii') - let c=substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g') - let c=substitute(c, ',\s*Octal\s*\d*', '', 'g') + let c = execute('ascii') + let c = substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g') + let c = substitute(c, ',\s*Oct\(al\)\=\s\d*\(, Digr ..\)\=', '', 'g') call add(chars, c) endfor return chars diff --git a/src/nvim/testdir/test_assign.vim b/src/nvim/testdir/test_assign.vim index a75e89d5dd..50415ad6fd 100644 --- a/src/nvim/testdir/test_assign.vim +++ b/src/nvim/testdir/test_assign.vim @@ -31,3 +31,17 @@ func Test_let_termcap() let &t_xx = "" call assert_fails('let x = &t_xx', 'E15') endfunc + +func Test_let_option_error() + let _w = &tw + let &tw = 80 + call assert_fails('let &tw .= 1', 'E734') + call assert_equal(80, &tw) + let &tw = _w + + let _w = &fillchars + let &fillchars = "vert:|" + call assert_fails('let &fillchars += "diff:-"', 'E734') + call assert_equal("vert:|", &fillchars) + let &fillchars = _w +endfunc diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 772b3f721c..9e8d2081c8 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1,5 +1,7 @@ " Tests for autocommands +source shared.vim + func! s:cleanup_buffers() abort for bnr in range(1, bufnr('$')) if bufloaded(bnr) && bufnr('%') != bnr @@ -248,6 +250,24 @@ func Test_augroup_warning() au! VimEnter endfunc +func Test_BufReadCmdHelp() + helptags ALL + " This used to cause access to free memory + au BufReadCmd * e +h + help + + au! BufReadCmd +endfunc + +func Test_BufReadCmdHelpJump() + " This used to cause access to free memory + au BufReadCmd * e +h{ + " } to fix highlighting + call assert_fails('help', 'E434:') + + au! BufReadCmd +endfunc + func Test_augroup_deleted() " This caused a crash before E936 was introduced augroup x @@ -567,7 +587,7 @@ func Test_OptionSet() " Cleanup au! OptionSet for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp'] - exe printf(":set %s&vi", opt) + exe printf(":set %s&vim", opt) endfor call test_override('starting', 0) delfunc! AutoCommandOptionSet @@ -1165,6 +1185,13 @@ func Test_nocatch_wipe_dummy_buffer() au! endfunc +func Test_wipe_cbuffer() + sv x + au * * bw + lb + au! +endfunc + " Test TextChangedI and TextChangedP func Test_ChangedP() " Nvim does not support test_override(). @@ -1221,3 +1248,46 @@ func Test_ChangedP() bw! endfunc + +let g:setline_handled = v:false +func! SetLineOne() + if !g:setline_handled + call setline(1, "(x)") + let g:setline_handled = v:true + endif +endfunc + +func Test_TextChangedI_with_setline() + throw 'skipped: Nvim does not support test_override()' + new + call test_override('char_avail', 1) + autocmd TextChangedI <buffer> call SetLineOne() + call feedkeys("i(\<CR>\<Esc>", 'tx') + call assert_equal('(', getline(1)) + call assert_equal('x)', getline(2)) + undo + call assert_equal('', getline(1)) + call assert_equal('', getline(2)) + + call test_override('starting', 0) + bwipe! +endfunc + +func Test_Changed_FirstTime() + if !has('terminal') || has('gui_running') + return + endif + " Prepare file for TextChanged event. + call writefile([''], 'Xchanged.txt') + let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3}) + call assert_equal('running', term_getstatus(buf)) + " It's only adding autocmd, so that no event occurs. + call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>") + call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>") + call WaitFor({-> term_getstatus(buf) == 'finished'}) + call assert_equal([''], readfile('Xchanged.txt')) + + " clean up + call delete('Xchanged.txt') + bwipe! +endfunc diff --git a/src/nvim/testdir/test_autoload.vim b/src/nvim/testdir/test_autoload.vim new file mode 100644 index 0000000000..7396c227c9 --- /dev/null +++ b/src/nvim/testdir/test_autoload.vim @@ -0,0 +1,17 @@ +" Tests for autoload + +set runtimepath=./sautest + +func Test_autoload_dict_func() + let g:loaded_foo_vim = 0 + let g:called_foo_bar_echo = 0 + call g:foo#bar.echo() + call assert_equal(1, g:loaded_foo_vim) + call assert_equal(1, g:called_foo_bar_echo) +endfunc + +func Test_source_autoload() + let g:loaded_sourced_vim = 0 + source sautest/autoload/sourced.vim + call assert_equal(1, g:loaded_sourced_vim) +endfunc diff --git a/src/nvim/testdir/test_behave.vim b/src/nvim/testdir/test_behave.vim new file mode 100644 index 0000000000..c26bfe7ce3 --- /dev/null +++ b/src/nvim/testdir/test_behave.vim @@ -0,0 +1,29 @@ +" Test the :behave command + +func Test_behave() + behave mswin + call assert_equal('mouse,key', &selectmode) + call assert_equal('popup', &mousemodel) + call assert_equal('startsel,stopsel', &keymodel) + call assert_equal('exclusive', &selection) + + behave xterm + call assert_equal('', &selectmode) + call assert_equal('extend', &mousemodel) + call assert_equal('', &keymodel) + call assert_equal('inclusive', &selection) + + set selection& + set mousemodel& + set keymodel& + set selection& +endfunc + +func Test_behave_completion() + call feedkeys(":behave \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"behave mswin xterm', @:) +endfunc + +func Test_behave_error() + call assert_fails('behave x', 'E475:') +endfunc diff --git a/src/nvim/testdir/test_blockedit.vim b/src/nvim/testdir/test_blockedit.vim new file mode 100644 index 0000000000..527224ccd2 --- /dev/null +++ b/src/nvim/testdir/test_blockedit.vim @@ -0,0 +1,33 @@ +" Test for block inserting +" +" TODO: rewrite test39.in into this new style test + +func Test_blockinsert_indent() + new + filetype plugin indent on + setlocal sw=2 et ft=vim + call setline(1, ['let a=[', ' ''eins'',', ' ''zwei'',', ' ''drei'']']) + call cursor(2, 3) + exe "norm! \<c-v>2jI\\ \<esc>" + call assert_equal(['let a=[', ' \ ''eins'',', ' \ ''zwei'',', ' \ ''drei'']'], + \ getline(1,'$')) + " reset to sane state + filetype off + bwipe! +endfunc + +func Test_blockinsert_delete() + new + let _bs = &bs + set bs=2 + call setline(1, ['case Arg is ', ' when Name_Async,', ' when Name_Num_Gangs,', 'end if;']) + exe "norm! ggjVj\<c-v>$o$A\<bs>\<esc>" + "call feedkeys("Vj\<c-v>$o$A\<bs>\<esc>", 'ti') + call assert_equal(["case Arg is ", " when Name_Async", " when Name_Num_Gangs,", "end if;"], + \ getline(1,'$')) + " reset to sane state + let &bs = _bs + bwipe! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim index a592cd7b11..a6b4524cc0 100644 --- a/src/nvim/testdir/test_bufwintabinfo.vim +++ b/src/nvim/testdir/test_bufwintabinfo.vim @@ -39,17 +39,35 @@ function Test_getbufwintabinfo() let w2_id = win_getid() tabnew | let w3_id = win_getid() new | let w4_id = win_getid() - new | let w5_id = win_getid() + vert new | let w5_id = win_getid() call setwinvar(0, 'signal', 'green') tabfirst let winlist = getwininfo() call assert_equal(5, len(winlist)) + call assert_equal(winwidth(1), winlist[0].width) + call assert_equal(0, winlist[0].wincol) + let tablineheight = winlist[0].winrow == 1 ? 1 : 0 + call assert_equal(tablineheight, winlist[0].winrow) " tabline adds one + call assert_equal(winbufnr(2), winlist[1].bufnr) call assert_equal(winheight(2), winlist[1].height) + call assert_equal(0, winlist[1].wincol) + call assert_equal(tablineheight + winheight(1) + 1, winlist[1].winrow) + call assert_equal(1, winlist[2].winnr) + call assert_equal(tablineheight, winlist[2].winrow) + call assert_equal(0, winlist[2].wincol) + + call assert_equal(winlist[2].width + 1, winlist[3].wincol) + call assert_equal(0, winlist[4].wincol) + + call assert_equal(1, winlist[0].tabnr) + call assert_equal(1, winlist[1].tabnr) + call assert_equal(2, winlist[2].tabnr) call assert_equal(2, winlist[3].tabnr) + call assert_equal(2, winlist[4].tabnr) + call assert_equal('green', winlist[2].variables.signal) - call assert_equal(winwidth(1), winlist[0].width) call assert_equal(w4_id, winlist[3].winid) let winfo = getwininfo(w5_id)[0] call assert_equal(2, winfo.tabnr) diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim new file mode 100644 index 0000000000..770ed55b8d --- /dev/null +++ b/src/nvim/testdir/test_cd.vim @@ -0,0 +1,67 @@ +" Test for :cd + +func Test_cd_large_path() + " This used to crash with a heap write overflow. + call assert_fails('cd ' . repeat('x', 5000), 'E472:') +endfunc + +func Test_cd_up_and_down() + let path = getcwd() + cd .. + call assert_notequal(path, getcwd()) + exe 'cd ' . path + call assert_equal(path, getcwd()) +endfunc + +func Test_cd_no_arg() + if has('unix') + " Test that cd without argument goes to $HOME directory on Unix systems. + let path = getcwd() + cd + call assert_equal($HOME, getcwd()) + call assert_notequal(path, getcwd()) + exe 'cd ' . path + call assert_equal(path, getcwd()) + else + " Test that cd without argument echoes cwd on non-Unix systems. + call assert_match(getcwd(), execute('cd')) + endif +endfunc + +func Test_cd_minus() + " Test the :cd - goes back to the previous directory. + let path = getcwd() + cd .. + let path_dotdot = getcwd() + call assert_notequal(path, path_dotdot) + cd - + call assert_equal(path, getcwd()) + cd - + call assert_equal(path_dotdot, getcwd()) + cd - + call assert_equal(path, getcwd()) +endfunc + +func Test_cd_with_cpo_chdir() + e Xfoo + call setline(1, 'foo') + let path = getcwd() + " set cpo+=. + + " :cd should fail when buffer is modified and 'cpo' contains dot. + " call assert_fails('cd ..', 'E747:') + call assert_equal(path, getcwd()) + + " :cd with exclamation mark should succeed. + cd! .. + call assert_notequal(path, getcwd()) + + " :cd should succeed when buffer has been written. + w! + exe 'cd ' . path + call assert_equal(path, getcwd()) + + call delete('Xfoo') + set cpo& + bw! +endfunc diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim index 444c4c4109..7c2c5e341c 100644 --- a/src/nvim/testdir/test_cindent.vim +++ b/src/nvim/testdir/test_cindent.vim @@ -68,9 +68,38 @@ func Test_cino_extern_c() call assert_equal(pair[2], getline(len(lines) + 1), 'Failed for "' . string(lines) . '"') endfor + bwipe! +endfunc +func Test_cindent_rawstring() + new + setl cindent + call feedkeys("i" . + \ "int main() {\<CR>" . + \ "R\"(\<CR>" . + \ ")\";\<CR>" . + \ "statement;\<Esc>", "x") + call assert_equal("\tstatement;", getline(line('.'))) + bw! +endfunc - bwipe! +func Test_cindent_expr() + new + func! MyIndentFunction() + return v:lnum == 1 ? shiftwidth() : 0 + endfunc + setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction() + call setline(1, ['var_a = something()', 'b = something()']) + call cursor(1, 1) + call feedkeys("^\<c-v>j$A;\<esc>", 'tnix') + call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$')) + + %d + call setline(1, [' var_a = something()', ' b = something()']) + call cursor(1, 1) + call feedkeys("^\<c-v>j$A;\<esc>", 'tnix') + call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$')) + bw! endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 5a43838218..26f1dcc333 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -137,6 +137,11 @@ func Test_getcompletion() let l = getcompletion('v:notexists', 'var') call assert_equal([], l) + args a.c b.c + let l = getcompletion('', 'arglist') + call assert_equal(['a.c', 'b.c'], l) + %argdelete + let l = getcompletion('', 'augroup') call assert_true(index(l, 'END') >= 0) let l = getcompletion('blahblah', 'augroup') @@ -222,6 +227,11 @@ func Test_getcompletion() let l = getcompletion('not', 'messages') call assert_equal([], l) + let l = getcompletion('', 'mapclear') + call assert_true(index(l, '<buffer>') >= 0) + let l = getcompletion('not', 'mapclear') + call assert_equal([], l) + if has('cscope') let l = getcompletion('', 'cscope') let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show'] @@ -311,6 +321,9 @@ func Test_paste_in_cmdline() call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx') call assert_equal('"aaa /tmp/some bbb', @:) + call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa '.getline(1).' bbb', @:) + set incsearch call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx') call assert_equal('"aaa verylongword bbb', @:) @@ -321,6 +334,17 @@ func Test_paste_in_cmdline() call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx') call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:) bwipe! + + " Error while typing a command used to cause that it was not executed + " in the end. + new + try + call feedkeys(":file \<C-R>%Xtestfile\<CR>", 'tx') + catch /^Vim\%((\a\+)\)\=:E32/ + " ignore error E32 + endtry + call assert_equal("Xtestfile", bufname("%")) + bwipe! endfunc func Test_remove_char_in_cmdline() @@ -375,6 +399,27 @@ func Test_cmdline_complete_user_cmd() delcommand Foo endfunc +func Test_cmdline_write_alternatefile() + new + call setline('.', ['one', 'two']) + f foo.txt + new + f #-A + call assert_equal('foo.txt-A', expand('%')) + f #<-B.txt + call assert_equal('foo-B.txt', expand('%')) + f %< + call assert_equal('foo-B', expand('%')) + new + call assert_fails('f #<', 'E95') + bw! + f foo-B.txt + f %<-A + call assert_equal('foo-B-A', expand('%')) + bw! + bw! +endfunc + " using a leading backslash here set cpo+=C @@ -430,6 +475,22 @@ func Test_getcmdtype() cunmap <F6> endfunc +func Test_getcmdwintype() + call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!') + call assert_equal('/', a) + + call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!') + call assert_equal('?', a) + + call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!') + call assert_equal(':', a) + + call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!') + call assert_equal(':', a) + + call assert_equal('', getcmdwintype()) +endfunc + func Test_verbosefile() set verbosefile=Xlog echomsg 'foo' @@ -440,4 +501,25 @@ func Test_verbosefile() call delete('Xlog') endfunc +func Test_setcmdpos() + func InsertTextAtPos(text, pos) + call assert_equal(0, setcmdpos(a:pos)) + return a:text + endfunc + + " setcmdpos() with position in the middle of the command line. + call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt') + call assert_equal('"1ab2', @:) + + call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt') + call assert_equal('"1b2a', @:) + + " setcmdpos() with position beyond the end of the command line. + call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt') + call assert_equal('"12ab', @:) + + " setcmdpos() returns 1 when not editing the command line. + call assert_equal(1, setcmdpos(3)) +endfunc + set cpo& diff --git a/src/nvim/testdir/test_comparators.vim b/src/nvim/testdir/test_comparators.vim new file mode 100644 index 0000000000..87be006cf2 --- /dev/null +++ b/src/nvim/testdir/test_comparators.vim @@ -0,0 +1,9 @@ +function Test_Comparators() + try + let oldisident=&isident + set isident+=# + call assert_equal(1, 1 is#1) + finally + let &isident=oldisident + endtry +endfunction diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim new file mode 100644 index 0000000000..4600a28da5 --- /dev/null +++ b/src/nvim/testdir/test_compiler.vim @@ -0,0 +1,54 @@ +" Test the :compiler command + +func Test_compiler() + if !executable('perl') + return + endif + + " $LANG changes the output of Perl. + if $LANG != '' + unlet $LANG + endif + + e Xfoo.pl + compiler perl + call assert_equal('perl', b:current_compiler) + call assert_fails('let g:current_compiler', 'E121:') + + call setline(1, ['#!/usr/bin/perl -w', 'use strict;', 'my $foo=1']) + w! + call feedkeys(":make\<CR>\<CR>", 'tx') + call assert_fails('clist', 'E42:') + + call setline(1, ['#!/usr/bin/perl -w', 'use strict;', '$foo=1']) + w! + call feedkeys(":make\<CR>\<CR>", 'tx') + let a=execute('clist') + call assert_match("\n 1 Xfoo.pl:3: Global symbol \"\$foo\" " + \ . "requires explicit package name", a) + + call delete('Xfoo.pl') + bw! +endfunc + +func Test_compiler_without_arg() + let a=split(execute('compiler')) + call assert_match(expand('^.*runtime/compiler/ant.vim$'), a[0]) + call assert_match(expand('^.*runtime/compiler/bcc.vim$'), a[1]) + call assert_match(expand('^.*runtime/compiler/xmlwf.vim$'), a[-1]) +endfunc + +func Test_compiler_completion() + call feedkeys(":compiler \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match('^"compiler ant bcc .* xmlwf$', @:) + + call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"compiler pbx perl php pylint pyunit', @:) + + call feedkeys(":compiler! p\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"compiler! pbx perl php pylint pyunit', @:) +endfunc + +func Test_compiler_error() + call assert_fails('compiler doesnotexist', 'E666:') +endfunc diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index d95b29759e..afe289b262 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -279,13 +279,13 @@ func Test_diffopt_icase() set diffopt=icase,foldcolumn:0 e one - call setline(1, ['One', 'Two', 'Three', 'Four']) + call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve']) redraw let normattr = screenattr(1, 1) diffthis botright vert new two - call setline(1, ['one', 'TWO', 'Three ', 'Four']) + call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE']) diffthis redraw @@ -294,6 +294,10 @@ func Test_diffopt_icase() call assert_notequal(normattr, screenattr(3, 1)) call assert_equal(normattr, screenattr(4, 1)) + let dtextattr = screenattr(5, 3) + call assert_notequal(dtextattr, screenattr(5, 1)) + call assert_notequal(dtextattr, screenattr(5, 5)) + diffoff! %bwipe! set diffopt& @@ -371,6 +375,29 @@ func Test_diffopt_vertical() %bwipe endfunc +func Test_diffopt_hiddenoff() + set diffopt=filler,foldcolumn:0,hiddenoff + e! one + call setline(1, ['Two', 'Three']) + redraw + let normattr = screenattr(1, 1) + diffthis + botright vert new two + call setline(1, ['One', 'Four']) + diffthis + redraw + call assert_notequal(normattr, screenattr(1, 1)) + set hidden + close + redraw + " should not diffing with hidden buffer two while 'hiddenoff' is enabled + call assert_equal(normattr, screenattr(1, 1)) + + bwipe! + bwipe! + set hidden& diffopt& +endfunc + func Test_diffoff_hidden() set diffopt=filler,foldcolumn:0 e! one @@ -561,3 +588,30 @@ func Test_diff_lastline() bwipe! bwipe! endfunc + +func Test_diff_with_cursorline() + if !CanRunVimInTerminal() + return + endif + + call writefile([ + \ 'hi CursorLine ctermbg=red ctermfg=white', + \ 'set cursorline', + \ 'call setline(1, ["foo","foo","foo","bar"])', + \ 'vnew', + \ 'call setline(1, ["bee","foo","foo","baz"])', + \ 'windo diffthis', + \ '2wincmd w', + \ ], 'Xtest_diff_cursorline') + let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {}) + + call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {}) + call term_sendkeys(buf, "j") + call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('Xtest_diff_cursorline') +endfunc diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim index 6290680305..271066df41 100644 --- a/src/nvim/testdir/test_digraph.vim +++ b/src/nvim/testdir/test_digraph.vim @@ -4,15 +4,15 @@ if !has("digraphs") || !has("multi_byte") finish endif -func! Put_Dig(chars) +func Put_Dig(chars) exe "norm! o\<c-k>".a:chars endfu -func! Put_Dig_BS(char1, char2) +func Put_Dig_BS(char1, char2) exe "norm! o".a:char1."\<bs>".a:char2 endfu -func! Test_digraphs() +func Test_digraphs() new call Put_Dig("00") call assert_equal("∞", getline('.')) @@ -214,7 +214,7 @@ func! Test_digraphs() bw! endfunc -func! Test_digraphs_option() +func Test_digraphs_option() " reset whichwrap option, so that testing <esc><bs>A works, " without moving up a line set digraph ww= @@ -420,7 +420,7 @@ func! Test_digraphs_option() bw! endfunc -func! Test_digraphs_output() +func Test_digraphs_output() new let out = execute(':digraph') call assert_equal('Eu € 8364', matchstr(out, '\C\<Eu\D*8364\>')) @@ -436,7 +436,7 @@ func! Test_digraphs_output() bw! endfunc -func! Test_loadkeymap() +func Test_loadkeymap() if !has('keymap') return endif @@ -450,7 +450,7 @@ func! Test_loadkeymap() bw! endfunc -func! Test_digraph_cmndline() +func Test_digraph_cmndline() " Create digraph on commandline " This is a hack, to let Vim create the digraph in commandline mode let s = '' @@ -458,4 +458,11 @@ func! Test_digraph_cmndline() call assert_equal("€", s) endfunc +func Test_show_digraph() + new + call Put_Dig("e=") + call assert_equal("\n<е> 1077, Hex 0435, Oct 2065, Digr e=", execute('ascii')) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim index d2474c06fe..f8946c6929 100644 --- a/src/nvim/testdir/test_edit.vim +++ b/src/nvim/testdir/test_edit.vim @@ -314,6 +314,33 @@ func! Test_edit_11() bw! endfunc +func! Test_edit_11_indentexpr() + " Test that indenting kicks in + new + " Use indentexpr instead of cindenting + func! Do_Indent() + let pline=prevnonblank(v:lnum) + if empty(getline(v:lnum)) + if getline(pline) =~ 'if\|then' + return shiftwidth() + else + return 0 + endif + else + return 0 + endif + endfunc + setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi + call setline(1, ['if [ $this ]']) + call cursor(1, 1) + call feedkeys("othen\<cr>that\<cr>fi", 'tnix') + call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$')) + set cinkeys&vim indentkeys&vim + set nocindent indentexpr= + delfu Do_Indent + bw! +endfunc + func! Test_edit_12() " Test changing indent in replace mode new @@ -1311,6 +1338,14 @@ func! Test_edit_rightleft() bw! endfunc +func Test_edit_backtick() + next a\`b c + call assert_equal('a`b', expand('%')) + next + call assert_equal('c', expand('%')) + call assert_equal('a\`b c', expand('##')) +endfunc + func Test_edit_quit() edit foo.txt split @@ -1363,3 +1398,48 @@ func Test_edit_complete_very_long_name() endif set swapfile& endfunc + +func Test_edit_alt() + " Keeping the cursor line didn't happen when the first line has indent. + new + call setline(1, [' one', 'two', 'three']) + w XAltFile + $ + call assert_equal(3, line('.')) + e Xother + e # + call assert_equal(3, line('.')) + + bwipe XAltFile + call delete('XAltFile') +endfunc + +func Test_leave_insert_autocmd() + new + au InsertLeave * let g:did_au = 1 + let g:did_au = 0 + call feedkeys("afoo\<Esc>", 'tx') + call assert_equal(1, g:did_au) + call assert_equal('foo', getline(1)) + + let g:did_au = 0 + call feedkeys("Sbar\<C-C>", 'tx') + call assert_equal(0, g:did_au) + call assert_equal('bar', getline(1)) + + inoremap x xx<Esc> + let g:did_au = 0 + call feedkeys("Saax", 'tx') + call assert_equal(1, g:did_au) + call assert_equal('aaxx', getline(1)) + + inoremap x xx<C-C> + let g:did_au = 0 + call feedkeys("Sbbx", 'tx') + call assert_equal(0, g:did_au) + call assert_equal('bbxx', getline(1)) + + bwipe! + au! InsertLeave + iunmap x +endfunc diff --git a/src/nvim/testdir/test_escaped_glob.vim b/src/nvim/testdir/test_escaped_glob.vim new file mode 100644 index 0000000000..aad3a1e835 --- /dev/null +++ b/src/nvim/testdir/test_escaped_glob.vim @@ -0,0 +1,34 @@ +" Test whether glob()/globpath() return correct results with certain escaped +" characters. + +function SetUp() + " consistent sorting of file names + set nofileignorecase +endfunction + +function Test_glob() + if !has('unix') + " This test fails on Windows because of the special characters in the + " filenames. Disable the test on non-Unix systems for now. + return + endif + + " Execute these commands in the sandbox, so that using the shell fails. + " Setting 'shell' to an invalid name causes a memory leak. + sandbox call assert_equal("", glob('Xxx\{')) + sandbox call assert_equal("", glob('Xxx\$')) + w! Xxx{ + " } to fix highlighting + w! Xxx\$ + sandbox call assert_equal("Xxx{", glob('Xxx\{')) + sandbox call assert_equal("Xxx$", glob('Xxx\$')) + call delete('Xxx{') + call delete('Xxx$') +endfunction + +function Test_globpath() + sandbox call assert_equal(expand("sautest/autoload/globone.vim\nsautest/autoload/globtwo.vim"), + \ globpath('sautest/autoload', 'glob*.vim')) + sandbox call assert_equal([expand('sautest/autoload/globone.vim'), expand('sautest/autoload/globtwo.vim')], + \ globpath('sautest/autoload', 'glob*.vim', 0, 1)) +endfunction diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim new file mode 100644 index 0000000000..92e1ec5335 --- /dev/null +++ b/src/nvim/testdir/test_eval_stuff.vim @@ -0,0 +1,13 @@ +" Tests for various eval things. + +function s:foo() abort + try + return [] == 0 + catch + return 1 + endtry +endfunction + +func Test_catch_return_with_error() + call assert_equal(1, s:foo()) +endfunc diff --git a/src/nvim/testdir/test_exec_while_if.vim b/src/nvim/testdir/test_exec_while_if.vim new file mode 100644 index 0000000000..d6afabff45 --- /dev/null +++ b/src/nvim/testdir/test_exec_while_if.vim @@ -0,0 +1,53 @@ +" Test for :execute, :while and :if + +function Test_exec_while_if() + new + + let i = 0 + while i < 12 + let i = i + 1 + if has("ebcdic") + execute "normal o" . i . "\047" + else + execute "normal o" . i . "\033" + endif + if i % 2 + normal Ax + if i == 9 + break + endif + if i == 5 + continue + else + let j = 9 + while j > 0 + if has("ebcdic") + execute "normal" j . "a" . j . "\x27" + else + execute "normal" j . "a" . j . "\x1b" + endif + let j = j - 1 + endwhile + endif + endif + if i == 9 + if has("ebcdic") + execute "normal Az\047" + else + execute "normal Az\033" + endif + endif + endwhile + unlet i j + + call assert_equal(["", + \ "1x999999999888888887777777666666555554444333221", + \ "2", + \ "3x999999999888888887777777666666555554444333221", + \ "4", + \ "5x", + \ "6", + \ "7x999999999888888887777777666666555554444333221", + \ "8", + \ "9x"], getline(1, 10)) +endfunction diff --git a/src/nvim/testdir/test_exists_autocmd.vim b/src/nvim/testdir/test_exists_autocmd.vim new file mode 100644 index 0000000000..7e44a72653 --- /dev/null +++ b/src/nvim/testdir/test_exists_autocmd.vim @@ -0,0 +1,26 @@ +" Test that groups and patterns are tested correctly when calling exists() for +" autocommands. + +function Test_AutoCommands() + let results=[] + augroup auexists + augroup END + call assert_true(exists("##BufEnter")) + call assert_false(exists("#BufEnter")) + au BufEnter * let g:entered=1 + call assert_true(exists("#BufEnter")) + call assert_false(exists("#auexists#BufEnter")) + augroup auexists + au BufEnter * let g:entered=1 + augroup END + call assert_true(exists("#auexists#BufEnter")) + call assert_false(exists("#BufEnter#*.test")) + au BufEnter *.test let g:entered=1 + call assert_true(exists("#BufEnter#*.test")) + edit testfile.test + call assert_false(exists("#BufEnter#<buffer>")) + au BufEnter <buffer> let g:entered=1 + call assert_true(exists("#BufEnter#<buffer>")) + edit testfile2.test + call assert_false(exists("#BufEnter#<buffer>")) +endfunction diff --git a/src/nvim/testdir/test_exit.vim b/src/nvim/testdir/test_exit.vim new file mode 100644 index 0000000000..8f02fd29e3 --- /dev/null +++ b/src/nvim/testdir/test_exit.vim @@ -0,0 +1,57 @@ +" Tests for exiting Vim. + +source shared.vim + +func Test_exiting() + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'quit', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) + endif + call delete('Xtestout') + + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'help', + \ 'wincmd w', + \ 'quit', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) + endif + call delete('Xtestout') + + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'split', + \ 'new', + \ 'qall', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) + endif + call delete('Xtestout') + + let after = [ + \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")', + \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', + \ 'augroup nasty', + \ ' au ExitPre * split', + \ 'augroup END', + \ 'quit', + \ 'augroup nasty', + \ ' au! ExitPre', + \ 'augroup END', + \ 'quit', + \ ] + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'], + \ readfile('Xtestout')) + endif + call delete('Xtestout') +endfunc diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index ad967c528c..aaf32dff04 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -166,6 +166,9 @@ function Test_printf_spec_s() endfunc function Test_printf_misc() + call assert_equal('123', printf('123')) + call assert_fails("call printf('123', 3)", "E767:") + call assert_equal('123', printf('%d', 123)) call assert_equal('123', printf('%i', 123)) call assert_equal('123', printf('%D', 123)) diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 43dc383f3d..b0a1ea0225 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -162,7 +162,7 @@ let s:filename_checks = { \ 'fetchmail': ['.fetchmailrc'], \ 'fgl': ['file.4gl', 'file.4gh', 'file.m4gl'], \ 'focexec': ['file.fex', 'file.focexec'], - \ 'forth': ['file.fs', 'file.ft'], + \ 'forth': ['file.fs', 'file.ft', 'file.fth'], \ 'fortran': ['file.f', 'file.for', 'file.fortran', 'file.fpp', 'file.ftn', 'file.f77', 'file.f90', 'file.f95', 'file.f03', 'file.f08'], \ 'framescript': ['file.fsl'], \ 'freebasic': ['file.fb', 'file.bi'], @@ -171,7 +171,7 @@ let s:filename_checks = { \ 'gdmo': ['file.mo', 'file.gdmo'], \ 'gedcom': ['file.ged', 'lltxxxxx.txt'], \ 'gitcommit': ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG'], - \ 'gitconfig': ['file.git/config', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config'], + \ 'gitconfig': ['file.git/config', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig'], \ 'gitolite': ['gitolite.conf'], \ 'gitrebase': ['git-rebase-todo'], \ 'gitsendemail': ['.gitsendemail.msg.xxxxxx'], @@ -322,7 +322,9 @@ let s:filename_checks = { \ 'pf': ['pf.conf'], \ 'pfmain': ['main.cf'], \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp'], - \ 'pike': ['file.pike', 'file.lpc', 'file.ulpc', 'file.pmod'], + \ 'lpc': ['file.lpc', 'file.ulpc'], + \ 'pike': ['file.pike', 'file.pmod'], + \ 'cmod': ['file.cmod'], \ 'pilrc': ['file.rcp'], \ 'pine': ['.pinerc', 'pinerc', '.pinercex', 'pinercex'], \ 'pinfo': ['/etc/pinforc', '/.pinforc'], @@ -347,7 +349,7 @@ let s:filename_checks = { \ 'protocols': ['/etc/protocols'], \ 'psf': ['file.psf'], \ 'pyrex': ['file.pyx', 'file.pxd'], - \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl'], + \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi'], \ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg'], \ 'radiance': ['file.rad', 'file.mat'], \ 'ratpoison': ['.ratpoisonrc', 'ratpoisonrc'], @@ -386,7 +388,7 @@ let s:filename_checks = { \ 'services': ['/etc/services'], \ 'setserial': ['/etc/serial.conf'], \ 'sh': ['/etc/udev/cdsymlinks.conf'], - \ 'sieve': ['file.siv'], + \ 'sieve': ['file.siv', 'file.sieve'], \ 'simula': ['file.sim'], \ 'sinda': ['file.sin', 'file.s85'], \ 'sisu': ['file.sst', 'file.ssm', 'file.ssi', 'file.-sst', 'file._sst', 'file.sst.meta', 'file.-sst.meta', 'file._sst.meta'], @@ -471,6 +473,7 @@ let s:filename_checks = { \ 'voscm': ['file.cm'], \ 'vrml': ['file.wrl'], \ 'vroom': ['file.vroom'], + \ 'wast': ['file.wast', 'file.wat'], \ 'webmacro': ['file.wm'], \ 'wget': ['.wgetrc', 'wgetrc'], \ 'winbatch': ['file.wbt'], @@ -481,7 +484,7 @@ let s:filename_checks = { \ 'xhtml': ['file.xhtml', 'file.xht'], \ 'xinetd': ['/etc/xinetd.conf'], \ 'xmath': ['file.msc', 'file.msf'], - \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ts', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul'], + \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ts', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl'], \ 'xmodmap': ['anyXmodmap'], \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'], \ 'xpm2': ['file.xpm2'], @@ -491,6 +494,7 @@ let s:filename_checks = { \ 'xslt': ['file.xsl', 'file.xslt'], \ 'yacc': ['file.yy', 'file.yxx', 'file.y++'], \ 'yaml': ['file.yaml', 'file.yml'], + \ 'raml': ['file.raml'], \ 'z8a': ['file.z8a'], \ 'zimbu': ['file.zu'], \ 'zimbutempl': ['file.zut'], @@ -539,6 +543,43 @@ let s:script_checks = { \ 'strace': [['execve("/usr/bin/pstree", ["pstree"], 0x7ff0 /* 63 vars */) = 0'], \ ['15:17:47 execve("/usr/bin/pstree", ["pstree"], ... "_=/usr/bin/strace"]) = 0'], \ ['__libc_start_main and something']], + \ 'clojure': [['#!/path/clojure']], + \ 'scala': [['#!/path/scala']], + \ 'tcsh': [['#!/path/tcsh']], + \ 'zsh': [['#!/path/zsh']], + \ 'tcl': [['#!/path/tclsh'], + \ ['#!/path/wish'], + \ ['#!/path/expectk'], + \ ['#!/path/itclsh'], + \ ['#!/path/itkwish']], + \ 'expect': [['#!/path/expect']], + \ 'gnuplot': [['#!/path/gnuplot']], + \ 'make': [['#!/path/make']], + \ 'pike': [['#!/path/pike'], + \ ['#!/path/pike0'], + \ ['#!/path/pike9']], + \ 'lua': [['#!/path/lua']], + \ 'perl6': [['#!/path/perl6']], + \ 'perl': [['#!/path/perl']], + \ 'php': [['#!/path/php']], + \ 'python': [['#!/path/python'], + \ ['#!/path/python2'], + \ ['#!/path/python3']], + \ 'groovy': [['#!/path/groovy']], + \ 'ruby': [['#!/path/ruby']], + \ 'javascript': [['#!/path/node'], + \ ['#!/path/js'], + \ ['#!/path/nodejs'], + \ ['#!/path/rhino']], + \ 'bc': [['#!/path/bc']], + \ 'sed': [['#!/path/sed']], + \ 'ocaml': [['#!/path/ocaml']], + \ 'awk': [['#!/path/awk']], + \ 'wml': [['#!/path/wml']], + \ 'scheme': [['#!/path/scheme']], + \ 'cfengine': [['#!/path/cfengine']], + \ 'erlang': [['#!/path/escript']], + \ 'haskell': [['#!/path/haskell']], \ } func Test_script_detection() diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim index 5aa5fa64df..86347ab77f 100644 --- a/src/nvim/testdir/test_filter_cmd.vim +++ b/src/nvim/testdir/test_filter_cmd.vim @@ -74,3 +74,16 @@ func Test_filter_cmd_completion() call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri')) call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri')) endfunc + +func Test_filter_cmd_with_filter() + new + set shelltemp + %!echo "a|b" + let out = getline(1) + bw! + if has('win32') + let out = trim(out, '" ') + endif + call assert_equal('a|b', out) + set shelltemp& +endfunction diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 6917378890..b6a545f959 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -1,5 +1,7 @@ " Test for folding +source view_util.vim + func PrepIndent(arg) return [a:arg] + repeat(["\t".a:arg], 5) endfu @@ -278,6 +280,7 @@ func Test_move_folds_around_manual() call assert_equal(0, foldlevel(6)) call assert_equal(9, foldclosedend(7)) call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)')) + %d " Ensure moving around the edges still works. call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"]) @@ -634,3 +637,40 @@ func Test_fold_move() set fdm& sw& fdl& enew! endfunc + +func Test_foldtext_recursive() + new + call setline(1, ['{{{', 'some text', '}}}']) + setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart) + " This was crashing because of endless recursion. + 2foldclose + redraw + call assert_equal(1, foldlevel(2)) + call assert_equal(1, foldclosed(2)) + call assert_equal(3, foldclosedend(2)) + bwipe! +endfunc + +func Test_fold_last_line_with_pagedown() + enew! + set fdm=manual + + let expect = '+-- 11 lines: 9---' + let content = range(1,19) + call append(0, content) + normal dd9G + normal zfG + normal zt + call assert_equal('9', getline(foldclosed('.'))) + call assert_equal('19', getline(foldclosedend('.'))) + call assert_equal(expect, ScreenLines(1, len(expect))[0]) + call feedkeys("\<C-F>", 'xt') + call assert_equal(expect, ScreenLines(1, len(expect))[0]) + call feedkeys("\<C-F>", 'xt') + call assert_equal(expect, ScreenLines(1, len(expect))[0]) + call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt') + call assert_equal(expect, ScreenLines(1, len(expect))[0]) + + set fdm& + enew! +endfunc diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index c59134908c..7dc9f31ce7 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -96,6 +96,30 @@ func Test_min() " call assert_fails('call min(v:none)', 'E712:') endfunc +func Test_strwidth() + for aw in ['single', 'double'] + exe 'set ambiwidth=' . aw + call assert_equal(0, strwidth('')) + call assert_equal(1, strwidth("\t")) + call assert_equal(3, strwidth('Vim')) + call assert_equal(4, strwidth(1234)) + call assert_equal(5, strwidth(-1234)) + + if has('multi_byte') + call assert_equal(2, strwidth('😉')) + call assert_equal(17, strwidth('EÄ¥oÅanÄo ĉiuĵaÅde')) + call assert_equal((aw == 'single') ? 6 : 7, strwidth('Straße')) + endif + + call assert_fails('call strwidth({->0})', 'E729:') + call assert_fails('call strwidth([])', 'E730:') + call assert_fails('call strwidth({})', 'E731:') + call assert_fails('call strwidth(1.2)', 'E806:') + endfor + + set ambiwidth& +endfunc + func Test_str2nr() call assert_equal(0, str2nr('')) call assert_equal(1, str2nr('1')) @@ -165,6 +189,52 @@ func Test_strftime() call assert_fails('call strftime("%Y", [])', 'E745:') endfunc +func Test_resolve() + if !has('unix') + return + endif + + " Xlink1 -> Xlink2 + " Xlink2 -> Xlink3 + silent !ln -s -f Xlink2 Xlink1 + silent !ln -s -f Xlink3 Xlink2 + call assert_equal('Xlink3', resolve('Xlink1')) + call assert_equal('./Xlink3', resolve('./Xlink1')) + call assert_equal('Xlink3/', resolve('Xlink2/')) + " FIXME: these tests result in things like "Xlink2/" instead of "Xlink3/"?! + "call assert_equal('Xlink3/', resolve('Xlink1/')) + "call assert_equal('./Xlink3/', resolve('./Xlink1/')) + "call assert_equal(getcwd() . '/Xlink3/', resolve(getcwd() . '/Xlink1/')) + call assert_equal(getcwd() . '/Xlink3', resolve(getcwd() . '/Xlink1')) + + " Test resolve() with a symlink cycle. + " Xlink1 -> Xlink2 + " Xlink2 -> Xlink3 + " Xlink3 -> Xlink1 + silent !ln -s -f Xlink1 Xlink3 + call assert_fails('call resolve("Xlink1")', 'E655:') + call assert_fails('call resolve("./Xlink1")', 'E655:') + call assert_fails('call resolve("Xlink2")', 'E655:') + call assert_fails('call resolve("Xlink3")', 'E655:') + call delete('Xlink1') + call delete('Xlink2') + call delete('Xlink3') + + silent !ln -s -f Xdir//Xfile Xlink + call assert_equal('Xdir/Xfile', resolve('Xlink')) + call delete('Xlink') + + silent !ln -s -f Xlink2/ Xlink1 + call assert_equal('Xlink2', resolve('Xlink1')) + call assert_equal('Xlink2/', resolve('Xlink1/')) + call delete('Xlink1') + + silent !ln -s -f ./Xlink2 Xlink1 + call assert_equal('Xlink2', resolve('Xlink1')) + call assert_equal('./Xlink2', resolve('./Xlink1')) + call delete('Xlink1') +endfunc + func Test_simplify() call assert_equal('', simplify('')) call assert_equal('/', simplify('/')) @@ -215,6 +285,21 @@ func Test_setbufvar_options() bwipe! endfunc +func Test_pathshorten() + call assert_equal('', pathshorten('')) + call assert_equal('foo', pathshorten('foo')) + call assert_equal('/foo', pathshorten('/foo')) + call assert_equal('f/', pathshorten('foo/')) + call assert_equal('f/bar', pathshorten('foo/bar')) + call assert_equal('f/b/foobar', pathshorten('foo/bar/foobar')) + call assert_equal('/f/b/foobar', pathshorten('/foo/bar/foobar')) + call assert_equal('.f/bar', pathshorten('.foo/bar')) + call assert_equal('~f/bar', pathshorten('~foo/bar')) + call assert_equal('~.f/bar', pathshorten('~.foo/bar')) + call assert_equal('.~f/bar', pathshorten('.~foo/bar')) + call assert_equal('~/f/bar', pathshorten('~/foo/bar')) +endfunc + func Test_strpart() call assert_equal('de', strpart('abcdefg', 3, 2)) call assert_equal('ab', strpart('abcdefg', -2, 4)) @@ -299,6 +384,11 @@ func Test_tolower() " Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase " in length (2 to 3 bytes) when lowercased. So let's test them. call assert_equal("â±¥ ⱦ", tolower("Ⱥ Ⱦ")) + + " This call to tolower with invalid utf8 sequence used to cause access to + " invalid memory. + call tolower("\xC0\x80\xC0") + call tolower("123\xC0\x80\xC0") endfunc func Test_toupper() @@ -369,6 +459,11 @@ func Test_toupper() call assert_equal("ZŹŻŽƵáºáº”", toupper("ZŹŻŽƵáºáº”")) call assert_equal("Ⱥ Ⱦ", toupper("â±¥ ⱦ")) + + " This call to toupper with invalid utf8 sequence used to cause access to + " invalid memory. + call toupper("\xC0\x80\xC0") + call toupper("123\xC0\x80\xC0") endfunc " Tests for the mode() function @@ -573,10 +668,46 @@ func Test_strridx() call assert_equal(-1, strridx('hello', 'hello world')) endfunc +func Test_match_func() + call assert_equal(4, match('testing', 'ing')) + call assert_equal(4, match('testing', 'ing', 2)) + call assert_equal(-1, match('testing', 'ing', 5)) + call assert_equal(-1, match('testing', 'ing', 8)) + call assert_equal(1, match(['vim', 'testing', 'execute'], 'ing')) + call assert_equal(-1, match(['vim', 'testing', 'execute'], 'img')) +endfunc + func Test_matchend() call assert_equal(7, matchend('testing', 'ing')) call assert_equal(7, matchend('testing', 'ing', 2)) call assert_equal(-1, matchend('testing', 'ing', 5)) + call assert_equal(-1, matchend('testing', 'ing', 8)) + call assert_equal(match(['vim', 'testing', 'execute'], 'ing'), matchend(['vim', 'testing', 'execute'], 'ing')) + call assert_equal(match(['vim', 'testing', 'execute'], 'img'), matchend(['vim', 'testing', 'execute'], 'img')) +endfunc + +func Test_matchlist() + call assert_equal(['acd', 'a', '', 'c', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)')) + call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2)) + call assert_equal([], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 4)) +endfunc + +func Test_matchstr() + call assert_equal('ing', matchstr('testing', 'ing')) + call assert_equal('ing', matchstr('testing', 'ing', 2)) + call assert_equal('', matchstr('testing', 'ing', 5)) + call assert_equal('', matchstr('testing', 'ing', 8)) + call assert_equal('testing', matchstr(['vim', 'testing', 'execute'], 'ing')) + call assert_equal('', matchstr(['vim', 'testing', 'execute'], 'img')) +endfunc + +func Test_matchstrpos() + call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing')) + call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2)) + call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5)) + call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8)) + call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing')) + call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img')) endfunc func Test_nextnonblank_prevnonblank() @@ -616,6 +747,7 @@ endfunc func Test_byte2line_line2byte() new + set endofline call setline(1, ['a', 'bc', 'd']) set fileformat=unix @@ -636,7 +768,16 @@ func Test_byte2line_line2byte() call assert_equal([-1, -1, 1, 4, 8, 11, -1], \ map(range(-1, 5), 'line2byte(v:val)')) - set fileformat& + bw! + set noendofline nofixendofline + normal a- + for ff in ["unix", "mac", "dos"] + let &fileformat = ff + call assert_equal(1, line2byte(1)) + call assert_equal(2, line2byte(2)) " line2byte(line("$") + 1) is the buffer size plus one (as per :help line2byte). + endfor + + set endofline& fixendofline& fileformat& bw! endfunc @@ -680,7 +821,14 @@ func Test_count() call assert_equal(0, count(d, 'c', 1)) call assert_fails('call count(d, "a", 0, 1)', 'E474:') - call assert_fails('call count("a", "a")', 'E712:') + + call assert_equal(0, count("foo", "bar")) + call assert_equal(1, count("foo", "oo")) + call assert_equal(2, count("foo", "o")) + call assert_equal(0, count("foo", "O")) + call assert_equal(2, count("foo", "O", 1)) + call assert_equal(2, count("fooooo", "oo")) + call assert_equal(0, count("foo", "")) endfunc func Test_changenr() @@ -716,6 +864,19 @@ func Test_filewritable() bw! endfunc +func Test_Executable() + if has('win32') + call assert_equal(1, executable('notepad')) + call assert_equal(1, executable('notepad.exe')) + call assert_equal(0, executable('notepad.exe.exe')) + call assert_equal(1, executable('shell32.dll')) + call assert_equal(1, executable('win.ini')) + elseif has('unix') + call assert_equal(1, executable('cat')) + call assert_equal(0, executable('nodogshere')) + endif +endfunc + func Test_hostname() let hostname_vim = hostname() if has('unix') @@ -764,6 +925,17 @@ func Test_col() bw! endfunc +func Test_inputlist() + call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>1\<cr>", 'tx') + call assert_equal(1, c) + call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>2\<cr>", 'tx') + call assert_equal(2, c) + call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>3\<cr>", 'tx') + call assert_equal(3, c) + + call assert_fails('call inputlist("")', 'E686:') +endfunc + func Test_balloon_show() if has('balloon_eval') " This won't do anything but must not crash either. @@ -823,3 +995,45 @@ func Test_redo_in_nested_functions() delfunc Operator delfunc Apply endfunc + +func Test_trim() + call assert_equal("Testing", trim(" \t\r\r\x0BTesting \t\n\r\n\t\x0B\x0B")) + call assert_equal("Testing", trim(" \t \r\r\n\n\x0BTesting \t\n\r\n\t\x0B\x0B")) + call assert_equal("RESERVE", trim("xyz \twwRESERVEzyww \t\t", " wxyz\t")) + call assert_equal("wRE \tSERVEzyww", trim("wRE \tSERVEzyww")) + call assert_equal("abcd\t xxxx tail", trim(" \tabcd\t xxxx tail")) + call assert_equal("\tabcd\t xxxx tail", trim(" \tabcd\t xxxx tail", " ")) + call assert_equal(" \tabcd\t xxxx tail", trim(" \tabcd\t xxxx tail", "abx")) + call assert_equal("RESERVE", trim("ä½ RESERVE好", "ä½ å¥½")) + call assert_equal("您R E SER V Eæ—©", trim("ä½ å¥½æ‚¨R E SER V Eæ—©å¥½ä½ ä½ ", "ä½ å¥½")) + call assert_equal("ä½ å¥½æ‚¨R E SER V Eæ—©å¥½ä½ ä½ ", trim(" \n\r\r ä½ å¥½æ‚¨R E SER V Eæ—©å¥½ä½ ä½ \t \x0B", )) + call assert_equal("您R E SER V Eæ—©å¥½ä½ ä½ \t \x0B", trim(" ä½ å¥½æ‚¨R E SER V Eæ—©å¥½ä½ ä½ \t \x0B", " ä½ å¥½")) + call assert_equal("您R E SER V Eæ—©å¥½ä½ ä½ \t \x0B", trim(" tteessttttä½ å¥½æ‚¨R E SER V Eæ—©å¥½ä½ ä½ \t \x0B ttestt", " ä½ å¥½tes")) + call assert_equal("您R E SER V Eæ—©å¥½ä½ ä½ \t \x0B", trim(" tteessttttä½ å¥½æ‚¨R E SER V Eæ—©å¥½ä½ ä½ \t \x0B ttestt", " ä½ ä½ ä½ å¥½å¥½å¥½tttsses")) + call assert_equal("留下", trim("这些些ä¸è¦è¿™äº›ç•™ä¸‹è¿™äº›", "这些ä¸è¦")) + call assert_equal("", trim("", "")) + call assert_equal("a", trim("a", "")) + call assert_equal("", trim("", "a")) + + let chars = join(map(range(1, 0x20) + [0xa0], {n -> nr2char(n)}), '') + call assert_equal("x", trim(chars . "x" . chars)) +endfunc + +func EditAnotherFile() + let word = expand('<cword>') + edit Xfuncrange2 +endfunc + +func Test_func_range_with_edit() + " Define a function that edits another buffer, then call it with a range that + " is invalid in that buffer. + call writefile(['just one line'], 'Xfuncrange2') + new + call setline(1, range(10)) + write Xfuncrange1 + call assert_fails('5,8call EditAnotherFile()', 'E16:') + + call delete('Xfuncrange1') + call delete('Xfuncrange2') + bwipe! +endfunc diff --git a/src/nvim/testdir/test_ga.vim b/src/nvim/testdir/test_ga.vim index f9357ddc87..6a7cba28f0 100644 --- a/src/nvim/testdir/test_ga.vim +++ b/src/nvim/testdir/test_ga.vim @@ -11,13 +11,13 @@ func Test_ga_command() new set display=uhex call assert_equal("\nNUL", Do_ga('')) - call assert_equal("\n<<01>> 1, Hex 01, Octal 001", Do_ga("\x01")) - call assert_equal("\n<<09>> 9, Hex 09, Octal 011", Do_ga("\t")) + call assert_equal("\n<<01>> 1, Hex 01, Oct 001, Digr SH", Do_ga("\x01")) + call assert_equal("\n<<09>> 9, Hex 09, Oct 011, Digr HT", Do_ga("\t")) set display= call assert_equal("\nNUL", Do_ga('')) - call assert_equal("\n<^A> 1, Hex 01, Octal 001", Do_ga("\x01")) - call assert_equal("\n<^I> 9, Hex 09, Octal 011", Do_ga("\t")) + call assert_equal("\n<^A> 1, Hex 01, Oct 001, Digr SH", Do_ga("\x01")) + call assert_equal("\n<^I> 9, Hex 09, Oct 011, Digr HT", Do_ga("\t")) call assert_equal("\n<e> 101, Hex 65, Octal 145", Do_ga('e')) @@ -26,8 +26,8 @@ func Test_ga_command() endif " Test a few multi-bytes characters. - call assert_equal("\n<é> 233, Hex 00e9, Octal 351", Do_ga('é')) - call assert_equal("\n<ẻ> 7867, Hex 1ebb, Octal 17273", Do_ga('ẻ')) + call assert_equal("\n<é> 233, Hex 00e9, Oct 351, Digr e'", Do_ga('é')) + call assert_equal("\n<ẻ> 7867, Hex 1ebb, Oct 17273, Digr e2", Do_ga('ẻ')) " Test with combining characters. call assert_equal("\n<e> 101, Hex 65, Octal 145 < Ì> 769, Hex 0301, Octal 1401", Do_ga("e\u0301")) diff --git a/src/nvim/testdir/test_getcwd.vim b/src/nvim/testdir/test_getcwd.vim new file mode 100644 index 0000000000..5d97295e9a --- /dev/null +++ b/src/nvim/testdir/test_getcwd.vim @@ -0,0 +1,112 @@ +function! GetCwdInfo(win, tab) + let tab_changed = 0 + let mod = ":t" + if a:tab > 0 && a:tab != tabpagenr() + let tab_changed = 1 + exec "tabnext " . a:tab + endif + let bufname = fnamemodify(bufname(winbufnr(a:win)), mod) + if tab_changed + tabprevious + endif + if a:win == 0 && a:tab == 0 + let dirname = fnamemodify(getcwd(), mod) + let lflag = haslocaldir() + elseif a:tab == 0 + let dirname = fnamemodify(getcwd(a:win), mod) + let lflag = haslocaldir(a:win) + else + let dirname = fnamemodify(getcwd(a:win, a:tab), mod) + let lflag = haslocaldir(a:win, a:tab) + endif + return bufname . ' ' . dirname . ' ' . lflag +endfunction + +" Do all test in a separate window to avoid E211 when we recursively +" delete the Xtopdir directory during cleanup +function SetUp() + set visualbell + set nocp viminfo+=nviminfo + + " On windows a swapfile in Xtopdir prevents it from being cleaned up. + set noswapfile + + " On windows a stale "Xtopdir" directory may exist, remove it so that + " we start from a clean state. + call delete("Xtopdir", "rf") + new + call mkdir('Xtopdir') + cd Xtopdir + let g:topdir = getcwd() + call mkdir('Xdir1') + call mkdir('Xdir2') + call mkdir('Xdir3') +endfunction + +let g:cwd=getcwd() +function TearDown() + q + exec "cd " . g:cwd + call delete("Xtopdir", "rf") +endfunction + +function Test_GetCwd() + new a + new b + new c + 3wincmd w + lcd Xdir1 + call assert_equal("a Xdir1 1", GetCwdInfo(0, 0)) + call assert_equal(g:topdir, getcwd(-1)) + wincmd W + call assert_equal("b Xtopdir 0", GetCwdInfo(0, 0)) + call assert_equal(g:topdir, getcwd(-1)) + wincmd W + lcd Xdir3 + call assert_equal("c Xdir3 1", GetCwdInfo(0, 0)) + call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), 0)) + call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), 0)) + call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), 0)) + call assert_equal(g:topdir, getcwd(-1)) + wincmd W + call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), tabpagenr())) + call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), tabpagenr())) + call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), tabpagenr())) + call assert_equal(g:topdir, getcwd(-1)) + + tabnew x + new y + new z + 3wincmd w + call assert_equal("x Xtopdir 0", GetCwdInfo(0, 0)) + call assert_equal(g:topdir, getcwd(-1)) + wincmd W + lcd Xdir2 + call assert_equal("y Xdir2 1", GetCwdInfo(0, 0)) + call assert_equal(g:topdir, getcwd(-1)) + wincmd W + lcd Xdir3 + call assert_equal("z Xdir3 1", GetCwdInfo(0, 0)) + call assert_equal("x Xtopdir 0", GetCwdInfo(bufwinnr("x"), 0)) + call assert_equal("y Xdir2 1", GetCwdInfo(bufwinnr("y"), 0)) + call assert_equal("z Xdir3 1", GetCwdInfo(bufwinnr("z"), 0)) + call assert_equal(g:topdir, getcwd(-1)) + let tp_nr = tabpagenr() + tabrewind + call assert_equal("x Xtopdir 0", GetCwdInfo(3, tp_nr)) + call assert_equal("y Xdir2 1", GetCwdInfo(2, tp_nr)) + call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr)) + call assert_equal(g:topdir, getcwd(-1)) +endfunc + +function Test_GetCwd_lcd_shellslash() + new + let root = fnamemodify('/', ':p') + exe 'lcd '.root + let cwd = getcwd() + if !exists('+shellslash') || &shellslash + call assert_equal(cwd[-1:], '/') + else + call assert_equal(cwd[-1:], '\') + endif +endfunc diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim new file mode 100644 index 0000000000..d6b6b69aa8 --- /dev/null +++ b/src/nvim/testdir/test_getvar.vim @@ -0,0 +1,104 @@ +" Tests for getwinvar(), gettabvar() and gettabwinvar(). +func Test_var() + " Use strings to test for memory leaks. First, check that in an empty + " window, gettabvar() returns the correct value + let t:testvar='abcd' + call assert_equal('abcd', gettabvar(1, 'testvar')) + call assert_equal('abcd', gettabvar(1, 'testvar')) + + " test for getwinvar() + let w:var_str = "Dance" + let def_str = "Chance" + call assert_equal('Dance', getwinvar(1, 'var_str')) + call assert_equal('Dance', getwinvar(1, 'var_str', def_str)) + call assert_equal({'var_str': 'Dance'}, getwinvar(1, '')) + call assert_equal({'var_str': 'Dance'}, getwinvar(1, '', def_str)) + unlet w:var_str + call assert_equal('Chance', getwinvar(1, 'var_str', def_str)) + call assert_equal({}, getwinvar(1, '')) + call assert_equal({}, getwinvar(1, '', def_str)) + call assert_equal('', getwinvar(9, '')) + call assert_equal('Chance', getwinvar(9, '', def_str)) + call assert_equal(0, getwinvar(1, '&nu')) + call assert_equal(0, getwinvar(1, '&nu', 1)) + unlet def_str + + " test for gettabvar() + tabnew + tabnew + let t:var_list = [1, 2, 3] + let t:other = 777 + let def_list = [4, 5, 6, 7] + tabrewind + call assert_equal([1, 2, 3], gettabvar(3, 'var_list')) + call assert_equal([1, 2, 3], gettabvar(3, 'var_list', def_list)) + call assert_equal({'var_list': [1, 2, 3], 'other': 777}, gettabvar(3, '')) + call assert_equal({'var_list': [1, 2, 3], 'other': 777}, + \ gettabvar(3, '', def_list)) + + tablast + unlet t:var_list + tabrewind + call assert_equal([4, 5, 6, 7], gettabvar(3, 'var_list', def_list)) + call assert_equal('', gettabvar(9, '')) + call assert_equal([4, 5, 6, 7], gettabvar(9, '', def_list)) + call assert_equal('', gettabvar(3, '&nu')) + call assert_equal([4, 5, 6, 7], gettabvar(3, '&nu', def_list)) + unlet def_list + tabonly + + " test for gettabwinvar() + tabnew + tabnew + tabprev + split + split + wincmd w + vert split + wincmd w + let w:var_dict = {'dict': 'tabwin'} + let def_dict = {'dict2': 'newval'} + wincmd b + tabrewind + call assert_equal({'dict': 'tabwin'}, gettabwinvar(2, 3, 'var_dict')) + call assert_equal({'dict': 'tabwin'}, + \ gettabwinvar(2, 3, 'var_dict', def_dict)) + call assert_equal({'var_dict': {'dict': 'tabwin'}}, gettabwinvar(2, 3, '')) + call assert_equal({'var_dict': {'dict': 'tabwin'}}, + \ gettabwinvar(2, 3, '', def_dict)) + + tabnext + 3wincmd w + unlet w:var_dict + tabrewind + call assert_equal({'dict2': 'newval'}, + \ gettabwinvar(2, 3, 'var_dict', def_dict)) + call assert_equal({}, gettabwinvar(2, 3, '')) + call assert_equal({}, gettabwinvar(2, 3, '', def_dict)) + call assert_equal("", gettabwinvar(2, 9, '')) + call assert_equal({'dict2': 'newval'}, gettabwinvar(2, 9, '', def_dict)) + call assert_equal('', gettabwinvar(9, 3, '')) + call assert_equal({'dict2': 'newval'}, gettabwinvar(9, 3, '', def_dict)) + + unlet def_dict + + call assert_equal('', gettabwinvar(2, 3, '&nux')) + call assert_equal(1, gettabwinvar(2, 3, '&nux', 1)) + tabonly +endfunc + +" It was discovered that "gettabvar()" would fail if called from within the +" tabline when the user closed a window. This test confirms the fix. +func Test_gettabvar_in_tabline() + let t:var_str = 'value' + + set tabline=%{assert_equal('value',gettabvar(1,'var_str'))} + set showtabline=2 + + " Simulate the user opening a split (which becomes window #1) and then + " closing the split, which triggers the redrawing of the tabline. + leftabove split + redrawstatus! + close + redrawstatus! +endfunc diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim index ef1bf1075b..c352379697 100644 --- a/src/nvim/testdir/test_gf.vim +++ b/src/nvim/testdir/test_gf.vim @@ -7,7 +7,8 @@ func Test_gf_url() \ "first test for URL://machine.name/tmp/vimtest2a and other text", \ "second test for URL://machine.name/tmp/vimtest2b. And other text", \ "third test for URL:\\\\machine.name\\vimtest2c and other text", - \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text" + \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text", + \ "fifth test for URL://machine.name/tmp?q=vim&opt=yes and other text", \ ]) call cursor(1,1) call search("^first") @@ -28,6 +29,10 @@ func Test_gf_url() call search("URL") call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("<cfile>")) + call search("^fifth") + call search("URL") + call assert_equal("URL://machine.name/tmp?q=vim&opt=yes", expand("<cfile>")) + set isf&vim enew! endfunc diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim index b2a2937d88..405425a42b 100644 --- a/src/nvim/testdir/test_gn.vim +++ b/src/nvim/testdir/test_gn.vim @@ -5,51 +5,51 @@ func Test_gn_command() noautocmd new " replace a single char by itsself quoted: call setline('.', 'abc x def x ghi x jkl') - let @/='x' + let @/ = 'x' exe "norm! cgn'x'\<esc>.." call assert_equal("abc 'x' def 'x' ghi 'x' jkl", getline('.')) sil! %d_ " simple search match call setline('.', 'foobar') - let @/='foobar' + let @/ = 'foobar' exe "norm! gncsearchmatch" call assert_equal('searchmatch', getline('.')) sil! %d _ " replace a multi-line match call setline('.', ['', 'one', 'two']) - let @/='one\_s*two\_s' + let @/ = 'one\_s*two\_s' exe "norm! gnceins\<CR>zwei" call assert_equal(['','eins','zwei'], getline(1,'$')) sil! %d _ " test count argument call setline('.', ['', 'abcdx | abcdx | abcdx']) - let @/='[a]bcdx' + let @/ = '[a]bcdx' exe "norm! 2gnd" call assert_equal(['','abcdx | | abcdx'], getline(1,'$')) sil! %d _ " join lines call setline('.', ['join ', 'lines']) - let @/='$' + let @/ = '$' exe "norm! 0gnd" call assert_equal(['join lines'], getline(1,'$')) sil! %d _ " zero-width match call setline('.', ['', 'zero width pattern']) - let @/='\>\zs' + let @/ = '\>\zs' exe "norm! 0gnd" call assert_equal(['', 'zerowidth pattern'], getline(1,'$')) sil! %d _ " delete first and last chars call setline('.', ['delete first and last chars']) - let @/='^' + let @/ = '^' exe "norm! 0gnd$" - let @/='\zs' + let @/ = '\zs' exe "norm! gnd" call assert_equal(['elete first and last char'], getline(1,'$')) sil! %d _ @@ -62,14 +62,14 @@ func Test_gn_command() " backwards search call setline('.', ['my very excellent mother just served us nachos']) - let @/='mother' + let @/ = 'mother' exe "norm! $cgNmongoose" call assert_equal(['my very excellent mongoose just served us nachos'], getline(1,'$')) sil! %d _ " search for single char call setline('.', ['','for (i=0; i<=10; i++)']) - let @/='i' + let @/ = 'i' exe "norm! cgnj" call assert_equal(['','for (j=0; i<=10; i++)'], getline(1,'$')) sil! %d _ @@ -77,28 +77,28 @@ func Test_gn_command() " search hex char call setline('.', ['','Y']) set noignorecase - let @/='\%x59' + let @/ = '\%x59' exe "norm! gnd" call assert_equal(['',''], getline(1,'$')) sil! %d _ " test repeating gdn call setline('.', ['', '1', 'Johnny', '2', 'Johnny', '3']) - let @/='Johnny' + let @/ = 'Johnny' exe "norm! dgn." call assert_equal(['','1', '', '2', '', '3'], getline(1,'$')) sil! %d _ " test repeating gUgn call setline('.', ['', '1', 'Depp', '2', 'Depp', '3']) - let @/='Depp' + let @/ = 'Depp' exe "norm! gUgn." call assert_equal(['', '1', 'DEPP', '2', 'DEPP', '3'], getline(1,'$')) sil! %d _ " test using look-ahead assertions call setline('.', ['a:10', '', 'a:1', '', 'a:20']) - let @/='a:0\@!\zs\d\+' + let @/ = 'a:0\@!\zs\d\+' exe "norm! 2nygno\<esc>p" call assert_equal(['a:10', '', 'a:1', '1', '', 'a:20'], getline(1,'$')) sil! %d _ @@ -111,6 +111,24 @@ func Test_gn_command() call assert_equal(['foo baz'], getline(1,'$')) sil! %d_ + " search upwards with nowrapscan set + call setline('.', ['foo', 'bar', 'foo', 'baz']) + set nowrapscan + let @/ = 'foo' + $ + norm! dgN + call assert_equal(['foo', 'bar', '', 'baz'], getline(1,'$')) + sil! %d_ + + " search using the \zs atom + call setline(1, [' nnoremap', '' , 'nnoremap']) + set wrapscan&vim + let @/ = '\_s\zsnnoremap' + $ + norm! cgnmatch + call assert_equal([' nnoremap', '', 'match'], getline(1,'$')) + sil! %d_ + set wrapscan&vim set belloff&vim endfu diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim index ea67fe7386..c0235b1707 100644 --- a/src/nvim/testdir/test_goto.vim +++ b/src/nvim/testdir/test_goto.vim @@ -309,3 +309,65 @@ func Test_gd_local_block() \ ] call XTest_goto_decl('1gd', lines, 11, 11) endfunc + +func Test_motion_if_elif_else_endif() + new + a +/* Test pressing % on #if, #else #elsif and #endif, + * with nested #if + */ +#if FOO +/* ... */ +# if BAR +/* ... */ +# endif +#elif BAR +/* ... */ +#else +/* ... */ +#endif +. + /#if FOO + norm % + call assert_equal([9, 1], getpos('.')[1:2]) + norm % + call assert_equal([11, 1], getpos('.')[1:2]) + norm % + call assert_equal([13, 1], getpos('.')[1:2]) + norm % + call assert_equal([4, 1], getpos('.')[1:2]) + /# if BAR + norm $% + call assert_equal([8, 1], getpos('.')[1:2]) + norm $% + call assert_equal([6, 1], getpos('.')[1:2]) + + bw! +endfunc + +func Test_motion_c_comment() + new + a +/* + * Test pressing % on beginning/end + * of C comments. + */ +/* Another comment */ +. + norm gg0% + call assert_equal([4, 3], getpos('.')[1:2]) + norm % + call assert_equal([1, 1], getpos('.')[1:2]) + norm gg0l% + call assert_equal([4, 3], getpos('.')[1:2]) + norm h% + call assert_equal([1, 1], getpos('.')[1:2]) + + norm G^ + norm % + call assert_equal([5, 21], getpos('.')[1:2]) + norm % + call assert_equal([5, 1], getpos('.')[1:2]) + + bw! +endfunc diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim index f630556bef..ced13b107c 100644 --- a/src/nvim/testdir/test_hardcopy.vim +++ b/src/nvim/testdir/test_hardcopy.vim @@ -63,12 +63,27 @@ func Test_with_syntax() endfunc func Test_fname_with_spaces() - if has('postscript') - split t\ e\ s\ t.txt - call setline(1, ['just', 'some', 'text']) - hardcopy > %.ps - call assert_true(filereadable('t e s t.txt.ps')) - call delete('t e s t.txt.ps') - bwipe! + if !has('postscript') + return + endif + split t\ e\ s\ t.txt + call setline(1, ['just', 'some', 'text']) + hardcopy > %.ps + call assert_true(filereadable('t e s t.txt.ps')) + call delete('t e s t.txt.ps') + bwipe! +endfunc + +func Test_illegal_byte() + if !has('postscript') || &enc != 'utf-8' + return endif + new + " conversion of 0xff will fail, this used to cause a crash + call setline(1, "\xff") + hardcopy >Xpstest + + bwipe! + call delete('Xpstest') endfunc + diff --git a/src/nvim/testdir/test_help.vim b/src/nvim/testdir/test_help.vim index 26edc16107..ed3181564c 100644 --- a/src/nvim/testdir/test_help.vim +++ b/src/nvim/testdir/test_help.vim @@ -13,4 +13,40 @@ endfunc func Test_help_errors() call assert_fails('help doesnotexist', 'E149:') call assert_fails('help!', 'E478:') + + new + set keywordprg=:help + call setline(1, " ") + call assert_fails('normal VK', 'E349:') + bwipe! +endfunc + +func Test_help_keyword() + new + set keywordprg=:help + call setline(1, " Visual ") + normal VK + call assert_match('^Visual mode', getline('.')) + call assert_equal('help', &ft) + close + bwipe! +endfunc + +func Test_help_local_additions() + call mkdir('Xruntime/doc', 'p') + call writefile(['*mydoc.txt* my awesome doc'], 'Xruntime/doc/mydoc.txt') + call writefile(['*mydoc-ext.txt* my extended awesome doc'], 'Xruntime/doc/mydoc-ext.txt') + let rtp_save = &rtp + set rtp+=./Xruntime + help + 1 + call search('mydoc.txt') + call assert_equal('|mydoc.txt| my awesome doc', getline('.')) + 1 + call search('mydoc-ext.txt') + call assert_equal('|mydoc-ext.txt| my extended awesome doc', getline('.')) + close + + call delete('Xruntime', 'rf') + let &rtp = rtp_save endfunc diff --git a/src/nvim/testdir/test_help_tagjump.vim b/src/nvim/testdir/test_help_tagjump.vim index 4d4a902031..c873487b92 100644 --- a/src/nvim/testdir/test_help_tagjump.vim +++ b/src/nvim/testdir/test_help_tagjump.vim @@ -38,6 +38,34 @@ func Test_help_tagjump() call assert_true(getline('.') =~ '\*:?\*') helpclose + help q? + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ '\*q?\*') + call assert_true(expand('<cword>') == 'q?') + helpclose + + help -? + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ '\*-?\*') + helpclose + + help v_g? + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ '\*v_g?\*') + helpclose + + help expr-!=? + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ '\*expr-!=?\*') + call assert_true(expand('<cword>') == 'expr-!=?') + helpclose + + help expr-isnot? + call assert_equal("help", &filetype) + call assert_true(getline('.') =~ '\*expr-isnot?\*') + call assert_true(expand('<cword>') == 'expr-isnot?') + helpclose + help FileW*Post call assert_equal("help", &filetype) call assert_true(getline('.') =~ '\*FileWritePost\*') diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim new file mode 100644 index 0000000000..33df79581c --- /dev/null +++ b/src/nvim/testdir/test_highlight.vim @@ -0,0 +1,535 @@ +" Tests for ":highlight" and highlighting. + +source view_util.vim + +func Test_highlight() + " basic test if ":highlight" doesn't crash + highlight + hi Search + + " test setting colors. + " test clearing one color and all doesn't generate error or warning + silent! hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan + silent! hi Group2 term= cterm= + hi Group3 term=underline cterm=bold + + let res = split(execute("hi NewGroup"), "\n")[0] + " filter ctermfg and ctermbg, the numbers depend on the terminal + let res = substitute(res, 'ctermfg=\d*', 'ctermfg=2', '') + let res = substitute(res, 'ctermbg=\d*', 'ctermbg=3', '') + call assert_equal("NewGroup xxx cterm=italic ctermfg=2 ctermbg=3", + \ res) + call assert_equal("Group2 xxx cleared", + \ split(execute("hi Group2"), "\n")[0]) + call assert_equal("Group3 xxx cterm=bold", + \ split(execute("hi Group3"), "\n")[0]) + + hi clear NewGroup + call assert_equal("NewGroup xxx cleared", + \ split(execute("hi NewGroup"), "\n")[0]) + call assert_equal("Group2 xxx cleared", + \ split(execute("hi Group2"), "\n")[0]) + hi Group2 NONE + call assert_equal("Group2 xxx cleared", + \ split(execute("hi Group2"), "\n")[0]) + hi clear + call assert_equal("Group3 xxx cleared", + \ split(execute("hi Group3"), "\n")[0]) + call assert_fails("hi Crash term='asdf", "E475:") +endfunc + +function! HighlightArgs(name) + return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '') +endfunction + +function! IsColorable() + return has('gui_running') || str2nr(&t_Co) >= 8 +endfunction + +function! HiCursorLine() + let hiCursorLine = HighlightArgs('CursorLine') + if has('gui_running') + let guibg = matchstr(hiCursorLine, 'guibg=\w\+') + let hi_ul = 'hi CursorLine gui=underline guibg=NONE' + let hi_bg = 'hi CursorLine gui=NONE ' . guibg + else + let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE' + let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray' + endif + return [hiCursorLine, hi_ul, hi_bg] +endfunction + +function! Check_lcs_eol_attrs(attrs, row, col) + let save_lcs = &lcs + set list + + call assert_equal(a:attrs, ScreenAttrs(a:row, a:col)[0]) + + set nolist + let &lcs = save_lcs +endfunction + +func Test_highlight_eol_with_cursorline() + let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() + + call NewWindow('topleft 5', 20) + call setline(1, 'abcd') + call matchadd('Search', '\n') + + " expected: + " 'abcd ' + " ^^^^ ^^^^^ no highlight + " ^ 'Search' highlight + let attrs0 = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3]) + call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9]) + call assert_notequal(attrs0[0], attrs0[4]) + + setlocal cursorline + + " underline + exe hi_ul + + " expected: + " 'abcd ' + " ^^^^ underline + " ^ 'Search' highlight with underline + " ^^^^^ underline + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[0]], 4), attrs[0:3]) + call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9]) + call assert_notequal(attrs[0], attrs[4]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[4], attrs[4]) + call Check_lcs_eol_attrs(attrs, 1, 10) + + if IsColorable() + " bg-color + exe hi_bg + + " expected: + " 'abcd ' + " ^^^^ bg-color of 'CursorLine' + " ^ 'Search' highlight + " ^^^^^ bg-color of 'CursorLine' + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[0]], 4), attrs[0:3]) + call assert_equal(repeat([attrs[5]], 5), attrs[5:9]) + call assert_equal(attrs0[4], attrs[4]) + call assert_notequal(attrs[0], attrs[4]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[5], attrs[5]) + call Check_lcs_eol_attrs(attrs, 1, 10) + endif + + call CloseWindow() + exe hiCursorLine +endfunc + +func Test_highlight_eol_with_cursorline_vertsplit() + if !has('vertsplit') + return + endif + + let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() + + call NewWindow('topleft 5', 5) + call setline(1, 'abcd') + call matchadd('Search', '\n') + + let expected = "abcd |abcd " + let actual = ScreenLines(1, 15)[0] + call assert_equal(expected, actual) + + " expected: + " 'abcd |abcd ' + " ^^^^ ^^^^^^^^^ no highlight + " ^ 'Search' highlight + " ^ 'VertSplit' highlight + let attrs0 = ScreenAttrs(1, 15)[0] + call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3]) + call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14]) + call assert_notequal(attrs0[0], attrs0[4]) + call assert_notequal(attrs0[0], attrs0[5]) + call assert_notequal(attrs0[4], attrs0[5]) + + setlocal cursorline + + " expected: + " 'abcd |abcd ' + " ^^^^ underline + " ^ 'Search' highlight with underline + " ^ 'VertSplit' highlight + " ^^^^^^^^^ no highlight + + " underline + exe hi_ul + + let actual = ScreenLines(1, 15)[0] + call assert_equal(expected, actual) + + let attrs = ScreenAttrs(1, 15)[0] + call assert_equal(repeat([attrs[0]], 4), attrs[0:3]) + call assert_equal(repeat([attrs[6]], 9), attrs[6:14]) + call assert_equal(attrs0[5:14], attrs[5:14]) + call assert_notequal(attrs[0], attrs[4]) + call assert_notequal(attrs[0], attrs[5]) + call assert_notequal(attrs[0], attrs[6]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs[5], attrs[6]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[4], attrs[4]) + call Check_lcs_eol_attrs(attrs, 1, 15) + + if IsColorable() + " bg-color + exe hi_bg + + let actual = ScreenLines(1, 15)[0] + call assert_equal(expected, actual) + + let attrs = ScreenAttrs(1, 15)[0] + call assert_equal(repeat([attrs[0]], 4), attrs[0:3]) + call assert_equal(repeat([attrs[6]], 9), attrs[6:14]) + call assert_equal(attrs0[5:14], attrs[5:14]) + call assert_notequal(attrs[0], attrs[4]) + call assert_notequal(attrs[0], attrs[5]) + call assert_notequal(attrs[0], attrs[6]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs[5], attrs[6]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_equal(attrs0[4], attrs[4]) + call Check_lcs_eol_attrs(attrs, 1, 15) + endif + + call CloseWindow() + exe hiCursorLine +endfunc + +func Test_highlight_eol_with_cursorline_rightleft() + if !has('rightleft') + return + endif + + let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() + + call NewWindow('topleft 5', 10) + setlocal rightleft + call setline(1, 'abcd') + call matchadd('Search', '\n') + let attrs0 = ScreenAttrs(1, 10)[0] + + setlocal cursorline + + " underline + exe hi_ul + + " expected: + " ' dcba' + " ^^^^ underline + " ^ 'Search' highlight with underline + " ^^^^^ underline + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[9]], 4), attrs[6:9]) + call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5]) + call assert_notequal(attrs[9], attrs[5]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs0[9], attrs[9]) + call assert_notequal(attrs0[5], attrs[5]) + call Check_lcs_eol_attrs(attrs, 1, 10) + + if IsColorable() + " bg-color + exe hi_bg + + " expected: + " ' dcba' + " ^^^^ bg-color of 'CursorLine' + " ^ 'Search' highlight + " ^^^^^ bg-color of 'CursorLine' + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[9]], 4), attrs[6:9]) + call assert_equal(repeat([attrs[4]], 5), attrs[0:4]) + call assert_equal(attrs0[5], attrs[5]) + call assert_notequal(attrs[9], attrs[5]) + call assert_notequal(attrs[5], attrs[4]) + call assert_notequal(attrs0[9], attrs[9]) + call assert_notequal(attrs0[4], attrs[4]) + call Check_lcs_eol_attrs(attrs, 1, 10) + endif + + call CloseWindow() + exe hiCursorLine +endfunc + +func Test_highlight_eol_with_cursorline_linewrap() + let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() + + call NewWindow('topleft 5', 10) + call setline(1, [repeat('a', 51) . 'bcd', '']) + call matchadd('Search', '\n') + + setlocal wrap + normal! gg$ + let attrs0 = ScreenAttrs(5, 10)[0] + setlocal cursorline + + " underline + exe hi_ul + + " expected: + " 'abcd ' + " ^^^^ underline + " ^ 'Search' highlight with underline + " ^^^^^ underline + let attrs = ScreenAttrs(5, 10)[0] + call assert_equal(repeat([attrs[0]], 4), attrs[0:3]) + call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9]) + call assert_notequal(attrs[0], attrs[4]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[4], attrs[4]) + call Check_lcs_eol_attrs(attrs, 5, 10) + + if IsColorable() + " bg-color + exe hi_bg + + " expected: + " 'abcd ' + " ^^^^ bg-color of 'CursorLine' + " ^ 'Search' highlight + " ^^^^^ bg-color of 'CursorLine' + let attrs = ScreenAttrs(5, 10)[0] + call assert_equal(repeat([attrs[0]], 4), attrs[0:3]) + call assert_equal(repeat([attrs[5]], 5), attrs[5:9]) + call assert_equal(attrs0[4], attrs[4]) + call assert_notequal(attrs[0], attrs[4]) + call assert_notequal(attrs[4], attrs[5]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[5], attrs[5]) + call Check_lcs_eol_attrs(attrs, 5, 10) + endif + + setlocal nocursorline nowrap + normal! gg$ + let attrs0 = ScreenAttrs(1, 10)[0] + setlocal cursorline + + " underline + exe hi_ul + + " expected: + " 'aaabcd ' + " ^^^^^^ underline + " ^ 'Search' highlight with underline + " ^^^ underline + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[0]], 6), attrs[0:5]) + call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9]) + call assert_notequal(attrs[0], attrs[6]) + call assert_notequal(attrs[6], attrs[7]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[6], attrs[6]) + call Check_lcs_eol_attrs(attrs, 1, 10) + + if IsColorable() + " bg-color + exe hi_bg + + " expected: + " 'aaabcd ' + " ^^^^^^ bg-color of 'CursorLine' + " ^ 'Search' highlight + " ^^^ bg-color of 'CursorLine' + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[0]], 6), attrs[0:5]) + call assert_equal(repeat([attrs[7]], 3), attrs[7:9]) + call assert_equal(attrs0[6], attrs[6]) + call assert_notequal(attrs[0], attrs[6]) + call assert_notequal(attrs[6], attrs[7]) + call assert_notequal(attrs0[0], attrs[0]) + call assert_notequal(attrs0[7], attrs[7]) + call Check_lcs_eol_attrs(attrs, 1, 10) + endif + + call CloseWindow() + exe hiCursorLine +endfunc + +func Test_highlight_eol_with_cursorline_sign() + if !has('signs') + return + endif + + let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() + + call NewWindow('topleft 5', 10) + call setline(1, 'abcd') + call matchadd('Search', '\n') + + sign define Sign text=>> + exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('') + let attrs0 = ScreenAttrs(1, 10)[0] + setlocal cursorline + + " underline + exe hi_ul + + " expected: + " '>>abcd ' + " ^^ sign + " ^^^^ underline + " ^ 'Search' highlight with underline + " ^^^ underline + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[2]], 4), attrs[2:5]) + call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9]) + call assert_notequal(attrs[2], attrs[6]) + call assert_notequal(attrs[6], attrs[7]) + call assert_notequal(attrs0[2], attrs[2]) + call assert_notequal(attrs0[6], attrs[6]) + call Check_lcs_eol_attrs(attrs, 1, 10) + + if IsColorable() + " bg-color + exe hi_bg + + " expected: + " '>>abcd ' + " ^^ sign + " ^^^^ bg-color of 'CursorLine' + " ^ 'Search' highlight + " ^^^ bg-color of 'CursorLine' + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[2]], 4), attrs[2:5]) + call assert_equal(repeat([attrs[7]], 3), attrs[7:9]) + call assert_equal(attrs0[6], attrs[6]) + call assert_notequal(attrs[2], attrs[6]) + call assert_notequal(attrs[6], attrs[7]) + call assert_notequal(attrs0[2], attrs[2]) + call assert_notequal(attrs0[7], attrs[7]) + call Check_lcs_eol_attrs(attrs, 1, 10) + endif + + sign unplace 1 + call CloseWindow() + exe hiCursorLine +endfunc + +func Test_highlight_eol_with_cursorline_breakindent() + if !has('linebreak') + return + endif + + let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() + + call NewWindow('topleft 5', 10) + setlocal breakindent breakindentopt=min:0,shift:1 showbreak=> + call setline(1, ' ' . repeat('a', 9) . 'bcd') + call matchadd('Search', '\n') + let attrs0 = ScreenAttrs(2, 10)[0] + setlocal cursorline + + " underline + exe hi_ul + + " expected: + " ' >bcd ' + " ^^^ breakindent and showbreak + " ^^^ underline + " ^ 'Search' highlight with underline + " ^^^ underline + let attrs = ScreenAttrs(2, 10)[0] + call assert_equal(repeat([attrs[0]], 2), attrs[0:1]) + call assert_equal(repeat([attrs[3]], 3), attrs[3:5]) + call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9]) + call assert_equal(attrs0[0], attrs[0]) + call assert_notequal(attrs[0], attrs[2]) + call assert_notequal(attrs[2], attrs[3]) + call assert_notequal(attrs[3], attrs[6]) + call assert_notequal(attrs[6], attrs[7]) + call assert_notequal(attrs0[2], attrs[2]) + call assert_notequal(attrs0[3], attrs[3]) + call assert_notequal(attrs0[6], attrs[6]) + call Check_lcs_eol_attrs(attrs, 2, 10) + + if IsColorable() + " bg-color + exe hi_bg + + " expected: + " ' >bcd ' + " ^^^ breakindent and showbreak + " ^^^ bg-color of 'CursorLine' + " ^ 'Search' highlight + " ^^^ bg-color of 'CursorLine' + let attrs = ScreenAttrs(2, 10)[0] + call assert_equal(repeat([attrs[0]], 2), attrs[0:1]) + call assert_equal(repeat([attrs[3]], 3), attrs[3:5]) + call assert_equal(repeat([attrs[7]], 3), attrs[7:9]) + call assert_equal(attrs0[0], attrs[0]) + call assert_equal(attrs0[6], attrs[6]) + call assert_notequal(attrs[0], attrs[2]) + call assert_notequal(attrs[2], attrs[3]) + call assert_notequal(attrs[3], attrs[6]) + call assert_notequal(attrs[6], attrs[7]) + call assert_notequal(attrs0[2], attrs[2]) + call assert_notequal(attrs0[3], attrs[3]) + call assert_notequal(attrs0[7], attrs[7]) + call Check_lcs_eol_attrs(attrs, 2, 10) + endif + + call CloseWindow() + set showbreak= + exe hiCursorLine +endfunc + +func Test_highlight_eol_on_diff() + call setline(1, ['abcd', '']) + call matchadd('Search', '\n') + let attrs0 = ScreenAttrs(1, 10)[0] + + diffthis + botright new + diffthis + + " expected: + " ' abcd ' + " ^^ sign + " ^^^^ ^^^ 'DiffAdd' highlight + " ^ 'Search' highlight + let attrs = ScreenAttrs(1, 10)[0] + call assert_equal(repeat([attrs[0]], 2), attrs[0:1]) + call assert_equal(repeat([attrs[2]], 4), attrs[2:5]) + call assert_equal(repeat([attrs[2]], 3), attrs[7:9]) + call assert_equal(attrs0[4], attrs[6]) + call assert_notequal(attrs[0], attrs[2]) + call assert_notequal(attrs[0], attrs[6]) + call assert_notequal(attrs[2], attrs[6]) + call Check_lcs_eol_attrs(attrs, 1, 10) + + bwipe! + diffoff +endfunc + +func Test_termguicolors() + if !exists('+termguicolors') + return + endif + if has('vtp') && !has('vcon') + " Win32: 'guicolors' doesn't work without virtual console. + call assert_fails('set termguicolors', 'E954:') + return + endif + + " Basic test that setting 'termguicolors' works with one color. + set termguicolors + redraw + set t_Co=1 + redraw + set t_Co=0 + redraw +endfunc diff --git a/src/nvim/testdir/test_hlsearch.vim b/src/nvim/testdir/test_hlsearch.vim index 066fdd0250..1fc7b04f88 100644 --- a/src/nvim/testdir/test_hlsearch.vim +++ b/src/nvim/testdir/test_hlsearch.vim @@ -4,7 +4,6 @@ function! Test_hlsearch() new call setline(1, repeat(['aaa'], 10)) set hlsearch nolazyredraw - let r=[] " redraw is needed to make hlsearch highlight the matches exe "normal! /aaa\<CR>" | redraw let r1 = screenattr(1, 1) @@ -32,3 +31,16 @@ function! Test_hlsearch() call getchar(1) enew! endfunction + +func Test_hlsearch_eol_highlight() + new + call append(1, repeat([''], 9)) + set hlsearch nolazyredraw + exe "normal! /$\<CR>" | redraw + let attr = screenattr(1, 1) + for row in range(2, 10) + call assert_equal(attr, screenattr(row, 1), 'in line ' . row) + endfor + set nohlsearch + bwipe! +endfunc diff --git a/src/nvim/testdir/test_increment.vim b/src/nvim/testdir/test_increment.vim index 8bfd95d810..ab11d943d9 100644 --- a/src/nvim/testdir/test_increment.vim +++ b/src/nvim/testdir/test_increment.vim @@ -3,6 +3,7 @@ func SetUp() new dummy set nrformats&vim + set nrformats+=octal endfunc func TearDown() @@ -364,11 +365,25 @@ endfunc " Expected: " 1) Ctrl-a on visually selected zero " 111 +" +" Also: 019 with "01" selected increments to "029". func Test_visual_increment_15() call setline(1, ["101"]) exec "norm! lv\<C-A>" call assert_equal(["111"], getline(1, '$')) call assert_equal([0, 1, 2, 0], getpos('.')) + + call setline(1, ["019"]) + exec "norm! 0vl\<C-A>" + call assert_equal("029", getline(1)) + + call setline(1, ["01239"]) + exec "norm! 0vlll\<C-A>" + call assert_equal("01249", getline(1)) + + call setline(1, ["01299"]) + exec "norm! 0vlll\<C-A>" + call assert_equal("1309", getline(1)) endfunc " 16) increment right aligned numbers @@ -756,5 +771,12 @@ func Test_normal_increment_03() call assert_equal([0, 3, 25, 0], getpos('.')) endfunc +func Test_increment_empty_line() + new + call setline(1, ['0', '0', '0', '0', '0', '0', '']) + exe "normal Gvgg\<C-A>" + call assert_equal(['1', '1', '1', '1', '1', '1', ''], getline(1, 7)) + bwipe! +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index c307e33cbf..5ff63e58ba 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -217,3 +217,22 @@ function Test_CompleteDoneList() let s:called_completedone = 0 au! CompleteDone endfunc + +func Test_omni_dash() + func Omni(findstart, base) + if a:findstart + return 5 + else + echom a:base + return ['-help', '-v'] + endif + endfunc + set omnifunc=Omni + new + exe "normal Gofind -\<C-x>\<C-o>" + call assert_equal("\n-\nmatch 1 of 2", execute(':2mess')) + + bwipe! + delfunc Omni + set omnifunc= +endfunc diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim new file mode 100644 index 0000000000..1c97414164 --- /dev/null +++ b/src/nvim/testdir/test_join.vim @@ -0,0 +1,35 @@ +" Test for joining lines. + +func Test_join_with_count() + new + call setline(1, ['one', 'two', 'three', 'four']) + normal J + call assert_equal('one two', getline(1)) + %del + call setline(1, ['one', 'two', 'three', 'four']) + normal 10J + call assert_equal('one two three four', getline(1)) + quit! +endfunc + +" Tests for setting the '[,'] marks when joining lines. +func Test_join_marks() + enew + call append(0, [ + \ "\t\tO sodales, ludite, vos qui", + \ "attamen consulite per voster honur. Tua pulchra " . + \ "facies me fay planszer milies", + \ "", + \ "This line.", + \ "Should be joined with the next line", + \ "and with this line"]) + + normal gg0gqj + call assert_equal([0, 1, 1, 0], getpos("'[")) + call assert_equal([0, 2, 1, 0], getpos("']")) + + /^This line/;'}-join + call assert_equal([0, 4, 11, 0], getpos("'[")) + call assert_equal([0, 4, 67, 0], getpos("']")) + enew! +endfunc diff --git a/src/nvim/testdir/test_lambda.vim b/src/nvim/testdir/test_lambda.vim index 311cc6e2cb..2ac84c2213 100644 --- a/src/nvim/testdir/test_lambda.vim +++ b/src/nvim/testdir/test_lambda.vim @@ -31,11 +31,11 @@ function! Test_lambda_with_timer() endfunction call s:Foo() - sleep 200ms + sleep 210ms " do not collect lambda call garbagecollect() let m = s:n - sleep 200ms + sleep 210ms call timer_stop(s:timer_id) call assert_true(m > 1) call assert_true(s:n > m + 1) diff --git a/src/nvim/testdir/test_largefile.vim b/src/nvim/testdir/test_largefile.vim index 1b3e02a0c8..3f9c2dc150 100644 --- a/src/nvim/testdir/test_largefile.vim +++ b/src/nvim/testdir/test_largefile.vim @@ -1,5 +1,5 @@ " Tests for large files -" This is only executed manually: "make test_largefile". +" This is only executed manually: "TEST_FILE=test_largefile.res make oldtest". " This is not run as part of "make test". func Test_largefile() diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim index 023332c90a..999d4dbd4a 100644 --- a/src/nvim/testdir/test_listdict.vim +++ b/src/nvim/testdir/test_listdict.vim @@ -106,6 +106,43 @@ func Test_list_range_assign() call assert_equal([1, 2], l) endfunc +" Test removing items in list +func Test_list_func_remove() + " Test removing 1 element + let l = [1, 2, 3, 4] + call assert_equal(1, remove(l, 0)) + call assert_equal([2, 3, 4], l) + + let l = [1, 2, 3, 4] + call assert_equal(2, remove(l, 1)) + call assert_equal([1, 3, 4], l) + + let l = [1, 2, 3, 4] + call assert_equal(4, remove(l, -1)) + call assert_equal([1, 2, 3], l) + + " Test removing range of element(s) + let l = [1, 2, 3, 4] + call assert_equal([3], remove(l, 2, 2)) + call assert_equal([1, 2, 4], l) + + let l = [1, 2, 3, 4] + call assert_equal([2, 3], remove(l, 1, 2)) + call assert_equal([1, 4], l) + + let l = [1, 2, 3, 4] + call assert_equal([2, 3], remove(l, -3, -2)) + call assert_equal([1, 4], l) + + " Test invalid cases + let l = [1, 2, 3, 4] + call assert_fails("call remove(l, 5)", 'E684:') + call assert_fails("call remove(l, 1, 5)", 'E684:') + call assert_fails("call remove(l, 3, 2)", 'E16:') + call assert_fails("call remove(1, 0)", 'E712:') + call assert_fails("call remove(l, l)", 'E745:') +endfunc + " Tests for Dictionary type func Test_dict() @@ -222,6 +259,17 @@ func Test_script_local_dict_func() unlet g:dict endfunc +" Test removing items in la dictionary +func Test_dict_func_remove() + let d = {1:'a', 2:'b', 3:'c'} + call assert_equal('b', remove(d, 2)) + call assert_equal({1:'a', 3:'c'}, d) + + call assert_fails("call remove(d, 1, 2)", 'E118:') + call assert_fails("call remove(d, 'a')", 'E716:') + call assert_fails("call remove(d, [])", 'E730:') +endfunc + " Nasty: remove func from Dict that's being called (works) func Test_dict_func_remove_in_use() let d = {1:1} diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim new file mode 100644 index 0000000000..0fb878b04a --- /dev/null +++ b/src/nvim/testdir/test_maparg.vim @@ -0,0 +1,56 @@ +" Tests for maparg(). +" Also test utf8 map with a 0x80 byte. +if !has("multi_byte") + finish +endif + +function s:SID() + return str2nr(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')) +endfun + +function Test_maparg() + new + set cpo-=< + set encoding=utf8 + " Test maparg() with a string result + map foo<C-V> is<F4>foo + vnoremap <script> <buffer> <expr> <silent> bar isbar + let sid = s:SID() + call assert_equal("is<F4>foo", maparg('foo<C-V>')) + call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>', + \ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'rhs': 'is<F4>foo', + \ 'buffer': 0}, maparg('foo<C-V>', '', 0, 1)) + call assert_equal({'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v', + \ 'nowait': 0, 'expr': 1, 'sid': sid, 'rhs': 'isbar', 'buffer': 1}, + \ maparg('bar', '', 0, 1)) + map <buffer> <nowait> foo bar + call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ', + \ 'nowait': 1, 'expr': 0, 'sid': sid, 'rhs': 'bar', 'buffer': 1}, + \ maparg('foo', '', 0, 1)) + + map abc x<char-114>x + call assert_equal("xrx", maparg('abc')) + map abc y<S-char-114>y + call assert_equal("yRy", maparg('abc')) + + map abc <Nop> + call assert_equal("<Nop>", maparg('abc')) + unmap abc +endfunction + +function Test_range_map() + new + " Outside of the range, minimum + inoremap <Char-0x1040> a + execute "normal a\u1040\<Esc>" + " Inside of the range, minimum + inoremap <Char-0x103f> b + execute "normal a\u103f\<Esc>" + " Inside of the range, maximum + inoremap <Char-0xf03f> c + execute "normal a\uf03f\<Esc>" + " Outside of the range, maximum + inoremap <Char-0xf040> d + execute "normal a\uf040\<Esc>" + call assert_equal("abcd", getline(1)) +endfunction diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index f4fe1c2705..247c01c98d 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -198,3 +198,35 @@ func Test_map_timeout() set timeoutlen& delfunc ExitInsert endfunc + +func Test_cabbr_visual_mode() + cabbr s su + call feedkeys(":s \<c-B>\"\<CR>", 'itx') + call assert_equal('"su ', getreg(':')) + call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx') + let expected = '"'. "'<,'>su " + call assert_equal(expected, getreg(':')) + call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx') + let expected = '" '. "'<,'>su " + call assert_equal(expected, getreg(':')) + call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx') + let expected = '"'. "'a,'bsu " + call assert_equal(expected, getreg(':')) + cunabbr s +endfunc + +func Test_abbreviation_CR() + new + func Eatchar(pat) + let c = nr2char(getchar(0)) + return (c =~ a:pat) ? '' : c + endfunc + iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr> + call feedkeys("GA~~7 \<esc>", 'xt') + call assert_equal('~~~~~~~', getline('$')) + %d + call feedkeys("GA~~7\<cr>\<esc>", 'xt') + call assert_equal(['~~~~~~~', ''], getline(1,'$')) + delfunc Eatchar + bw! +endfunc diff --git a/src/nvim/testdir/test_marks.vim b/src/nvim/testdir/test_marks.vim index 18a0c71aab..8858cd22b8 100644 --- a/src/nvim/testdir/test_marks.vim +++ b/src/nvim/testdir/test_marks.vim @@ -68,3 +68,71 @@ func Test_setpos() call win_gotoid(twowin) bwipe! endfunc + +func Test_marks_cmd() + new Xone + call setline(1, ['aaa', 'bbb']) + norm! maG$mB + w! + new Xtwo + call setline(1, ['ccc', 'ddd']) + norm! $mcGmD + w! + + b Xone + let a = split(execute('marks'), "\n") + call assert_equal(9, len(a)) + call assert_equal('mark line col file/text', a[0]) + call assert_equal(" ' 2 0 bbb", a[1]) + call assert_equal(' a 1 0 aaa', a[2]) + call assert_equal(' B 2 2 bbb', a[3]) + call assert_equal(' D 2 0 Xtwo', a[4]) + call assert_equal(' " 1 0 aaa', a[5]) + call assert_equal(' [ 1 0 aaa', a[6]) + call assert_equal(' ] 2 0 bbb', a[7]) + call assert_equal(' . 2 0 bbb', a[8]) + + b Xtwo + let a = split(execute('marks'), "\n") + call assert_equal(9, len(a)) + call assert_equal('mark line col file/text', a[0]) + call assert_equal(" ' 1 0 ccc", a[1]) + call assert_equal(' c 1 2 ccc', a[2]) + call assert_equal(' B 2 2 Xone', a[3]) + call assert_equal(' D 2 0 ddd', a[4]) + call assert_equal(' " 2 0 ddd', a[5]) + call assert_equal(' [ 1 0 ccc', a[6]) + call assert_equal(' ] 2 0 ddd', a[7]) + call assert_equal(' . 2 0 ddd', a[8]) + + b Xone + delmarks aB + let a = split(execute('marks aBcD'), "\n") + call assert_equal(2, len(a)) + call assert_equal('mark line col file/text', a[0]) + call assert_equal(' D 2 0 Xtwo', a[1]) + + b Xtwo + delmarks cD + call assert_fails('marks aBcD', 'E283:') + + call delete('Xone') + call delete('Xtwo') + %bwipe +endfunc + +func Test_marks_cmd_multibyte() + if !has('multi_byte') + return + endif + new Xone + call setline(1, [repeat('á', &columns)]) + norm! ma + + let a = split(execute('marks a'), "\n") + call assert_equal(2, len(a)) + let expected = ' a 1 0 ' . repeat('á', &columns - 16) + call assert_equal(expected, a[1]) + + bwipe! +endfunc diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index 066bb2f6a1..e608a2e58b 100644 --- a/src/nvim/testdir/test_match.vim +++ b/src/nvim/testdir/test_match.vim @@ -1,5 +1,5 @@ " Test for :match, :2match, :3match, clearmatches(), getmatches(), matchadd(), -" matchaddpos(), matcharg(), matchdelete(), matchstrpos() and setmatches(). +" matchaddpos(), matcharg(), matchdelete(), and setmatches(). function Test_match() highlight MyGroup1 term=bold ctermbg=red guibg=red @@ -150,18 +150,6 @@ function Test_match() highlight MyGroup3 NONE endfunc -func Test_matchstrpos() - call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing')) - - call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2)) - - call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5)) - - call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing')) - - call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img')) -endfunc - func Test_matchaddpos() syntax on set hlsearch diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim index c11f1a84a9..b918525dbc 100644 --- a/src/nvim/testdir/test_matchadd_conceal.vim +++ b/src/nvim/testdir/test_matchadd_conceal.vim @@ -3,17 +3,7 @@ if !has('conceal') finish endif -function! s:screenline(lnum) abort - let line = [] - for c in range(1, winwidth(0)) - call add(line, nr2char(screenchar(a:lnum, c))) - endfor - return s:trim(join(line, '')) -endfunction - -function! s:trim(str) abort - return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$') -endfunction +source shared.vim function! Test_simple_matchadd() new @@ -26,7 +16,7 @@ function! Test_simple_matchadd() call matchadd('Conceal', '\%2l ') redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) @@ -49,7 +39,7 @@ function! Test_simple_matchadd_and_conceal() call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'}) redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -75,7 +65,7 @@ function! Test_matchadd_and_conceallevel_3() call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'}) redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -88,7 +78,7 @@ function! Test_matchadd_and_conceallevel_3() call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'}) redraw! - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2) , screenattr(lnum, 7)) call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 10)) @@ -112,7 +102,7 @@ function! Test_default_conceal_char() call matchadd('Conceal', '\%2l ', 10, -1, {}) redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -125,7 +115,7 @@ function! Test_default_conceal_char() set listchars=conceal:+ redraw! - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -149,7 +139,7 @@ function! Test_syn_and_match_conceal() syntax match MyConceal /\%2l / conceal containedin=ALL cchar=* redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -161,7 +151,7 @@ function! Test_syn_and_match_conceal() call clearmatches() redraw! - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -187,7 +177,7 @@ function! Test_clearmatches() redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -200,7 +190,7 @@ function! Test_clearmatches() call setmatches(a) redraw! - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10)) @@ -228,7 +218,7 @@ function! Test_using_matchaddpos() redraw! let lnum = 2 - call assert_equal(expect, s:screenline(lnum)) + call assert_equal(expect, Screenline(lnum)) call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 2)) call assert_notequal(screenattr(lnum, 2) , screenattr(lnum, 7)) call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 7)) @@ -250,13 +240,13 @@ function! Test_matchadd_repeat_conceal_with_syntax_off() 1put ='TARGET_TARGETTARGET' call cursor(1, 1) redraw - call assert_equal('TARGET_TARGETTARGET', s:screenline(2)) + call assert_equal('TARGET_TARGETTARGET', Screenline(2)) setlocal conceallevel=2 call matchadd('Conceal', 'TARGET', 10, -1, {'conceal': 't'}) redraw - call assert_equal('t_tt', s:screenline(2)) + call assert_equal('t_tt', Screenline(2)) quit! endfunction @@ -272,13 +262,13 @@ function! Test_matchadd_and_syn_conceal() syntax on syntax keyword coqKwd bool conceal cchar=- redraw! - call assert_equal(expect, s:screenline(1)) + call assert_equal(expect, Screenline(1)) call assert_notequal(screenattr(1, 10) , screenattr(1, 11)) call assert_notequal(screenattr(1, 11) , screenattr(1, 12)) call assert_equal(screenattr(1, 11) , screenattr(1, 32)) call matchadd('CheckedByCoq', '\%<2l\%>9c\%<16c') redraw! - call assert_equal(expect, s:screenline(1)) + call assert_equal(expect, Screenline(1)) call assert_notequal(screenattr(1, 10) , screenattr(1, 11)) call assert_notequal(screenattr(1, 11) , screenattr(1, 12)) call assert_equal(screenattr(1, 11) , screenattr(1, 32)) diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim index 4774cf4af5..9ba264deb6 100644 --- a/src/nvim/testdir/test_mksession.vim +++ b/src/nvim/testdir/test_mksession.vim @@ -19,7 +19,8 @@ func Test_mksession() \ 'two tabs in one line', \ 'one ä multibyteCharacter', \ 'aä Ä two multiByte characters', - \ 'Aäöü three mulTibyte characters' + \ 'Aäöü three mulTibyte characters', + \ 'short line', \ ]) let tmpfile = 'Xtemp' exec 'w! ' . tmpfile @@ -41,6 +42,8 @@ func Test_mksession() norm! j16| split norm! j16| + split + norm! j$ wincmd l set nowrap @@ -63,7 +66,7 @@ func Test_mksession() split call wincol() mksession! Xtest_mks.out - let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') + let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! [0$]\\|^ *exe ''normal!\\)"') let expected = [ \ 'normal! 016|', \ 'normal! 016|', @@ -73,6 +76,7 @@ func Test_mksession() \ 'normal! 016|', \ 'normal! 016|', \ 'normal! 016|', + \ 'normal! $', \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", \ " normal! 016|", \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", @@ -151,5 +155,87 @@ func Test_mksession_one_buffer_two_windows() call delete('Xtest_mks.out') endfunc +" Test :mkview with a file argument. +func Test_mkview_file() + " Create a view with line number and a fold. + help :mkview + set number + norm! V}zf0 + let pos = getpos('.') + let linefoldclosed1 = foldclosed('.') + mkview! Xview + set nonumber + norm! zrj + " We can close the help window, as mkview with a file name should + " generate a command to edit the file. + helpclose + + source Xview + call assert_equal(1, &number) + call assert_match('\*:mkview\*$', getline('.')) + call assert_equal(pos, getpos('.')) + call assert_equal(linefoldclosed1, foldclosed('.')) + + " Creating a view again with the same file name should fail (file + " already exists). But with a !, the previous view should be + " overwritten without error. + help :loadview + call assert_fails('mkview Xview', 'E189:') + call assert_match('\*:loadview\*$', getline('.')) + mkview! Xview + call assert_match('\*:loadview\*$', getline('.')) + + call delete('Xview') + bwipe +endfunc + +" Test :mkview and :loadview with a custom 'viewdir'. +func Test_mkview_loadview_with_viewdir() + set viewdir=Xviewdir + + help :mkview + set number + norm! V}zf + let pos = getpos('.') + let linefoldclosed1 = foldclosed('.') + mkview 1 + set nonumber + norm! zrj + + loadview 1 + + " The directory Xviewdir/ should have been created and the view + " should be stored in that directory. + let pathsep = has('win32') ? '\' : '/' + call assert_equal('Xviewdir' . pathsep . + \ substitute( + \ substitute( + \ expand('%:p'), pathsep, '=+', 'g'), ':', '=-', 'g') . '=1.vim', + \ glob('Xviewdir/*')) + call assert_equal(1, &number) + call assert_match('\*:mkview\*$', getline('.')) + call assert_equal(pos, getpos('.')) + call assert_equal(linefoldclosed1, foldclosed('.')) + + call delete('Xviewdir', 'rf') + set viewdir& + helpclose +endfunc + +func Test_mkview_no_file_name() + new + " :mkview or :mkview {nr} should fail in a unnamed buffer. + call assert_fails('mkview', 'E32:') + call assert_fails('mkview 1', 'E32:') + + " :mkview {file} should succeed in a unnamed buffer. + mkview Xview + help + source Xview + call assert_equal('', bufname('%')) + + call delete('Xview') + %bwipe +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_move.vim b/src/nvim/testdir/test_move.vim new file mode 100644 index 0000000000..d774c93dbd --- /dev/null +++ b/src/nvim/testdir/test_move.vim @@ -0,0 +1,40 @@ +" Test the ":move" command. + +func Test_move() + enew! + call append(0, ['line 1', 'line 2', 'line 3']) + g /^$/ delete _ + set nomodified + + move . + call assert_equal(['line 1', 'line 2', 'line 3'], getline(1, 3)) + call assert_false(&modified) + + 1,2move 0 + call assert_equal(['line 1', 'line 2', 'line 3'], getline(1, 3)) + call assert_false(&modified) + + 1,3move 3 + call assert_equal(['line 1', 'line 2', 'line 3'], getline(1, 3)) + call assert_false(&modified) + + 1move 2 + call assert_equal(['line 2', 'line 1', 'line 3'], getline(1, 3)) + call assert_true(&modified) + set nomodified + + 3move 0 + call assert_equal(['line 3', 'line 2', 'line 1'], getline(1, 3)) + call assert_true(&modified) + set nomodified + + 2,3move 0 + call assert_equal(['line 2', 'line 1', 'line 3'], getline(1, 3)) + call assert_true(&modified) + set nomodified + + call assert_fails('1,2move 1', 'E134') + call assert_fails('2,3move 2', 'E134') + + %bwipeout! +endfunc diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index c638920dd3..d07b3fdbce 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -392,10 +392,31 @@ func! Test_normal10_expand() call setline(1, ['1', 'ifooar,,cbar']) 2 norm! $ - let a=expand('<cword>') - let b=expand('<cWORD>') - call assert_equal('cbar', a) - call assert_equal('ifooar,,cbar', b) + call assert_equal('cbar', expand('<cword>')) + call assert_equal('ifooar,,cbar', expand('<cWORD>')) + + call setline(1, ['prx = list[idx];']) + 1 + let expected = ['', 'prx', 'prx', 'prx', + \ 'list', 'list', 'list', 'list', 'list', 'list', 'list', + \ 'idx', 'idx', 'idx', 'idx', + \ 'list[idx]', + \ '];', + \ ] + for i in range(1, 16) + exe 'norm ' . i . '|' + call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i) + endfor + + if executable('echo') + " Test expand(`...`) i.e. backticks command expansion. + " MS-Windows has a trailing space. + call assert_match('^abcde *$', expand('`echo abcde`')) + endif + + " Test expand(`=...`) i.e. backticks expression expansion + call assert_equal('5', expand('`=2+3`')) + " clean up bw! endfunc @@ -1201,6 +1222,13 @@ func! Test_normal19_z_spell() call assert_match("Word 'goood' added to ./Xspellfile2.add", a) call assert_equal('goood', cnt[0]) + " Test for :spellgood! + let temp = execute(':spe!0/0') + call assert_match('Invalid region', temp) + let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0') + call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile)) + call delete(spellfile) + " clean up exe "lang" oldlang call delete("./Xspellfile.add") @@ -1529,12 +1557,12 @@ fun! Test_normal29_brace() \ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a', \ 'paragraph boundary |posix|.', \ '{', - \ 'This is no paragaraph', + \ 'This is no paragraph', \ 'unless the ''{'' is set', \ 'in ''cpoptions''', \ '}', \ '.IP', - \ 'The nroff macros IP seperates a paragraph', + \ 'The nroff macros IP separates a paragraph', \ 'That means, it must be a ''.''', \ 'followed by IP', \ '.LPIt does not matter, if afterwards some', @@ -1549,7 +1577,7 @@ fun! Test_normal29_brace() 1 norm! 0d2} call assert_equal(['.IP', - \ 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', 'followed by IP', + \ 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', 'followed by IP', \ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff', \ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$')) norm! 0d} @@ -1569,21 +1597,21 @@ fun! Test_normal29_brace() " set cpo+={ " 1 " norm! 0d2} - " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', - " \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', + " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', + " \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.', " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$')) " $ " norm! d} - " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', - " \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', + " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', + " \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.', " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$')) " norm! gg} " norm! d5} - " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$')) + " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$')) " clean up set cpo-={ @@ -1802,11 +1830,6 @@ fun! Test_normal33_g_cmd2() call assert_equal(15, col('.')) call assert_equal('l', getreg(0)) - " Test for g Ctrl-G - set ff=unix - let a=execute(":norm! g\<c-g>") - call assert_match('Col 15 of 43; Line 2 of 2; Word 2 of 2; Byte 16 of 45', a) - " Test for gI norm! gIfoo call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$')) @@ -1825,6 +1848,81 @@ fun! Test_normal33_g_cmd2() bw! endfunc +func! Test_g_ctrl_g() + new + + let a = execute(":norm! g\<c-g>") + call assert_equal("\n--No lines in buffer--", a) + + call setline(1, ['first line', 'second line']) + + " Test g CTRL-g with dos, mac and unix file type. + norm! gojll + set ff=dos + let a = execute(":norm! g\<c-g>") + call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a) + + set ff=mac + let a = execute(":norm! g\<c-g>") + call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a) + + set ff=unix + let a = execute(":norm! g\<c-g>") + call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a) + + " Test g CTRL-g in visual mode (v) + let a = execute(":norm! gojllvlg\<c-g>") + call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a) + + " Test g CTRL-g in visual mode (CTRL-V) with end col > start col + let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>") + call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a) + + " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col + let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>") + call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a) + + " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL + let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>") + call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a) + + " There should be one byte less with noeol + set bin noeol + let a = execute(":norm! \<Esc>gog\<c-g>") + call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a) + set bin & eol& + + if has('multi_byte') + call setline(1, ['Français', '日本語']) + + let a = execute(":norm! \<Esc>gojlg\<c-g>") + call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20", a) + + let a = execute(":norm! \<Esc>gojvlg\<c-g>") + call assert_equal("\nSelected 1 of 2 Lines; 1 of 2 Words; 2 of 13 Chars; 6 of 20 Bytes", a) + + let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>") + call assert_equal("\nSelected 4 Cols; 2 of 2 Lines; 2 of 2 Words; 6 of 13 Chars; 11 of 20 Bytes", a) + + set fenc=utf8 bomb + let a = execute(":norm! \<Esc>gojlg\<c-g>") + call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+3 for BOM)", a) + + set fenc=utf16 bomb + let a = execute(":norm! g\<c-g>") + call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+2 for BOM)", a) + + set fenc=utf32 bomb + let a = execute(":norm! g\<c-g>") + call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+4 for BOM)", a) + + set fenc& bomb& + endif + + set ff& + bwipe! +endfunc + fun! Test_normal34_g_cmd3() if !has("multi_byte") return @@ -2173,10 +2271,11 @@ func! Test_normal44_textobjects2() endfunc func! Test_normal45_drop() - if !has("dnd") + if !has('dnd') return endif - " basic test for :drop command + + " basic test for drag-n-drop " unfortunately, without a gui, we can't really test much here, " so simply test that ~p fails (which uses the drop register) new diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index f0aec42ae1..7b640ee2ff 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -29,6 +29,19 @@ function! Test_isfname() set isfname& endfunction +function Test_wildchar() + " Empty 'wildchar' used to access invalid memory. + call assert_fails('set wildchar=', 'E521:') + call assert_fails('set wildchar=abc', 'E521:') + set wildchar=<Esc> + let a=execute('set wildchar?') + call assert_equal("\n wildchar=<Esc>", a) + set wildchar=27 + let a=execute('set wildchar?') + call assert_equal("\n wildchar=<Esc>", a) + set wildchar& +endfunction + function! Test_options() let caught = 'ok' try @@ -249,7 +262,7 @@ func Test_set_ttytype() " in travis on some builds. Why? Catch both for now try set ttytype= - call assert_report('set ttype= did not fail') + call assert_report('set ttytype= did not fail') catch /E529\|E522/ endtry @@ -257,7 +270,7 @@ func Test_set_ttytype() " check for failure of finding the entry and for missing 'cm' entry. try set ttytype=xxx - call assert_report('set ttype=xxx did not fail') + call assert_report('set ttytype=xxx did not fail') catch /E522\|E437/ endtry @@ -338,4 +351,62 @@ func Test_copy_winopt() bnext call assert_equal(4,&numberwidth) bw! + + set hidden& +endfunc + +func Test_shortmess_F() + new + call assert_match('\[No Name\]', execute('file')) + set shortmess+=F + call assert_match('\[No Name\]', execute('file')) + call assert_match('^\s*$', execute('file foo')) + call assert_match('foo', execute('file')) + set shortmess-=F + call assert_match('bar', execute('file bar')) + call assert_match('bar', execute('file')) + set shortmess& + bwipe +endfunc + +func Test_set_all() + set tw=75 + set iskeyword=a-z,A-Z + set nosplitbelow + let out = execute('set all') + call assert_match('textwidth=75', out) + call assert_match('iskeyword=a-z,A-Z', out) + call assert_match('nosplitbelow', out) + set tw& iskeyword& splitbelow& +endfunc + +func Test_set_values() + " The file is only generated when running "make test" in the src directory. + if filereadable('opt_test.vim') + source opt_test.vim + endif +endfunc + +func Test_shortmess_F2() + e file1 + e file2 + " Accommodate Nvim default. + set shortmess-=F + call assert_match('file1', execute('bn', '')) + call assert_match('file2', execute('bn', '')) + set shortmess+=F + call assert_true(empty(execute('bn', ''))) + call assert_true(empty(execute('bn', ''))) + set hidden + call assert_true(empty(execute('bn', ''))) + call assert_true(empty(execute('bn', ''))) + set nohidden + call assert_true(empty(execute('bn', ''))) + call assert_true(empty(execute('bn', ''))) + " Accommodate Nvim default. + set shortmess-=F + call assert_match('file1', execute('bn', '')) + call assert_match('file2', execute('bn', '')) + bwipe + bwipe endfunc diff --git a/src/nvim/testdir/test_plus_arg_edit.vim b/src/nvim/testdir/test_plus_arg_edit.vim new file mode 100644 index 0000000000..71dbea1991 --- /dev/null +++ b/src/nvim/testdir/test_plus_arg_edit.vim @@ -0,0 +1,10 @@ +" Tests for complicated + argument to :edit command +function Test_edit() + call writefile(["foo|bar"], "Xfile1") + call writefile(["foo/bar"], "Xfile2") + edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w + call assert_equal(["fooPIPEbar"], readfile("Xfile1")) + call assert_equal(["fooSLASHbar"], readfile("Xfile2")) + call delete('Xfile1') + call delete('Xfile2') +endfunction diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 2191e3144f..6fd58a1483 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -1,5 +1,7 @@ " Test for completion menu +source shared.vim + let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] let g:setting = '' @@ -665,4 +667,30 @@ func Test_complete_CTRLN_startofbuffer() bwipe! endfunc +func Test_popup_and_window_resize() + if !has('terminal') || has('gui_running') + return + endif + let h = winheight(0) + if h < 15 + return + endif + let g:buf = term_start([$NVIM_PRG, '--clean', '-c', 'set noswapfile'], {'term_rows': h / 3}) + call term_sendkeys(g:buf, (h / 3 - 1)."o\<esc>G") + call term_sendkeys(g:buf, "i\<c-x>") + call term_wait(g:buf, 100) + call term_sendkeys(g:buf, "\<c-v>") + call term_wait(g:buf, 100) + call assert_match('^!\s*$', term_getline(g:buf, 1)) + exe 'resize +' . (h - 1) + call term_wait(g:buf, 100) + redraw! + call WaitFor('"" == term_getline(g:buf, 1)') + call assert_equal('', term_getline(g:buf, 1)) + sleep 100m + call WaitFor('"^!" =~ term_getline(g:buf, term_getcursor(g:buf)[0] + 1)') + call assert_match('^!\s*$', term_getline(g:buf, term_getcursor(g:buf)[0] + 1)) + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_preview.vim b/src/nvim/testdir/test_preview.vim new file mode 100644 index 0000000000..91923fb1e9 --- /dev/null +++ b/src/nvim/testdir/test_preview.vim @@ -0,0 +1,13 @@ +" Tests for the preview window + +func Test_Psearch() + " this used to cause ml_get errors + help + let wincount = winnr('$') + 0f + ps. + call assert_equal(wincount + 1, winnr('$')) + pclose + call assert_equal(wincount, winnr('$')) + bwipe +endfunc diff --git a/src/nvim/testdir/test_put.vim b/src/nvim/testdir/test_put.vim index 38c812bc9c..0b8961c52b 100644 --- a/src/nvim/testdir/test_put.vim +++ b/src/nvim/testdir/test_put.vim @@ -34,3 +34,16 @@ func Test_put_char_block2() bw! call setreg('a', a[0], a[1]) endfunc + +func Test_put_expr() + new + call setline(1, repeat(['A'], 6)) + exec "1norm! \"=line('.')\<cr>p" + norm! j0. + norm! j0. + exec "4norm! \"=\<cr>P" + norm! j0. + norm! j0. + call assert_equal(['A1','A2','A3','4A','5A','6A'], getline(1,'$')) + bw! +endfunc diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 8d2c61f6f0..bfe5791ec8 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -11,7 +11,7 @@ func s:setup_commands(cchar) command! -nargs=* -bang Xlist <mods>clist<bang> <args> command! -nargs=* Xgetexpr <mods>cgetexpr <args> command! -nargs=* Xaddexpr <mods>caddexpr <args> - command! -nargs=* Xolder <mods>colder <args> + command! -nargs=* -count Xolder <mods><count>colder <args> command! -nargs=* Xnewer <mods>cnewer <args> command! -nargs=* Xopen <mods>copen <args> command! -nargs=* Xwindow <mods>cwindow <args> @@ -43,7 +43,7 @@ func s:setup_commands(cchar) command! -nargs=* -bang Xlist <mods>llist<bang> <args> command! -nargs=* Xgetexpr <mods>lgetexpr <args> command! -nargs=* Xaddexpr <mods>laddexpr <args> - command! -nargs=* Xolder <mods>lolder <args> + command! -nargs=* -count Xolder <mods><count>lolder <args> command! -nargs=* Xnewer <mods>lnewer <args> command! -nargs=* Xopen <mods>lopen <args> command! -nargs=* Xwindow <mods>lwindow <args> @@ -1702,7 +1702,8 @@ func Xproperty_tests(cchar) Xopen wincmd p call g:Xsetlist([{'filename':'foo', 'lnum':27}]) - call g:Xsetlist([], 'a', {'title' : 'Sample'}) + let s = g:Xsetlist([], 'a', {'title' : 'Sample'}) + call assert_equal(0, s) let d = g:Xgetlist({"title":1}) call assert_equal('Sample', d.title) @@ -1726,7 +1727,7 @@ func Xproperty_tests(cchar) call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title) " Changing the title of an earlier quickfix list - call g:Xsetlist([], ' ', {'title' : 'NewTitle', 'nr' : 2}) + call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2}) call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title) " Changing the title of an invalid quickfix list @@ -1756,7 +1757,8 @@ func Xproperty_tests(cchar) endif " Context related tests - call g:Xsetlist([], 'a', {'context':[1,2,3]}) + let s = g:Xsetlist([], 'a', {'context':[1,2,3]}) + call assert_equal(0, s) call test_garbagecollect_now() let d = g:Xgetlist({'context':1}) call assert_equal([1,2,3], d.context) @@ -1792,10 +1794,10 @@ func Xproperty_tests(cchar) Xexpr "One" Xexpr "Two" Xexpr "Three" - call g:Xsetlist([], ' ', {'context' : [1], 'nr' : 1}) - call g:Xsetlist([], ' ', {'context' : [2], 'nr' : 2}) + call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1}) + call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2}) " Also, check for setting the context using quickfix list number zero. - call g:Xsetlist([], ' ', {'context' : [3], 'nr' : 0}) + call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0}) call test_garbagecollect_now() let l = g:Xgetlist({'nr' : 1, 'context' : 1}) call assert_equal([1], l.context) @@ -1821,8 +1823,9 @@ func Xproperty_tests(cchar) " Test for setting/getting items Xexpr "" let qfprev = g:Xgetlist({'nr':0}) - call g:Xsetlist([], ' ', {'title':'Green', + let s = g:Xsetlist([], ' ', {'title':'Green', \ 'items' : [{'filename':'F1', 'lnum':10}]}) + call assert_equal(0, s) let qfcur = g:Xgetlist({'nr':0}) call assert_true(qfcur.nr == qfprev.nr + 1) let l = g:Xgetlist({'items':1}) @@ -1841,6 +1844,11 @@ func Xproperty_tests(cchar) let l = g:Xgetlist({'items':1}) call assert_equal(0, len(l.items)) + " The following used to crash Vim with address sanitizer + call g:Xsetlist([], 'f') + call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) + call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) + " Save and restore the quickfix stack call g:Xsetlist([], 'f') call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) @@ -1871,8 +1879,9 @@ func Xproperty_tests(cchar) call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) let l1=g:Xgetlist({'nr':1,'all':1}) let l2=g:Xgetlist({'nr':2,'all':1}) - let l1.nr=2 - let l2.nr=1 + let save_id = l1.id + let l1.id=l2.id + let l2.id=save_id call g:Xsetlist([], 'r', l1) call g:Xsetlist([], 'r', l2) let newl1=g:Xgetlist({'nr':1,'all':1}) @@ -2226,6 +2235,35 @@ func Test_cclose_in_autocmd() " call test_override('starting', 0) endfunc +" Check that ":file" without an argument is possible even when "curbuf_lock" +" is set. +func Test_file_from_copen() + " Works without argument. + augroup QF_Test + au! + au FileType qf file + augroup END + copen + + augroup QF_Test + au! + augroup END + cclose + + " Fails with argument. + augroup QF_Test + au! + au FileType qf call assert_fails(':file foo', 'E788') + augroup END + copen + augroup QF_Test + au! + augroup END + cclose + + augroup! QF_Test +endfunction + func Test_resize_from_copen() augroup QF_Test au! @@ -2242,3 +2280,360 @@ func Test_resize_from_copen() augroup! QF_Test endtry endfunc + +" Tests for the quickfix buffer b:changedtick variable +func Xchangedtick_tests(cchar) + call s:setup_commands(a:cchar) + + new | only + + Xexpr "" | Xexpr "" | Xexpr "" + + Xopen + Xolder + Xolder + Xaddexpr "F1:10:Line10" + Xaddexpr "F2:20:Line20" + call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') + call g:Xsetlist([], 'f') + call assert_equal(8, getbufvar('%', 'changedtick')) + Xclose +endfunc + +func Test_changedtick() + call Xchangedtick_tests('c') + call Xchangedtick_tests('l') +endfunc + +" Tests for parsing an expression using setqflist() +func Xsetexpr_tests(cchar) + call s:setup_commands(a:cchar) + + let t = ["File1:10:Line10", "File1:20:Line20"] + call g:Xsetlist([], ' ', {'lines' : t}) + call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) + + let l = g:Xgetlist() + call assert_equal(3, len(l)) + call assert_equal(20, l[1].lnum) + call assert_equal('Line30', l[2].text) + call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) + let l = g:Xgetlist() + call assert_equal(1, len(l)) + call assert_equal('Line5', l[0].text) + call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) + call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) + + call g:Xsetlist([], 'f') + " Add entries to multiple lists + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) + call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) + call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) + + " Adding entries using a custom efm + set efm& + call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', + \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) + call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) + call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) + call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) + call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) + call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], + \ 'lines' : ['F1:10:L10']})) +endfunc + +func Test_setexpr() + call Xsetexpr_tests('c') + call Xsetexpr_tests('l') +endfunc + +" Tests for per quickfix/location list directory stack +func Xmultidirstack_tests(cchar) + call s:setup_commands(a:cchar) + + call g:Xsetlist([], 'f') + Xexpr "" | Xexpr "" + + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) + + let l1 = g:Xgetlist({'nr':1, 'items':1}) + let l2 = g:Xgetlist({'nr':2, 'items':1}) + call assert_equal(expand('Xone/a/one.txt'), bufname(l1.items[1].bufnr)) + call assert_equal(3, l1.items[1].lnum) + call assert_equal(expand('Xtwo/a/two.txt'), bufname(l2.items[1].bufnr)) + call assert_equal(5, l2.items[1].lnum) +endfunc + +func Test_multidirstack() + call mkdir('Xone/a', 'p') + call mkdir('Xtwo/a', 'p') + let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] + call writefile(lines, 'Xone/a/one.txt') + call writefile(lines, 'Xtwo/a/two.txt') + let save_efm = &efm + set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' + + call Xmultidirstack_tests('c') + call Xmultidirstack_tests('l') + + let &efm = save_efm + call delete('Xone', 'rf') + call delete('Xtwo', 'rf') +endfunc + +" Tests for per quickfix/location list file stack +func Xmultifilestack_tests(cchar) + call s:setup_commands(a:cchar) + + call g:Xsetlist([], 'f') + Xexpr "" | Xexpr "" + + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) + call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) + call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) + + let l1 = g:Xgetlist({'nr':1, 'items':1}) + let l2 = g:Xgetlist({'nr':2, 'items':1}) + call assert_equal('one.txt', bufname(l1.items[1].bufnr)) + call assert_equal(3, l1.items[1].lnum) + call assert_equal('two.txt', bufname(l2.items[1].bufnr)) + call assert_equal(5, l2.items[1].lnum) +endfunc + +func Test_multifilestack() + let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] + call writefile(lines, 'one.txt') + call writefile(lines, 'two.txt') + let save_efm = &efm + set efm=%+P[%f],(%l\\,%c)\ %m,%-Q + + call Xmultifilestack_tests('c') + call Xmultifilestack_tests('l') + + let &efm = save_efm + call delete('one.txt') + call delete('two.txt') +endfunc + +" Tests for per buffer 'efm' setting +func Test_perbuf_efm() + call writefile(["File1-10-Line10"], 'one.txt') + call writefile(["File2#20#Line20"], 'two.txt') + set efm=%f#%l#%m + new | only + new + setlocal efm=%f-%l-%m + cfile one.txt + wincmd w + caddfile two.txt + + let l = getqflist() + call assert_equal(10, l[0].lnum) + call assert_equal('Line20', l[1].text) + + set efm& + new | only + call delete('one.txt') + call delete('two.txt') +endfunc + +" Open multiple help windows using ":lhelpgrep +" This test used to crash Vim +func Test_Multi_LL_Help() + new | only + lhelpgrep window + lopen + e# + lhelpgrep buffer + call assert_equal(3, winnr('$')) + call assert_true(len(getloclist(1)) != 0) + call assert_true(len(getloclist(2)) != 0) + new | only +endfunc + +" Tests for adding new quickfix lists using setqflist() +func XaddQf_tests(cchar) + call s:setup_commands(a:cchar) + + " Create a new list using ' ' for action + call g:Xsetlist([], 'f') + call g:Xsetlist([], ' ', {'title' : 'Test1'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(1, l.nr) + call assert_equal('Test1', l.title) + + " Create a new list using ' ' for action and '$' for 'nr' + call g:Xsetlist([], 'f') + call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(1, l.nr) + call assert_equal('Test2', l.title) + + " Create a new list using 'a' for action + call g:Xsetlist([], 'f') + call g:Xsetlist([], 'a', {'title' : 'Test3'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(1, l.nr) + call assert_equal('Test3', l.title) + + " Create a new list using 'a' for action and '$' for 'nr' + call g:Xsetlist([], 'f') + call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) + call g:Xsetlist([], 'a', {'title' : 'Test4'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(1, l.nr) + call assert_equal('Test4', l.title) + + " Adding a quickfix list should remove all the lists following the current + " list. + Xexpr "" | Xexpr "" | Xexpr "" + silent! 10Xolder + call g:Xsetlist([], ' ', {'title' : 'Test5'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(2, l.nr) + call assert_equal('Test5', l.title) + + " Add a quickfix list using '$' as the list number. + let lastqf = g:Xgetlist({'nr':'$'}).nr + silent! 99Xolder + call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(lastqf + 1, l.nr) + call assert_equal('Test6', l.title) + + " Add a quickfix list using 'nr' set to one more than the quickfix + " list size. + let lastqf = g:Xgetlist({'nr':'$'}).nr + silent! 99Xolder + call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(lastqf + 1, l.nr) + call assert_equal('Test7', l.title) + + " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' + exe repeat('Xexpr "" |', 9) . 'Xexpr ""' + silent! 99Xolder + call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) + let l = g:Xgetlist({'nr' : '$', 'all' : 1}) + call assert_equal(10, l.nr) + call assert_equal('Test8', l.title) + + " Add a quickfix list using 'nr' set to a value greater than 10 + call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) + + " Try adding a quickfix list with 'nr' set to a value greater than the + " quickfix list size but less than 10. + call g:Xsetlist([], 'f') + Xexpr "" | Xexpr "" | Xexpr "" + silent! 99Xolder + call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) + + " Add a quickfix list using 'nr' set to a some string or list + call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) +endfunc + +func Test_add_qf() + call XaddQf_tests('c') + call XaddQf_tests('l') +endfunc + +" Test for getting the quickfix list items from some text without modifying +" the quickfix stack +func XgetListFromLines(cchar) + call s:setup_commands(a:cchar) + call g:Xsetlist([], 'f') + + let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items + call assert_equal(2, len(l)) + call assert_equal(30, l[1].lnum) + + call assert_equal({}, g:Xgetlist({'lines' : 10})) + call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) + call assert_equal([], g:Xgetlist({'lines' : []}).items) + call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) + + " Parse text using a custom efm + set efm& + let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items + call assert_equal('Line30', l[0].text) + let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items + call assert_equal('File3:30:Line30', l[0].text) + let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) + call assert_equal({}, l) + call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') + call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') + + " Make sure that the quickfix stack is not modified + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) +endfunc + +func Test_get_list_from_lines() + call XgetListFromLines('c') + call XgetListFromLines('l') +endfunc + +" Tests for the quickfix list id +func Xqfid_tests(cchar) + call s:setup_commands(a:cchar) + + call g:Xsetlist([], 'f') + call assert_equal({}, g:Xgetlist({'id':0})) + Xexpr '' + let start_id = g:Xgetlist({'id' : 0}).id + Xexpr '' | Xexpr '' + Xolder + call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) + call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) + call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) + call assert_equal({}, g:Xgetlist({'id':0, 'nr':99})) + call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) + call assert_equal({}, g:Xgetlist({'id':99, 'nr':0})) + call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0})) + + call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) + call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) + call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) + call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) + call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) + call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) + + let qfid = g:Xgetlist({'id':0, 'nr':0}) + call g:Xsetlist([], 'f') + call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0})) +endfunc + +func Test_qf_id() + call Xqfid_tests('c') + call Xqfid_tests('l') +endfunc + +" Test for shortening/simplifying the file name when opening the +" quickfix window or when displaying the quickfix list +func Test_shorten_fname() + if !has('unix') + return + endif + %bwipe + " Create a quickfix list with a absolute path filename + let fname = getcwd() . '/test_quickfix.vim' + call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) + call assert_equal(fname, bufname('test_quickfix.vim')) + " Opening the quickfix window should simplify the file path + cwindow + call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) + cclose + %bwipe + " Create a quickfix list with a absolute path filename + call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) + call assert_equal(fname, bufname('test_quickfix.vim')) + " Displaying the quickfix list should simplify the file path + silent! clist + call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) +endfunc diff --git a/src/nvim/testdir/test_regex_char_classes.vim b/src/nvim/testdir/test_regex_char_classes.vim new file mode 100644 index 0000000000..2192b5e8fc --- /dev/null +++ b/src/nvim/testdir/test_regex_char_classes.vim @@ -0,0 +1,58 @@ +" Tests for regexp with backslash and other special characters inside [] +" Also test backslash for hex/octal numbered character. + +function RunSTest(value, calls, expected) + new + call feedkeys("i" . a:value, "mx") + exec a:calls + call assert_equal(a:expected, getline(1), printf("wrong result for %s", a:calls)) + quit! +endfunction + +function RunXTest(value, search_exp, expected) + new + call feedkeys("i" . a:value, "mx") + call feedkeys("gg" . a:search_exp . "\nx", "mx") + call assert_equal(a:expected, getline(1), printf("wrong result for %s", a:search_exp)) + quit! +endfunction + + +function Test_x_search() + let res = "test text test text" + call RunXTest("test \\text test text", "/[\\x]", res) + call RunXTest("test \ttext test text", "/[\\t\\]]", res) + call RunXTest("test text ]test text", "/[]y]", res) + call RunXTest("test ]text test text", "/[\\]]", res) + call RunXTest("test text te^st text", "/[y^]", res) + call RunXTest("test te$xt test text", "/[$y]", res) + call RunXTest("test taext test text", "/[\\x61]", res) + call RunXTest("test tbext test text","/[\\x60-\\x64]", res) + call RunXTest("test 5text test text","/[\\x785]", res) + call RunXTest("testc text test text","/[\\o143]", res) + call RunXTest("tesdt text test text","/[\\o140-\\o144]", res) + call RunXTest("test7 text test text", "/[\\o417]", res) + call RunXTest("test text tBest text", "/\\%x42", res) + call RunXTest("test text teCst text", "/\\%o103", res) + call RunXTest("test text \<C-V>x00test text", "/[\\x00]", res) +endfunction + +function Test_s_search() + let res = "test text test text" + call RunSTest("test te\<C-V>x00xt t\<C-V>x04est t\<C-V>x10ext", "s/[\\x00-\\x10]//g", res) + call RunSTest("test \\xyztext test text", "s/[\\x-z]\\+//", res) + call RunSTest("test text tev\\uyst text", "s/[\\u-z]\\{2,}//", res) + call RunSTest("xx aaaaa xx a", "s/\\(a\\)\\+//", "xx xx a") + call RunSTest("xx aaaaa xx a", "s/\\(a*\\)\\+//", "xx aaaaa xx a") + call RunSTest("xx aaaaa xx a", "s/\\(a*\\)*//", "xx aaaaa xx a") + call RunSTest("xx aaaaa xx", "s/\\(a\\)\\{2,3}/A/", "xx Aaa xx") + call RunSTest("xx aaaaa xx", "s/\\(a\\)\\{-2,3}/A/", "xx Aaaa xx") + call RunSTest("xx aaa12aa xx", "s/\\(a\\)*\\(12\\)\\@>/A/", "xx Aaa xx") + call RunSTest("xx foobar xbar xx", "s/\\(foo\\)\\@<!bar/A/", "xx foobar xA xx") + call RunSTest("xx an file xx", "s/\\(an\\_s\\+\\)\\@<=file/A/", "xx an A xx") + call RunSTest("x= 9;", "s/^\\(\\h\\w*\\%(->\\|\\.\\)\\=\\)\\+=/XX/", "XX 9;") + call RunSTest("hh= 77;", "s/^\\(\\h\\w*\\%(->\\|\\.\\)\\=\\)\\+=/YY/", "YY 77;") + call RunSTest(" aaa ", "s/aaa/xyz/", " xyz ") + call RunSTest(" xyz", "s/~/bcd/", " bcd") + call RunSTest(" bcdbcdbcd", "s/~\\+/BB/", " BB") +endfunction diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim new file mode 100644 index 0000000000..d7b6de5652 --- /dev/null +++ b/src/nvim/testdir/test_registers.vim @@ -0,0 +1,65 @@ + +func Test_yank_shows_register() + enew + set report=0 + call setline(1, ['foo', 'bar']) + " Line-wise + exe 'norm! yy' + call assert_equal('1 line yanked', v:statusmsg) + exe 'norm! "zyy' + call assert_equal('1 line yanked into "z', v:statusmsg) + exe 'norm! yj' + call assert_equal('2 lines yanked', v:statusmsg) + exe 'norm! "zyj' + call assert_equal('2 lines yanked into "z', v:statusmsg) + + " Block-wise + exe "norm! \<C-V>y" + call assert_equal('block of 1 line yanked', v:statusmsg) + exe "norm! \<C-V>\"zy" + call assert_equal('block of 1 line yanked into "z', v:statusmsg) + exe "norm! \<C-V>jy" + call assert_equal('block of 2 lines yanked', v:statusmsg) + exe "norm! \<C-V>j\"zy" + call assert_equal('block of 2 lines yanked into "z', v:statusmsg) + + bwipe! +endfunc + +func Test_display_registers() + e file1 + e file2 + call setline(1, ['foo', 'bar']) + /bar + exe 'norm! y2l"axx' + call feedkeys("i\<C-R>=2*4\n\<esc>") + call feedkeys(":ls\n", 'xt') + + let a = execute('display') + let b = execute('registers') + + call assert_equal(a, b) + call assert_match('^\n--- Registers ---\n' + \ . '"" a\n' + \ . '"0 ba\n' + \ . '"1 b\n' + \ . '"a b\n' + \ . '.*' + \ . '"- a\n' + \ . '.*' + \ . '": ls\n' + \ . '"% file2\n' + \ . '"# file1\n' + \ . '"/ bar\n' + \ . '"= 2\*4', a) + + let a = execute('registers a') + call assert_match('^\n--- Registers ---\n' + \ . '"a b', a) + + let a = execute('registers :') + call assert_match('^\n--- Registers ---\n' + \ . '": ls', a) + + bwipe! +endfunc diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 5da9397be5..ecd840d40c 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -453,3 +453,39 @@ func Test_search_multibyte() enew! let &encoding = save_enc endfunc + +func Test_search_undefined_behaviour() + if !has("terminal") + return + endif + let h = winheight(0) + if h < 3 + return + endif + " did cause an undefined left shift + let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3}) + call assert_equal([''], getline(1, '$')) + call term_sendkeys(g:buf, ":qa!\<cr>") + bwipe! +endfunc + +func Test_search_undefined_behaviour2() + call search("\%UC0000000") +endfunc + +" This was causing E874. Also causes an invalid read? +func Test_look_behind() + new + call setline(1, '0\|\&\n\@<=') + call search(getline(".")) + bwipe! +endfunc + +func Test_search_sentence() + new + " this used to cause a crash + call assert_fails("/\\%')", 'E486') + call assert_fails("/", 'E486') + /\%'( + / +endfunc diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim index a967435346..d3c6d05f4f 100644 --- a/src/nvim/testdir/test_signs.vim +++ b/src/nvim/testdir/test_signs.vim @@ -14,7 +14,7 @@ func Test_sign() " the icon name when listing signs. sign define Sign1 text=x try - sign define Sign2 text=xy texthl=Title linehl=Error icon=../../pixmaps/stock_vim_find_help.png + sign define Sign2 text=xy texthl=Title linehl=Error numhl=Number icon=../../pixmaps/stock_vim_find_help.png catch /E255:/ " ignore error: E255: Couldn't read in sign data! " This error can happen when running in gui. @@ -23,7 +23,7 @@ func Test_sign() " Test listing signs. let a=execute('sign list') - call assert_match("^\nsign Sign1 text=x \nsign Sign2 icon=../../pixmaps/stock_vim_find_help.png .*text=xy linehl=Error texthl=Title$", a) + call assert_match("^\nsign Sign1 text=x \nsign Sign2 icon=../../pixmaps/stock_vim_find_help.png .*text=xy linehl=Error texthl=Title numhl=Number$", a) let a=execute('sign list Sign1') call assert_equal("\nsign Sign1 text=x ", a) @@ -140,7 +140,7 @@ func Test_sign_completion() call assert_equal('"sign define jump list place undefine unplace', @:) call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_equal('"sign define Sign icon= linehl= text= texthl=', @:) + call assert_equal('"sign define Sign icon= linehl= numhl= text= texthl=', @:) call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"sign define Sign linehl=SpellBad SpellCap SpellLocal SpellRare', @:) diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim index 4fddb47b58..14d008a17f 100644 --- a/src/nvim/testdir/test_sort.vim +++ b/src/nvim/testdir/test_sort.vim @@ -1,13 +1,13 @@ -" Test sort() +" Tests for the "sort()" function and for the ":sort" command. -:func Compare1(a, b) abort +func Compare1(a, b) abort call sort(range(3), 'Compare2') return a:a - a:b -:endfunc +endfunc -:func Compare2(a, b) abort +func Compare2(a, b) abort return a:a - a:b -:endfunc +endfunc func Test_sort_strings() " numbers compared as strings @@ -45,7 +45,7 @@ func Test_sort_default() call assert_fails('call sort([3.3, 1, "2"], 3)', "E474") endfunc -" Tests for the :sort command +" Tests for the ":sort" command. func Test_sort_cmd() let tests = [ \ { @@ -1167,18 +1167,87 @@ func Test_sort_cmd() \ '1.234', \ '123.456' \ ] - \ } + \ }, + \ { + \ 'name' : 'alphabetical, sorted input', + \ 'cmd' : 'sort', + \ 'input' : [ + \ 'a', + \ 'b', + \ 'c', + \ ], + \ 'expected' : [ + \ 'a', + \ 'b', + \ 'c', + \ ] + \ }, + \ { + \ 'name' : 'alphabetical, sorted input, unique at end', + \ 'cmd' : 'sort u', + \ 'input' : [ + \ 'aa', + \ 'bb', + \ 'cc', + \ 'cc', + \ ], + \ 'expected' : [ + \ 'aa', + \ 'bb', + \ 'cc', + \ ] + \ }, \ ] for t in tests enew! call append(0, t.input) $delete _ - exe t.cmd + setlocal nomodified + execute t.cmd + call assert_equal(t.expected, getline(1, '$'), t.name) + + " Previously, the ":sort" command would set 'modified' even if the buffer + " contents did not change. Here, we check that this problem is fixed. + if t.input == t.expected + call assert_false(&modified, t.name . ': &mod is not correct') + else + call assert_true(&modified, t.name . ': &mod is not correct') + endif endfor call assert_fails('sort no', 'E474') enew! endfunc + +func Test_sort_cmd_report() + enew! + call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3)) + $delete _ + setlocal nomodified + let res = execute('%sort u') + + call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0')) + call assert_match("6 fewer lines", res) + enew! + call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3)) + $delete _ + setlocal nomodified report=10 + let res = execute('%sort u') + + call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0')) + call assert_equal("", res) + enew! + call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3)) + $delete _ + setl report&vim + setlocal nomodified + let res = execute('1g/^/%sort u') + + call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0')) + " the output comes from the :g command, not from the :sort + call assert_match("6 fewer lines", res) + enew! + endfunc diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim index a2828b21d2..b3438cc649 100644 --- a/src/nvim/testdir/test_spell.vim +++ b/src/nvim/testdir/test_spell.vim @@ -85,6 +85,36 @@ func Test_spellreall() bwipe! endfunc +func Test_spellinfo() + throw 'skipped: Nvim does not support enc=latin1' + new + + set enc=latin1 spell spelllang=en + call assert_match("^\nfile: .*/runtime/spell/en.latin1.spl\n$", execute('spellinfo')) + + set enc=cp1250 spell spelllang=en + call assert_match("^\nfile: .*/runtime/spell/en.ascii.spl\n$", execute('spellinfo')) + + if has('multi_byte') + set enc=utf-8 spell spelllang=en + call assert_match("^\nfile: .*/runtime/spell/en.utf-8.spl\n$", execute('spellinfo')) + endif + + set enc=latin1 spell spelllang=en_us,en_nz + call assert_match("^\n" . + \ "file: .*/runtime/spell/en.latin1.spl\n" . + \ "file: .*/runtime/spell/en.latin1.spl\n$", execute('spellinfo')) + + set spell spelllang= + call assert_fails('spellinfo', 'E756:') + + set nospell spelllang=en + call assert_fails('spellinfo', 'E756:') + + set enc& spell& spelllang& + bwipe +endfunc + func Test_zz_basic() call LoadAffAndDic(g:test_data_aff1, g:test_data_dic1) call RunGoodBad("wrong OK puts. Test the end", diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 7b77402115..2f4d857986 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -248,7 +248,7 @@ func Test_silent_ex_mode() endif " This caused an ml_get error. - let out = system(GetVimCommand() . '-u NONE -es -c''set verbose=1|h|exe "%norm\<c-y>\<c-d>"'' -c cq') + let out = system(GetVimCommand() . ' -u NONE -es -c''set verbose=1|h|exe "%norm\<c-y>\<c-d>"'' -c cq') call assert_notmatch('E315:', out) endfunc @@ -264,3 +264,27 @@ func Test_default_term() call assert_match('nvim', out) let $TERM = save_term endfunc + +func Test_zzz_startinsert() + " Test :startinsert + call writefile(['123456'], 'Xtestout') + let after = [ + \ ':startinsert', + \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")' + \ ] + if RunVim([], after, 'Xtestout') + let lines = readfile('Xtestout') + call assert_equal(['foobar123456'], lines) + endif + " Test :startinsert! + call writefile(['123456'], 'Xtestout') + let after = [ + \ ':startinsert!', + \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")' + \ ] + if RunVim([], after, 'Xtestout') + let lines = readfile('Xtestout') + call assert_equal(['123456foobar'], lines) + endif + call delete('Xtestout') +endfunc diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim index 0a09130b0c..c276df0a92 100644 --- a/src/nvim/testdir/test_stat.vim +++ b/src/nvim/testdir/test_stat.vim @@ -43,7 +43,16 @@ func Test_existent_directory() call assert_equal(0, getfsize(dname)) call assert_equal('dir', getftype(dname)) - call assert_equal('rwx', getfperm(dname)[0:2]) + call assert_equal(has('win32') ? 'rw-' : 'rwx', getfperm(dname)[0:2]) +endfunc + +func SleepForTimestamp() + " FAT has a granularity of 2 seconds, otherwise it's usually 1 second + if has('win32') + sleep 2 + else + sleep 2 + endif endfunc func Test_checktime() @@ -53,12 +62,7 @@ func Test_checktime() call writefile(fl, fname) set autoread exec 'e' fname - " FAT has a granularity of 2 seconds, otherwise it's usually 1 second - if has('win32') - sleep 2 - else - sleep 2 - endif + call SleepForTimestamp() let fl = readfile(fname) let fl[0] .= ' - checktime' call writefile(fl, fname) @@ -68,6 +72,46 @@ func Test_checktime() call delete(fname) endfunc +func Test_autoread_file_deleted() + new Xautoread + set autoread + call setline(1, 'original') + w! + + call SleepForTimestamp() + if has('win32') + silent !echo changed > Xautoread + else + silent !echo 'changed' > Xautoread + endif + checktime + call assert_equal('changed', trim(getline(1))) + + call SleepForTimestamp() + messages clear + if has('win32') + silent !del Xautoread + else + silent !rm Xautoread + endif + checktime + call assert_match('E211:', execute('messages')) + call assert_equal('changed', trim(getline(1))) + + call SleepForTimestamp() + if has('win32') + silent !echo recreated > Xautoread + else + silent !echo 'recreated' > Xautoread + endif + checktime + call assert_equal('recreated', trim(getline(1))) + + call delete('Xautoread') + bwipe! +endfunc + + func Test_nonexistent_file() let fname = 'Xtest.tmp' @@ -78,6 +122,41 @@ func Test_nonexistent_file() call assert_equal('', getfperm(fname)) endfunc +func Test_getftype() + call assert_equal('file', getftype(v:progpath)) + call assert_equal('dir', getftype('.')) + + if !has('unix') + return + endif + + silent !ln -s Xfile Xlink + call assert_equal('link', getftype('Xlink')) + call delete('Xlink') + + if executable('mkfifo') + silent !mkfifo Xfifo + call assert_equal('fifo', getftype('Xfifo')) + call delete('Xfifo') + endif + + for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null') + call assert_equal('cdev', getftype(cdevfile)) + endfor + + for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null') + call assert_equal('bdev', getftype(bdevfile)) + endfor + + " The /run/ directory typically contains socket files. + " If it does not, test won't fail but will not test socket files. + for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null') + call assert_equal('socket', getftype(socketfile)) + endfor + + " TODO: file type 'other' is not tested. How can we test it? +endfunc + func Test_win32_symlink_dir() " On Windows, non-admin users cannot create symlinks. " So we use an existing symlink for this test. diff --git a/src/nvim/testdir/test_suspend.vim b/src/nvim/testdir/test_suspend.vim new file mode 100644 index 0000000000..a9964b0400 --- /dev/null +++ b/src/nvim/testdir/test_suspend.vim @@ -0,0 +1,51 @@ +" Test :suspend + +source shared.vim + +func Test_suspend() + if !has('terminal') || !executable('/bin/sh') + return + endif + + let buf = term_start('/bin/sh') + " Wait for shell prompt. + call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))}) + + call term_sendkeys(buf, v:progpath + \ . " --clean -X" + \ . " -c 'set nu'" + \ . " -c 'call setline(1, \"foo\")'" + \ . " Xfoo\<CR>") + " Cursor in terminal buffer should be on first line in spawned vim. + call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))}) + + for suspend_cmd in [":suspend\<CR>", + \ ":stop\<CR>", + \ ":suspend!\<CR>", + \ ":stop!\<CR>", + \ "\<C-Z>"] + " Suspend and wait for shell prompt. + call term_sendkeys(buf, suspend_cmd) + call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))}) + + " Without 'autowrite', buffer should not be written. + call assert_equal(0, filereadable('Xfoo')) + + call term_sendkeys(buf, "fg\<CR>") + call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))}) + endfor + + " Test that :suspend! with 'autowrite' writes content of buffers if modified. + call term_sendkeys(buf, ":set autowrite\<CR>") + call assert_equal(0, filereadable('Xfoo')) + call term_sendkeys(buf, ":suspend\<CR>") + " Wait for shell prompt. + call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))}) + call assert_equal(['foo'], readfile('Xfoo')) + call term_sendkeys(buf, "fg\<CR>") + call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))}) + + exe buf . 'bwipe!' + call delete('Xfoo') + set autowrite& +endfunc diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 245e1f18bb..bc7b7c00d3 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -46,3 +46,18 @@ func Test_swap_directory() call delete("Xtest2", "rf") call delete("Xtest.je", "rf") endfunc + +func Test_missing_dir() + call mkdir('Xswapdir') + exe 'set directory=' . getcwd() . '/Xswapdir' + + call assert_equal('', glob('foo')) + call assert_equal('', glob('bar')) + edit foo/x.txt + " This should not give a warning for an existing swap file. + split bar/x.txt + only + + set directory& + call delete('Xswapdir', 'rf') +endfunc diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index 6d164ac895..e35c0f1105 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -450,7 +450,7 @@ func Test_bg_detection() hi Normal ctermbg=15 call assert_equal('light', &bg) - " manually-set &bg takes precendence over auto-detection + " manually-set &bg takes precedence over auto-detection set bg=light hi Normal ctermbg=4 call assert_equal('light', &bg) @@ -458,3 +458,27 @@ func Test_bg_detection() hi Normal ctermbg=12 call assert_equal('dark', &bg) endfunc + +fun Test_synstack_synIDtrans() + new + setfiletype c + syntax on + call setline(1, ' /* A comment with a TODO */') + + call assert_equal([], synstack(1, 1)) + + norm f/ + call assert_equal(['cComment', 'cCommentStart'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) + call assert_equal(['Comment', 'Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) + + norm fA + call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) + call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) + + norm fT + call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")')) + call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")')) + + syn clear + bw! +endfunc diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index 180563ebbd..add9b3d7cf 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -1,5 +1,6 @@ " Tests for tabpage + function Test_tabpage() bw! " Simple test for opening and closing a tab page @@ -41,40 +42,38 @@ function Test_tabpage() call assert_true(t:val_num == 100 && t:val_str == 'SetTabVar test' && t:val_list == ['red', 'blue', 'green']) tabclose - if has('nvim') || has('gui') || has('clientserver') - " Test for ":tab drop exist-file" to keep current window. - sp test1 - tab drop test1 - call assert_true(tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1) - close - " - " - " Test for ":tab drop new-file" to keep current window of tabpage 1. - split - tab drop newfile - call assert_true(tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1) - tabclose - q - " - " - " Test for ":tab drop multi-opend-file" to keep current tabpage and window. - new test1 - tabnew - new test1 - tab drop test1 - call assert_true(tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1) - tabclose - q - " - " - " Test for ":tab drop vertical-split-window" to jump test1 buffer - tabedit test1 - vnew - tabfirst - tab drop test1 - call assert_equal([2, 2, 2, 2], [tabpagenr('$'), tabpagenr(), tabpagewinnr(2, '$'), tabpagewinnr(2)]) - 1tabonly - endif + " Test for ":tab drop exist-file" to keep current window. + sp test1 + tab drop test1 + call assert_true(tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1) + close + " + " + " Test for ":tab drop new-file" to keep current window of tabpage 1. + split + tab drop newfile + call assert_true(tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1) + tabclose + q + " + " + " Test for ":tab drop multi-opend-file" to keep current tabpage and window. + new test1 + tabnew + new test1 + tab drop test1 + call assert_true(tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1) + tabclose + q + " + " + " Test for ":tab drop vertical-split-window" to jump test1 buffer + tabedit test1 + vnew + tabfirst + tab drop test1 + call assert_equal([2, 2, 2, 2], [tabpagenr('$'), tabpagenr(), tabpagewinnr(2, '$'), tabpagewinnr(2)]) + 1tabonly " " for i in range(9) | tabnew | endfor @@ -106,6 +105,19 @@ function Test_tabpage() call assert_equal(4, tabpagenr()) 7tabmove 5 call assert_equal(5, tabpagenr()) + + " The following are a no-op + norm! 2gt + call assert_equal(2, tabpagenr()) + tabmove 2 + call assert_equal(2, tabpagenr()) + 2tabmove + call assert_equal(2, tabpagenr()) + tabmove 1 + call assert_equal(2, tabpagenr()) + 1tabmove + call assert_equal(2, tabpagenr()) + call assert_fails("99tabmove", 'E16:') call assert_fails("+99tabmove", 'E16:') call assert_fails("-99tabmove", 'E16:') @@ -319,6 +331,34 @@ function s:reconstruct_tabpage_for_test(nr) endfor endfunc +func Test_tabpage_ctrl_pgup_pgdown() + enew! + tabnew tab1 + tabnew tab2 + + call assert_equal(3, tabpagenr()) + exe "norm! \<C-PageUp>" + call assert_equal(2, tabpagenr()) + exe "norm! \<C-PageDown>" + call assert_equal(3, tabpagenr()) + + " Check wrapping at last or first page. + exe "norm! \<C-PageDown>" + call assert_equal(1, tabpagenr()) + exe "norm! \<C-PageUp>" + call assert_equal(3, tabpagenr()) + + " With a count, <C-PageUp> and <C-PageDown> are not symmetrical somehow: + " - {count}<C-PageUp> goes {count} pages downward (relative count) + " - {count}<C-PageDown> goes to page number {count} (absolute count) + exe "norm! 2\<C-PageUp>" + call assert_equal(1, tabpagenr()) + exe "norm! 2\<C-PageDown>" + call assert_equal(2, tabpagenr()) + + 1tabonly! +endfunc + " Test for [count] of tabclose function Test_tabpage_with_tabclose() @@ -493,4 +533,18 @@ func Test_close_on_quitpre() buf Xtest endfunc +func Test_tabs() + enew! + tabnew tab1 + norm ixxx + let a=split(execute(':tabs'), "\n") + call assert_equal(['Tab page 1', + \ ' [No Name]', + \ 'Tab page 2', + \ '> + tab1'], a) + + 1tabonly! + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 268a153077..f9bd8b5246 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -230,4 +230,32 @@ func Test_tag_file_encoding() call delete('Xtags1') endfunc +func Test_tagjump_etags() + if !has('emacs_tags') + return + endif + call writefile([ + \ "void foo() {}", + \ "int main(int argc, char **argv)", + \ "{", + \ "\tfoo();", + \ "\treturn 0;", + \ "}", + \ ], 'Xmain.c') + + call writefile([ + \ "\x0c", + \ "Xmain.c,64", + \ "void foo() {}\x7ffoo\x011,0", + \ "int main(int argc, char **argv)\x7fmain\x012,14", + \ ], 'Xtags') + set tags=Xtags + ta foo + call assert_equal('void foo() {}', getline('.')) + + call delete('Xtags') + call delete('Xmain.c') + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim index 2d1557ebd9..3ad2025915 100644 --- a/src/nvim/testdir/test_taglist.vim +++ b/src/nvim/testdir/test_taglist.vim @@ -1,4 +1,4 @@ -" test 'taglist' function +" test 'taglist' function and :tags command func Test_taglist() call writefile([ @@ -56,3 +56,8 @@ func Test_taglist_ctags_etags() call delete('Xtags') endfunc + +func Test_tags_too_long() + call assert_fails('tag ' . repeat('x', 1020), 'E426') + tags +endfunc diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim index 684f197f5f..6a2f5044cc 100644 --- a/src/nvim/testdir/test_textobjects.vim +++ b/src/nvim/testdir/test_textobjects.vim @@ -121,6 +121,23 @@ func Test_string_html_objects() enew! endfunc +func Test_empty_html_tag() + new + call setline(1, '<div></div>') + normal 0citxxx + call assert_equal('<div>xxx</div>', getline(1)) + + call setline(1, '<div></div>') + normal 0f<cityyy + call assert_equal('<div>yyy</div>', getline(1)) + + call setline(1, '<div></div>') + normal 0f<vitsaaa + call assert_equal('aaa', getline(1)) + + bwipe! +endfunc + " Tests for match() and matchstr() func Test_match() call assert_equal("b", matchstr("abcd", ".", 0, 2)) @@ -152,3 +169,91 @@ func Test_match() call assert_equal(3 , match('abc', '\zs', 3, 1)) call assert_equal(-1, match('abc', '\zs', 4, 1)) endfunc + +" This was causing an illegal memory access +func Test_inner_tag() + new + norm ixxx + call feedkeys("v", 'xt') + insert +x +x +. + norm it + q! +endfunc + +func Test_sentence() + enew! + call setline(1, 'A sentence. A sentence? A sentence!') + + normal yis + call assert_equal('A sentence.', @") + normal yas + call assert_equal('A sentence. ', @") + + normal ) + + normal yis + call assert_equal('A sentence?', @") + normal yas + call assert_equal('A sentence? ', @") + + normal ) + + normal yis + call assert_equal('A sentence!', @") + normal yas + call assert_equal(' A sentence!', @") + + normal 0 + normal 2yis + call assert_equal('A sentence. ', @") + normal 3yis + call assert_equal('A sentence. A sentence?', @") + normal 2yas + call assert_equal('A sentence. A sentence? ', @") + + %delete _ +endfunc + +func Test_sentence_with_quotes() + enew! + call setline(1, 'A "sentence." A sentence.') + + normal yis + call assert_equal('A "sentence."', @") + normal yas + call assert_equal('A "sentence." ', @") + + normal ) + + normal yis + call assert_equal('A sentence.', @") + normal yas + call assert_equal(' A sentence.', @") + + %delete _ +endfunc + +func! Test_sentence_with_cursor_on_delimiter() + enew! + call setline(1, "A '([sentence.])' A sentence.") + + normal! 15|yis + call assert_equal("A '([sentence.])'", @") + normal! 15|yas + call assert_equal("A '([sentence.])' ", @") + + normal! 16|yis + call assert_equal("A '([sentence.])'", @") + normal! 16|yas + call assert_equal("A '([sentence.])' ", @") + + normal! 17|yis + call assert_equal("A '([sentence.])'", @") + normal! 17|yas + call assert_equal("A '([sentence.])' ", @") + + %delete _ +endfunc diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 81ac2b6171..8a3e57bb02 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -20,9 +20,9 @@ func Test_oneshot() let slept = WaitFor('g:val == 1') call assert_equal(1, g:val) if has('reltime') - call assert_inrange(40, 100, slept) + call assert_inrange(40, 120, slept) else - call assert_inrange(20, 100, slept) + call assert_inrange(20, 120, slept) endif endfunc @@ -39,11 +39,12 @@ func Test_repeat_three() endfunc func Test_repeat_many() + call timer_stopall() let g:val = 0 let timer = timer_start(50, 'MyHandler', {'repeat': -1}) sleep 200m call timer_stop(timer) - call assert_inrange(2, 4, g:val) + call assert_inrange((has('mac') ? 1 : 2), 4, g:val) endfunc func Test_with_partial_callback() @@ -89,6 +90,7 @@ func Test_info() endfunc func Test_stopall() + call timer_stopall() let id1 = timer_start(1000, 'MyHandler') let id2 = timer_start(2000, 'MyHandler') let info = timer_info() @@ -161,13 +163,72 @@ func StopTimerAll(timer) endfunc func Test_stop_all_in_callback() + call timer_stopall() let g:timer1 = timer_start(10, 'StopTimerAll') let info = timer_info() call assert_equal(1, len(info)) + if has('mac') + sleep 100m + endif sleep 40m let info = timer_info() call assert_equal(0, len(info)) endfunc +func FeedkeysCb(timer) + call feedkeys("hello\<CR>", 'nt') +endfunc + +func InputCb(timer) + call timer_start(10, 'FeedkeysCb') + let g:val = input('?') + call Resume() +endfunc + +func Test_input_in_timer() + let g:val = '' + call timer_start(10, 'InputCb') + call Standby(1000) + call assert_equal('hello', g:val) +endfunc + +func FuncWithCaughtError(timer) + let g:call_count += 1 + try + doesnotexist + catch + " nop + endtry +endfunc + +func Test_timer_catch_error() + let g:call_count = 0 + let timer = timer_start(10, 'FuncWithCaughtError', {'repeat': 4}) + " Timer will not be stopped. + call WaitFor('g:call_count == 4') + sleep 50m + call assert_equal(4, g:call_count) +endfunc + +func FeedAndPeek(timer) + call test_feedinput('a') + call getchar(1) +endfunc + +func Interrupt(timer) + call test_feedinput("\<C-C>") +endfunc + +func Test_peek_and_get_char() + throw 'skipped: Nvim does not support test_feedinput()' + if !has('unix') && !has('gui_running') + return + endif + call timer_start(0, 'FeedAndPeek') + let intr = timer_start(100, 'Interrupt') + let c = getchar() + call assert_equal(char2nr('a'), c) + call timer_stop(intr) +endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim index 2bc6073d52..83ede1dc37 100644 --- a/src/nvim/testdir/test_undo.vim +++ b/src/nvim/testdir/test_undo.vim @@ -4,28 +4,88 @@ " Also tests :earlier and :later. func Test_undotree() - exe "normal Aabc\<Esc>" + new + + normal! Aabc set ul=100 - exe "normal Adef\<Esc>" + let d = undotree() + call assert_equal(1, d.seq_last) + call assert_equal(1, d.seq_cur) + call assert_equal(0, d.save_last) + call assert_equal(0, d.save_cur) + call assert_equal(1, len(d.entries)) + call assert_equal(1, d.entries[0].newhead) + call assert_equal(1, d.entries[0].seq) + call assert_true(d.entries[0].time <= d.time_cur) + + normal! Adef set ul=100 + let d = undotree() + call assert_equal(2, d.seq_last) + call assert_equal(2, d.seq_cur) + call assert_equal(0, d.save_last) + call assert_equal(0, d.save_cur) + call assert_equal(2, len(d.entries)) + call assert_equal(1, d.entries[0].seq) + call assert_equal(1, d.entries[1].newhead) + call assert_equal(2, d.entries[1].seq) + call assert_true(d.entries[1].time <= d.time_cur) + + undo + set ul=100 + let d = undotree() + call assert_equal(2, d.seq_last) + call assert_equal(1, d.seq_cur) + call assert_equal(0, d.save_last) + call assert_equal(0, d.save_cur) + call assert_equal(2, len(d.entries)) + call assert_equal(1, d.entries[0].seq) + call assert_equal(1, d.entries[1].curhead) + call assert_equal(1, d.entries[1].newhead) + call assert_equal(2, d.entries[1].seq) + call assert_true(d.entries[1].time == d.time_cur) + + normal! Aghi + set ul=100 + let d = undotree() + call assert_equal(3, d.seq_last) + call assert_equal(3, d.seq_cur) + call assert_equal(0, d.save_last) + call assert_equal(0, d.save_cur) + call assert_equal(2, len(d.entries)) + call assert_equal(1, d.entries[0].seq) + call assert_equal(2, d.entries[1].alt[0].seq) + call assert_equal(1, d.entries[1].newhead) + call assert_equal(3, d.entries[1].seq) + call assert_true(d.entries[1].time <= d.time_cur) + undo + set ul=100 let d = undotree() - call assert_true(d.seq_last > 0) - call assert_true(d.seq_cur > 0) - call assert_true(d.seq_cur < d.seq_last) - call assert_true(len(d.entries) > 0) - " TODO: check more members of d + call assert_equal(3, d.seq_last) + call assert_equal(1, d.seq_cur) + call assert_equal(0, d.save_last) + call assert_equal(0, d.save_cur) + call assert_equal(2, len(d.entries)) + call assert_equal(1, d.entries[0].seq) + call assert_equal(2, d.entries[1].alt[0].seq) + call assert_equal(1, d.entries[1].curhead) + call assert_equal(1, d.entries[1].newhead) + call assert_equal(3, d.entries[1].seq) + call assert_true(d.entries[1].time == d.time_cur) w! Xtest - call assert_equal(d.save_last + 1, undotree().save_last) + let d = undotree() + call assert_equal(1, d.save_cur) + call assert_equal(1, d.save_last) call delete('Xtest') - bwipe Xtest + bwipe! Xtest endfunc func FillBuffer() for i in range(1,13) put=i - " Set 'undolevels' to split undo. + " Set 'undolevels' to split undo. exe "setg ul=" . &g:ul endfor endfunc @@ -135,19 +195,19 @@ func Test_undolist() new set ul=100 - let a=execute('undolist') + let a = execute('undolist') call assert_equal("\nNothing to undo", a) " 1 leaf (2 changes). call feedkeys('achange1', 'xt') call feedkeys('achange2', 'xt') - let a=execute('undolist') + let a = execute('undolist') call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a) " 2 leaves. call feedkeys('u', 'xt') call feedkeys('achange3\<Esc>', 'xt') - let a=execute('undolist') + let a = execute('undolist') call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a) close! endfunc @@ -270,7 +330,7 @@ endfunc " Also test this in an empty buffer. func Test_cmd_in_reg_undo() enew! - let @a="Ox\<Esc>jAy\<Esc>kdd" + let @a = "Ox\<Esc>jAy\<Esc>kdd" edit +/^$ test_undo.vim normal @au call assert_equal(0, &modified) @@ -279,7 +339,7 @@ func Test_cmd_in_reg_undo() normal @au call assert_equal(0, &modified) only! - let @a='' + let @a = '' endfunc func Test_redo_empty_line() @@ -288,3 +348,89 @@ func Test_redo_empty_line() exe "norm." bwipe! endfunc + +" This used to cause an illegal memory access +func Test_undo_append() + new + call feedkeys("axx\<Esc>v", 'xt') + undo + norm o + quit +endfunc + +funct Test_undofile() + " Test undofile() without setting 'undodir'. + if has('persistent_undo') + call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo')) + else + call assert_equal('', undofile('Xundofoo')) + endif + call assert_equal('', undofile('')) + + " Test undofile() with 'undodir' set to to an existing directory. + call mkdir('Xundodir') + set undodir=Xundodir + let cwd = getcwd() + if has('win32') + " Replace windows drive such as C:... into C%... + let cwd = substitute(cwd, '^\([A-Z]\):', '\1%', 'g') + endif + let pathsep = has('win32') ? '\' : '/' + let cwd = substitute(cwd . pathsep . 'Xundofoo', pathsep, '%', 'g') + if has('persistent_undo') + call assert_equal('Xundodir' . pathsep . cwd, undofile('Xundofoo')) + else + call assert_equal('', undofile('Xundofoo')) + endif + call assert_equal('', undofile('')) + call delete('Xundodir', 'd') + + " Test undofile() with 'undodir' set to a non-existing directory. + " call assert_equal('', undofile('Xundofoo')) + + set undodir& +endfunc + +func Test_undo_0() + new + set ul=100 + normal i1 + undo + normal i2 + undo + normal i3 + + undo 0 + let d = undotree() + call assert_equal('', getline(1)) + call assert_equal(0, d.seq_cur) + + redo + let d = undotree() + call assert_equal('3', getline(1)) + call assert_equal(3, d.seq_cur) + + undo 2 + undo 0 + let d = undotree() + call assert_equal('', getline(1)) + call assert_equal(0, d.seq_cur) + + redo + let d = undotree() + call assert_equal('2', getline(1)) + call assert_equal(2, d.seq_cur) + + undo 1 + undo 0 + let d = undotree() + call assert_equal('', getline(1)) + call assert_equal(0, d.seq_cur) + + redo + let d = undotree() + call assert_equal('1', getline(1)) + call assert_equal(1, d.seq_cur) + + bwipe! +endfunc diff --git a/src/nvim/testdir/test_unlet.vim b/src/nvim/testdir/test_unlet.vim index 3f06058d03..b02bdaab3b 100644 --- a/src/nvim/testdir/test_unlet.vim +++ b/src/nvim/testdir/test_unlet.vim @@ -28,3 +28,37 @@ endfunc func Test_unlet_fails() call assert_fails('unlet v:["count"]', 'E46:') endfunc + +func Test_unlet_env() + let envcmd = has('win32') ? 'set' : 'env' + + let $FOOBAR = 'test' + let found = 0 + for kv in split(system(envcmd), "\r*\n") + if kv == 'FOOBAR=test' + let found = 1 + endif + endfor + call assert_equal(1, found) + + unlet $FOOBAR + let found = 0 + for kv in split(system(envcmd), "\r*\n") + if kv == 'FOOBAR=test' + let found = 1 + endif + endfor + call assert_equal(0, found) + + unlet $MUST_NOT_BE_AN_ERROR +endfunc + +func Test_unlet_complete() + let g:FOOBAR = 1 + call feedkeys(":unlet g:FOO\t\n", 'tx') + call assert_true(!exists('g:FOOBAR')) + + let $FOOBAR = 1 + call feedkeys(":unlet $FOO\t\n", 'tx') + call assert_true(!exists('$FOOBAR') || empty($FOOBAR)) +endfunc diff --git a/src/nvim/testdir/test_user_func.vim b/src/nvim/testdir/test_user_func.vim new file mode 100644 index 0000000000..e7a3701386 --- /dev/null +++ b/src/nvim/testdir/test_user_func.vim @@ -0,0 +1,96 @@ +" Test for user functions. +" Also test an <expr> mapping calling a function. +" Also test that a builtin function cannot be replaced. +" Also test for regression when calling arbitrary expression. + +func Table(title, ...) + let ret = a:title + let idx = 1 + while idx <= a:0 + exe "let ret = ret . a:" . idx + let idx = idx + 1 + endwhile + return ret +endfunc + +func Compute(n1, n2, divname) + if a:n2 == 0 + return "fail" + endif + exe "let g:" . a:divname . " = ". a:n1 / a:n2 + return "ok" +endfunc + +func Expr1() + silent! normal! v + return "111" +endfunc + +func Expr2() + call search('XX', 'b') + return "222" +endfunc + +func ListItem() + let g:counter += 1 + return g:counter . '. ' +endfunc + +func ListReset() + let g:counter = 0 + return '' +endfunc + +func FuncWithRef(a) + unlet g:FuncRef + return a:a +endfunc + +func Test_user_func() + let g:FuncRef=function("FuncWithRef") + let g:counter = 0 + inoremap <expr> ( ListItem() + inoremap <expr> [ ListReset() + imap <expr> + Expr1() + imap <expr> * Expr2() + let g:retval = "nop" + + call assert_equal('xxx4asdf', Table("xxx", 4, "asdf")) + call assert_equal('fail', Compute(45, 0, "retval")) + call assert_equal('nop', g:retval) + call assert_equal('ok', Compute(45, 5, "retval")) + call assert_equal(9, g:retval) + call assert_equal(333, g:FuncRef(333)) + + enew + + normal oXX+-XX + call assert_equal('XX111-XX', getline('.')) + normal o---*--- + call assert_equal('---222---', getline('.')) + normal o(one + call assert_equal('1. one', getline('.')) + normal o(two + call assert_equal('2. two', getline('.')) + normal o[(one again + call assert_equal('1. one again', getline('.')) + + call assert_equal(3, max([1, 2, 3])) + call assert_fails("call extend(g:, {'max': function('min')})", 'E704') + call assert_equal(3, max([1, 2, 3])) + + " Regression: the first line below used to throw ?E110: Missing ')'? + " Second is here just to prove that this line is correct when not skipping + " rhs of &&. + call assert_equal(0, (0 && (function('tr'))(1, 2, 3))) + call assert_equal(1, (1 && (function('tr'))(1, 2, 3))) + + delfunc Table + delfunc Compute + delfunc Expr1 + delfunc Expr2 + delfunc ListItem + delfunc ListReset + unlet g:retval g:counter + enew! +endfunc diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim index 2b8849f488..d49025237b 100644 --- a/src/nvim/testdir/test_virtualedit.vim +++ b/src/nvim/testdir/test_virtualedit.vim @@ -41,3 +41,21 @@ func Test_paste_end_of_line() bwipe! set virtualedit= endfunc + +func Test_edit_CTRL_G() + new + set virtualedit=insert + call setline(1, ['123', '1', '12']) + exe "normal! ggA\<c-g>jx\<c-g>jx" + call assert_equal(['123', '1 x', '12 x'], getline(1,'$')) + + set virtualedit=all + %d_ + call setline(1, ['1', '12']) + exe "normal! ggllix\<c-g>jx" + call assert_equal(['1 x', '12x'], getline(1,'$')) + + + bwipe! + set virtualedit= +endfunc diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index 0f2e7e493e..756a455ebd 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -17,6 +17,14 @@ func Test_block_shift_multibyte() q! endfunc +func Test_block_shift_overflow() + " This used to cause a multiplication overflow followed by a crash. + new + normal ii + exe "normal \<C-V>876543210>" + q! +endfunc + func Test_Visual_ctrl_o() new call setline(1, ['one', 'two', 'three']) @@ -118,9 +126,34 @@ func Test_blockwise_visual() enew! endfunc +" Test swapping corners in blockwise visual mode with o and O +func Test_blockwise_visual_o_O() + enew! + + exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr " + exe "norm! gvO\<Esc>ra" + exe "norm! gvO\<Esc>rb" + exe "norm! gvo\<C-c>rc" + exe "norm! gvO\<C-c>rd" + + call assert_equal(['..........', + \ '...c d..', + \ '... ..', + \ '...a b..', + \ '..........'], getline(1, '$')) + + enew! +endfun + " Test Virtual replace mode. func Test_virtual_replace() throw 'skipped: TODO: ' + if exists('&t_kD') + let save_t_kD = &t_kD + endif + if exists('&t_kb') + let save_t_kb = &t_kb + endif exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08" enew! exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz" @@ -151,4 +184,96 @@ func Test_virtual_replace() call assert_equal(['AB......CDEFGHI.Jkl', \ 'AB IJKLMNO QRst'], getline(12, 13)) enew! + set noai bs&vim + if exists('save_t_kD') + let &t_kD = save_t_kD + endif + if exists('save_t_kb') + let &t_kb = save_t_kb + endif +endfunc + +" Test Virtual replace mode. +func Test_virtual_replace2() + enew! + set bs=2 + exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz" + call cursor(1,1) + " Test 1: Test that del deletes the newline + exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR" + call assert_equal(['0 1', + \ 'A', + \ 'BCDEFGHIJ', + \ ' KL', + \ 'MNO', + \ 'PQR', + \ ], getline(1, 6)) + " Test 2: + " a newline is not deleted, if no newline has been added in virtual replace mode + %d_ + call setline(1, ['abcd', 'efgh', 'ijkl']) + call cursor(2,1) + exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>" + call assert_equal(['abcd', + \ '123h', + \ 'ijkl'], getline(1, '$')) + " Test 3: + " a newline is deleted, if a newline has been inserted before in virtual replace mode + %d_ + call setline(1, ['abcd', 'efgh', 'ijkl']) + call cursor(2,1) + exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>" + call assert_equal(['abcd', + \ '1234', + \ 'ijkl'], getline(1, '$')) + " Test 4: + " delete add a newline, delete it, add it again and check undo + %d_ + call setline(1, ['abcd', 'efgh', 'ijkl']) + call cursor(2,1) + " break undo sequence explicitly + let &ul = &ul + exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>" + let &ul = &ul + call assert_equal(['abcd', + \ '123456', + \ ''], getline(1, '$')) + norm! u + call assert_equal(['abcd', + \ 'efgh', + \ 'ijkl'], getline(1, '$')) + " clean up + %d_ + set bs&vim +endfunc + +" Test for Visual mode not being reset causing E315 error. +func TriggerTheProblem() + " At this point there is no visual selection because :call reset it. + " Let's restore the selection: + normal gv + '<,'>del _ + try + exe "normal \<Esc>" + catch /^Vim\%((\a\+)\)\=:E315/ + echom 'Snap! E315 error!' + let g:msg = 'Snap! E315 error!' + endtry +endfunc + +func Test_visual_mode_reset() + set belloff=all + enew + let g:msg = "Everything's fine." + enew + setl buftype=nofile + call append(line('$'), 'Delete this line.') + + " NOTE: this has to be done by a call to a function because executing :del + " the ex-way will require the colon operator which resets the visual mode + " thus preventing the problem: + exe "normal! GV:call TriggerTheProblem()\<CR>" + call assert_equal("Everything's fine.", g:msg) + + set belloff& endfunc diff --git a/src/nvim/testdir/test_winbuf_close.vim b/src/nvim/testdir/test_winbuf_close.vim index ed64dd79b7..e4618610cd 100644 --- a/src/nvim/testdir/test_winbuf_close.vim +++ b/src/nvim/testdir/test_winbuf_close.vim @@ -122,3 +122,39 @@ func Test_winbuf_close() call delete('Xtest2') call delete('Xtest3') endfunc + +" Test that ":close" will respect 'winfixheight' when possible. +func Test_winfixheight_on_close() + set nosplitbelow nosplitright + + split | split | vsplit + + $wincmd w + setlocal winfixheight + let l:height = winheight(0) + + 3close + + call assert_equal(l:height, winheight(0)) + + %bwipeout! + setlocal nowinfixheight splitbelow& splitright& +endfunc + +" Test that ":close" will respect 'winfixwidth' when possible. +func Test_winfixwidth_on_close() + set nosplitbelow nosplitright + + vsplit | vsplit | split + + $wincmd w + setlocal winfixwidth + let l:width = winwidth(0) + + 3close + + call assert_equal(l:width, winwidth(0)) + + %bwipeout! + setlocal nowinfixwidth splitbelow& splitright& +endfunction diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index 139d29a48b..b3ab6957dc 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -17,7 +17,7 @@ func Test_window_cmd_ls0_with_split() endfunc func Test_window_cmd_cmdwin_with_vsp() - let efmt='Expected 0 but got %d (in ls=%d, %s window)' + let efmt = 'Expected 0 but got %d (in ls=%d, %s window)' for v in range(0, 2) exec "set ls=" . v vsplit @@ -374,6 +374,19 @@ func Test_equalalways_on_close() set equalalways& endfunc +func Test_win_screenpos() + call assert_equal(1, winnr('$')) + split + vsplit + 10wincmd _ + 30wincmd | + call assert_equal([1, 1], win_screenpos(1)) + call assert_equal([1, 32], win_screenpos(2)) + call assert_equal([12, 1], win_screenpos(3)) + call assert_equal([0, 0], win_screenpos(4)) + only +endfunc + func Test_window_jump_tag() help /iccf @@ -417,4 +430,92 @@ func Test_window_newtab() endfunc +" Tests for adjusting window and contents +func GetScreenStr(row) + let str = "" + for c in range(1,3) + let str .= nr2char(screenchar(a:row, c)) + endfor + return str +endfunc + +func Test_window_contents() + enew! | only | new + call setline(1, range(1,256)) + + exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+" + redraw + let s3 = GetScreenStr(1) + wincmd p + call assert_equal(1, line("w0")) + call assert_equal('1 ', s3) + + exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+" + redraw + let s3 = GetScreenStr(1) + wincmd p + call assert_equal(50, line("w0")) + call assert_equal('50 ', s3) + + exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+" + redraw + let s3 = GetScreenStr(1) + wincmd p + call assert_equal(59, line("w0")) + call assert_equal('59 ', s3) + + bwipeout! + call test_garbagecollect_now() +endfunc + +func Test_access_freed_mem() + " This was accessing freed memory + au * 0 vs xxx + arg 0 + argadd + all + all + au! + bwipe xxx +endfunc + +func Test_visual_cleared_after_window_split() + new | only! + let smd_save = &showmode + set showmode + let ls_save = &laststatus + set laststatus=1 + call setline(1, ['a', 'b', 'c', 'd', '']) + norm! G + exe "norm! kkvk" + redraw + exe "norm! \<C-W>v" + redraw + " check if '-- VISUAL --' disappeared from command line + let columns = range(1, &columns) + let cmdlinechars = map(columns, 'nr2char(screenchar(&lines, v:val))') + let cmdline = join(cmdlinechars, '') + let cmdline_ltrim = substitute(cmdline, '^\s*', "", "") + let mode_shown = substitute(cmdline_ltrim, '\s*$', "", "") + call assert_equal('', mode_shown) + let &showmode = smd_save + let &laststatus = ls_save + bwipe! +endfunc + +func Test_winrestcmd() + 2split + 3vsplit + let a = winrestcmd() + call assert_equal(2, winheight(0)) + call assert_equal(3, winwidth(0)) + wincmd = + call assert_notequal(2, winheight(0)) + call assert_notequal(3, winwidth(0)) + exe a + call assert_equal(2, winheight(0)) + call assert_equal(3, winwidth(0)) + only +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_windows_home.vim b/src/nvim/testdir/test_windows_home.vim new file mode 100644 index 0000000000..bbcbf96050 --- /dev/null +++ b/src/nvim/testdir/test_windows_home.vim @@ -0,0 +1,121 @@ +" Test for $HOME on Windows. + +if !has('win32') + finish +endif + +let s:env = {} + +func s:restore_env() + for i in keys(s:env) + exe 'let ' . i . '=s:env["' . i . '"]' + endfor +endfunc + +func s:save_env(...) + for i in a:000 + exe 'let s:env["' . i . '"]=' . i + endfor +endfunc + +func s:unlet_env(...) + for i in a:000 + exe 'let ' . i . '=""' + endfor +endfunc + +func CheckHomeIsMissingFromSubprocessEnvironment() + silent! let out = system('set') + let env = filter(split(out, "\n"), 'v:val=~"^HOME="') + call assert_equal(0, len(env)) +endfunc + +func CheckHomeIsInSubprocessEnvironment(exp) + silent! let out = system('set') + let env = filter(split(out, "\n"), 'v:val=~"^HOME="') + let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '') + call assert_equal(a:exp, home) +endfunc + +func CheckHome(exp, ...) + call assert_equal(a:exp, $HOME) + call assert_equal(a:exp, expand('~', ':p')) + if !a:0 + call CheckHomeIsMissingFromSubprocessEnvironment() + else + call CheckHomeIsInSubprocessEnvironment(a:1) + endif +endfunc + +func Test_WindowsHome() + command! -nargs=* SaveEnv call <SID>save_env(<f-args>) + command! -nargs=* RestoreEnv call <SID>restore_env() + command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>) + set noshellslash + + let save_home = $HOME + SaveEnv $USERPROFILE $HOMEDRIVE $HOMEPATH + try + " Normal behavior: use $HOMEDRIVE and $HOMEPATH, ignore $USERPROFILE + let $USERPROFILE = 'unused' + let $HOMEDRIVE = 'C:' + let $HOMEPATH = '\foobar' + let $HOME = '' " Force recomputing "homedir" + call CheckHome('C:\foobar') + + " Same, but with $HOMEPATH not set + UnletEnv $HOMEPATH + let $HOME = '' " Force recomputing "homedir" + call CheckHome('C:\') + + " Use $USERPROFILE if $HOMEPATH and $HOMEDRIVE are empty + UnletEnv $HOMEDRIVE $HOMEPATH + let $USERPROFILE = 'C:\foo' + let $HOME = '' " Force recomputing "homedir" + call CheckHome('C:\foo') + + " If $HOME is set the others don't matter + let $HOME = 'C:\bar' + let $USERPROFILE = 'unused' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + call CheckHome('C:\bar', 'C:\bar') + + " If $HOME contains %USERPROFILE% it is expanded + let $USERPROFILE = 'C:\foo' + let $HOME = '%USERPROFILE%\bar' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + " call CheckHome('C:\foo\bar', '%USERPROFILE%\bar') + + " Invalid $HOME is kept + let $USERPROFILE = 'C:\foo' + let $HOME = '%USERPROFILE' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + call CheckHome('%USERPROFILE', '%USERPROFILE') + + " %USERPROFILE% not at start of $HOME is not expanded + let $USERPROFILE = 'unused' + let $HOME = 'C:\%USERPROFILE%' + let $HOMEDRIVE = 'unused' + let $HOMEPATH = 'unused' + call CheckHome('C:\%USERPROFILE%', 'C:\%USERPROFILE%') + + if has('channel') + RestoreEnv + let $HOME = save_home + let env = '' + let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}}) + sleep 1 + let env = filter(split(env, "\n"), 'v:val=="HOME"') + let home = len(env) == 0 ? "" : env[0] + call assert_equal('', home) + endif + finally + RestoreEnv + delcommand SaveEnv + delcommand RestoreEnv + delcommand UnletEnv + endtry +endfunc diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim index 8b031646b5..1cd5fb306a 100644 --- a/src/nvim/testdir/test_writefile.vim +++ b/src/nvim/testdir/test_writefile.vim @@ -31,3 +31,103 @@ func Test_writefile_fails_gently() call assert_fails('call writefile([], [])', 'E730:') endfunc + +func Test_writefile_fails_conversion() + if !has('multi_byte') || !has('iconv') + return + endif + set nobackup nowritebackup + new + let contents = ["line one", "line two"] + call writefile(contents, 'Xfile') + edit Xfile + call setline(1, ["first line", "cannot convert \u010b", "third line"]) + call assert_fails('write ++enc=cp932') + call assert_equal(contents, readfile('Xfile')) + + call delete('Xfile') + bwipe! + set backup& writebackup& +endfunc + +func SetFlag(timer) + let g:flag = 1 +endfunc + +func Test_write_quit_split() + " Prevent exiting by splitting window on file write. + augroup testgroup + autocmd BufWritePre * split + augroup END + e! Xfile + call setline(1, 'nothing') + wq + + if has('timers') + " timer will not run if "exiting" is still set + let g:flag = 0 + call timer_start(1, 'SetFlag') + sleep 50m + call assert_equal(1, g:flag) + unlet g:flag + endif + au! testgroup + bwipe Xfile + call delete('Xfile') +endfunc + +func Test_nowrite_quit_split() + " Prevent exiting by opening a help window. + e! Xfile + help + wincmd w + exe winnr() . 'q' + + if has('timers') + " timer will not run if "exiting" is still set + let g:flag = 0 + call timer_start(1, 'SetFlag') + sleep 50m + call assert_equal(1, g:flag) + unlet g:flag + endif + bwipe Xfile +endfunc + +func Test_writefile_autowrite() + set autowrite + new + next Xa Xb Xc + call setline(1, 'aaa') + next + call assert_equal(['aaa'], readfile('Xa')) + call setline(1, 'bbb') + call assert_fails('edit XX') + call assert_false(filereadable('Xb')) + + set autowriteall + edit XX + call assert_equal(['bbb'], readfile('Xb')) + + bwipe! + call delete('Xa') + call delete('Xb') + set noautowrite +endfunc + +func Test_writefile_autowrite_nowrite() + set autowrite + new + next Xa Xb Xc + set buftype=nowrite + call setline(1, 'aaa') + let buf = bufnr('%') + " buffer contents silently lost + edit XX + call assert_false(filereadable('Xa')) + rewind + call assert_equal('', getline(1)) + + bwipe! + set noautowrite +endfunc diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim index eb92630761..29ea073f97 100644 --- a/src/nvim/testdir/view_util.vim +++ b/src/nvim/testdir/view_util.vim @@ -1,5 +1,10 @@ " Functions about view shared by several tests +" Only load this script once. +if exists('*ScreenLines') + finish +endif + " ScreenLines(lnum, width) or " ScreenLines([start, end], width) function! ScreenLines(lnum, width) abort @@ -18,6 +23,22 @@ function! ScreenLines(lnum, width) abort return lines endfunction +function! ScreenAttrs(lnum, width) abort + redraw! + if type(a:lnum) == v:t_list + let start = a:lnum[0] + let end = a:lnum[1] + else + let start = a:lnum + let end = a:lnum + endif + let attrs = [] + for l in range(start, end) + let attrs += [map(range(1, a:width), 'screenattr(l, v:val)')] + endfor + return attrs +endfunction + function! NewWindow(height, width) abort exe a:height . 'new' exe a:width . 'vsp' diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index 2f07e83158..ad86dd928b 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -14,74 +14,12 @@ #include "nvim/message.h" #include "nvim/option.h" #include "nvim/tui/terminfo.h" +#include "nvim/tui/terminfo_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/terminfo.c.generated.h" #endif -// One creates the dumps from terminfo.src by using -// od -t d1 -w | cut -c9- | sed -e 's/\>/,/g' -// on the compiled files. - -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -// This is a 256-colour terminfo description that lacks true-colour and -// DECSTBM/DECSLRM/DECLRMM capabilities that xterm actually has. -static const signed char xterm_256colour_terminfo[] = { - 26, 1, 37, 0, 29, 0, 15, 0, 105, 1, -42, 5, 120, 116, 101, 114, 109, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 120, 116, 101, 114, 109, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 38, 0, 42, 0, 46, 0, -1, -1, 57, 0, 74, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 102, 0, -1, -1, 106, 0, 110, 0, 120, 0, 124, 0, -1, -1, -1, -1,-128, 0,-124, 0,-119, 0,-114, 0, -1, -1,-105, 0,-100, 0, -95, 0, -1, -1, -90, 0, -85, 0, -80, 0, -75, 0, -66, 0, -62, 0, -55, 0, -1, -1, -46, 0, -41, 0, -35, 0, -29, 0, -1, -1, -1, -1, -1, -1, -11, 0, -1, -1, -1, -1, -1, -1, 7, 1, -1, -1, 11, 1, -1, -1, -1, -1, -1, -1, 13, 1, -1, -1, 18, 1, -1, -1, -1, -1, -1, -1, -1, -1, 22, 1, 26, 1, 32, 1, 36, 1, 40, 1, 44, 1, 50, 1, 56, 1, 62, 1, 68, 1, 74, 1, 78, 1, -1, -1, 83, 1, -1, -1, 87, 1, 92, 1, 97, 1, 101, 1, 108, 1, -1, -1, 115, 1, 119, 1, 127, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-121, 1,-112, 1, -1, -1, -1, -1,-103, 1, -94, 1, -85, 1, -76, 1, -67, 1, -58, 1, -49, 1, -40, 1, -31, 1, -22, 1, -1, -1, -1, -1, -1, -1, -13, 1, -9, 1, -4, 1, -1, -1, 1, 2, 10, 2, -1, -1, -1, -1, 28, 2, 31, 2, 42, 2, 45, 2, 47, 2, 50, 2,-113, 2, -1, -1,-110, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-108, 2, -1, -1, -1, -1, -1, -1, -1, -1,-104, 2, -1, -1, -51, 2, -1, -1, -1, -1, -47, 2, -41, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -35, 2, -31, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -27, 2, -1, -1, -1, -1, -20, 2, -1, -1, -1, -1, -1, -1, -1, -1, -13, 2, -6, 2, 1, 3, -1, -1, -1, -1, 8, 3, -1, -1, 15, 3, -1, -1, -1, -1, -1, -1, 22, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29, 3, 35, 3, 41, 3, 48, 3, 55, 3, 62, 3, 69, 3, 77, 3, 85, 3, 93, 3, 101, 3, 109, 3, 117, 3, 125, 3,-123, 3,-116, 3,-109, 3,-102, 3, -95, 3, -87, 3, -79, 3, -71, 3, -63, 3, -55, 3, -47, 3, -39, 3, -31, 3, -24, 3, -17, 3, -10, 3, -3, 3, 5, 4, 13, 4, 21, 4, 29, 4, 37, 4, 45, 4, 53, 4, 61, 4, 68, 4, 75, 4, 82, 4, 89, 4, 97, 4, 105, 4, 113, 4, 121, 4,-127, 4,-119, 4,-111, 4,-103, 4, -96, 4, -89, 4, -82, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -77, 4, -66, 4, -61, 4, -42, 4, -38, 4, -29, 4, -22, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 72, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 83, 5, -1, -1, -1, -1, -1, -1, 87, 5,-106, 5, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 49, 50, 108, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 63, 49, 50, 59, 50, 53, 104, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 40, 48, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 49, 48, 52, 57, 104, 0, 27, 91, 50, 109, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 27, 40, 66, 0, 27, 40, 66, 27, 91, 109, 0, 27, 91, 63, 49, 48, 52, 57, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 33, 112, 27, 91, 63, 51, 59, 52, 108, 27, 91, 52, 108, 27, 62, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 79, 72, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 49, 59, 50, 66, 0, 27, 91, 49, 59, 50, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 63, 49, 48, 51, 52, 108, 0, 27, 91, 63, 49, 48, 51, 52, 104, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 91, 105, 0, 27, 91, 52, 105, 0, 27, 91, 53, 105, 0, 27, 99, 27, 93, 49, 48, 52, 7, 0, 27, 91, 33, 112, 27, 91, 63, 51, 59, 52, 108, 27, 91, 52, 108, 27, 62, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 37, 63, 37, 112, 57, 37, 116, 27, 40, 48, 37, 101, 27, 40, 66, 37, 59, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 53, 37, 116, 59, 50, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 109, 0, 27, 72, 0, 9, 0, 27, 79, 69, 0, 96, 96, 97, 97, 102, 102, 103, 103, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 79, 70, 0, 27, 79, 77, 0, 27, 91, 51, 59, 50, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 50, 72, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 68, 0, 27, 91, 54, 59, 50, 126, 0, 27, 91, 53, 59, 50, 126, 0, 27, 91, 49, 59, 50, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 59, 50, 80, 0, 27, 91, 49, 59, 50, 81, 0, 27, 91, 49, 59, 50, 82, 0, 27, 91, 49, 59, 50, 83, 0, 27, 91, 49, 53, 59, 50, 126, 0, 27, 91, 49, 55, 59, 50, 126, 0, 27, 91, 49, 56, 59, 50, 126, 0, 27, 91, 49, 57, 59, 50, 126, 0, 27, 91, 50, 48, 59, 50, 126, 0, 27, 91, 50, 49, 59, 50, 126, 0, 27, 91, 50, 51, 59, 50, 126, 0, 27, 91, 50, 52, 59, 50, 126, 0, 27, 91, 49, 59, 53, 80, 0, 27, 91, 49, 59, 53, 81, 0, 27, 91, 49, 59, 53, 82, 0, 27, 91, 49, 59, 53, 83, 0, 27, 91, 49, 53, 59, 53, 126, 0, 27, 91, 49, 55, 59, 53, 126, 0, 27, 91, 49, 56, 59, 53, 126, 0, 27, 91, 49, 57, 59, 53, 126, 0, 27, 91, 50, 48, 59, 53, 126, 0, 27, 91, 50, 49, 59, 53, 126, 0, 27, 91, 50, 51, 59, 53, 126, 0, 27, 91, 50, 52, 59, 53, 126, 0, 27, 91, 49, 59, 54, 80, 0, 27, 91, 49, 59, 54, 81, 0, 27, 91, 49, 59, 54, 82, 0, 27, 91, 49, 59, 54, 83, 0, 27, 91, 49, 53, 59, 54, 126, 0, 27, 91, 49, 55, 59, 54, 126, 0, 27, 91, 49, 56, 59, 54, 126, 0, 27, 91, 49, 57, 59, 54, 126, 0, 27, 91, 50, 48, 59, 54, 126, 0, 27, 91, 50, 49, 59, 54, 126, 0, 27, 91, 50, 51, 59, 54, 126, 0, 27, 91, 50, 52, 59, 54, 126, 0, 27, 91, 49, 59, 51, 80, 0, 27, 91, 49, 59, 51, 81, 0, 27, 91, 49, 59, 51, 82, 0, 27, 91, 49, 59, 51, 83, 0, 27, 91, 49, 53, 59, 51, 126, 0, 27, 91, 49, 55, 59, 51, 126, 0, 27, 91, 49, 56, 59, 51, 126, 0, 27, 91, 49, 57, 59, 51, 126, 0, 27, 91, 50, 48, 59, 51, 126, 0, 27, 91, 50, 49, 59, 51, 126, 0, 27, 91, 50, 51, 59, 51, 126, 0, 27, 91, 50, 52, 59, 51, 126, 0, 27, 91, 49, 59, 52, 80, 0, 27, 91, 49, 59, 52, 81, 0, 27, 91, 49, 59, 52, 82, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 37, 91, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 93, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 49, 48, 52, 7, 0, 27, 93, 52, 59, 37, 112, 49, 37, 100, 59, 114, 103, 98, 58, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 27, 92, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0 -}; -// Taken from unibilium/t/static_tmux.c as of 2015-08-14. -// This is an 256-colour terminfo description that lacks -// status line capabilities that tmux actually has. -static const signed char tmux_256colour_terminfo[] = { - 26, 1, 56, 0, 15, 0, 15, 0, 105, 1, -48, 2, 116, 109, 117, 120, 124, 86, 84, 32, 49, 48, 48, 47, 65, 78, 83, 73, 32, 88, 51, 46, 54, 52, 32, 118, 105, 114, 116, 117, 97, 108, 32, 116, 101, 114, 109, 105, 110, 97, 108, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 37, 0, 41, 0, -1, -1, -1, -1, 45, 0, 62, 0, 64, 0, 68, 0, 75, 0, -1, -1, 77, 0, 89, 0, -1, -1, 93, 0, 96, 0, 102, 0, 106, 0, -1, -1, -1, -1, 110, 0, 112, 0, 117, 0, 122, 0, -1, -1, -1, -1, 123, 0, -1, -1, -1, -1, -128, 0, -123, 0, -118, 0, -1, -1, -113, 0, -111, 0, -106, 0, -1, -1, -105, 0, -100, 0, -94, 0, -88, 0, -1, -1, -1, -1, -1, -1, -85, 0, -1, -1, -1, -1, -1, -1, -81, 0, -1, -1, -77, 0, -1, -1, -1, -1, -1, -1, -75, 0, -1, -1, -70, 0, -1, -1, -1, -1, -1, -1, -1, -1, -66, 0, -62, 0, -56, 0, -52, 0, -48, 0, -44, 0, -38, 0, -32, 0, -26, 0, -20, 0, -14, 0, -9, 0, -1, -1, -4, 0, -1, -1, 0, 1, 5, 1, 10, 1, -1, -1, -1, -1, -1, -1, 14, 1, 18, 1, 26, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, 1, -1, -1, 37, 1, 46, 1, 55, 1, 64, 1, -1, -1, 73, 1, 82, 1, 91, 1, -1, -1, 100, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, 1, -1, -1, -1, -1, 126, 1, -1, -1, -127, 1, -124, 1, -122, 1, -119, 1, -46, 1, -1, -1, -43, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -41, 1, -1, -1, 24, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 2, 46, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 71, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 77, 2, -1, -1, -1, -1, -1, -1, 81, 2, -112, 2, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 51, 52, 104, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 77, 0, 27, 91, 51, 52, 108, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 103, 0, 27, 41, 48, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 69, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 49, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 43, 43, 44, 44, 45, 45, 46, 46, 48, 48, 96, 96, 97, 97, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 52, 126, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0 -}; -// Taken from unibilium/t/static_screen-256color.c as of 2015-08-14. -// This is an 256-colour terminfo description that lacks -// status line capabilities that screen actually has. -static const signed char screen_256colour_terminfo[] = { - 26, 1, 43, 0, 43, 0, 15, 0, 105, 1, -43, 2, 115, 99, 114, 101, 101, 110, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 71, 78, 85, 32, 83, 99, 114, 101, 101, 110, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 37, 0, 41, 0, -1, -1, -1, -1, 45, 0, 62, 0, 64, 0, 68, 0, 75, 0, -1, -1, 77, 0, 89, 0, -1, -1, 93, 0, 96, 0, 102, 0, 106, 0, -1, -1, -1, -1, 110, 0, 112, 0, 117, 0, 122, 0, -1, -1, -1, -1, -125, 0, -1, -1, -1, -1, -120, 0, -115, 0, -110, 0, -1, -1, -105, 0, -103, 0, -98, 0, -1, -1, -89, 0, -84, 0, -78, 0, -72, 0, -1, -1, -1, -1, -1, -1, -69, 0, -1, -1, -1, -1, -1, -1, -65, 0, -1, -1, -61, 0, -1, -1, -1, -1, -1, -1, -59, 0, -1, -1, -54, 0, -1, -1, -1, -1, -1, -1, -1, -1, -50, 0, -46, 0, -40, 0, -36, 0, -32, 0, -28, 0, -22, 0, -16, 0, -10, 0, -4, 0, 2, 1, 7, 1, -1, -1, 12, 1, -1, -1, 16, 1, 21, 1, 26, 1, -1, -1, -1, -1, -1, -1, 30, 1, 34, 1, 42, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 1, -1, -1, 53, 1, 62, 1, 71, 1, 80, 1, -1, -1, 89, 1, 98, 1, 107, 1, -1, -1, 116, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 125, 1, -1, -1, -1, -1, -114, 1, -1, -1, -111, 1, -108, 1, -106, 1, -103, 1, -30, 1, -1, -1, -27, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -25, 1, -1, -1, 40, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, 2, 62, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 73, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, 2, -1, -1, -1, -1, -1, -1, 86, 2, -107, 2, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 51, 52, 104, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 77, 0, 27, 91, 51, 52, 108, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 49, 48, 52, 57, 104, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 51, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 63, 49, 48, 52, 57, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 51, 109, 0, 27, 91, 50, 52, 109, 0, 27, 103, 0, 27, 41, 48, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 69, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 49, 37, 116, 59, 51, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 43, 43, 44, 44, 45, 45, 46, 46, 48, 48, 96, 96, 97, 97, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 52, 126, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 0, 3, 0, 1, 0, 24, 0, 52, 0, -112, 0, 1, 1, 0, 0, 1, 0, 0, 0, 4, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 3, 0, 6, 0, 9, 0, 12, 0, 15, 0, 18, 0, 23, 0, 28, 0, 32, 0, 37, 0, 43, 0, 49, 0, 55, 0, 61, 0, 66, 0, 71, 0, 77, 0, 83, 0, 89, 0, 95, 0, 101, 0, 107, 0, 111, 0, 116, 0, 120, 0, 124, 0, -128, 0, 27, 40, 66, 0, 27, 40, 37, 112, 49, 37, 99, 0, 65, 88, 0, 71, 48, 0, 88, 84, 0, 85, 56, 0, 69, 48, 0, 83, 48, 0, 107, 68, 67, 53, 0, 107, 68, 67, 54, 0, 107, 68, 78, 0, 107, 68, 78, 53, 0, 107, 69, 78, 68, 53, 0, 107, 69, 78, 68, 54, 0, 107, 72, 79, 77, 53, 0, 107, 72, 79, 77, 54, 0, 107, 73, 67, 53, 0, 107, 73, 67, 54, 0, 107, 76, 70, 84, 53, 0, 107, 78, 88, 84, 53, 0, 107, 78, 88, 84, 54, 0, 107, 80, 82, 86, 53, 0, 107, 80, 82, 86, 54, 0, 107, 82, 73, 84, 53, 0, 107, 85, 80, 0, 107, 85, 80, 53, 0, 107, 97, 50, 0, 107, 98, 49, 0, 107, 98, 51, 0, 107, 99, 50, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -static const signed char iterm_256colour_terminfo[] = { - 26, 1, 57, 0, 29, 0, 15, 0, 105, 1, 73, 3, 105, 84, 101, 114, 109, 46, 97, 112, 112, 124, 105, 116, 101, 114, 109, 124, 105, 84, 101, 114, 109, 46, 97, 112, 112, 32, 116, 101, 114, 109, 105, 110, 97, 108, 32, 101, 109, 117, 108, 97, 116, 111, 114, 32, 102, 111, 114, 32, 77, 97, 99, 32, 79, 83, 32, 88, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, 50, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, -1, -1, 0, 0, 2, 0, -2, -1, 4, 0, 9, 0, 16, 0, 20, 0, 24, 0, -1, -1, 35, 0, 52, 0, 54, 0, 58, 0, 65, 0, -1, -1, 67, 0, 74, 0, -1, -1, 78, 0, -1, -1, 82, 0, 86, 0, 90, 0, -1, -1, 96, 0, 98, 0, 103, 0, 108, 0, -1, -1, -2, -1, 117, 0, 122, 0, -1, -1, 127, 0,-124, 0,-119, 0, -1, -1,-114, 0,-112, 0,-107, 0, -1, -1, -94, 0, -89, 0, -85, 0, -81, 0, -1, -1, -63, 0, -1, -1, -1, -1, -1, -1, -1, -1, -61, 0, -57, 0, -1, -1, -53, 0, -1, -1, -1, -1, -1, -1, -51, 0, -1, -1, -46, 0, -1, -1, -1, -1, -1, -1, -1, -1, -42, 0, -38, 0, -32, 0, -28, 0, -24, 0, -20, 0, -14, 0, -8, 0, -2, 0, 4, 1, 10, 1, -1, -1, -1, -1, 14, 1, -1, -1, 18, 1, 23, 1, 28, 1, -1, -1, -1, -1, -1, -1, 32, 1, 36, 1, 44, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 52, 1, 61, 1, 70, 1, 79, 1, -1, -1, 88, 1, 97, 1, 106, 1, -1, -1, 115, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124, 1, -1, -1, -1, -1,-104, 1,-101, 1, -90, 1, -87, 1, -85, 1, -82, 1, -4, 1, -1, -1, -1, 1, 1, 2, -1, -1, -1, -1, -1, -1, 6, 2, 10, 2, 14, 2, 18, 2, 22, 2, -1, -1, -1, -1, 26, 2, -1, -1, -1, -1, -1, -1, -1, -1, 77, 2, 83, 2, -1, -1, -1, -1, 89, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 2, 100, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, 2, 110, 2, 116, 2, 122, 2,-128, 2,-122, 2,-116, 2,-110, 2, 104, 2, -98, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -92, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -87, 2, -76, 2, -71, 2, -63, 2, -59, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -54, 2, 9, 3, 7, 0, 13, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 93, 50, 59, 7, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 55, 27, 91, 63, 52, 55, 104, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 27, 56, 0, 27, 91, 52, 108, 0, 27, 91, 109, 0, 27, 91, 109, 0, 27, 91, 63, 53, 104, 36, 60, 50, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 7, 0, 27, 91, 64, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 79, 72, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 62, 27, 91, 63, 51, 108, 27, 91, 63, 52, 108, 27, 91, 63, 53, 108, 27, 91, 63, 55, 104, 27, 91, 63, 56, 104, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 93, 50, 59, 0, 27, 79, 113, 0, 27, 79, 115, 0, 27, 79, 114, 0, 27, 79, 112, 0, 27, 79, 110, 0, 96, 96, 97, 97, 102, 102, 103, 103, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 40, 66, 27, 41, 48, 0, 27, 79, 70, 0, 27, 79, 77, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 50, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 49, 59, 50, 99, 0, 27, 91, 99, 0, 27, 91, 48, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -// This is a 256-colour terminfo description that lacks true-colour -// capabilities that rxvt actually has. -static const signed char rxvt_256colour_terminfo[] = { - 26, 1, 47, 0, 29, 0, 15, 0, 110, 1, -31, 4, 114, 120, 118, 116, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 114, 120, 118, 116, 32, 50, 46, 55, 46, 57, 32, 119, 105, 116, 104, 32, 120, 116, 101, 114, 109, 32, 50, 53, 54, 45, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, -1, -1, 0, 0, 2, 0, 4, 0, 21, 0, 26, 0, 34, 0, 38, 0, 42, 0, -1, -1, 53, 0, 70, 0, 72, 0, 76, 0, 83, 0, -1, -1, 85, 0, 92, 0, -1, -1, 96, 0, -1, -1, -1, -1, 100, 0, -1, -1, -1, -1, 104, 0, 106, 0, 111, 0, 116, 0, -1, -1, -1, -1, 125, 0, -1, -1, -1, -1,-126, 0,-121, 0,-116, 0, -1, -1,-111, 0,-109, 0,-104, 0, -1, -1, -91, 0, -86, 0, -80, 0, -74, 0, -1, -1, -1, -1, -56, 0, -42, 0, -1, -1, -1, -1, -8, 0, -4, 0, -1, -1, 0, 1, -1, -1, -1, -1, -1, -1, 2, 1, -1, -1, 7, 1, -1, -1, 11, 1, -1, -1, 16, 1, 22, 1, 28, 1, 34, 1, 40, 1, 46, 1, 52, 1, 58, 1, 64, 1, 70, 1, 76, 1, 82, 1, 87, 1, -1, -1, 92, 1, -1, -1, 96, 1, 101, 1, 106, 1, 110, 1, 114, 1, -1, -1, 118, 1, 122, 1, 125, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-128, 1,-119, 1,-110, 1, -1, -1,-101, 1, -92, 1, -83, 1, -1, -1, -74, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -65, 1, -32, 1, -1, -1, -1, -1, 18, 2, 21, 2, 32, 2, 35, 2, 37, 2, 40, 2, 107, 2, -1, -1, 110, 2, -1, -1, -1, -1, -1, -1, -1, -1, 112, 2, 116, 2, 120, 2, 124, 2,-128, 2, -1, -1, -1, -1,-124, 2, -1, -1, -73, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -69, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -62, 2, -57, 2, -1, -1, -53, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -48, 2, -1, -1, -43, 2, -38, 2, -1, -1, -1, -1, -1, -1, -1, -1, -33, 2, -28, 2, -23, 2, -1, -1, -1, -1, -19, 2, -1, -1, -14, 2, -1, -1, -1, -1, -1, -1, -9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -5, 2, 1, 3, 7, 3, 13, 3, 19, 3, 25, 3, 31, 3, 37, 3, 43, 3, 49, 3, 55, 3, 61, 3, 67, 3, 73, 3, 79, 3, 85, 3, 91, 3, 97, 3, 103, 3, 109, 3, 115, 3, 121, 3, 127, 3,-123, 3,-117, 3,-111, 3,-105, 3, -99, 3, -93, 3, -87, 3, -81, 3, -75, 3, -69, 3, -63, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -57, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -52, 3, -41, 3, -36, 3, -28, 3, -24, 3, -15, 3, -8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 86, 4, -1, -1, -1, -1, -1, -1, 90, 4,-103, 4, -1, -1, -1, -1, -1, -1, -39, 4, -35, 4, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 55, 27, 91, 63, 52, 55, 104, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 27, 56, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 63, 52, 55, 108, 27, 61, 27, 91, 63, 49, 108, 0, 27, 91, 114, 27, 91, 109, 27, 91, 50, 74, 27, 91, 72, 27, 91, 63, 55, 104, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 91, 52, 108, 0, 27, 91, 64, 0, 27, 91, 76, 0, 8, 0, 27, 91, 51, 126, 0, 27, 91, 66, 0, 27, 91, 56, 94, 0, 27, 91, 50, 49, 126, 0, 27, 91, 49, 49, 126, 0, 27, 91, 50, 49, 126, 0, 27, 91, 49, 50, 126, 0, 27, 91, 49, 51, 126, 0, 27, 91, 49, 52, 126, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 55, 126, 0, 27, 91, 50, 126, 0, 27, 91, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 91, 67, 0, 27, 91, 97, 0, 27, 91, 98, 0, 27, 91, 65, 0, 27, 62, 0, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 62, 27, 91, 49, 59, 51, 59, 52, 59, 53, 59, 54, 108, 27, 91, 63, 55, 104, 27, 91, 109, 27, 91, 114, 27, 91, 50, 74, 27, 91, 72, 0, 27, 91, 114, 27, 91, 109, 27, 91, 50, 74, 27, 91, 72, 27, 91, 63, 55, 104, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 79, 119, 0, 27, 79, 121, 0, 27, 79, 117, 0, 27, 79, 113, 0, 27, 79, 115, 0, 96, 96, 97, 97, 102, 102, 103, 103, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 56, 126, 0, 27, 79, 77, 0, 27, 91, 49, 126, 0, 27, 91, 51, 36, 0, 27, 91, 52, 126, 0, 27, 91, 56, 36, 0, 27, 91, 55, 36, 0, 27, 91, 50, 36, 0, 27, 91, 100, 0, 27, 91, 54, 36, 0, 27, 91, 53, 36, 0, 27, 91, 99, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 51, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 50, 51, 36, 0, 27, 91, 50, 52, 36, 0, 27, 91, 49, 49, 94, 0, 27, 91, 49, 50, 94, 0, 27, 91, 49, 51, 94, 0, 27, 91, 49, 52, 94, 0, 27, 91, 49, 53, 94, 0, 27, 91, 49, 55, 94, 0, 27, 91, 49, 56, 94, 0, 27, 91, 49, 57, 94, 0, 27, 91, 50, 48, 94, 0, 27, 91, 50, 49, 94, 0, 27, 91, 50, 51, 94, 0, 27, 91, 50, 52, 94, 0, 27, 91, 50, 53, 94, 0, 27, 91, 50, 54, 94, 0, 27, 91, 50, 56, 94, 0, 27, 91, 50, 57, 94, 0, 27, 91, 51, 49, 94, 0, 27, 91, 51, 50, 94, 0, 27, 91, 51, 51, 94, 0, 27, 91, 51, 52, 94, 0, 27, 91, 50, 51, 64, 0, 27, 91, 50, 52, 64, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 49, 59, 50, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 49, 48, 52, 7, 0, 27, 93, 52, 59, 37, 112, 49, 37, 100, 59, 114, 103, 98, 58, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 27, 92, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 40, 66, 0, 27, 40, 48, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -// This is a 16-colour terminfo description that lacks true-colour -// and 256-colour capabilities that linux (4.8+) actually has. -static const signed char linux_16colour_terminfo[] = { - 26, 1, 43, 0, 29, 0, 16, 0, 125, 1, 125, 3, 108, 105, 110, 117, 120, 45, 49, 54, 99, 111, 108, 111, 114, 124, 108, 105, 110, 117, 120, 32, 99, 111, 110, 115, 111, 108, 101, 32, 119, 105, 116, 104, 32, 49, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 8, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 0, 0, 1, 42, 0, -1, -1, 0, 0, 2, 0, 4, 0, 21, 0, 26, 0, 33, 0, 37, 0, 41, 0, -1, -1, 52, 0, 69, 0, 71, 0, 75, 0, 87, 0, -1, -1, 89, 0, 101, 0, -1, -1, 105, 0, 109, 0, 121, 0, 125, 0, -1, -1, -1, -1,-127, 0,-125, 0,-120, 0, -1, -1, -1, -1,-115, 0,-110, 0, -1, -1, -1, -1,-105, 0,-100, 0, -95, 0, -90, 0, -81, 0, -79, 0, -1, -1, -1, -1, -74, 0, -69, 0, -63, 0, -57, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -39, 0, -35, 0, -1, -1, -31, 0, -1, -1, -1, -1, -1, -1, -29, 0, -1, -1, -24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -20, 0, -15, 0, -9, 0, -4, 0, 1, 1, 6, 1, 11, 1, 17, 1, 23, 1, 29, 1, 35, 1, 40, 1, -1, -1, 45, 1, -1, -1, 49, 1, 54, 1, 59, 1, -1, -1, -1, -1, -1, -1, 63, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67, 1, -1, -1, 70, 1, 79, 1, 88, 1, 97, 1, -1, -1, 106, 1, 115, 1, 124, 1, -1, -1,-123, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-114, 1, -1, -1, -1, -1, -1, -1,-108, 1,-105, 1, -94, 1, -91, 1, -89, 1, -86, 1, 1, 2, -1, -1, 4, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, 10, 2, -1, -1, 77, 2, -1, -1, -1, -1, 81, 2, 87, 2, -1, -1, -1, -1, 93, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 97, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 102, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, 2, 110, 2, 116, 2, 122, 2,-128, 2,-122, 2,-116, 2,-110, 2,-104, 2, -98, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -92, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -87, 2, -76, 2, -71, 2, -65, 2, -61, 2, -52, 2, -48, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 3, -1, -1, -1, -1, -1, -1, 37, 3, 75, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113, 3, 119, 3, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 27, 91, 63, 49, 99, 0, 8, 0, 27, 91, 63, 50, 53, 104, 27, 91, 63, 48, 99, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 63, 50, 53, 104, 27, 91, 63, 56, 99, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 50, 109, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 50, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 64, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 91, 66, 0, 27, 91, 91, 65, 0, 27, 91, 50, 49, 126, 0, 27, 91, 91, 66, 0, 27, 91, 91, 67, 0, 27, 91, 91, 68, 0, 27, 91, 91, 69, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 91, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 91, 67, 0, 27, 91, 65, 0, 13, 10, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 27, 93, 82, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 59, 49, 48, 37, 63, 37, 112, 49, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 53, 37, 116, 59, 50, 37, 59, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 91, 71, 0, 43, 43, 44, 44, 45, 45, 46, 46, 48, 48, 95, 95, 96, 96, 97, 97, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 99, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 41, 48, 0, 27, 91, 52, 126, 0, 26, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 51, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 54, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 82, 0, 27, 93, 80, 37, 112, 49, 37, 120, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 48, 50, 120, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 48, 50, 120, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 48, 50, 120, 0, 27, 91, 77, 0, 27, 91, 51, 37, 112, 49, 37, 123, 56, 125, 37, 109, 37, 100, 37, 63, 37, 112, 49, 37, 123, 55, 125, 37, 62, 37, 116, 59, 49, 37, 101, 59, 50, 49, 37, 59, 109, 0, 27, 91, 52, 37, 112, 49, 37, 123, 56, 125, 37, 109, 37, 100, 37, 63, 37, 112, 49, 37, 123, 55, 125, 37, 62, 37, 116, 59, 53, 37, 101, 59, 50, 53, 37, 59, 109, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 48, 109, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -static const signed char putty_256colour_terminfo[] = { - 26, 1, 48, 0, 29, 0, 16, 0, 125, 1,-106, 4, 112, 117, 116, 116, 121, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 80, 117, 84, 84, 89, 32, 48, 46, 53, 56, 32, 119, 105, 116, 104, 32, 120, 116, 101, 114, 109, 32, 50, 53, 54, 45, 99, 111, 108, 111, 114, 115, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, -1, 8, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 22, 0, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 37, 0, 41, 0, 45, 0, -1, -1, 56, 0, 73, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 96, 0, -1, -1, 100, 0, -1, -1, 103, 0, 107, 0, 111, 0, -1, -1, 117, 0, 119, 0, 124, 0,-127, 0, -1, -1, -1, -1,-120, 0, -1, -1, -1, -1,-115, 0,-110, 0,-105, 0,-100, 0, -91, 0, -89, 0, -84, 0, -1, -1, -73, 0, -68, 0, -62, 0, -56, 0, -1, -1, -38, 0, -1, -1, -36, 0, -1, -1, -1, -1, -1, -1, -2, 0, -1, -1, 2, 1, -1, -1, -1, -1, -1, -1, 4, 1, -1, -1, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, 13, 1, 19, 1, 25, 1, 31, 1, 37, 1, 43, 1, 49, 1, 55, 1, 61, 1, 67, 1, 73, 1, 78, 1, -1, -1, 83, 1, -1, -1, 87, 1, 92, 1, 97, 1, 101, 1, 105, 1, -1, -1, 109, 1, 113, 1, 121, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-127, 1, -1, -1,-124, 1,-115, 1,-106, 1, -1, -1, -97, 1, -88, 1, -79, 1, -70, 1, -61, 1, -52, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -43, 1, -1, -1, -1, -1, -10, 1, -7, 1, 4, 2, 7, 2, 9, 2, 12, 2, 84, 2, -1, -1, 87, 2, 89, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 94, 2, -1, -1, -1, -1, -1, -1, -1, -1, 98, 2, -1, -1,-107, 2, -1, -1, -1, -1,-103, 2, -97, 2, -1, -1, -1, -1, -91, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -84, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -79, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -77, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -73, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -69, 2, -63, 2, -57, 2, -51, 2, -45, 2, -39, 2, -33, 2, -27, 2, -21, 2, -15, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -4, 2, 7, 3, 12, 3, 18, 3, 22, 3, 31, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, 3, -1, -1, -1, -1, -1, -1, 39, 3, 102, 3, -1, -1, -1, -1, -1, -1, -90, 3, -84, 3, -78, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -72, 3,-118, 4,-112, 4, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 27, 68, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 77, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 93, 48, 59, 7, 0, 14, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 52, 55, 104, 0, 27, 91, 52, 104, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 15, 0, 27, 91, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 7, 0, 27, 55, 27, 91, 114, 27, 91, 109, 27, 91, 63, 55, 104, 27, 91, 63, 49, 59, 52, 59, 54, 108, 27, 91, 52, 108, 27, 56, 27, 62, 27, 93, 82, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 91, 49, 49, 126, 0, 27, 91, 50, 49, 126, 0, 27, 91, 49, 50, 126, 0, 27, 91, 49, 51, 126, 0, 27, 91, 49, 52, 126, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 66, 0, 27, 91, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 13, 10, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 60, 27, 91, 34, 112, 27, 91, 53, 48, 59, 54, 34, 112, 27, 99, 27, 91, 63, 51, 108, 27, 93, 82, 27, 91, 63, 49, 48, 48, 48, 108, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 49, 37, 112, 54, 37, 124, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 93, 48, 59, 0, 27, 91, 71, 0, 96, 96, 97, 97, 102, 102, 103, 103, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 40, 66, 27, 41, 48, 0, 27, 91, 52, 126, 0, 26, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 50, 53, 126, 0, 27, 91, 50, 54, 126, 0, 27, 91, 50, 56, 126, 0, 27, 91, 50, 57, 126, 0, 27, 91, 51, 49, 126, 0, 27, 91, 51, 50, 126, 0, 27, 91, 51, 51, 126, 0, 27, 91, 51, 52, 126, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 54, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 82, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 49, 48, 109, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 50, 109, 0, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-105,-104, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 48, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-105,-103, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 50, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-103,-128, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 51, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-103, -86, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 52, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-103, -85, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 53, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-104, -68, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 50, 55, 125, 37, 61, 37, 116, 27, 37, 37, 71, -30,-122,-112, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 123, 49, 53, 53, 125, 37, 61, 37, 116, 27, 37, 37, 71, -32,-126, -94, 27, 37, 37, 64, 37, 101, 37, 112, 49, 37, 99, 37, 59, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 48, 109, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -static const signed char interix_8colour_terminfo[] = { - 26, 1, 82, 0, 15, 0, 16, 0, 105, 1, 123, 2, 105, 110, 116, 101, 114, 105, 120, 124, 111, 112, 101, 110, 110, 116, 124, 111, 112, 101, 110, 110, 116, 45, 50, 53, 124, 110, 116, 99, 111, 110, 115, 111, 108, 101, 124, 110, 116, 99, 111, 110, 115, 111, 108, 101, 45, 50, 53, 124, 79, 112, 101, 110, 78, 84, 45, 116, 101, 114, 109, 32, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 119, 105, 116, 104, 32, 99, 111, 108, 111, 114, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 0, -1, -1, 25, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 0, 64, 0, 3, 0, 0, 0, 4, 0, -1, -1, -1, -1, -1, -1, 6, 0, 11, 0, 15, 0, -1, -1, -1, -1, 19, 0, 36, 0, 38, 0, -1, -1, 42, 0, -1, -1, -1, -1, 46, 0, 50, 0, 54, 0, -1, -1, -1, -1, 58, 0, -1, -1, -1, -1, -1, -1, -1, -1, 62, 0, 67, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 75, 0, 80, 0, 85, 0, -1, -1, -1, -1, 90, 0, 95, 0, -1, -1, -1, -1, 107, 0, 111, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 115, 0, -1, -1, 119, 0, -1, -1, -1, -1, -1, -1, 121, 0, -1, -1, 125, 0, -1, -1, -1, -1, -1, -1,-127, 0,-123, 0,-119, 0,-115, 0,-111, 0,-107, 0,-103, 0, -99, 0, -95, 0, -91, 0, -87, 0, -1, -1, -83, 0, -1, -1, -79, 0, -75, 0, -71, 0, -67, 0, -63, 0, -1, -1, -1, -1, -1, -1, -59, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -55, 0, -1, -1, -1, -1, -52, 0, -43, 0, -1, -1, -34, 0, -25, 0, -16, 0, -7, 0, 2, 1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 1, -1, -1, -1, -1, -1, -1, 23, 1, -1, -1, 27, 1, 31, 1, 35, 1, -1, -1, -1, -1, -1, -1, 39, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, 1, -1, -1, 104, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 108, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112, 1, 116, 1, 120, 1, 124, 1,-128, 1,-124, 1,-120, 1,-116, 1,-112, 1,-108, 1,-104, 1,-100, 1, -96, 1, -92, 1, -88, 1, -84, 1, -80, 1, -76, 1, -72, 1, -68, 1, -64, 1, -60, 1, -56, 1, -52, 1, -48, 1, -44, 1, -40, 1, -36, 1, -32, 1, -28, 1, -24, 1, -20, 1, -16, 1, -12, 1, -8, 1, -4, 1, 0, 2, 4, 2, 8, 2, 12, 2, 16, 2, 20, 2, 24, 2, 28, 2, 32, 2, 36, 2, 40, 2, 44, 2, 48, 2, 52, 2, 56, 2, 60, 2, 64, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68, 2, -1, -1, -1, -1, -1, -1, -1, -1, 72, 2, 88, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 103, 2, 113, 2, 27, 91, 90, 0, 7, 0, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 85, 0, 27, 91, 65, 0, 27, 91, 77, 0, 27, 91, 49, 109, 0, 27, 91, 115, 27, 91, 49, 98, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 48, 109, 0, 27, 91, 50, 98, 27, 91, 117, 13, 27, 91, 75, 0, 27, 91, 109, 0, 27, 91, 109, 0, 27, 91, 76, 0, 8, 0, 27, 91, 77, 0, 27, 91, 66, 0, 27, 70, 65, 0, 27, 70, 49, 0, 27, 70, 65, 0, 27, 70, 50, 0, 27, 70, 51, 0, 27, 70, 52, 0, 27, 70, 53, 0, 27, 70, 54, 0, 27, 70, 55, 0, 27, 70, 56, 0, 27, 70, 57, 0, 27, 91, 76, 0, 27, 91, 68, 0, 27, 91, 85, 0, 27, 91, 84, 0, 27, 91, 83, 0, 27, 91, 67, 0, 27, 91, 65, 0, 13, 10, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 0, 27, 91, 117, 0, 27, 91, 115, 0, 27, 91, 83, 0, 27, 91, 84, 0, 9, 0, 43, 16, 44, 17, 45, 24, 46, 25, 48, -37, 96, 4, 97, -79, 102, -8, 103, -15, 104, -80, 106, -39, 107, -65, 108, -38, 109, -64, 110, -59, 111, 126, 112, -60, 113, -60, 114, -60, 115, 95, 116, -61, 117, -76, 118, -63, 119, -62, 120, -77, 121, -13, 122, -14, 123, -29, 124, -40, 125,-100, 126, -2, 0, 27, 91, 90, 0, 27, 91, 85, 0, 27, 70, 66, 0, 27, 70, 67, 0, 27, 70, 68, 0, 27, 70, 69, 0, 27, 70, 70, 0, 27, 70, 71, 0, 27, 70, 72, 0, 27, 70, 73, 0, 27, 70, 74, 0, 27, 70, 75, 0, 27, 70, 76, 0, 27, 70, 77, 0, 27, 70, 78, 0, 27, 70, 79, 0, 27, 70, 80, 0, 27, 70, 81, 0, 27, 70, 82, 0, 27, 70, 83, 0, 27, 70, 84, 0, 27, 70, 85, 0, 27, 70, 86, 0, 27, 70, 87, 0, 27, 70, 88, 0, 27, 70, 89, 0, 27, 70, 90, 0, 27, 70, 97, 0, 27, 70, 98, 0, 27, 70, 99, 0, 27, 70, 100, 0, 27, 70, 101, 0, 27, 70, 102, 0, 27, 70, 103, 0, 27, 70, 104, 0, 27, 70, 105, 0, 27, 70, 106, 0, 27, 70, 107, 0, 27, 70, 109, 0, 27, 70, 110, 0, 27, 70, 111, 0, 27, 70, 112, 0, 27, 70, 113, 0, 27, 70, 114, 0, 27, 70, 115, 0, 27, 70, 116, 0, 27, 70, 117, 0, 27, 70, 118, 0, 27, 70, 119, 0, 27, 70, 120, 0, 27, 70, 121, 0, 27, 70, 122, 0, 27, 70, 43, 0, 27, 70, 45, 0, 27, 70, 12, 0, 27, 91, 109, 0, 27, 91, 37, 112, 49, 37, 123, 51, 48, 125, 37, 43, 37, 100, 109, 0, 27, 91, 37, 112, 49, 37, 39, 40, 39, 37, 43, 37, 100, 109, 0, 27, 91, 51, 37, 112, 49, 37, 100, 109, 0, 27, 91, 52, 37, 112, 49, 37, 100, 109, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -// This is a 256-colour terminfo description that lacks true-colour -// capabilities that stterm actually has. -static const signed char st_256colour_terminfo[] = { - 26, 1, 55, 0, 29, 0, 15, 0, 105, 1, 117, 5, 115, 116, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 115, 116, 116, 101, 114, 109, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 115, 105, 109, 112, 108, 101, 116, 101, 114, 109, 32, 119, 105, 116, 104, 32, 50, 53, 54, 32, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 38, 0, 42, 0, 46, 0, -1, -1, 57, 0, 74, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 102, 0, -1, -1, 106, 0, 110, 0, 117, 0, 121, 0, -1, -1, -1, -1, 125, 0,-127, 0,-122, 0,-117, 0, -1, -1, -1, -1,-108, 0,-103, 0, -1, -1, -98, 0, -93, 0, -88, 0, -83, 0, -74, 0, -70, 0, -65, 0, -1, -1, -56, 0, -51, 0, -45, 0, -39, 0, -1, -1, -21, 0, -1, -1, -19, 0, -1, -1, -1, -1, -1, -1, -4, 0, -1, -1, 0, 1, -1, -1, 2, 1, -1, -1, 9, 1, 14, 1, 21, 1, 25, 1, 32, 1, 39, 1, -1, -1, 46, 1, 50, 1, 56, 1, 60, 1, 64, 1, 68, 1, 74, 1, 80, 1, 86, 1, 92, 1, 98, 1, 103, 1, 108, 1, 115, 1, -1, -1, 119, 1, 124, 1,-127, 1,-123, 1,-116, 1, -1, -1,-109, 1,-105, 1, -97, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -89, 1, -80, 1, -71, 1, -62, 1, -53, 1, -44, 1, -35, 1, -26, 1, -1, -1, -17, 1, -1, -1, -1, -1, -1, -1, -8, 1, -4, 1, 1, 2, -1, -1, 6, 2, 9, 2, -1, -1, -1, -1, 24, 2, 27, 2, 38, 2, 41, 2, 43, 2, 46, 2,-128, 2, -1, -1,-125, 2,-123, 2, -1, -1, -1, -1, -1, -1,-118, 2,-113, 2,-108, 2,-104, 2, -99, 2, -1, -1, -1, -1, -94, 2, -1, -1, -29, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -25, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -21, 2, -16, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -12, 2, -1, -1, -1, -1, -5, 2, -1, -1, -1, -1, -1, -1, -1, -1, 2, 3, 9, 3, 16, 3, -1, -1, -1, -1, 23, 3, -1, -1, 30, 3, -1, -1, -1, -1, -1, -1, 37, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 3, 50, 3, 56, 3, 63, 3, 70, 3, 77, 3, 84, 3, 92, 3, 100, 3, 108, 3, 116, 3, 124, 3,-124, 3,-116, 3,-108, 3,-101, 3, -94, 3, -87, 3, -80, 3, -72, 3, -64, 3, -56, 3, -48, 3, -40, 3, -32, 3, -24, 3, -16, 3, -9, 3, -2, 3, 5, 4, 12, 4, 20, 4, 28, 4, 36, 4, 44, 4, 52, 4, 60, 4, 68, 4, 76, 4, 83, 4, 90, 4, 97, 4, 104, 4, 112, 4, 120, 4,-128, 4,-120, 4,-112, 4,-104, 4, -96, 4, -88, 4, -81, 4, -74, 4, -67, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -62, 4, -51, 4, -46, 4, -38, 4, -34, 4, -2, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -25, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -20, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -14, 4, -1, -1, -1, -1, -1, -1, -10, 4, 53, 5, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 49, 50, 108, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 40, 48, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 63, 49, 48, 52, 57, 104, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 27, 40, 66, 0, 27, 91, 48, 109, 0, 27, 91, 63, 49, 48, 52, 57, 108, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 7, 0, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 51, 52, 108, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 59, 53, 126, 0, 27, 91, 51, 126, 0, 27, 91, 51, 59, 50, 126, 0, 27, 79, 66, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 53, 70, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 91, 49, 126, 0, 27, 91, 50, 126, 0, 27, 91, 50, 59, 53, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 49, 59, 50, 66, 0, 27, 91, 49, 59, 50, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 91, 105, 0, 27, 91, 52, 105, 0, 27, 91, 53, 105, 0, 27, 99, 0, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 51, 52, 108, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 37, 63, 37, 112, 57, 37, 116, 27, 40, 48, 37, 101, 27, 40, 66, 37, 59, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 109, 0, 27, 72, 0, 9, 0, 27, 93, 48, 59, 0, 27, 91, 49, 126, 0, 27, 91, 53, 126, 0, 27, 79, 117, 0, 27, 91, 52, 126, 0, 27, 91, 54, 126, 0, 43, 67, 44, 68, 45, 65, 46, 66, 48, 69, 96, 96, 97, 97, 102, 102, 103, 103, 104, 70, 105, 71, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 41, 48, 0, 27, 91, 52, 126, 0, 27, 79, 77, 0, 27, 91, 51, 59, 50, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 50, 72, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 68, 0, 27, 91, 54, 59, 50, 126, 0, 27, 91, 53, 59, 50, 126, 0, 27, 91, 49, 59, 50, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 59, 50, 80, 0, 27, 91, 49, 59, 50, 81, 0, 27, 91, 49, 59, 50, 82, 0, 27, 91, 49, 59, 50, 83, 0, 27, 91, 49, 53, 59, 50, 126, 0, 27, 91, 49, 55, 59, 50, 126, 0, 27, 91, 49, 56, 59, 50, 126, 0, 27, 91, 49, 57, 59, 50, 126, 0, 27, 91, 50, 48, 59, 50, 126, 0, 27, 91, 50, 49, 59, 50, 126, 0, 27, 91, 50, 51, 59, 50, 126, 0, 27, 91, 50, 52, 59, 50, 126, 0, 27, 91, 49, 59, 53, 80, 0, 27, 91, 49, 59, 53, 81, 0, 27, 91, 49, 59, 53, 82, 0, 27, 91, 49, 59, 53, 83, 0, 27, 91, 49, 53, 59, 53, 126, 0, 27, 91, 49, 55, 59, 53, 126, 0, 27, 91, 49, 56, 59, 53, 126, 0, 27, 91, 49, 57, 59, 53, 126, 0, 27, 91, 50, 48, 59, 53, 126, 0, 27, 91, 50, 49, 59, 53, 126, 0, 27, 91, 50, 51, 59, 53, 126, 0, 27, 91, 50, 52, 59, 53, 126, 0, 27, 91, 49, 59, 54, 80, 0, 27, 91, 49, 59, 54, 81, 0, 27, 91, 49, 59, 54, 82, 0, 27, 91, 49, 59, 54, 83, 0, 27, 91, 49, 53, 59, 54, 126, 0, 27, 91, 49, 55, 59, 54, 126, 0, 27, 91, 49, 56, 59, 54, 126, 0, 27, 91, 49, 57, 59, 54, 126, 0, 27, 91, 50, 48, 59, 54, 126, 0, 27, 91, 50, 49, 59, 54, 126, 0, 27, 91, 50, 51, 59, 54, 126, 0, 27, 91, 50, 52, 59, 54, 126, 0, 27, 91, 49, 59, 51, 80, 0, 27, 91, 49, 59, 51, 81, 0, 27, 91, 49, 59, 51, 82, 0, 27, 91, 49, 59, 51, 83, 0, 27, 91, 49, 53, 59, 51, 126, 0, 27, 91, 49, 55, 59, 51, 126, 0, 27, 91, 49, 56, 59, 51, 126, 0, 27, 91, 49, 57, 59, 51, 126, 0, 27, 91, 50, 48, 59, 51, 126, 0, 27, 91, 50, 49, 59, 51, 126, 0, 27, 91, 50, 51, 59, 51, 126, 0, 27, 91, 50, 52, 59, 51, 126, 0, 27, 91, 49, 59, 52, 80, 0, 27, 91, 49, 59, 52, 81, 0, 27, 91, 49, 59, 52, 82, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 49, 59, 50, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -// This is a 256-colour terminfo description that lacks true-colour -// capabilities that gnome actually has. -static const signed char vte_256colour_terminfo[] = { - 26, 1, 52, 0, 29, 0, 15, 0, 105, 1, -55, 5, 103, 110, 111, 109, 101, 45, 50, 53, 54, 99, 111, 108, 111, 114, 124, 71, 78, 79, 77, 69, 32, 84, 101, 114, 109, 105, 110, 97, 108, 32, 119, 105, 116, 104, 32, 120, 116, 101, 114, 109, 32, 50, 53, 54, 45, 99, 111, 108, 111, 114, 115, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 127, 0, 0, 4, 0, 6, 0, 8, 0, 25, 0, 30, 0, 38, 0, 42, 0, 46, 0, -1, -1, 57, 0, 74, 0, 76, 0, 80, 0, 87, 0, -1, -1, 89, 0, 96, 0, -1, -1, 100, 0, -1, -1, 104, 0, 108, 0, -1, -1, -1, -1, 112, 0, -1, -1, 114, 0, 119, 0, -1, -1, -128, 0, -123, 0, -118, 0, -1, -1,-113, 0, -108, 0, -103, 0, -98, 0, -89, 0, -87, 0, -81, 0, -1, -1, -68, 0, -63, 0, -57, 0, -51, 0, -1, -1, -1, -1, -1, -1, -33, 0, -1, -1, -1, -1, -1, -1, 0, 1, -1, -1, 4, 1, -1, -1, -1, -1, -1, -1, 6, 1, -1, -1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 1, 19, 1, 25, 1, 29, 1, 33, 1, 37, 1, 43, 1, 49, 1, 55, 1, 61, 1, 67, 1, 71, 1, -1, -1, 76, 1, -1, -1, 80, 1, 85, 1, 90, 1, 94, 1, 101, 1, -1, -1, 108, 1, 112, 1, 120, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -128, 1,-119, 1, -110, 1, -101, 1, -92, 1, -83, 1, -74, 1, -65, 1, -56, 1, -47, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -38, 1, -35, 1, -1, -1, -1, -1, 16, 2, 19, 2, 30, 2, 33, 2, 35, 2, 38, 2, 116, 2, -1, -1, 119, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 121, 2, -1, -1, -1, -1, -1, -1, -1, -1, 125, 2, -1, -1, -78, 2, -1, -1, -1, -1, -74, 2, -68, 2, -1, -1, -1, -1, -62, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -58, 2, -54, 2, -1, -1, -50, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -45, 2, -1, -1, -38, 2, -33, 2, -1, -1, -1, -1, -1, -1, -1, -1, -26, 2, -19, 2, -12, 2, -1, -1, -1, -1, -5, 2, -1, -1, 2, 3, -1, -1, -1, -1, -1, -1, 9, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16, 3, 22, 3, 28, 3, 35, 3, 42, 3, 49, 3, 56, 3, 64, 3, 72, 3, 80, 3, 88, 3, 96, 3, 104, 3, 112, 3, 120, 3, 127, 3, -122, 3, -115, 3,-108, 3, -100, 3, -92, 3, -84, 3, -76, 3, -68, 3, -60, 3, -52, 3, -44, 3, -37, 3, -30, 3, -23, 3, -16, 3, -8, 3, 0, 4, 8, 4, 16, 4, 24, 4, 32, 4, 40, 4, 48, 4, 55, 4, 62, 4, 69, 4, 76, 4, 84, 4, 92, 4, 100, 4, 108, 4, 116, 4, 124, 4, -124, 4,-116, 4, -109, 4, -102, 4, -95, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -90, 4, -79, 4, -74, 4, -55, 4, -51, 4, -42, 4, -35, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 64, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 70, 5, -1, -1, -1, -1, -1, -1, 74, 5, -119, 5, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 114, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 50, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 10, 0, 27, 91, 72, 0, 27, 91, 63, 50, 53, 108, 0, 8, 0, 27, 91, 63, 50, 53, 104, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 80, 0, 27, 91, 77, 0, 14, 0, 27, 91, 49, 109, 0, 27, 55, 27, 91, 63, 52, 55, 104, 0, 27, 91, 50, 109, 0, 27, 91, 52, 104, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 15, 0, 27, 91, 48, 109, 15, 0, 27, 91, 50, 74, 27, 91, 63, 52, 55, 108, 27, 56, 0, 27, 91, 52, 108, 0, 27, 91, 50, 55, 109, 0, 27, 91, 50, 52, 109, 0, 27, 91, 63, 53, 104, 36, 60, 49, 48, 48, 47, 62, 27, 91, 63, 53, 108, 0, 27, 91, 109, 27, 91, 63, 55, 104, 27, 91, 52, 108, 27, 62, 27, 55, 27, 91, 114, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 56, 0, 27, 91, 76, 0, 127, 0, 27, 91, 51, 126, 0, 27, 79, 66, 0, 27, 79, 80, 0, 27, 91, 50, 49, 126, 0, 27, 79, 81, 0, 27, 79, 82, 0, 27, 79, 83, 0, 27, 91, 49, 53, 126, 0, 27, 91, 49, 55, 126, 0, 27, 91, 49, 56, 126, 0, 27, 91, 49, 57, 126, 0, 27, 91, 50, 48, 126, 0, 27, 79, 72, 0, 27, 91, 50, 126, 0, 27, 79, 68, 0, 27, 91, 54, 126, 0, 27, 91, 53, 126, 0, 27, 79, 67, 0, 27, 91, 49, 59, 50, 66, 0, 27, 91, 49, 59, 50, 65, 0, 27, 79, 65, 0, 27, 91, 63, 49, 108, 27, 62, 0, 27, 91, 63, 49, 104, 27, 61, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 99, 0, 27, 55, 27, 91, 114, 27, 56, 27, 91, 109, 27, 91, 63, 55, 104, 27, 91, 33, 112, 27, 91, 63, 49, 59, 51, 59, 52, 59, 54, 108, 27, 91, 52, 108, 27, 62, 27, 91, 63, 49, 48, 48, 48, 108, 27, 91, 63, 50, 53, 104, 0, 27, 56, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 27, 55, 0, 10, 0, 27, 77, 0, 27, 91, 48, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 53, 37, 116, 59, 50, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 37, 63, 37, 112, 49, 37, 112, 51, 37, 124, 37, 116, 59, 55, 37, 59, 109, 37, 63, 37, 112, 57, 37, 116, 14, 37, 101, 15, 37, 59, 0, 27, 72, 0, 9, 0, 27, 91, 69, 0, 96, 96, 97, 97, 102, 102, 103, 103, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 0, 27, 91, 90, 0, 27, 91, 63, 55, 104, 0, 27, 91, 63, 55, 108, 0, 27, 41, 48, 0, 27, 79, 70, 0, 27, 79, 77, 0, 27, 91, 49, 126, 0, 27, 91, 51, 59, 50, 126, 0, 27, 91, 52, 126, 0, 27, 91, 49, 59, 50, 70, 0, 27, 91, 49, 59, 50, 72, 0, 27, 91, 50, 59, 50, 126, 0, 27, 91, 49, 59, 50, 68, 0, 27, 91, 54, 59, 50, 126, 0, 27, 91, 53, 59, 50, 126, 0, 27, 91, 49, 59, 50, 67, 0, 27, 91, 50, 51, 126, 0, 27, 91, 50, 52, 126, 0, 27, 91, 49, 59, 50, 80, 0, 27, 91, 49, 59, 50, 81, 0, 27, 91, 49, 59, 50, 82, 0, 27, 91, 49, 59, 50, 83, 0, 27, 91, 49, 53, 59, 50, 126, 0, 27, 91, 49, 55, 59, 50, 126, 0, 27, 91, 49, 56, 59, 50, 126, 0, 27, 91, 49, 57, 59, 50, 126, 0, 27, 91, 50, 48, 59, 50, 126, 0, 27, 91, 50, 49, 59, 50, 126, 0, 27, 91, 50, 51, 59, 50, 126, 0, 27, 91, 50, 52, 59, 50, 126, 0, 27, 91, 49, 59, 53, 80, 0, 27, 91, 49, 59, 53, 81, 0, 27, 91, 49, 59, 53, 82, 0, 27, 91, 49, 59, 53, 83, 0, 27, 91, 49, 53, 59, 53, 126, 0, 27, 91, 49, 55, 59, 53, 126, 0, 27, 91, 49, 56, 59, 53, 126, 0, 27, 91, 49, 57, 59, 53, 126, 0, 27, 91, 50, 48, 59, 53, 126, 0, 27, 91, 50, 49, 59, 53, 126, 0, 27, 91, 50, 51, 59, 53, 126, 0, 27, 91, 50, 52, 59, 53, 126, 0, 27, 91, 49, 59, 54, 80, 0, 27, 91, 49, 59, 54, 81, 0, 27, 91, 49, 59, 54, 82, 0, 27, 91, 49, 59, 54, 83, 0, 27, 91, 49, 53, 59, 54, 126, 0, 27, 91, 49, 55, 59, 54, 126, 0, 27, 91, 49, 56, 59, 54, 126, 0, 27, 91, 49, 57, 59, 54, 126, 0, 27, 91, 50, 48, 59, 54, 126, 0, 27, 91, 50, 49, 59, 54, 126, 0, 27, 91, 50, 51, 59, 54, 126, 0, 27, 91, 50, 52, 59, 54, 126, 0, 27, 91, 49, 59, 51, 80, 0, 27, 91, 49, 59, 51, 81, 0, 27, 91, 49, 59, 51, 82, 0, 27, 91, 49, 59, 51, 83, 0, 27, 91, 49, 53, 59, 51, 126, 0, 27, 91, 49, 55, 59, 51, 126, 0, 27, 91, 49, 56, 59, 51, 126, 0, 27, 91, 49, 57, 59, 51, 126, 0, 27, 91, 50, 48, 59, 51, 126, 0, 27, 91, 50, 49, 59, 51, 126, 0, 27, 91, 50, 51, 59, 51, 126, 0, 27, 91, 50, 52, 59, 51, 126, 0, 27, 91, 49, 59, 52, 80, 0, 27, 91, 49, 59, 52, 81, 0, 27, 91, 49, 59, 52, 82, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 37, 91, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 93, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 93, 49, 48, 52, 7, 0, 27, 93, 52, 59, 37, 112, 49, 37, 100, 59, 114, 103, 98, 58, 37, 112, 50, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 51, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 47, 37, 112, 52, 37, 123, 50, 53, 53, 125, 37, 42, 37, 123, 49, 48, 48, 48, 125, 37, 47, 37, 50, 46, 50, 88, 27, 92, 0, 27, 91, 51, 109, 0, 27, 91, 50, 51, 109, 0, 27, 91, 77, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 51, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 57, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 51, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0, 27, 91, 37, 63, 37, 112, 49, 37, 123, 56, 125, 37, 60, 37, 116, 52, 37, 112, 49, 37, 100, 37, 101, 37, 112, 49, 37, 123, 49, 54, 125, 37, 60, 37, 116, 49, 48, 37, 112, 49, 37, 123, 56, 125, 37, 45, 37, 100, 37, 101, 52, 56, 59, 53, 59, 37, 112, 49, 37, 100, 37, 59, 109, 0 -}; -// Taken from Dickey ncurses terminfo.src dated 2017-04-22. -static const signed char ansi_terminfo[] = { - 26, 1, 40, 0, 23, 0, 16, 0, 125, 1, 68, 2, 97, 110, 115, 105, 124, 97, 110, 115, 105, 47, 112, 99, 45, 116, 101, 114, 109, 32, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 32, 119, 105, 116, 104, 32, 99, 111, 108, 111, 114, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 0, 8, 0, 24, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 0, 64, 0, 3, 0, 0, 0, 4, 0, 6, 0, -1, -1, 8, 0, 13, 0, 20, 0, 24, 0, 28, 0, -1, -1, 39, 0, 56, 0, 60, 0, -1, -1, 64, 0, -1, -1, -1, -1, 68, 0, -1, -1, 72, 0, -1, -1, 76, 0, 80, 0, -1, -1, -1, -1, 84, 0, 90, 0, 95, 0, -1, -1, -1, -1, -1, -1, -1, -1, 100, 0, -1, -1, 105, 0, 110, 0, 115, 0, 120, 0,-127, 0,-121, 0, -1, -1, -1, -1, -1, -1,-113, 0,-109, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-105, 0, -1, -1,-101, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -99, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -95, 0, -91, 0, -1, -1, -87, 0, -1, -1, -1, -1, -1, -1, -83, 0, -1, -1, -1, -1, -1, -1, -79, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -75, 0, -1, -1, -70, 0, -61, 0, -52, 0, -43, 0, -34, 0, -25, 0, -16, 0, -7, 0, 2, 1, 11, 1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 1, 25, 1, 30, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, 1, -1, -1, 61, 1, -1, -1, 63, 1,-107, 1, -1, -1,-104, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-100, 1, -1, -1, -37, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -33, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -28, 1, -17, 1, -12, 1, 7, 2, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 2, 30, 2, -1, -1, -1, -1, -1, -1, 40, 2, 44, 2, 48, 2, 52, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 56, 2, 62, 2, 27, 91, 90, 0, 7, 0, 13, 0, 27, 91, 51, 103, 0, 27, 91, 72, 27, 91, 74, 0, 27, 91, 75, 0, 27, 91, 74, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 71, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 59, 37, 112, 50, 37, 100, 72, 0, 27, 91, 66, 0, 27, 91, 72, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 65, 0, 27, 91, 80, 0, 27, 91, 77, 0, 27, 91, 49, 49, 109, 0, 27, 91, 53, 109, 0, 27, 91, 49, 109, 0, 27, 91, 56, 109, 0, 27, 91, 55, 109, 0, 27, 91, 55, 109, 0, 27, 91, 52, 109, 0, 27, 91, 37, 112, 49, 37, 100, 88, 0, 27, 91, 49, 48, 109, 0, 27, 91, 48, 59, 49, 48, 109, 0, 27, 91, 109, 0, 27, 91, 109, 0, 27, 91, 76, 0, 8, 0, 27, 91, 66, 0, 27, 91, 72, 0, 27, 91, 76, 0, 27, 91, 68, 0, 27, 91, 67, 0, 27, 91, 65, 0, 13, 27, 91, 83, 0, 27, 91, 37, 112, 49, 37, 100, 80, 0, 27, 91, 37, 112, 49, 37, 100, 77, 0, 27, 91, 37, 112, 49, 37, 100, 66, 0, 27, 91, 37, 112, 49, 37, 100, 64, 0, 27, 91, 37, 112, 49, 37, 100, 83, 0, 27, 91, 37, 112, 49, 37, 100, 76, 0, 27, 91, 37, 112, 49, 37, 100, 68, 0, 27, 91, 37, 112, 49, 37, 100, 67, 0, 27, 91, 37, 112, 49, 37, 100, 84, 0, 27, 91, 37, 112, 49, 37, 100, 65, 0, 27, 91, 52, 105, 0, 27, 91, 53, 105, 0, 37, 112, 49, 37, 99, 27, 91, 37, 112, 50, 37, 123, 49, 125, 37, 45, 37, 100, 98, 0, 27, 91, 37, 105, 37, 112, 49, 37, 100, 100, 0, 10, 0, 27, 91, 48, 59, 49, 48, 37, 63, 37, 112, 49, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 50, 37, 116, 59, 52, 37, 59, 37, 63, 37, 112, 51, 37, 116, 59, 55, 37, 59, 37, 63, 37, 112, 52, 37, 116, 59, 53, 37, 59, 37, 63, 37, 112, 54, 37, 116, 59, 49, 37, 59, 37, 63, 37, 112, 55, 37, 116, 59, 56, 37, 59, 37, 63, 37, 112, 57, 37, 116, 59, 49, 49, 37, 59, 109, 0, 27, 72, 0, 27, 91, 73, 0, 43, 16, 44, 17, 45, 24, 46, 25, 48, -37, 96, 4, 97, -79, 102, -8, 103, -15, 104, -80, 106, -39, 107, -65, 108, -38, 109, -64, 110, -59, 111, 126, 112, -60, 113, -60, 114, -60, 115, 95, 116, -61, 117, -76, 118, -63, 119, -62, 120, -77, 121, -13, 122, -14, 123, -29, 124, -40, 125,-100, 126, -2, 0, 27, 91, 90, 0, 27, 91, 49, 75, 0, 27, 91, 37, 105, 37, 100, 59, 37, 100, 82, 0, 27, 91, 54, 110, 0, 27, 91, 63, 37, 91, 59, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 93, 99, 0, 27, 91, 99, 0, 27, 91, 51, 57, 59, 52, 57, 109, 0, 27, 91, 51, 37, 112, 49, 37, 100, 109, 0, 27, 91, 52, 37, 112, 49, 37, 100, 109, 0, 27, 40, 66, 0, 27, 41, 66, 0, 27, 42, 66, 0, 27, 43, 66, 0, 27, 91, 49, 49, 109, 0, 27, 91, 49, 48, 109, 0 -}; - bool terminfo_is_term_family(const char *term, const char *family) { if (!term) { @@ -206,7 +144,7 @@ void terminfo_info_msg(const unibi_term *const ut) for (enum unibi_numeric i = unibi_numeric_begin_ + 1; i < unibi_numeric_end_; i++) { int n = unibi_get_num(ut, i); // -1 means "empty" - msg_printf_attr(0, " %-25s %-10s = %hd\n", unibi_name_num(i), + msg_printf_attr(0, " %-25s %-10s = %d\n", unibi_name_num(i), unibi_short_name_num(i), n); } @@ -235,7 +173,7 @@ void terminfo_info_msg(const unibi_term *const ut) if (unibi_count_ext_num(ut)) { msg_puts("Extended numeric capabilities:\n"); for (size_t i = 0; i < unibi_count_ext_num(ut); i++) { - msg_printf_attr(0, " %-25s = %hd\n", + msg_printf_attr(0, " %-25s = %d\n", unibi_get_ext_num_name(ut, i), unibi_get_ext_num(ut, i)); } diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h new file mode 100644 index 0000000000..000c0ea8e7 --- /dev/null +++ b/src/nvim/tui/terminfo_defs.h @@ -0,0 +1,1654 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +// +// Generated by scripts/update_terminfo.sh and ncurses 6.1.20180127 +// + +#ifndef NVIM_TUI_TERMINFO_DEFS_H +#define NVIM_TUI_TERMINFO_DEFS_H + +#include <stdint.h> + +// ansi|ansi/pc-term compatible with color, +// auto_right_margin, +// backspaces_with_bs, +// move_insert_mode, +// move_standout_mode, +// prtr_silent, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#8, +// max_pairs#64, +// no_color_video#3, +// acs_chars=+^P\054^Q-^X.^Y0\333`^Da\261f\370g\361h\260j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\E[B, +// cursor_home=\E[H, +// cursor_left=\E[D, +// cursor_right=\E[C, +// cursor_up=\E[A, +// delete_character=\E[P, +// delete_line=\E[M, +// enter_alt_charset_mode=\E[11m, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_pc_charset_mode=\E[11m, +// enter_reverse_mode=\E[7m, +// enter_secure_mode=\E[8m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// erase_chars=\E[%p1%dX, +// exit_alt_charset_mode=\E[10m, +// exit_attribute_mode=\E[0;10m, +// exit_pc_charset_mode=\E[10m, +// exit_standout_mode=\E[m, +// exit_underline_mode=\E[m, +// insert_line=\E[L, +// key_backspace=^H, +// key_btab=\E[Z, +// key_down=\E[B, +// key_home=\E[H, +// key_ic=\E[L, +// key_left=\E[D, +// key_right=\E[C, +// key_up=\E[A, +// newline=\r\E[S, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_rindex=\E[%p1%dT, +// parm_up_cursor=\E[%p1%dA, +// prtr_off=\E[4i, +// prtr_on=\E[5i, +// repeat_char=%p1%c\E[%p2%{1}%-%db, +// row_address=\E[%i%p1%dd, +// scroll_forward=\n, +// set0_des_seq=\E(B, +// set1_des_seq=\E)B, +// set2_des_seq=\E*B, +// set3_des_seq=\E+B, +// set_a_background=\E[4%p1%dm, +// set_a_foreground=\E[3%p1%dm, +// set_attributes=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m, +// set_tab=\EH, +// tab=\E[I, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?%[;0123456789]c, +// user9=\E[c, +static const int8_t ansi_terminfo[] = { + 26,1,40,0,38,0,16,0,125,1,68,2,97,110,115,105,124,97,110,115,105,47,112,99,45,116,101,114,109,32,99,111,109,112,97,116,105,98,108,101,32,119,105,116,104,32,99,111,108,111,114,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,80,0,8,0,24,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,3,0,0,0,4,0,6,0,-1,-1,8,0,13,0,20,0,24,0,28,0,-1,-1,39,0,56,0,60,0,-1,-1,64,0,-1,-1,-1,-1,68,0,-1,-1,72,0,-1,-1,76,0,80,0,-1,-1,-1,-1,84,0,90,0,95,0,-1,-1,-1,-1,-1,-1,-1,-1,100,0,-1,-1,105,0,110,0,115,0,120,0,-127,0,-121,0,-1,-1,-1,-1,-1,-1,-113,0,-109,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-105,0,-1,-1,-101,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-99,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-95,0,-91,0,-1,-1,-87,0,-1,-1,-1,-1,-1,-1,-83,0,-1,-1,-1,-1,-1,-1,-79,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-75,0,-1,-1,-70,0,-61,0,-52,0,-43,0,-34,0,-25,0,-16,0,-7,0,2,1,11,1,-1,-1,-1,-1,-1,-1,-1,-1,20,1,25,1,30,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,50,1,-1,-1,61,1,-1,-1,63,1,-107,1,-1,-1,-104,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-100,1,-1,-1,-37,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-33,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-28,1,-17,1,-12,1,7,2,11,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,20,2,30,2,-1,-1,-1,-1,-1,-1,40,2,44,2,48,2,52,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,56,2,62,2,27,91,90,0,7,0,13,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,91,66,0,27,91,72,0,27,91,68,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,91,49,49,109,0,27,91,53,109,0,27,91,49,109,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,91,49,48,109,0,27,91,48,59,49,48,109,0,27,91,109,0,27,91,109,0,27,91,76,0,8,0,27,91,66,0,27,91,72,0,27,91,76,0,27,91,68,0,27,91,67,0,27,91,65,0,13,27,91,83,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,52,105,0,27,91,53,105,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,91,37,105,37,112,49,37,100,100,0,10,0,27,91,48,59,49,48,37,63,37,112,49,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,55,37,116,59,56,37,59,37,63,37,112,57,37,116,59,49,49,37,59,109,0,27,72,0,27,91,73,0,43,16,44,17,45,24,46,25,48,-37,96,4,97,-79,102,-8,103,-15,104,-80,106,-39,107,-65,108,-38,109,-64,110,-59,111,126,112,-60,113,-60,114,-60,115,95,116,-61,117,-76,118,-63,119,-62,120,-77,121,-13,122,-14,123,-29,124,-40,125,-100,126,-2,0,27,91,90,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0,27,40,66,0,27,41,66,0,27,42,66,0,27,43,66,0,27,91,49,49,109,0,27,91,49,48,109,0,1,0,0,0,0,0,1,0,3,0,1,0,0,0,65,88,0 +}; + +// interix|opennt|opennt-25|ntconsole|ntconsole-25|OpenNT-term compatible with color, +// auto_right_margin, +// back_color_erase, +// move_standout_mode, +// columns#80, +// init_tabs#8, +// lines#25, +// max_colors#8, +// max_pairs#64, +// no_color_video#3, +// acs_chars=+^P\054^Q-^X.^Y0\333`^Da\261f\370g\361h\260j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376, +// bell=^G, +// carriage_return=\r, +// clear_screen=\E[2J, +// clr_eol=\E[K, +// clr_eos=\E[J, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_left=\E[D, +// cursor_right=\E[C, +// cursor_to_ll=\E[U, +// cursor_up=\E[A, +// delete_line=\E[M, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[s\E[1b, +// enter_reverse_mode=\E[7m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// exit_attribute_mode=\E[0m, +// exit_ca_mode=\E[2b\E[u\r\E[K, +// exit_standout_mode=\E[m, +// exit_underline_mode=\E[m, +// insert_line=\E[L, +// key_backspace=^H, +// key_btab=\E[Z, +// key_dc=\177, +// key_down=\E[B, +// key_end=\E[U, +// key_f0=\EFA, +// key_f1=\EF1, +// key_f10=\EFA, +// key_f11=\EFB, +// key_f12=\EFC, +// key_f13=\EFD, +// key_f14=\EFE, +// key_f15=\EFF, +// key_f16=\EFG, +// key_f17=\EFH, +// key_f18=\EFI, +// key_f19=\EFJ, +// key_f2=\EF2, +// key_f20=\EFK, +// key_f21=\EFL, +// key_f22=\EFM, +// key_f23=\EFN, +// key_f24=\EFO, +// key_f25=\EFP, +// key_f26=\EFQ, +// key_f27=\EFR, +// key_f28=\EFS, +// key_f29=\EFT, +// key_f3=\EF3, +// key_f30=\EFU, +// key_f31=\EFV, +// key_f32=\EFW, +// key_f33=\EFX, +// key_f34=\EFY, +// key_f35=\EFZ, +// key_f36=\EFa, +// key_f37=\EFb, +// key_f38=\EFc, +// key_f39=\EFd, +// key_f4=\EF4, +// key_f40=\EFe, +// key_f41=\EFf, +// key_f42=\EFg, +// key_f43=\EFh, +// key_f44=\EFi, +// key_f45=\EFj, +// key_f46=\EFk, +// key_f47=\EFm, +// key_f48=\EFn, +// key_f49=\EFo, +// key_f5=\EF5, +// key_f50=\EFp, +// key_f51=\EFq, +// key_f52=\EFr, +// key_f53=\EFs, +// key_f54=\EFt, +// key_f55=\EFu, +// key_f56=\EFv, +// key_f57=\EFw, +// key_f58=\EFx, +// key_f59=\EFy, +// key_f6=\EF6, +// key_f60=\EFz, +// key_f7=\EF7, +// key_f8=\EF8, +// key_f9=\EF9, +// key_home=\E[H, +// key_ic=\E[L, +// key_left=\E[D, +// key_ll=\E[U, +// key_npage=\E[T, +// key_ppage=\E[S, +// key_right=\E[C, +// key_sf=\EF+, +// key_sleft=\EF\136, +// key_sr=\EF-, +// key_sright=\EF$, +// key_up=\E[A, +// newline=\r\n, +// orig_pair=\E[m, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_rindex=\E[%p1%dT, +// parm_up_cursor=\E[%p1%dA, +// repeat_char=%p1%c\E[%p2%{1}%-%db, +// reset_1string=\Ec, +// restore_cursor=\E[u, +// save_cursor=\E[s, +// scroll_forward=\E[S, +// scroll_reverse=\E[T, +// set_a_background=\E[4%p1%dm, +// set_a_foreground=\E[3%p1%dm, +// tab=^I, +static const int8_t interix_8colour_terminfo[] = { + 26,1,82,0,29,0,16,0,105,1,116,2,105,110,116,101,114,105,120,124,111,112,101,110,110,116,124,111,112,101,110,110,116,45,50,53,124,110,116,99,111,110,115,111,108,101,124,110,116,99,111,110,115,111,108,101,45,50,53,124,79,112,101,110,78,84,45,116,101,114,109,32,99,111,109,112,97,116,105,98,108,101,32,119,105,116,104,32,99,111,108,111,114,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,80,0,8,0,25,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,3,0,-1,-1,0,0,2,0,-1,-1,-1,-1,4,0,9,0,13,0,-1,-1,-1,-1,17,0,34,0,36,0,-1,-1,40,0,-1,-1,-1,-1,44,0,48,0,52,0,-1,-1,-1,-1,56,0,-1,-1,-1,-1,-1,-1,-1,-1,60,0,65,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,73,0,78,0,83,0,-1,-1,-1,-1,88,0,93,0,-1,-1,-1,-1,105,0,109,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,113,0,-1,-1,117,0,-1,-1,-1,-1,-1,-1,119,0,-1,-1,121,0,-1,-1,-1,-1,-1,-1,125,0,-127,0,-123,0,-119,0,-115,0,-111,0,-107,0,-103,0,-99,0,-95,0,-91,0,-87,0,-83,0,-1,-1,-79,0,-75,0,-71,0,-67,0,-63,0,-59,0,-55,0,-1,-1,-51,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-47,0,-1,-1,-1,-1,-44,0,-35,0,-1,-1,-26,0,-17,0,-8,0,1,1,10,1,19,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,1,48,1,-1,-1,-1,-1,-1,-1,51,1,-1,-1,55,1,59,1,63,1,-1,-1,-1,-1,-1,-1,67,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,69,1,-1,-1,-124,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-120,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-116,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-112,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-108,1,-104,1,-100,1,-96,1,-92,1,-88,1,-84,1,-80,1,-76,1,-72,1,-68,1,-64,1,-60,1,-56,1,-52,1,-48,1,-44,1,-40,1,-36,1,-32,1,-28,1,-24,1,-20,1,-16,1,-12,1,-8,1,-4,1,0,2,4,2,8,2,12,2,16,2,20,2,24,2,28,2,32,2,36,2,40,2,44,2,48,2,52,2,56,2,60,2,64,2,68,2,72,2,76,2,80,2,84,2,88,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,92,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,96,2,106,2,7,0,13,0,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,68,0,27,91,67,0,27,91,85,0,27,91,65,0,27,91,77,0,27,91,49,109,0,27,91,115,27,91,49,98,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,48,109,0,27,91,50,98,27,91,117,13,27,91,75,0,27,91,109,0,27,91,109,0,27,91,76,0,8,0,127,0,27,91,66,0,27,70,65,0,27,70,49,0,27,70,65,0,27,70,50,0,27,70,51,0,27,70,52,0,27,70,53,0,27,70,54,0,27,70,55,0,27,70,56,0,27,70,57,0,27,91,72,0,27,91,76,0,27,91,68,0,27,91,85,0,27,91,84,0,27,91,83,0,27,91,67,0,27,70,43,0,27,70,45,0,27,91,65,0,13,10,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,99,0,27,91,117,0,27,91,115,0,27,91,83,0,27,91,84,0,9,0,43,16,44,17,45,24,46,25,48,-37,96,4,97,-79,102,-8,103,-15,104,-80,106,-39,107,-65,108,-38,109,-64,110,-59,111,126,112,-60,113,-60,114,-60,115,95,116,-61,117,-76,118,-63,119,-62,120,-77,121,-13,122,-14,123,-29,124,-40,125,-100,126,-2,0,27,91,90,0,27,91,85,0,27,70,94,0,27,70,36,0,27,70,66,0,27,70,67,0,27,70,68,0,27,70,69,0,27,70,70,0,27,70,71,0,27,70,72,0,27,70,73,0,27,70,74,0,27,70,75,0,27,70,76,0,27,70,77,0,27,70,78,0,27,70,79,0,27,70,80,0,27,70,81,0,27,70,82,0,27,70,83,0,27,70,84,0,27,70,85,0,27,70,86,0,27,70,87,0,27,70,88,0,27,70,89,0,27,70,90,0,27,70,97,0,27,70,98,0,27,70,99,0,27,70,100,0,27,70,101,0,27,70,102,0,27,70,103,0,27,70,104,0,27,70,105,0,27,70,106,0,27,70,107,0,27,70,109,0,27,70,110,0,27,70,111,0,27,70,112,0,27,70,113,0,27,70,114,0,27,70,115,0,27,70,116,0,27,70,117,0,27,70,118,0,27,70,119,0,27,70,120,0,27,70,121,0,27,70,122,0,27,91,109,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0 +}; + +// iTerm2.app|iterm2|terminal emulator for Mac OS X, +// auto_right_margin, +// back_color_erase, +// eat_newline_glitch, +// has_status_line, +// move_insert_mode, +// move_standout_mode, +// no_pad_char, +// xon_xoff, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// width_status_line#50, +// acs_chars=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[?25h, +// cursor_right=\E[C, +// cursor_up=\E[A, +// delete_character=\E[P, +// delete_line=\E[M, +// dis_status_line=\E]2;^G, +// ena_acs=\E(B\E)0, +// enter_alt_charset_mode=^N, +// enter_am_mode=\E[?7h, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[?1049h\E[22;0;0t, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_italics_mode=\E[3m, +// enter_reverse_mode=\E[7m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// exit_alt_charset_mode=^O, +// exit_am_mode=\E[?7l, +// exit_attribute_mode=\E[m^O, +// exit_ca_mode=\E[?1049l\E[23;0;0t, +// exit_insert_mode=\E[4l, +// exit_italics_mode=\E[23m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<200/>\E[?5l, +// from_status_line=^G, +// insert_character=\E[@, +// insert_line=\E[L, +// key_a1@, +// key_a3@, +// key_b2@, +// key_backspace=\177, +// key_btab=\E[Z, +// key_c1@, +// key_c3@, +// key_dc=\E[3~, +// key_down=\EOB, +// key_end=\EOF, +// key_enter@, +// key_f1=\EOP, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[1;2P, +// key_f14=\E[1;2Q, +// key_f15=\E[1;2R, +// key_f16=\E[1;2S, +// key_f17=\E[15;2~, +// key_f18=\E[17;2~, +// key_f19=\E[18;2~, +// key_f2=\EOQ, +// key_f20=\E[19;2~, +// key_f21=\E[20;2~, +// key_f22=\E[21;2~, +// key_f23=\E[23;2~, +// key_f24=\E[24;2~, +// key_f3=\EOR, +// key_f4=\EOS, +// key_f5=\E[15~, +// key_f6=\E[17~, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\EOH, +// key_left=\EOD, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_send=\E[1;2F, +// key_sf=\E[1;2B, +// key_shome=\E[1;2H, +// key_sleft=\E[1;2D, +// key_sr=\E[1;2A, +// key_sright=\E[1;2C, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// newline=\EE, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_rindex=\E[%p1%dT, +// parm_up_cursor=\E[%p1%dA, +// reset_2string=\E[\041p\E[?3;4l\E[4l\E>\E[?1000l, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +// to_status_line=\E]2;, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?%[;0123456789]c, +// user9=\E[c, +static const int8_t iterm_256colour_terminfo[] = { + 30,2,49,0,29,0,15,0,105,1,-29,3,105,84,101,114,109,50,46,97,112,112,124,105,116,101,114,109,50,124,116,101,114,109,105,110,97,108,32,101,109,117,108,97,116,111,114,32,102,111,114,32,77,97,99,32,79,83,32,88,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,50,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,75,0,79,0,86,0,-1,-1,88,0,95,0,-1,-1,99,0,-1,-1,103,0,107,0,111,0,-1,-1,117,0,119,0,124,0,-127,0,-1,-1,-109,0,-104,0,-1,-1,-1,-1,-99,0,-94,0,-89,0,-1,-1,-84,0,-82,0,-77,0,-1,-1,-59,0,-54,0,-48,0,-42,0,-1,-1,-24,0,-1,-1,-1,-1,-1,-1,-1,-1,-22,0,-18,0,-1,-1,-14,0,-1,-1,-1,-1,-1,-1,-12,0,-1,-1,-7,0,-1,-1,-1,-1,-1,-1,-1,-1,-3,0,1,1,7,1,11,1,15,1,19,1,25,1,31,1,37,1,43,1,49,1,-1,-1,-1,-1,53,1,-1,-1,57,1,62,1,67,1,71,1,78,1,-1,-1,85,1,89,1,97,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,105,1,-1,-1,108,1,117,1,126,1,-121,1,-112,1,-103,1,-94,1,-85,1,-76,1,-67,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-1,-1,-1,-1,-32,1,-29,1,-18,1,-15,1,-13,1,-10,1,68,2,-1,-1,71,2,73,2,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-1,-1,78,2,-1,-1,-127,2,-1,-1,-1,-1,-123,2,-117,2,-1,-1,-1,-1,-111,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-104,2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-100,2,-1,-1,-1,-1,-1,-1,-1,-1,-93,2,-1,-1,-86,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-79,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-72,2,-66,2,-60,2,-53,2,-46,2,-39,2,-32,2,-24,2,-16,2,-8,2,0,3,8,3,16,3,24,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,32,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,37,3,48,3,53,3,72,3,76,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,85,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,90,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,96,3,-1,-1,-1,-1,-1,-1,100,3,-93,3,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,93,50,59,7,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,27,91,50,50,59,48,59,48,116,0,27,91,50,109,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,63,49,48,52,57,108,27,91,50,51,59,48,59,48,116,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,50,48,48,47,62,27,91,63,53,108,0,7,0,27,91,64,0,27,91,76,0,127,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,69,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,27,91,63,49,48,48,48,108,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,93,50,59,0,96,96,97,97,102,102,103,103,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,40,66,27,41,48,0,27,79,70,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,49,59,50,68,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,1,0,0,0,33,0,67,0,-37,1,0,0,0,0,5,0,32,0,37,0,45,0,52,0,59,0,66,0,74,0,81,0,88,0,96,0,104,0,111,0,119,0,126,0,-123,0,-115,0,-107,0,-102,0,-94,0,-87,0,-80,0,-74,0,-68,0,-63,0,-55,0,-48,0,-41,0,-36,0,-28,0,-21,0,-14,0,0,0,3,0,6,0,9,0,14,0,19,0,24,0,29,0,35,0,41,0,47,0,53,0,59,0,65,0,71,0,77,0,83,0,89,0,95,0,101,0,107,0,113,0,119,0,125,0,-125,0,-119,0,-113,0,-107,0,-101,0,-95,0,-90,0,-85,0,-80,0,-75,0,27,93,50,59,0,27,91,63,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,27,91,66,0,27,91,49,59,49,48,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,57,70,0,27,91,49,59,49,48,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,49,51,70,0,27,91,49,59,49,52,70,0,27,91,49,59,57,72,0,27,91,49,59,49,48,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,49,51,72,0,27,91,49,59,49,52,72,0,27,27,91,68,0,27,91,49,59,49,48,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,27,91,54,126,0,27,27,91,53,126,0,27,27,91,67,0,27,91,49,59,49,48,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,27,91,65,0,27,91,49,59,49,48,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,77,37,63,37,112,52,37,116,51,37,101,37,112,51,37,39,32,39,37,43,37,99,37,59,37,112,50,37,39,33,39,37,43,37,99,37,112,49,37,39,33,39,37,43,37,99,0,65,88,0,84,83,0,88,77,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,78,88,84,51,0,107,80,82,86,51,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,120,109,0 +}; + +// linux|linux console, +// auto_right_margin, +// back_color_erase, +// can_change, +// eat_newline_glitch, +// erase_overstrike, +// move_insert_mode, +// move_standout_mode, +// xon_xoff, +// init_tabs#8, +// max_colors#8, +// max_pairs#64, +// no_color_video#18, +// acs_chars=++\054\054--..00__``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}c~~, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l\E[?1c, +// cursor_left=^H, +// cursor_normal=\E[?25h\E[?0c, +// cursor_right=\E[C, +// cursor_up=\E[A, +// cursor_visible=\E[?25h\E[?8c, +// delete_character=\E[P, +// delete_line=\E[M, +// ena_acs=\E)0, +// enter_alt_charset_mode=^N, +// enter_am_mode=\E[?7h, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_pc_charset_mode=\E[11m, +// enter_reverse_mode=\E[7m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// erase_chars=\E[%p1%dX, +// exit_alt_charset_mode=^O, +// exit_am_mode=\E[?7l, +// exit_attribute_mode=\E[m^O, +// exit_insert_mode=\E[4l, +// exit_pc_charset_mode=\E[10m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<200/>\E[?5l, +// initialize_color=\E]P%p1%x%p2%{255}%*%{1000}%/%02x%p3%{255}%*%{1000}%/%02x%p4%{255}%*%{1000}%/%02x, +// insert_character=\E[@, +// insert_line=\E[L, +// key_b2=\E[G, +// key_backspace=\177, +// key_btab=\E[Z, +// key_dc=\E[3~, +// key_down=\E[B, +// key_end=\E[4~, +// key_f1=\E[[A, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[25~, +// key_f14=\E[26~, +// key_f15=\E[28~, +// key_f16=\E[29~, +// key_f17=\E[31~, +// key_f18=\E[32~, +// key_f19=\E[33~, +// key_f2=\E[[B, +// key_f20=\E[34~, +// key_f3=\E[[C, +// key_f4=\E[[D, +// key_f5=\E[[E, +// key_f6=\E[17~, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\E[1~, +// key_ic=\E[2~, +// key_left=\E[D, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\E[C, +// key_suspend=^Z, +// key_up=\E[A, +// newline=\r\n, +// orig_colors=\E]R, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_up_cursor=\E[%p1%dA, +// reset_1string=\Ec\E]R, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[4%p1%dm, +// set_a_foreground=\E[3%p1%dm, +// set_attributes=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p6%t;1%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?6c, +// user9=\E[c, +static const int8_t linux_16colour_terminfo[] = { + 26,1,20,0,29,0,16,0,125,1,69,3,108,105,110,117,120,124,108,105,110,117,120,32,99,111,110,115,111,108,101,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,-1,-1,8,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,18,0,-1,-1,0,0,2,0,4,0,21,0,26,0,33,0,37,0,41,0,-1,-1,52,0,69,0,71,0,75,0,87,0,-1,-1,89,0,101,0,-1,-1,105,0,109,0,121,0,125,0,-1,-1,-1,-1,-127,0,-125,0,-120,0,-1,-1,-1,-1,-115,0,-110,0,-1,-1,-1,-1,-105,0,-100,0,-95,0,-90,0,-81,0,-79,0,-1,-1,-1,-1,-74,0,-69,0,-63,0,-57,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-39,0,-35,0,-1,-1,-31,0,-1,-1,-1,-1,-1,-1,-29,0,-1,-1,-24,0,-1,-1,-1,-1,-1,-1,-1,-1,-20,0,-15,0,-9,0,-4,0,1,1,6,1,11,1,17,1,23,1,29,1,35,1,40,1,-1,-1,45,1,-1,-1,49,1,54,1,59,1,-1,-1,-1,-1,-1,-1,63,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,67,1,-1,-1,70,1,79,1,88,1,97,1,-1,-1,106,1,115,1,124,1,-1,-1,-123,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-114,1,-1,-1,-1,-1,-1,-1,-108,1,-105,1,-94,1,-91,1,-89,1,-86,1,1,2,-1,-1,4,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,6,2,-1,-1,-1,-1,-1,-1,-1,-1,10,2,-1,-1,77,2,-1,-1,-1,-1,81,2,87,2,-1,-1,-1,-1,93,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,97,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,102,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,104,2,110,2,116,2,122,2,-128,2,-122,2,-116,2,-110,2,-104,2,-98,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-92,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-87,2,-76,2,-71,2,-65,2,-61,2,-52,2,-48,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,33,3,-1,-1,-1,-1,-1,-1,37,3,47,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,57,3,63,3,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,27,91,63,49,99,0,8,0,27,91,63,50,53,104,27,91,63,48,99,0,27,91,67,0,27,91,65,0,27,91,63,50,53,104,27,91,63,56,99,0,27,91,80,0,27,91,77,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,50,109,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,15,0,27,91,109,15,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,50,48,48,47,62,27,91,63,53,108,0,27,91,64,0,27,91,76,0,127,0,27,91,51,126,0,27,91,66,0,27,91,91,65,0,27,91,50,49,126,0,27,91,91,66,0,27,91,91,67,0,27,91,91,68,0,27,91,91,69,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,65,0,13,10,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,93,82,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,59,49,48,37,63,37,112,49,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,54,37,116,59,49,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,91,71,0,43,43,44,44,45,45,46,46,48,48,95,95,96,96,97,97,102,102,103,103,104,104,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,99,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,41,48,0,27,91,52,126,0,26,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,54,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,82,0,27,93,80,37,112,49,37,120,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,48,50,120,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,48,50,120,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,48,50,120,0,27,91,77,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0,27,91,49,49,109,0,27,91,49,48,109,0,0,3,0,1,0,12,0,28,0,63,0,1,0,0,0,1,0,-1,-1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,33,0,39,0,43,0,47,0,51,0,55,0,27,91,51,74,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,69,51,0,83,48,0,84,83,0,88,77,0,107,69,78,68,53,0,107,72,79,77,53,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 +}; + +// putty-256color|PuTTY 0.58 with xterm 256-colors, +// auto_left_margin, +// auto_right_margin, +// back_color_erase, +// eat_newline_glitch, +// has_status_line, +// move_insert_mode, +// move_standout_mode, +// xon_xoff, +// init_tabs#8, +// max_colors#0x100, +// max_pairs#0x10000, +// no_color_video#22, +// acs_chars=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\ED, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[?25h, +// cursor_right=\E[C, +// cursor_up=\EM, +// delete_character=\E[P, +// delete_line=\E[M, +// dis_status_line=\E]0;^G, +// display_pc_char=%?%p1%{8}%=%t\E%%G\342\227\230\E%%@%e%p1%{10}%=%t\E%%G\342\227\231\E%%@%e%p1%{12}%=%t\E%%G\342\231\0\E%%@%e%p1%{13}%=%t\E%%G\342\231\252\E%%@%e%p1%{14}%=%t\E%%G\342\231\253\E%%@%e%p1%{15}%=%t\E%%G\342\230\274\E%%@%e%p1%{27}%=%t\E%%G\342\206\220\E%%@%e%p1%{155}%=%t\E%%G\340\202\242\E%%@%e%p1%c%;, +// ena_acs=\E(B\E)0, +// enter_alt_charset_mode=^N, +// enter_am_mode=\E[?7h, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[?47h, +// enter_insert_mode=\E[4h, +// enter_pc_charset_mode=\E[11m, +// enter_reverse_mode=\E[7m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// erase_chars=\E[%p1%dX, +// exit_alt_charset_mode=^O, +// exit_am_mode=\E[?7l, +// exit_attribute_mode=\E[m^O, +// exit_ca_mode=\E[2J\E[?47l, +// exit_insert_mode=\E[4l, +// exit_pc_charset_mode=\E[10m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<100/>\E[?5l, +// from_status_line=^G, +// init_2string=\E7\E[r\E[m\E[?7h\E[?1;4;6l\E[4l\E8\E>\E]R, +// insert_line=\E[L, +// key_b2=\E[G, +// key_backspace=\177, +// key_btab=\E[Z, +// key_dc=\E[3~, +// key_down=\EOB, +// key_end=\E[4~, +// key_f1=\E[11~, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[25~, +// key_f14=\E[26~, +// key_f15=\E[28~, +// key_f16=\E[29~, +// key_f17=\E[31~, +// key_f18=\E[32~, +// key_f19=\E[33~, +// key_f2=\E[12~, +// key_f20=\E[34~, +// key_f3=\E[13~, +// key_f4=\E[14~, +// key_f5=\E[15~, +// key_f6=\E[17~, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\E[1~, +// key_ic=\E[2~, +// key_left=\EOD, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_sf=\E[B, +// key_sleft=\E[D, +// key_sr=\E[A, +// key_sright=\E[C, +// key_suspend=^Z, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// newline=\r\n, +// orig_colors=\E]R, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_rindex=\E[%p1%dT, +// parm_up_cursor=\E[%p1%dA, +// reset_2string=\E<\E["p\E[50;6"p\Ec\E[?3l\E]R\E[?1000l, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set0_des_seq=\E[10m, +// set1_des_seq=\E[11m, +// set2_des_seq=\E[12m, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +// to_status_line=\E]0;, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?6c, +// user9=\E[c, +static const int8_t putty_256colour_terminfo[] = { + 30,2,48,0,29,0,16,0,125,1,-106,4,112,117,116,116,121,45,50,53,54,99,111,108,111,114,124,80,117,84,84,89,32,48,46,53,56,32,119,105,116,104,32,120,116,101,114,109,32,50,53,54,45,99,111,108,111,114,115,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,-1,-1,-1,-1,8,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,22,0,0,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,76,0,80,0,87,0,-1,-1,89,0,96,0,-1,-1,100,0,-1,-1,103,0,107,0,111,0,-1,-1,117,0,119,0,124,0,-127,0,-1,-1,-1,-1,-120,0,-1,-1,-1,-1,-115,0,-110,0,-105,0,-100,0,-91,0,-89,0,-84,0,-1,-1,-73,0,-68,0,-62,0,-56,0,-1,-1,-38,0,-1,-1,-36,0,-1,-1,-1,-1,-1,-1,-2,0,-1,-1,2,1,-1,-1,-1,-1,-1,-1,4,1,-1,-1,9,1,-1,-1,-1,-1,-1,-1,-1,-1,13,1,19,1,25,1,31,1,37,1,43,1,49,1,55,1,61,1,67,1,73,1,78,1,-1,-1,83,1,-1,-1,87,1,92,1,97,1,101,1,105,1,-1,-1,109,1,113,1,121,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-127,1,-1,-1,-124,1,-115,1,-106,1,-1,-1,-97,1,-88,1,-79,1,-70,1,-61,1,-52,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-43,1,-1,-1,-1,-1,-10,1,-7,1,4,2,7,2,9,2,12,2,84,2,-1,-1,87,2,89,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,94,2,-1,-1,-1,-1,-1,-1,-1,-1,98,2,-1,-1,-107,2,-1,-1,-1,-1,-103,2,-97,2,-1,-1,-1,-1,-91,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-84,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-79,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-77,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-73,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-69,2,-63,2,-57,2,-51,2,-45,2,-39,2,-33,2,-27,2,-21,2,-15,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-9,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-4,2,7,3,12,3,18,3,22,3,31,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,35,3,-1,-1,-1,-1,-1,-1,39,3,102,3,-1,-1,-1,-1,-1,-1,-90,3,-84,3,-78,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-72,3,-118,4,-112,4,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,68,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,77,0,27,91,80,0,27,91,77,0,27,93,48,59,7,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,52,55,104,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,15,0,27,91,109,15,0,27,91,50,74,27,91,63,52,55,108,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,7,0,27,55,27,91,114,27,91,109,27,91,63,55,104,27,91,63,49,59,52,59,54,108,27,91,52,108,27,56,27,62,27,93,82,0,27,91,76,0,127,0,27,91,51,126,0,27,79,66,0,27,91,49,49,126,0,27,91,50,49,126,0,27,91,49,50,126,0,27,91,49,51,126,0,27,91,49,52,126,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,66,0,27,91,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,13,10,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,60,27,91,34,112,27,91,53,48,59,54,34,112,27,99,27,91,63,51,108,27,93,82,27,91,63,49,48,48,48,108,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,49,37,112,54,37,124,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,93,48,59,0,27,91,71,0,96,96,97,97,102,102,103,103,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,40,66,27,41,48,0,27,91,52,126,0,26,0,27,91,68,0,27,91,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,54,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,82,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,49,48,109,0,27,91,49,49,109,0,27,91,49,50,109,0,37,63,37,112,49,37,123,56,125,37,61,37,116,27,37,37,71,-30,-105,-104,27,37,37,64,37,101,37,112,49,37,123,49,48,125,37,61,37,116,27,37,37,71,-30,-105,-103,27,37,37,64,37,101,37,112,49,37,123,49,50,125,37,61,37,116,27,37,37,71,-30,-103,-128,27,37,37,64,37,101,37,112,49,37,123,49,51,125,37,61,37,116,27,37,37,71,-30,-103,-86,27,37,37,64,37,101,37,112,49,37,123,49,52,125,37,61,37,116,27,37,37,71,-30,-103,-85,27,37,37,64,37,101,37,112,49,37,123,49,53,125,37,61,37,116,27,37,37,71,-30,-104,-68,27,37,37,64,37,101,37,112,49,37,123,50,55,125,37,61,37,116,27,37,37,71,-30,-122,-112,27,37,37,64,37,101,37,112,49,37,123,49,53,53,125,37,61,37,116,27,37,37,71,-32,-126,-94,27,37,37,64,37,101,37,112,49,37,99,37,59,0,27,91,49,49,109,0,27,91,49,48,109,0,3,0,1,0,60,0,124,0,74,1,0,0,1,0,1,0,0,0,-1,-1,0,0,-1,-1,-1,-1,-1,-1,5,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,39,0,45,0,50,0,55,0,60,0,65,0,70,0,74,0,79,0,84,0,89,0,94,0,99,0,105,0,111,0,117,0,123,0,-127,0,-121,0,-115,0,-109,0,-103,0,-97,0,-91,0,-85,0,-80,0,-75,0,-69,0,-63,0,-57,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,25,1,30,1,35,1,40,1,45,1,49,1,53,1,57,1,61,1,27,91,51,74,0,27,93,48,59,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,69,51,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,53,0,107,73,67,54,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,53,0,107,78,88,84,54,0,107,80,82,86,51,0,107,80,82,86,53,0,107,80,82,86,54,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 +}; + +// rxvt-256color|rxvt 2.7.9 with xterm 256-colors, +// auto_right_margin, +// back_color_erase, +// backspaces_with_bs, +// can_change, +// eat_newline_glitch, +// erase_overstrike, +// move_insert_mode, +// move_standout_mode, +// xon_xoff, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// acs_chars=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[2J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[?25h, +// cursor_right=\E[C, +// cursor_up=\E[A, +// delete_line=\E[M, +// ena_acs=\E(B\E)0, +// enter_alt_charset_mode=^N, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E7\E[?47h, +// enter_insert_mode=\E[4h, +// enter_reverse_mode=\E[7m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// exit_alt_charset_mode=^O, +// exit_attribute_mode=\E[m^O, +// exit_ca_mode=\E[2J\E[?47l\E8, +// exit_insert_mode=\E[4l, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<100/>\E[?5l, +// init_1string=\E[?47l\E=\E[?1l, +// init_2string=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l, +// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\, +// insert_character=\E[@, +// insert_line=\E[L, +// key_a1=\EOw, +// key_a3=\EOy, +// key_b2=\EOu, +// key_backspace=^H, +// key_btab=\E[Z, +// key_c1=\EOq, +// key_c3=\EOs, +// key_dc=\E[3~, +// key_down=\E[B, +// key_end=\E[8~, +// key_enter=\EOM, +// key_eol=\E[8\136, +// key_f0=\E[21~, +// key_f1=\E[11~, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[25~, +// key_f14=\E[26~, +// key_f15=\E[28~, +// key_f16=\E[29~, +// key_f17=\E[31~, +// key_f18=\E[32~, +// key_f19=\E[33~, +// key_f2=\E[12~, +// key_f20=\E[34~, +// key_f21=\E[23$, +// key_f22=\E[24$, +// key_f23=\E[11\136, +// key_f24=\E[12\136, +// key_f25=\E[13\136, +// key_f26=\E[14\136, +// key_f27=\E[15\136, +// key_f28=\E[17\136, +// key_f29=\E[18\136, +// key_f3=\E[13~, +// key_f30=\E[19\136, +// key_f31=\E[20\136, +// key_f32=\E[21\136, +// key_f33=\E[23\136, +// key_f34=\E[24\136, +// key_f35=\E[25\136, +// key_f36=\E[26\136, +// key_f37=\E[28\136, +// key_f38=\E[29\136, +// key_f39=\E[31\136, +// key_f4=\E[14~, +// key_f40=\E[32\136, +// key_f41=\E[33\136, +// key_f42=\E[34\136, +// key_f43=\E[23@, +// key_f44=\E[24@, +// key_f5=\E[15~, +// key_f6=\E[17~, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_find=\E[1~, +// key_home=\E[7~, +// key_ic=\E[2~, +// key_left=\E[D, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\E[C, +// key_sdc=\E[3$, +// key_select=\E[4~, +// key_send=\E[8$, +// key_sf=\E[a, +// key_shome=\E[7$, +// key_sic=\E[2$, +// key_sleft=\E[d, +// key_snext=\E[6$, +// key_sprevious=\E[5$, +// key_sr=\E[b, +// key_sright=\E[c, +// key_up=\E[A, +// keypad_local=\E>, +// keypad_xmit=\E=, +// orig_colors=\E]104^G, +// orig_pair=\E[39;49m, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_up_cursor=\E[%p1%dA, +// reset_1string=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H, +// reset_2string=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>\E[?1000l\E[?25h, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set0_des_seq=\E(B, +// set1_des_seq=\E(0, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?1;2c, +// user9=\E[c, +static const int8_t rxvt_256colour_terminfo[] = { + 30,2,47,0,38,0,15,0,110,1,-31,4,114,120,118,116,45,50,53,54,99,111,108,111,114,124,114,120,118,116,32,50,46,55,46,57,32,119,105,116,104,32,120,116,101,114,109,32,50,53,54,45,99,111,108,111,114,115,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,-1,-1,0,0,2,0,4,0,21,0,26,0,34,0,38,0,42,0,-1,-1,53,0,70,0,72,0,76,0,83,0,-1,-1,85,0,92,0,-1,-1,96,0,-1,-1,-1,-1,100,0,-1,-1,-1,-1,104,0,106,0,111,0,116,0,-1,-1,-1,-1,125,0,-1,-1,-1,-1,-126,0,-121,0,-116,0,-1,-1,-111,0,-109,0,-104,0,-1,-1,-91,0,-86,0,-80,0,-74,0,-1,-1,-1,-1,-56,0,-42,0,-1,-1,-1,-1,-8,0,-4,0,-1,-1,0,1,-1,-1,-1,-1,-1,-1,2,1,-1,-1,7,1,-1,-1,11,1,-1,-1,16,1,22,1,28,1,34,1,40,1,46,1,52,1,58,1,64,1,70,1,76,1,82,1,87,1,-1,-1,92,1,-1,-1,96,1,101,1,106,1,110,1,114,1,-1,-1,118,1,122,1,125,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-128,1,-119,1,-110,1,-1,-1,-101,1,-92,1,-83,1,-1,-1,-74,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-65,1,-32,1,-1,-1,-1,-1,18,2,21,2,32,2,35,2,37,2,40,2,107,2,-1,-1,110,2,-1,-1,-1,-1,-1,-1,-1,-1,112,2,116,2,120,2,124,2,-128,2,-1,-1,-1,-1,-124,2,-1,-1,-73,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-69,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-62,2,-57,2,-1,-1,-53,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-48,2,-1,-1,-43,2,-38,2,-1,-1,-1,-1,-1,-1,-1,-1,-33,2,-28,2,-23,2,-1,-1,-1,-1,-19,2,-1,-1,-14,2,-1,-1,-1,-1,-1,-1,-9,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-5,2,1,3,7,3,13,3,19,3,25,3,31,3,37,3,43,3,49,3,55,3,61,3,67,3,73,3,79,3,85,3,91,3,97,3,103,3,109,3,115,3,121,3,127,3,-123,3,-117,3,-111,3,-105,3,-99,3,-93,3,-87,3,-81,3,-75,3,-69,3,-63,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-57,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-52,3,-41,3,-36,3,-28,3,-24,3,-15,3,-8,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,86,4,-1,-1,-1,-1,-1,-1,90,4,-103,4,-1,-1,-1,-1,-1,-1,-39,4,-35,4,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,77,0,14,0,27,91,53,109,0,27,91,49,109,0,27,55,27,91,63,52,55,104,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,50,74,27,91,63,52,55,108,27,56,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,63,52,55,108,27,61,27,91,63,49,108,0,27,91,114,27,91,109,27,91,50,74,27,91,72,27,91,63,55,104,27,91,63,49,59,51,59,52,59,54,108,27,91,52,108,0,27,91,64,0,27,91,76,0,8,0,27,91,51,126,0,27,91,66,0,27,91,56,94,0,27,91,50,49,126,0,27,91,49,49,126,0,27,91,50,49,126,0,27,91,49,50,126,0,27,91,49,51,126,0,27,91,49,52,126,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,55,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,97,0,27,91,98,0,27,91,65,0,27,62,0,27,61,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,62,27,91,49,59,51,59,52,59,53,59,54,108,27,91,63,55,104,27,91,109,27,91,114,27,91,50,74,27,91,72,0,27,91,114,27,91,109,27,91,50,74,27,91,72,27,91,63,55,104,27,91,63,49,59,51,59,52,59,54,108,27,91,52,108,27,62,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,79,119,0,27,79,121,0,27,79,117,0,27,79,113,0,27,79,115,0,96,96,97,97,102,102,103,103,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,40,66,27,41,48,0,27,91,56,126,0,27,79,77,0,27,91,49,126,0,27,91,51,36,0,27,91,52,126,0,27,91,56,36,0,27,91,55,36,0,27,91,50,36,0,27,91,100,0,27,91,54,36,0,27,91,53,36,0,27,91,99,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,50,51,36,0,27,91,50,52,36,0,27,91,49,49,94,0,27,91,49,50,94,0,27,91,49,51,94,0,27,91,49,52,94,0,27,91,49,53,94,0,27,91,49,55,94,0,27,91,49,56,94,0,27,91,49,57,94,0,27,91,50,48,94,0,27,91,50,49,94,0,27,91,50,51,94,0,27,91,50,52,94,0,27,91,50,53,94,0,27,91,50,54,94,0,27,91,50,56,94,0,27,91,50,57,94,0,27,91,51,49,94,0,27,91,51,50,94,0,27,91,51,51,94,0,27,91,51,52,94,0,27,91,50,51,64,0,27,91,50,52,64,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,49,59,50,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,40,66,0,27,40,48,0,0,2,0,0,0,25,0,52,0,-27,0,1,1,-1,-1,-1,-1,0,0,5,0,10,0,14,0,18,0,23,0,28,0,33,0,38,0,43,0,48,0,52,0,57,0,62,0,67,0,72,0,76,0,80,0,84,0,88,0,92,0,96,0,-1,-1,0,0,3,0,6,0,9,0,12,0,17,0,22,0,26,0,31,0,37,0,43,0,49,0,55,0,60,0,65,0,71,0,77,0,83,0,89,0,95,0,101,0,105,0,110,0,114,0,118,0,122,0,126,0,27,91,51,94,0,27,91,51,64,0,27,91,98,0,27,79,98,0,27,91,56,94,0,27,91,56,64,0,27,91,55,94,0,27,91,55,64,0,27,91,50,94,0,27,91,50,64,0,27,79,100,0,27,91,54,94,0,27,91,54,64,0,27,91,53,94,0,27,91,53,64,0,27,79,99,0,27,91,97,0,27,79,97,0,27,79,120,0,27,79,116,0,27,79,118,0,27,79,114,0,65,88,0,88,84,0,84,83,0,88,77,0,107,68,67,53,0,107,68,67,54,0,107,68,78,0,107,68,78,53,0,107,69,78,68,53,0,107,69,78,68,54,0,107,72,79,77,53,0,107,72,79,77,54,0,107,73,67,53,0,107,73,67,54,0,107,76,70,84,53,0,107,78,88,84,53,0,107,78,88,84,54,0,107,80,82,86,53,0,107,80,82,86,54,0,107,82,73,84,53,0,107,85,80,0,107,85,80,53,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 +}; + +// screen-256color|GNU Screen with 256 colors, +// auto_right_margin, +// backspaces_with_bs, +// eat_newline_glitch, +// has_hardware_tabs, +// has_meta_key, +// move_insert_mode, +// move_standout_mode, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// acs_chars=++\054\054--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[34h\E[?25h, +// cursor_right=\E[C, +// cursor_up=\EM, +// cursor_visible=\E[34l, +// delete_character=\E[P, +// delete_line=\E[M, +// ena_acs=\E(B\E)0, +// enter_alt_charset_mode=^N, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[?1049h, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_reverse_mode=\E[7m, +// enter_standout_mode=\E[3m, +// enter_underline_mode=\E[4m, +// exit_alt_charset_mode=^O, +// exit_attribute_mode=\E[m^O, +// exit_ca_mode=\E[?1049l, +// exit_insert_mode=\E[4l, +// exit_standout_mode=\E[23m, +// exit_underline_mode=\E[24m, +// flash_screen=\Eg, +// init_2string=\E)0, +// insert_line=\E[L, +// key_backspace=^H, +// key_btab=\E[Z, +// key_dc=\E[3~, +// key_down=\EOB, +// key_end=\E[4~, +// key_f1=\EOP, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f2=\EOQ, +// key_f3=\EOR, +// key_f4=\EOS, +// key_f5=\E[15~, +// key_f6=\E[17~, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\E[1~, +// key_ic=\E[2~, +// key_left=\EOD, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// newline=\EE, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_up_cursor=\E[%p1%dA, +// reset_2string=\Ec\E[?1000l\E[?25h, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=\E[0%?%p6%t;1%;%?%p1%t;3%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +static const int8_t screen_256colour_terminfo[] = { + 30,2,43,0,43,0,15,0,105,1,4,3,115,99,114,101,101,110,45,50,53,54,99,111,108,111,114,124,71,78,85,32,83,99,114,101,101,110,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,75,0,79,0,86,0,-1,-1,88,0,100,0,-1,-1,104,0,107,0,113,0,117,0,-1,-1,-1,-1,121,0,123,0,-128,0,-123,0,-1,-1,-114,0,-109,0,-1,-1,-1,-1,-104,0,-99,0,-94,0,-1,-1,-89,0,-87,0,-82,0,-1,-1,-73,0,-68,0,-62,0,-56,0,-1,-1,-1,-1,-1,-1,-53,0,-1,-1,-1,-1,-1,-1,-49,0,-1,-1,-45,0,-1,-1,-1,-1,-1,-1,-43,0,-1,-1,-38,0,-1,-1,-1,-1,-1,-1,-1,-1,-34,0,-30,0,-24,0,-20,0,-16,0,-12,0,-6,0,0,1,6,1,12,1,18,1,23,1,-1,-1,28,1,-1,-1,32,1,37,1,42,1,-1,-1,-1,-1,-1,-1,46,1,50,1,58,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,66,1,-1,-1,69,1,78,1,87,1,96,1,105,1,114,1,123,1,-124,1,-1,-1,-115,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-106,1,-1,-1,-1,-1,-89,1,-86,1,-75,1,-72,1,-70,1,-67,1,17,2,-1,-1,20,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,2,-1,-1,87,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,91,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,98,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,103,2,109,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,115,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,120,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-127,2,-1,-1,-1,-1,-1,-1,-123,2,-60,2,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,51,52,104,27,91,63,50,53,104,0,27,91,67,0,27,77,0,27,91,51,52,108,0,27,91,80,0,27,91,77,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,50,109,0,27,91,52,104,0,27,91,55,109,0,27,91,51,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,63,49,48,52,57,108,0,27,91,52,108,0,27,91,50,51,109,0,27,91,50,52,109,0,27,103,0,27,41,48,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,69,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,49,37,116,59,51,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,43,43,44,44,45,45,46,46,48,48,96,96,97,97,102,102,103,103,104,104,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,40,66,27,41,48,0,27,91,52,126,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,3,0,1,0,33,0,70,0,-71,0,1,1,0,0,1,0,0,0,0,0,4,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,29,0,34,0,39,0,44,0,49,0,53,0,58,0,63,0,68,0,73,0,78,0,84,0,90,0,96,0,102,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-102,0,-98,0,-94,0,-90,0,-86,0,27,40,66,0,27,40,37,112,49,37,99,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,83,48,0,84,83,0,88,77,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,53,0,107,72,79,77,53,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 +}; + +// st-256color|stterm-256color|simpleterm with 256 colors, +// auto_right_margin, +// back_color_erase, +// eat_newline_glitch, +// has_status_line, +// move_insert_mode, +// move_standout_mode, +// no_pad_char, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// acs_chars=+C\054D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[2J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[?12l\E[?25h, +// cursor_right=\E[C, +// cursor_up=\E[A, +// cursor_visible=\E[?25h, +// delete_character=\E[P, +// delete_line=\E[M, +// dis_status_line=\E]0;^G, +// ena_acs=\E)0, +// enter_alt_charset_mode=\E(0, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[?1049h, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_italics_mode=\E[3m, +// enter_reverse_mode=\E[7m, +// enter_secure_mode=\E[8m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// erase_chars=\E[%p1%dX, +// exit_alt_charset_mode=\E(B, +// exit_attribute_mode=\E[0m, +// exit_ca_mode=\E[?1049l, +// exit_insert_mode=\E[4l, +// exit_italics_mode=\E[23m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<100/>\E[?5l, +// from_status_line=^G, +// init_2string=\E[4l\E>\E[?1034l, +// initialize_color@, +// insert_line=\E[L, +// key_a1=\E[1~, +// key_a3=\E[5~, +// key_b2=\EOu, +// key_backspace=\177, +// key_c1=\E[4~, +// key_c3=\E[6~, +// key_clear=\E[3;5~, +// key_dc=\E[3~, +// key_dl=\E[3;2~, +// key_down=\EOB, +// key_eic=\E[2;2~, +// key_end=\E[4~, +// key_eol=\E[1;2F, +// key_eos=\E[1;5F, +// key_f1=\EOP, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[1;2P, +// key_f14=\E[1;2Q, +// key_f15=\E[1;2R, +// key_f16=\E[1;2S, +// key_f17=\E[15;2~, +// key_f18=\E[17;2~, +// key_f19=\E[18;2~, +// key_f2=\EOQ, +// key_f20=\E[19;2~, +// key_f21=\E[20;2~, +// key_f22=\E[21;2~, +// key_f23=\E[23;2~, +// key_f24=\E[24;2~, +// key_f25=\E[1;5P, +// key_f26=\E[1;5Q, +// key_f27=\E[1;5R, +// key_f28=\E[1;5S, +// key_f29=\E[15;5~, +// key_f3=\EOR, +// key_f30=\E[17;5~, +// key_f31=\E[18;5~, +// key_f32=\E[19;5~, +// key_f33=\E[20;5~, +// key_f34=\E[21;5~, +// key_f35=\E[23;5~, +// key_f36=\E[24;5~, +// key_f37=\E[1;6P, +// key_f38=\E[1;6Q, +// key_f39=\E[1;6R, +// key_f4=\EOS, +// key_f40=\E[1;6S, +// key_f41=\E[15;6~, +// key_f42=\E[17;6~, +// key_f43=\E[18;6~, +// key_f44=\E[19;6~, +// key_f45=\E[20;6~, +// key_f46=\E[21;6~, +// key_f47=\E[23;6~, +// key_f48=\E[24;6~, +// key_f49=\E[1;3P, +// key_f5=\E[15~, +// key_f50=\E[1;3Q, +// key_f51=\E[1;3R, +// key_f52=\E[1;3S, +// key_f53=\E[15;3~, +// key_f54=\E[17;3~, +// key_f55=\E[18;3~, +// key_f56=\E[19;3~, +// key_f57=\E[20;3~, +// key_f58=\E[21;3~, +// key_f59=\E[23;3~, +// key_f6=\E[17~, +// key_f60=\E[24;3~, +// key_f61=\E[1;4P, +// key_f62=\E[1;4Q, +// key_f63=\E[1;4R, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\E[1~, +// key_ic=\E[2~, +// key_il=\E[2;5~, +// key_left=\EOD, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_sdc=\E[3;2~, +// key_send=\E[1;2F, +// key_sf=\E[1;2B, +// key_shome=\E[1;2H, +// key_sic=\E[2;2~, +// key_sleft=\E[1;2D, +// key_snext=\E[6;2~, +// key_sprevious=\E[5;2~, +// key_sr=\E[1;2A, +// key_sright=\E[1;2C, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// orig_colors@, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_up_cursor=\E[%p1%dA, +// print_screen=\E[i, +// prtr_off=\E[4i, +// prtr_on=\E[5i, +// reset_1string=\Ec, +// reset_2string=\E[4l\E>\E[?1034l, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m, +// set_tab=\EH, +// tab=^I, +// to_status_line=\E]0;, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?1;2c, +// user9=\E[c, +static const int8_t st_256colour_terminfo[] = { + 30,2,55,0,29,0,15,0,105,1,-125,5,115,116,45,50,53,54,99,111,108,111,114,124,115,116,116,101,114,109,45,50,53,54,99,111,108,111,114,124,115,105,109,112,108,101,116,101,114,109,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,102,0,-1,-1,106,0,110,0,117,0,121,0,125,0,-1,-1,-125,0,-121,0,-116,0,-111,0,-1,-1,-102,0,-97,0,-92,0,-1,-1,-87,0,-82,0,-77,0,-72,0,-63,0,-59,0,-54,0,-1,-1,-45,0,-40,0,-34,0,-28,0,-1,-1,-10,0,-1,-1,-8,0,-1,-1,-1,-1,-1,-1,7,1,-1,-1,11,1,-1,-1,13,1,-1,-1,20,1,25,1,32,1,36,1,43,1,50,1,-1,-1,57,1,61,1,67,1,71,1,75,1,79,1,85,1,91,1,97,1,103,1,109,1,114,1,119,1,126,1,-1,-1,-126,1,-121,1,-116,1,-112,1,-105,1,-1,-1,-98,1,-94,1,-86,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-78,1,-69,1,-60,1,-51,1,-42,1,-33,1,-24,1,-15,1,-1,-1,-6,1,-1,-1,-1,-1,-1,-1,3,2,7,2,12,2,-1,-1,17,2,20,2,-1,-1,-1,-1,35,2,38,2,49,2,52,2,54,2,57,2,-106,2,-1,-1,-103,2,-101,2,-1,-1,-1,-1,-1,-1,-96,2,-91,2,-86,2,-82,2,-77,2,-1,-1,-1,-1,-72,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-7,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,3,-1,-1,-1,-1,9,3,-1,-1,-1,-1,-1,-1,-1,-1,16,3,23,3,30,3,-1,-1,-1,-1,37,3,-1,-1,44,3,-1,-1,-1,-1,-1,-1,51,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,58,3,64,3,70,3,77,3,84,3,91,3,98,3,106,3,114,3,122,3,-126,3,-118,3,-110,3,-102,3,-94,3,-87,3,-80,3,-73,3,-66,3,-58,3,-50,3,-42,3,-34,3,-26,3,-18,3,-10,3,-2,3,5,4,12,4,19,4,26,4,34,4,42,4,50,4,58,4,66,4,74,4,82,4,90,4,97,4,104,4,111,4,118,4,126,4,-122,4,-114,4,-106,4,-98,4,-90,4,-82,4,-74,4,-67,4,-60,4,-53,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-48,4,-37,4,-32,4,-24,4,-20,4,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-11,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-6,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,5,-1,-1,-1,-1,-1,-1,4,5,67,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,63,50,53,104,0,27,91,80,0,27,91,77,0,27,93,48,59,7,0,27,40,48,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,91,48,109,0,27,91,63,49,48,52,57,108,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,7,0,27,91,52,108,27,62,27,91,63,49,48,51,52,108,0,27,91,76,0,127,0,27,91,51,59,53,126,0,27,91,51,126,0,27,91,51,59,50,126,0,27,79,66,0,27,91,50,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,53,70,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,50,59,53,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,91,105,0,27,91,52,105,0,27,91,53,105,0,27,99,0,27,91,52,108,27,62,27,91,63,49,48,51,52,108,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,37,63,37,112,57,37,116,27,40,48,37,101,27,40,66,37,59,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,55,37,116,59,56,37,59,109,0,27,72,0,9,0,27,93,48,59,0,27,91,49,126,0,27,91,53,126,0,27,79,117,0,27,91,52,126,0,27,91,54,126,0,43,67,44,68,45,65,46,66,48,69,96,96,97,97,102,102,103,103,104,70,105,71,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,41,48,0,27,91,52,126,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,49,59,50,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,3,0,1,0,71,0,-110,0,-1,1,0,0,1,0,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,18,0,24,0,34,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,39,0,-1,-1,46,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,53,0,-1,-1,60,0,-1,-1,-1,-1,67,0,-1,-1,74,0,-1,-1,-1,-1,81,0,-1,-1,88,0,-1,-1,-1,-1,95,0,-1,-1,102,0,-1,-1,-1,-1,-1,-1,109,0,-1,-1,116,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,123,0,-127,0,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,42,0,48,0,53,0,58,0,63,0,68,0,73,0,77,0,82,0,87,0,92,0,97,0,102,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-77,0,-72,0,-67,0,-62,0,-57,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,67,1,72,1,77,1,82,1,87,1,92,1,96,1,100,1,104,1,108,1,113,1,118,1,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,93,48,59,0,27,91,49,59,51,66,0,27,91,49,59,53,66,0,27,91,49,59,51,68,0,27,91,49,59,53,68,0,27,91,54,59,51,126,0,27,91,54,59,53,126,0,27,91,53,59,51,126,0,27,91,53,59,53,126,0,27,91,49,59,51,67,0,27,91,49,59,53,67,0,27,91,49,59,51,65,0,27,91,49,59,53,65,0,27,91,50,57,109,0,27,91,57,109,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 +}; + +// tmux-256color|tmux with 256 colors, +// auto_right_margin, +// backspaces_with_bs, +// eat_newline_glitch, +// has_hardware_tabs, +// has_meta_key, +// has_status_line, +// move_insert_mode, +// move_standout_mode, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// acs_chars=++\054\054--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[34h\E[?25h, +// cursor_right=\E[C, +// cursor_up=\EM, +// cursor_visible=\E[34l, +// delete_character=\E[P, +// delete_line=\E[M, +// dis_status_line=\E]0;^G, +// ena_acs=\E(B\E)0, +// enter_alt_charset_mode=^N, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[?1049h, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_italics_mode=\E[3m, +// enter_reverse_mode=\E[7m, +// enter_secure_mode=\E[8m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// exit_alt_charset_mode=^O, +// exit_attribute_mode=\E[m^O, +// exit_ca_mode=\E[?1049l, +// exit_insert_mode=\E[4l, +// exit_italics_mode=\E[23m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\Eg, +// from_status_line=^G, +// init_2string=\E)0, +// insert_line=\E[L, +// key_backspace=^H, +// key_btab=\E[Z, +// key_dc=\E[3~, +// key_down=\EOB, +// key_end=\E[4~, +// key_f1=\EOP, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[1;2P, +// key_f14=\E[1;2Q, +// key_f15=\E[1;2R, +// key_f16=\E[1;2S, +// key_f17=\E[15;2~, +// key_f18=\E[17;2~, +// key_f19=\E[18;2~, +// key_f2=\EOQ, +// key_f20=\E[19;2~, +// key_f21=\E[20;2~, +// key_f22=\E[21;2~, +// key_f23=\E[23;2~, +// key_f24=\E[24;2~, +// key_f25=\E[1;5P, +// key_f26=\E[1;5Q, +// key_f27=\E[1;5R, +// key_f28=\E[1;5S, +// key_f29=\E[15;5~, +// key_f3=\EOR, +// key_f30=\E[17;5~, +// key_f31=\E[18;5~, +// key_f32=\E[19;5~, +// key_f33=\E[20;5~, +// key_f34=\E[21;5~, +// key_f35=\E[23;5~, +// key_f36=\E[24;5~, +// key_f37=\E[1;6P, +// key_f38=\E[1;6Q, +// key_f39=\E[1;6R, +// key_f4=\EOS, +// key_f40=\E[1;6S, +// key_f41=\E[15;6~, +// key_f42=\E[17;6~, +// key_f43=\E[18;6~, +// key_f44=\E[19;6~, +// key_f45=\E[20;6~, +// key_f46=\E[21;6~, +// key_f47=\E[23;6~, +// key_f48=\E[24;6~, +// key_f49=\E[1;3P, +// key_f5=\E[15~, +// key_f50=\E[1;3Q, +// key_f51=\E[1;3R, +// key_f52=\E[1;3S, +// key_f53=\E[15;3~, +// key_f54=\E[17;3~, +// key_f55=\E[18;3~, +// key_f56=\E[19;3~, +// key_f57=\E[20;3~, +// key_f58=\E[21;3~, +// key_f59=\E[23;3~, +// key_f6=\E[17~, +// key_f60=\E[24;3~, +// key_f61=\E[1;4P, +// key_f62=\E[1;4Q, +// key_f63=\E[1;4R, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\E[1~, +// key_ic=\E[2~, +// key_left=\EOD, +// key_mouse=\E[M, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_sdc=\E[3;2~, +// key_send=\E[1;2F, +// key_sf=\E[1;2B, +// key_shome=\E[1;2H, +// key_sic=\E[2;2~, +// key_sleft=\E[1;2D, +// key_snext=\E[6;2~, +// key_sprevious=\E[5;2~, +// key_sr=\E[1;2A, +// key_sright=\E[1;2C, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// newline=\EE, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_up_cursor=\E[%p1%dA, +// reset_2string=\Ec\E[?1000l\E[?25h, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +// to_status_line=\E]0;, +static const int8_t tmux_256colour_terminfo[] = { + 30,2,35,0,43,0,15,0,105,1,-15,4,116,109,117,120,45,50,53,54,99,111,108,111,114,124,116,109,117,120,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,75,0,79,0,86,0,-1,-1,88,0,100,0,-1,-1,104,0,107,0,113,0,117,0,121,0,-1,-1,127,0,-127,0,-122,0,-117,0,-1,-1,-108,0,-103,0,-98,0,-1,-1,-93,0,-88,0,-83,0,-1,-1,-78,0,-76,0,-71,0,-1,-1,-62,0,-57,0,-51,0,-45,0,-1,-1,-42,0,-1,-1,-40,0,-1,-1,-1,-1,-1,-1,-36,0,-1,-1,-32,0,-1,-1,-1,-1,-1,-1,-30,0,-1,-1,-25,0,-1,-1,-1,-1,-1,-1,-1,-1,-21,0,-17,0,-11,0,-7,0,-3,0,1,1,7,1,13,1,19,1,25,1,31,1,36,1,-1,-1,41,1,-1,-1,45,1,50,1,55,1,59,1,66,1,-1,-1,73,1,77,1,85,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,93,1,-1,-1,96,1,105,1,114,1,123,1,-124,1,-115,1,-106,1,-97,1,-1,-1,-88,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-79,1,-1,-1,-1,-1,-62,1,-59,1,-48,1,-45,1,-43,1,-40,1,49,2,-1,-1,52,2,54,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,59,2,-1,-1,124,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-128,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-121,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-116,2,-1,-1,-1,-1,-109,2,-1,-1,-1,-1,-1,-1,-1,-1,-102,2,-95,2,-88,2,-1,-1,-1,-1,-81,2,-1,-1,-74,2,-1,-1,-1,-1,-1,-1,-67,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-60,2,-54,2,-48,2,-41,2,-34,2,-27,2,-20,2,-12,2,-4,2,4,3,12,3,20,3,28,3,36,3,44,3,51,3,58,3,65,3,72,3,80,3,88,3,96,3,104,3,112,3,120,3,-128,3,-120,3,-113,3,-106,3,-99,3,-92,3,-84,3,-76,3,-68,3,-60,3,-52,3,-44,3,-36,3,-28,3,-21,3,-14,3,-7,3,0,4,8,4,16,4,24,4,32,4,40,4,48,4,56,4,64,4,71,4,78,4,85,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,90,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,99,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,104,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,110,4,-1,-1,-1,-1,-1,-1,114,4,-79,4,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,51,52,104,27,91,63,50,53,104,0,27,91,67,0,27,77,0,27,91,51,52,108,0,27,91,80,0,27,91,77,0,27,93,48,59,7,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,63,49,48,52,57,108,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,103,0,7,0,27,41,48,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,69,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,55,37,116,59,56,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,93,48,59,0,43,43,44,44,45,45,46,46,48,48,96,96,97,97,102,102,103,103,104,104,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,40,66,27,41,48,0,27,91,52,126,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,3,0,1,0,73,0,-106,0,65,3,1,1,0,0,1,0,0,0,0,0,7,0,19,0,23,0,28,0,46,0,54,0,60,0,70,0,-1,-1,-1,-1,-1,-1,75,0,82,0,89,0,96,0,103,0,110,0,117,0,124,0,-125,0,-118,0,-111,0,-104,0,-97,0,-90,0,-83,0,-76,0,-1,-1,-69,0,-62,0,-55,0,-48,0,-41,0,-1,-1,-34,0,-27,0,-20,0,-13,0,-6,0,1,1,8,1,15,1,22,1,29,1,36,1,43,1,50,1,57,1,64,1,71,1,78,1,85,1,92,1,99,1,106,1,113,1,120,1,127,1,-122,1,-115,1,-108,1,-101,1,-94,1,-87,1,-80,1,-1,-1,-1,-1,-1,-1,-1,-1,-73,1,-67,1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,93,49,49,50,7,0,27,93,49,50,59,37,112,49,37,115,7,0,27,40,66,0,27,91,51,74,0,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,40,37,112,49,37,99,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,93,48,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 +}; + +// vte-256color|VTE with xterm 256-colors, +// auto_right_margin, +// back_color_erase, +// backspaces_with_bs, +// can_change, +// eat_newline_glitch, +// move_insert_mode, +// move_standout_mode, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// acs_chars=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[2J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[?25h, +// cursor_right=\E[C, +// cursor_up=\E[A, +// delete_character=\E[P, +// delete_line=\E[M, +// ena_acs=\E)0, +// enter_alt_charset_mode=^N, +// enter_am_mode=\E[?7h, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E7\E[?47h, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_italics_mode=\E[3m, +// enter_reverse_mode=\E[7m, +// enter_secure_mode=\E[8m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// erase_chars=\E[%p1%dX, +// exit_alt_charset_mode=^O, +// exit_am_mode=\E[?7l, +// exit_attribute_mode=\E[0m^O, +// exit_ca_mode=\E[2J\E[?47l\E8, +// exit_insert_mode=\E[4l, +// exit_italics_mode=\E[23m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<100/>\E[?5l, +// init_2string=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8, +// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\, +// insert_line=\E[L, +// key_b2=\E[E, +// key_backspace=\177, +// key_btab=\E[Z, +// key_dc=\E[3~, +// key_down=\EOB, +// key_end=\EOF, +// key_enter=\EOM, +// key_f1=\EOP, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[1;2P, +// key_f14=\E[1;2Q, +// key_f15=\E[1;2R, +// key_f16=\E[1;2S, +// key_f17=\E[15;2~, +// key_f18=\E[17;2~, +// key_f19=\E[18;2~, +// key_f2=\EOQ, +// key_f20=\E[19;2~, +// key_f21=\E[20;2~, +// key_f22=\E[21;2~, +// key_f23=\E[23;2~, +// key_f24=\E[24;2~, +// key_f25=\E[1;5P, +// key_f26=\E[1;5Q, +// key_f27=\E[1;5R, +// key_f28=\E[1;5S, +// key_f29=\E[15;5~, +// key_f3=\EOR, +// key_f30=\E[17;5~, +// key_f31=\E[18;5~, +// key_f32=\E[19;5~, +// key_f33=\E[20;5~, +// key_f34=\E[21;5~, +// key_f35=\E[23;5~, +// key_f36=\E[24;5~, +// key_f37=\E[1;6P, +// key_f38=\E[1;6Q, +// key_f39=\E[1;6R, +// key_f4=\EOS, +// key_f40=\E[1;6S, +// key_f41=\E[15;6~, +// key_f42=\E[17;6~, +// key_f43=\E[18;6~, +// key_f44=\E[19;6~, +// key_f45=\E[20;6~, +// key_f46=\E[21;6~, +// key_f47=\E[23;6~, +// key_f48=\E[24;6~, +// key_f49=\E[1;3P, +// key_f5=\E[15~, +// key_f50=\E[1;3Q, +// key_f51=\E[1;3R, +// key_f52=\E[1;3S, +// key_f53=\E[15;3~, +// key_f54=\E[17;3~, +// key_f55=\E[18;3~, +// key_f56=\E[19;3~, +// key_f57=\E[20;3~, +// key_f58=\E[21;3~, +// key_f59=\E[23;3~, +// key_f6=\E[17~, +// key_f60=\E[24;3~, +// key_f61=\E[1;4P, +// key_f62=\E[1;4Q, +// key_f63=\E[1;4R, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_find=\E[1~, +// key_home=\EOH, +// key_ic=\E[2~, +// key_left=\EOD, +// key_mouse=\E[<, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_sdc=\E[3;2~, +// key_select=\E[4~, +// key_send=\E[1;2F, +// key_sf=\E[1;2B, +// key_shome=\E[1;2H, +// key_sic=\E[2;2~, +// key_sleft=\E[1;2D, +// key_snext=\E[6;2~, +// key_sprevious=\E[5;2~, +// key_sr=\E[1;2A, +// key_sright=\E[1;2C, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// memory_lock=\El, +// memory_unlock=\Em, +// orig_colors=\E]104^G, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_rindex=\E[%p1%dT, +// parm_up_cursor=\E[%p1%dA, +// reset_1string=\Ec, +// reset_2string=\E7\E[r\E8\E[m\E[?7h\E[\041p\E[?1;3;4;6l\E[4l\E>\E[?1000l\E[?25h, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p5%t;2%;%?%p7%t;8%;%?%p1%p3%|%t;7%;m%?%p9%t^N%e^O%;, +// set_tab=\EH, +// tab=^I, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?%[;0123456789]c, +// user9=\E[c, +static const int8_t vte_256colour_terminfo[] = { + 30,2,39,0,38,0,15,0,-99,1,-49,5,118,116,101,45,50,53,54,99,111,108,111,114,124,86,84,69,32,119,105,116,104,32,120,116,101,114,109,32,50,53,54,45,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,96,0,-1,-1,100,0,-1,-1,104,0,108,0,-1,-1,-1,-1,112,0,-1,-1,114,0,119,0,-1,-1,-128,0,-123,0,-118,0,-1,-1,-113,0,-108,0,-103,0,-98,0,-89,0,-87,0,-81,0,-1,-1,-68,0,-63,0,-57,0,-51,0,-1,-1,-1,-1,-1,-1,-33,0,-1,-1,-1,-1,-1,-1,0,1,-1,-1,4,1,-1,-1,-1,-1,-1,-1,6,1,-1,-1,11,1,-1,-1,-1,-1,-1,-1,-1,-1,15,1,19,1,25,1,29,1,33,1,37,1,43,1,49,1,55,1,61,1,67,1,71,1,-1,-1,76,1,-1,-1,80,1,85,1,90,1,94,1,101,1,-1,-1,108,1,112,1,120,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-128,1,-119,1,-110,1,-101,1,-92,1,-83,1,-74,1,-65,1,-56,1,-47,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-38,1,-35,1,-1,-1,-1,-1,16,2,19,2,30,2,33,2,35,2,38,2,116,2,-1,-1,119,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,121,2,-1,-1,-1,-1,-1,-1,-1,-1,125,2,-1,-1,-78,2,-1,-1,-1,-1,-74,2,-68,2,-1,-1,-1,-1,-62,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-58,2,-54,2,-1,-1,-50,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-45,2,-1,-1,-38,2,-33,2,-1,-1,-1,-1,-1,-1,-1,-1,-26,2,-19,2,-12,2,-1,-1,-1,-1,-5,2,-1,-1,2,3,-1,-1,-1,-1,-1,-1,9,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,3,22,3,28,3,35,3,42,3,49,3,56,3,64,3,72,3,80,3,88,3,96,3,104,3,112,3,120,3,127,3,-122,3,-115,3,-108,3,-100,3,-92,3,-84,3,-76,3,-68,3,-60,3,-52,3,-44,3,-37,3,-30,3,-23,3,-16,3,-8,3,0,4,8,4,16,4,24,4,32,4,40,4,48,4,55,4,62,4,69,4,76,4,84,4,92,4,100,4,108,4,116,4,124,4,-124,4,-116,4,-109,4,-102,4,-95,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-90,4,-79,4,-74,4,-55,4,-51,4,-42,4,-35,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,59,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,64,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,70,5,-1,-1,-1,-1,-1,-1,74,5,-119,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-55,5,-52,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,14,0,27,91,49,109,0,27,55,27,91,63,52,55,104,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,15,0,27,91,48,109,15,0,27,91,50,74,27,91,63,52,55,108,27,56,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,109,27,91,63,55,104,27,91,52,108,27,62,27,55,27,91,114,27,91,63,49,59,51,59,52,59,54,108,27,56,0,27,91,76,0,127,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,99,0,27,55,27,91,114,27,56,27,91,109,27,91,63,55,104,27,91,33,112,27,91,63,49,59,51,59,52,59,54,108,27,91,52,108,27,62,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,55,37,116,59,56,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,91,69,0,96,96,97,97,102,102,103,103,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,41,48,0,27,79,70,0,27,79,77,0,27,91,49,126,0,27,91,51,59,50,126,0,27,91,52,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,51,109,0,27,91,50,51,109,0,27,91,60,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,108,0,27,109,0,0,3,0,1,0,73,0,-106,0,57,3,0,0,1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,-1,-1,32,0,39,0,46,0,53,0,60,0,67,0,74,0,81,0,88,0,95,0,102,0,109,0,116,0,123,0,-126,0,-119,0,-1,-1,-112,0,-105,0,-98,0,-91,0,-84,0,-1,-1,-77,0,-70,0,-63,0,-56,0,-49,0,-42,0,-35,0,-28,0,-21,0,-14,0,-7,0,0,1,7,1,14,1,21,1,28,1,35,1,42,1,49,1,56,1,63,1,70,1,77,1,84,1,91,1,98,1,105,1,112,1,119,1,126,1,-123,1,-1,-1,-1,-1,-1,-1,-1,-1,-116,1,-110,1,-105,1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,91,63,49,48,48,54,59,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,27,91,60,37,112,49,37,100,59,37,112,50,37,100,59,37,112,51,37,100,59,37,63,37,112,52,37,116,77,37,101,109,37,59,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 +}; + +// xterm-256color|xterm with 256 colors, +// auto_right_margin, +// back_color_erase, +// backspaces_with_bs, +// can_change, +// eat_newline_glitch, +// has_meta_key, +// move_insert_mode, +// move_standout_mode, +// no_pad_char, +// prtr_silent, +// columns#80, +// init_tabs#8, +// lines#24, +// max_colors#0x100, +// max_pairs#0x10000, +// acs_chars=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, +// back_tab=\E[Z, +// bell=^G, +// carriage_return=\r, +// change_scroll_region=\E[%i%p1%d;%p2%dr, +// clear_all_tabs=\E[3g, +// clear_screen=\E[H\E[2J, +// clr_bol=\E[1K, +// clr_eol=\E[K, +// clr_eos=\E[J, +// column_address=\E[%i%p1%dG, +// cursor_address=\E[%i%p1%d;%p2%dH, +// cursor_down=\n, +// cursor_home=\E[H, +// cursor_invisible=\E[?25l, +// cursor_left=^H, +// cursor_normal=\E[?12l\E[?25h, +// cursor_right=\E[C, +// cursor_up=\E[A, +// cursor_visible=\E[?12;25h, +// delete_character=\E[P, +// delete_line=\E[M, +// enter_alt_charset_mode=\E(0, +// enter_am_mode=\E[?7h, +// enter_blink_mode=\E[5m, +// enter_bold_mode=\E[1m, +// enter_ca_mode=\E[?1049h\E[22;0;0t, +// enter_dim_mode=\E[2m, +// enter_insert_mode=\E[4h, +// enter_italics_mode=\E[3m, +// enter_reverse_mode=\E[7m, +// enter_secure_mode=\E[8m, +// enter_standout_mode=\E[7m, +// enter_underline_mode=\E[4m, +// erase_chars=\E[%p1%dX, +// exit_alt_charset_mode=\E(B, +// exit_am_mode=\E[?7l, +// exit_attribute_mode=\E(B\E[m, +// exit_ca_mode=\E[?1049l\E[23;0;0t, +// exit_insert_mode=\E[4l, +// exit_italics_mode=\E[23m, +// exit_standout_mode=\E[27m, +// exit_underline_mode=\E[24m, +// flash_screen=\E[?5h$<100/>\E[?5l, +// init_2string=\E[\041p\E[?3;4l\E[4l\E>, +// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\, +// insert_line=\E[L, +// key_b2=\EOE, +// key_backspace=^H, +// key_btab=\E[Z, +// key_dc=\E[3~, +// key_down=\EOB, +// key_end=\EOF, +// key_enter=\EOM, +// key_f1=\EOP, +// key_f10=\E[21~, +// key_f11=\E[23~, +// key_f12=\E[24~, +// key_f13=\E[1;2P, +// key_f14=\E[1;2Q, +// key_f15=\E[1;2R, +// key_f16=\E[1;2S, +// key_f17=\E[15;2~, +// key_f18=\E[17;2~, +// key_f19=\E[18;2~, +// key_f2=\EOQ, +// key_f20=\E[19;2~, +// key_f21=\E[20;2~, +// key_f22=\E[21;2~, +// key_f23=\E[23;2~, +// key_f24=\E[24;2~, +// key_f25=\E[1;5P, +// key_f26=\E[1;5Q, +// key_f27=\E[1;5R, +// key_f28=\E[1;5S, +// key_f29=\E[15;5~, +// key_f3=\EOR, +// key_f30=\E[17;5~, +// key_f31=\E[18;5~, +// key_f32=\E[19;5~, +// key_f33=\E[20;5~, +// key_f34=\E[21;5~, +// key_f35=\E[23;5~, +// key_f36=\E[24;5~, +// key_f37=\E[1;6P, +// key_f38=\E[1;6Q, +// key_f39=\E[1;6R, +// key_f4=\EOS, +// key_f40=\E[1;6S, +// key_f41=\E[15;6~, +// key_f42=\E[17;6~, +// key_f43=\E[18;6~, +// key_f44=\E[19;6~, +// key_f45=\E[20;6~, +// key_f46=\E[21;6~, +// key_f47=\E[23;6~, +// key_f48=\E[24;6~, +// key_f49=\E[1;3P, +// key_f5=\E[15~, +// key_f50=\E[1;3Q, +// key_f51=\E[1;3R, +// key_f52=\E[1;3S, +// key_f53=\E[15;3~, +// key_f54=\E[17;3~, +// key_f55=\E[18;3~, +// key_f56=\E[19;3~, +// key_f57=\E[20;3~, +// key_f58=\E[21;3~, +// key_f59=\E[23;3~, +// key_f6=\E[17~, +// key_f60=\E[24;3~, +// key_f61=\E[1;4P, +// key_f62=\E[1;4Q, +// key_f63=\E[1;4R, +// key_f7=\E[18~, +// key_f8=\E[19~, +// key_f9=\E[20~, +// key_home=\EOH, +// key_ic=\E[2~, +// key_left=\EOD, +// key_mouse=\E[<, +// key_npage=\E[6~, +// key_ppage=\E[5~, +// key_right=\EOC, +// key_sdc=\E[3;2~, +// key_send=\E[1;2F, +// key_sf=\E[1;2B, +// key_shome=\E[1;2H, +// key_sic=\E[2;2~, +// key_sleft=\E[1;2D, +// key_snext=\E[6;2~, +// key_sprevious=\E[5;2~, +// key_sr=\E[1;2A, +// key_sright=\E[1;2C, +// key_up=\EOA, +// keypad_local=\E[?1l\E>, +// keypad_xmit=\E[?1h\E=, +// memory_lock=\El, +// memory_unlock=\Em, +// meta_off=\E[?1034l, +// meta_on=\E[?1034h, +// orig_colors=\E]104^G, +// orig_pair=\E[39;49m, +// parm_dch=\E[%p1%dP, +// parm_delete_line=\E[%p1%dM, +// parm_down_cursor=\E[%p1%dB, +// parm_ich=\E[%p1%d@, +// parm_index=\E[%p1%dS, +// parm_insert_line=\E[%p1%dL, +// parm_left_cursor=\E[%p1%dD, +// parm_right_cursor=\E[%p1%dC, +// parm_rindex=\E[%p1%dT, +// parm_up_cursor=\E[%p1%dA, +// print_screen=\E[i, +// prtr_off=\E[4i, +// prtr_on=\E[5i, +// repeat_char=%p1%c\E[%p2%{1}%-%db, +// reset_1string=\Ec\E]104^G, +// reset_2string=\E[\041p\E[?3;4l\E[4l\E>, +// restore_cursor=\E8, +// row_address=\E[%i%p1%dd, +// save_cursor=\E7, +// scroll_forward=\n, +// scroll_reverse=\EM, +// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, +// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, +// set_attributes=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, +// set_tab=\EH, +// tab=^I, +// user6=\E[%i%d;%dR, +// user7=\E[6n, +// user8=\E[?%[;0123456789]c, +// user9=\E[c, +static const int8_t xterm_256colour_terminfo[] = { + 30,2,37,0,38,0,15,0,-99,1,2,6,120,116,101,114,109,45,50,53,54,99,111,108,111,114,124,120,116,101,114,109,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,102,0,-1,-1,106,0,110,0,120,0,124,0,-1,-1,-1,-1,-128,0,-124,0,-119,0,-114,0,-1,-1,-96,0,-91,0,-86,0,-1,-1,-81,0,-76,0,-71,0,-66,0,-57,0,-53,0,-46,0,-1,-1,-28,0,-23,0,-17,0,-11,0,-1,-1,-1,-1,-1,-1,7,1,-1,-1,-1,-1,-1,-1,25,1,-1,-1,29,1,-1,-1,-1,-1,-1,-1,31,1,-1,-1,36,1,-1,-1,-1,-1,-1,-1,-1,-1,40,1,44,1,50,1,54,1,58,1,62,1,68,1,74,1,80,1,86,1,92,1,96,1,-1,-1,101,1,-1,-1,105,1,110,1,115,1,119,1,126,1,-1,-1,-123,1,-119,1,-111,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-103,1,-94,1,-1,-1,-1,-1,-85,1,-76,1,-67,1,-58,1,-49,1,-40,1,-31,1,-22,1,-13,1,-4,1,-1,-1,-1,-1,-1,-1,5,2,9,2,14,2,19,2,39,2,48,2,-1,-1,-1,-1,66,2,69,2,80,2,83,2,85,2,88,2,-75,2,-1,-1,-72,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-70,2,-1,-1,-1,-1,-1,-1,-1,-1,-66,2,-1,-1,-13,2,-1,-1,-1,-1,-9,2,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,3,7,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,3,-1,-1,-1,-1,18,3,-1,-1,-1,-1,-1,-1,-1,-1,25,3,32,3,39,3,-1,-1,-1,-1,46,3,-1,-1,53,3,-1,-1,-1,-1,-1,-1,60,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,67,3,73,3,79,3,86,3,93,3,100,3,107,3,115,3,123,3,-125,3,-117,3,-109,3,-101,3,-93,3,-85,3,-78,3,-71,3,-64,3,-57,3,-49,3,-41,3,-33,3,-25,3,-17,3,-9,3,-1,3,7,4,14,4,21,4,28,4,35,4,43,4,51,4,59,4,67,4,75,4,83,4,91,4,99,4,106,4,113,4,120,4,127,4,-121,4,-113,4,-105,4,-97,4,-89,4,-81,4,-73,4,-65,4,-58,4,-51,4,-44,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-39,4,-28,4,-23,4,-4,4,0,5,9,5,16,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,110,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,115,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,121,5,-1,-1,-1,-1,-1,-1,125,5,-68,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-4,5,-1,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,63,49,50,59,50,53,104,0,27,91,80,0,27,91,77,0,27,40,48,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,27,91,50,50,59,48,59,48,116,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,40,66,27,91,109,0,27,91,63,49,48,52,57,108,27,91,50,51,59,48,59,48,116,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,63,49,48,51,52,108,0,27,91,63,49,48,51,52,104,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,105,0,27,91,52,105,0,27,91,53,105,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,99,27,93,49,48,52,7,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,37,63,37,112,57,37,116,27,40,48,37,101,27,40,66,37,59,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,55,37,116,59,56,37,59,109,0,27,72,0,9,0,27,79,69,0,96,96,97,97,102,102,103,103,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,79,70,0,27,79,77,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,51,109,0,27,91,50,51,109,0,27,91,60,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,108,0,27,109,0,3,0,1,0,73,0,-106,0,115,3,1,0,1,0,-1,-1,-1,-1,0,0,7,0,-1,-1,19,0,24,0,-1,-1,42,0,48,0,-1,-1,58,0,-1,-1,-1,-1,90,0,97,0,104,0,111,0,118,0,125,0,-124,0,-117,0,-110,0,-103,0,-96,0,-89,0,-82,0,-75,0,-68,0,-61,0,-1,-1,-54,0,-47,0,-40,0,-33,0,-26,0,-1,-1,-19,0,-12,0,-5,0,2,1,9,1,16,1,23,1,30,1,37,1,44,1,51,1,58,1,65,1,72,1,79,1,86,1,93,1,100,1,107,1,114,1,121,1,-128,1,-121,1,-114,1,-107,1,-100,1,-93,1,-86,1,-79,1,-72,1,-65,1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-52,1,-47,1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,93,49,49,50,7,0,27,93,49,50,59,37,112,49,37,115,7,0,27,91,51,74,0,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,91,63,49,48,48,54,59,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,27,91,60,37,112,49,37,100,59,37,112,50,37,100,59,37,112,51,37,100,59,37,63,37,112,52,37,116,77,37,101,109,37,59,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 +}; +#endif // NVIM_TUI_TERMINFO_DEFS_H diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index f41c715696..b6986b77e9 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -20,6 +20,7 @@ #include "nvim/vim.h" #include "nvim/log.h" #include "nvim/ui.h" +#include "nvim/highlight.h" #include "nvim/map.h" #include "nvim/main.h" #include "nvim/memory.h" @@ -31,13 +32,13 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/strings.h" +#include "nvim/syntax.h" #include "nvim/ui_bridge.h" #include "nvim/ugrid.h" #include "nvim/tui/input.h" #include "nvim/tui/tui.h" #include "nvim/tui/terminfo.h" #include "nvim/cursor_shape.h" -#include "nvim/syntax.h" #include "nvim/macros.h" // Space reserved in two output buffers to make the cursor normal or invisible @@ -87,17 +88,24 @@ typedef struct { bool cont_received; UGrid grid; kvec_t(Rect) invalid_regions; + int row, col; int out_fd; bool scroll_region_is_full_screen; bool can_change_scroll_region; bool can_set_lr_margin; bool can_set_left_right_margin; + bool can_erase_chars; bool immediate_wrap_after_last_column; + bool bce; bool mouse_enabled; bool busy, is_invisible; bool cork, overflow; + bool cursor_color_changed; cursorentry_T cursor_shapes[SHAPE_IDX_COUNT]; - HlAttrs print_attrs; + HlAttrs clear_attrs; + kvec_t(HlAttrs) attrs; + int print_attr_id; + bool has_bg; bool default_attr; ModeShape showing_mode; struct { @@ -106,11 +114,14 @@ typedef struct { int enable_lr_margin, disable_lr_margin; int set_rgb_foreground, set_rgb_background; int set_cursor_color; + int reset_cursor_color; int enable_focus_reporting, disable_focus_reporting; int resize_screen; int reset_scroll_region; int set_cursor_style, reset_cursor_style; + int enter_undercurl_mode, exit_undercurl_mode, set_underline_color; } unibi_ext; + char *space_buf; } TUIData; static bool volatile got_winch = false; @@ -125,10 +136,9 @@ UI *tui_start(void) { UI *ui = xcalloc(1, sizeof(UI)); // Freed by ui_bridge_stop(). ui->stop = tui_stop; - ui->resize = tui_resize; - ui->clear = tui_clear; - ui->eol_clear = tui_eol_clear; - ui->cursor_goto = tui_cursor_goto; + ui->grid_resize = tui_grid_resize; + ui->grid_clear = tui_grid_clear; + ui->grid_cursor_goto = tui_grid_cursor_goto; ui->mode_info_set = tui_mode_info_set; ui->update_menu = tui_update_menu; ui->busy_start = tui_busy_start; @@ -136,10 +146,8 @@ UI *tui_start(void) ui->mouse_on = tui_mouse_on; ui->mouse_off = tui_mouse_off; ui->mode_change = tui_mode_change; - ui->set_scroll_region = tui_set_scroll_region; - ui->scroll = tui_scroll; - ui->highlight_set = tui_highlight_set; - ui->put = tui_put; + ui->grid_scroll = tui_grid_scroll; + ui->hl_attr_define = tui_hl_attr_define; ui->bell = tui_bell; ui->visual_bell = tui_visual_bell; ui->default_colors_set = tui_default_colors_set; @@ -148,8 +156,10 @@ UI *tui_start(void) ui->set_title = tui_set_title; ui->set_icon = tui_set_icon; ui->option_set= tui_option_set; + ui->raw_line = tui_raw_line; memset(ui->ui_ext, 0, sizeof(ui->ui_ext)); + ui->ui_ext[kUILinegrid] = true; return ui_bridge_attach(ui, tui_main, tui_scheduler); } @@ -177,14 +187,17 @@ static void terminfo_start(UI *ui) data->scroll_region_is_full_screen = true; data->bufpos = 0; data->default_attr = false; + data->has_bg = false; data->is_invisible = true; data->busy = false; data->cork = false; data->overflow = false; + data->cursor_color_changed = false; data->showing_mode = SHAPE_IDX_N; data->unibi_ext.enable_mouse = -1; data->unibi_ext.disable_mouse = -1; data->unibi_ext.set_cursor_color = -1; + data->unibi_ext.reset_cursor_color = -1; data->unibi_ext.enable_bracketed_paste = -1; data->unibi_ext.disable_bracketed_paste = -1; data->unibi_ext.enable_lr_margin = -1; @@ -230,9 +243,11 @@ static void terminfo_start(UI *ui) data->can_set_left_right_margin = !!unibi_get_str(data->ut, unibi_set_left_margin_parm) && !!unibi_get_str(data->ut, unibi_set_right_margin_parm); + data->can_erase_chars = !!unibi_get_str(data->ut, unibi_erase_chars); data->immediate_wrap_after_last_column = terminfo_is_term_family(term, "cygwin") || terminfo_is_term_family(term, "interix"); + data->bce = unibi_get_bool(data->ut, unibi_back_color_erase); data->normlen = unibi_pre_fmt_str(data, unibi_cursor_normal, data->norm, sizeof data->norm); data->invislen = unibi_pre_fmt_str(data, unibi_cursor_invisible, @@ -272,6 +287,9 @@ static void terminfo_stop(UI *ui) unibi_out(ui, unibi_cursor_normal); unibi_out(ui, unibi_keypad_local); unibi_out(ui, unibi_exit_ca_mode); + if (data->cursor_color_changed) { + unibi_out_ext(ui, data->unibi_ext.reset_cursor_color); + } // Disable bracketed paste unibi_out_ext(ui, data->unibi_ext.disable_bracketed_paste); // Disable focus reporting @@ -289,7 +307,7 @@ static void terminfo_stop(UI *ui) static void tui_terminal_start(UI *ui) { TUIData *data = ui->data; - data->print_attrs = HLATTRS_INIT; + data->print_attr_id = -1; ugrid_init(&data->grid); terminfo_start(ui); update_size(ui); @@ -310,6 +328,12 @@ static void tui_terminal_after_startup(UI *ui) static void tui_terminal_stop(UI *ui) { TUIData *data = ui->data; + if (uv_is_closing(STRUCT_CAST(uv_handle_t, &data->output_handle))) { + // Race between SIGCONT (tui.c) and SIGHUP (os/signal.c)? #8075 + ELOG("TUI already stopped (race?)"); + ui->data = NULL; // Flag UI as "stopped". + return; + } term_input_stop(&data->input); signal_watcher_stop(&data->winch_handle); terminfo_stop(ui); @@ -319,8 +343,7 @@ static void tui_terminal_stop(UI *ui) static void tui_stop(UI *ui) { tui_terminal_stop(ui); - // Flag UI as "stopped". - ui->data = NULL; + ui->data = NULL; // Flag UI as "stopped". } /// Returns true if UI `ui` is stopped. @@ -345,6 +368,9 @@ static void tui_main(UIBridgeData *bridge, UI *ui) signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT); #endif + // TODO(bfredl): zero hl is empty, send this explicitly? + kv_push(data->attrs, HLATTRS_INIT); + #if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18 data->input.tk_ti_hook_fn = tui_tk_ti_getstr; #endif @@ -379,6 +405,8 @@ static void tui_main(UIBridgeData *bridge, UI *ui) signal_watcher_close(&data->winch_handle, NULL); loop_close(&tui_loop, false); kv_destroy(data->invalid_regions); + kv_destroy(data->attrs); + xfree(data->space_buf); xfree(data); } @@ -413,55 +441,76 @@ static void sigwinch_cb(SignalWatcher *watcher, int signum, void *data) ui_schedule_refresh(); } -static bool attrs_differ(HlAttrs a1, HlAttrs a2, bool rgb) +static bool attrs_differ(UI *ui, int id1, int id2, bool rgb) { + TUIData *data = ui->data; + if (id1 == id2) { + return false; + } else if (id1 < 0 || id2 < 0) { + return true; + } + HlAttrs a1 = kv_A(data->attrs, (size_t)id1); + HlAttrs a2 = kv_A(data->attrs, (size_t)id2); + if (rgb) { - // TODO(bfredl): when we start to support special color, - // rgb_sp_color must be added here return a1.rgb_fg_color != a2.rgb_fg_color || a1.rgb_bg_color != a2.rgb_bg_color - || a1.rgb_ae_attr != a2.rgb_ae_attr; + || a1.rgb_ae_attr != a2.rgb_ae_attr + || a1.rgb_sp_color != a2.rgb_sp_color; } else { return a1.cterm_fg_color != a2.cterm_fg_color || a1.cterm_bg_color != a2.cterm_bg_color - || a1.cterm_ae_attr != a2.cterm_ae_attr; + || a1.cterm_ae_attr != a2.cterm_ae_attr + || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL) + && a1.rgb_sp_color != a2.rgb_sp_color); } } -static void update_attrs(UI *ui, HlAttrs attrs) +static void update_attrs(UI *ui, int attr_id) { TUIData *data = ui->data; - if (!attrs_differ(attrs, data->print_attrs, ui->rgb)) { + if (!attrs_differ(ui, attr_id, data->print_attr_id, ui->rgb)) { + data->print_attr_id = attr_id; return; } - - data->print_attrs = attrs; - UGrid *grid = &data->grid; + data->print_attr_id = attr_id; + HlAttrs attrs = kv_A(data->attrs, (size_t)attr_id); int fg = ui->rgb ? attrs.rgb_fg_color : (attrs.cterm_fg_color - 1); if (fg == -1) { - fg = ui->rgb ? grid->clear_attrs.rgb_fg_color - : (grid->clear_attrs.cterm_fg_color - 1); + fg = ui->rgb ? data->clear_attrs.rgb_fg_color + : (data->clear_attrs.cterm_fg_color - 1); } int bg = ui->rgb ? attrs.rgb_bg_color : (attrs.cterm_bg_color - 1); if (bg == -1) { - bg = ui->rgb ? grid->clear_attrs.rgb_bg_color - : (grid->clear_attrs.cterm_bg_color - 1); + bg = ui->rgb ? data->clear_attrs.rgb_bg_color + : (data->clear_attrs.cterm_bg_color - 1); } + data->has_bg = bg != -1; + int attr = ui->rgb ? attrs.rgb_ae_attr : attrs.cterm_ae_attr; bool bold = attr & HL_BOLD; bool italic = attr & HL_ITALIC; bool reverse = attr & HL_INVERSE; bool standout = attr & HL_STANDOUT; - bool underline = attr & (HL_UNDERLINE), undercurl = attr & (HL_UNDERCURL); + + bool underline; + bool undercurl; + if (data->unibi_ext.enter_undercurl_mode) { + underline = attr & HL_UNDERLINE; + undercurl = attr & HL_UNDERCURL; + } else { + underline = (attr & HL_UNDERLINE) || (attr & HL_UNDERCURL); + undercurl = false; + } if (unibi_get_str(data->ut, unibi_set_attributes)) { - if (bold || reverse || underline || undercurl || standout) { + if (bold || reverse || underline || standout) { UNIBI_SET_NUM_VAR(data->params[0], standout); - UNIBI_SET_NUM_VAR(data->params[1], underline || undercurl); + UNIBI_SET_NUM_VAR(data->params[1], underline); UNIBI_SET_NUM_VAR(data->params[2], reverse); UNIBI_SET_NUM_VAR(data->params[3], 0); // blink UNIBI_SET_NUM_VAR(data->params[4], 0); // dim @@ -480,7 +529,7 @@ static void update_attrs(UI *ui, HlAttrs attrs) if (bold) { unibi_out(ui, unibi_enter_bold_mode); } - if (underline || undercurl) { + if (underline) { unibi_out(ui, unibi_enter_underline_mode); } if (standout) { @@ -493,6 +542,18 @@ static void update_attrs(UI *ui, HlAttrs attrs) if (italic) { unibi_out(ui, unibi_enter_italics_mode); } + if (undercurl && data->unibi_ext.enter_undercurl_mode) { + unibi_out_ext(ui, data->unibi_ext.enter_undercurl_mode); + } + if ((undercurl || underline) && data->unibi_ext.set_underline_color) { + int color = attrs.rgb_sp_color; + if (color != -1) { + UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red + UNIBI_SET_NUM_VAR(data->params[1], (color >> 8) & 0xff); // green + UNIBI_SET_NUM_VAR(data->params[2], color & 0xff); // blue + unibi_out_ext(ui, data->unibi_ext.set_underline_color); + } + } if (ui->rgb) { if (fg != -1) { UNIBI_SET_NUM_VAR(data->params[0], (fg >> 16) & 0xff); // red @@ -527,7 +588,7 @@ static void final_column_wrap(UI *ui) { TUIData *data = ui->data; UGrid *grid = &data->grid; - if (grid->col == ui->width) { + if (grid->row != -1 && grid->col == ui->width) { grid->col = 0; if (grid->row < MIN(ui->height, grid->height - 1)) { grid->row++; @@ -546,7 +607,7 @@ static void print_cell(UI *ui, UCell *ptr) // Printing the next character finally advances the cursor. final_column_wrap(ui); } - update_attrs(ui, ptr->attrs); + update_attrs(ui, ptr->attr); out(ui, ptr->data, strlen(ptr->data)); grid->col++; if (data->immediate_wrap_after_last_column) { @@ -562,7 +623,8 @@ static bool cheap_to_print(UI *ui, int row, int col, int next) UCell *cell = grid->cells[row] + col; while (next) { next--; - if (attrs_differ(cell->attrs, data->print_attrs, ui->rgb)) { + if (attrs_differ(ui, cell->attr, + data->print_attr_id, ui->rgb)) { if (data->default_attr) { return false; } @@ -596,6 +658,9 @@ static void cursor_goto(UI *ui, int row, int col) ugrid_goto(grid, row, col); return; } + if (grid->row == -1) { + goto safe_move; + } if (0 == col ? col != grid->col : row != grid->row ? false : 1 == col ? 2 < grid->col && cheap_to_print(ui, grid->row, 0, col) : @@ -609,7 +674,7 @@ static void cursor_goto(UI *ui, int row, int col) int n = col - grid->col; if (n <= (row == grid->row ? 4 : 2) && cheap_to_print(ui, grid->row, grid->col, n)) { - UGRID_FOREACH_CELL(grid, grid->row, grid->row, grid->col, col - 1, { + UGRID_FOREACH_CELL(grid, grid->row, grid->col, col, { print_cell(ui, cell); }); } @@ -674,96 +739,81 @@ static void cursor_goto(UI *ui, int row, int col) return; } } + +safe_move: unibi_goto(ui, row, col); ugrid_goto(grid, row, col); } -static void clear_region(UI *ui, int top, int bot, int left, int right) +static void clear_region(UI *ui, int top, int bot, int left, int right, + int attr_id) { TUIData *data = ui->data; UGrid *grid = &data->grid; - int saved_row = grid->row; - int saved_col = grid->col; - - bool cleared = false; - bool nobg = ui->rgb ? grid->clear_attrs.rgb_bg_color == -1 - : grid->clear_attrs.cterm_bg_color == 0; - if (nobg && right == ui->width -1) { - // Background is set to the default color and the right edge matches the - // screen end, try to use terminal codes for clearing the requested area. - update_attrs(ui, grid->clear_attrs); - if (left == 0) { - if (bot == ui->height - 1) { - if (top == 0) { - unibi_out(ui, unibi_clear_screen); - ugrid_goto(&data->grid, top, left); - } else { - cursor_goto(ui, top, 0); - unibi_out(ui, unibi_clr_eos); - } - cleared = true; - } + + update_attrs(ui, attr_id); + + // non-BCE terminals can't clear with non-default background color + bool can_clear = data->bce || !data->has_bg; + + // Background is set to the default color and the right edge matches the + // screen end, try to use terminal codes for clearing the requested area. + if (can_clear && left == 0 && right == ui->width && bot == ui->height) { + if (top == 0) { + unibi_out(ui, unibi_clear_screen); + ugrid_goto(&data->grid, top, left); + } else { + cursor_goto(ui, top, 0); + unibi_out(ui, unibi_clr_eos); } + } else { + int width = right-left; - if (!cleared) { - // iterate through each line and clear with clr_eol - for (int row = top; row <= bot; row++) { - cursor_goto(ui, row, left); + // iterate through each line and clear + for (int row = top; row < bot; row++) { + cursor_goto(ui, row, left); + if (can_clear && right == ui->width) { unibi_out(ui, unibi_clr_eol); + } else if (data->can_erase_chars && can_clear && width >= 5) { + UNIBI_SET_NUM_VAR(data->params[0], width); + unibi_out(ui, unibi_erase_chars); + } else { + out(ui, data->space_buf, (size_t)width); + grid->col += width; + if (data->immediate_wrap_after_last_column) { + // Printing at the right margin immediately advances the cursor. + final_column_wrap(ui); + } } - cleared = true; } } - - if (!cleared) { - // could not clear using faster terminal codes, refresh the whole region - UGRID_FOREACH_CELL(grid, top, bot, left, right, { - cursor_goto(ui, row, col); - print_cell(ui, cell); - }); - } - - // restore cursor - cursor_goto(ui, saved_row, saved_col); -} - -static bool can_use_scroll(UI * ui) -{ - TUIData *data = ui->data; - UGrid *grid = &data->grid; - - return data->scroll_region_is_full_screen - || (data->can_change_scroll_region - && ((grid->left == 0 && grid->right == ui->width - 1) - || data->can_set_lr_margin - || data->can_set_left_right_margin)); } -static void set_scroll_region(UI *ui) +static void set_scroll_region(UI *ui, int top, int bot, int left, int right) { TUIData *data = ui->data; UGrid *grid = &data->grid; - UNIBI_SET_NUM_VAR(data->params[0], grid->top); - UNIBI_SET_NUM_VAR(data->params[1], grid->bot); + UNIBI_SET_NUM_VAR(data->params[0], top); + UNIBI_SET_NUM_VAR(data->params[1], bot); unibi_out(ui, unibi_change_scroll_region); - if (grid->left != 0 || grid->right != ui->width - 1) { + if (left != 0 || right != ui->width - 1) { unibi_out_ext(ui, data->unibi_ext.enable_lr_margin); if (data->can_set_lr_margin) { - UNIBI_SET_NUM_VAR(data->params[0], grid->left); - UNIBI_SET_NUM_VAR(data->params[1], grid->right); + UNIBI_SET_NUM_VAR(data->params[0], left); + UNIBI_SET_NUM_VAR(data->params[1], right); unibi_out(ui, unibi_set_lr_margin); } else { - UNIBI_SET_NUM_VAR(data->params[0], grid->left); + UNIBI_SET_NUM_VAR(data->params[0], left); unibi_out(ui, unibi_set_left_margin_parm); - UNIBI_SET_NUM_VAR(data->params[0], grid->right); + UNIBI_SET_NUM_VAR(data->params[0], right); unibi_out(ui, unibi_set_right_margin_parm); } } - unibi_goto(ui, grid->row, grid->col); + grid->row = -1; } -static void reset_scroll_region(UI *ui) +static void reset_scroll_region(UI *ui, bool fullwidth) { TUIData *data = ui->data; UGrid *grid = &data->grid; @@ -775,7 +825,7 @@ static void reset_scroll_region(UI *ui) UNIBI_SET_NUM_VAR(data->params[1], ui->height - 1); unibi_out(ui, unibi_change_scroll_region); } - if (grid->left != 0 || grid->right != ui->width - 1) { + if (!fullwidth) { if (data->can_set_lr_margin) { UNIBI_SET_NUM_VAR(data->params[0], 0); UNIBI_SET_NUM_VAR(data->params[1], ui->width - 1); @@ -788,13 +838,26 @@ static void reset_scroll_region(UI *ui) } unibi_out_ext(ui, data->unibi_ext.disable_lr_margin); } - unibi_goto(ui, grid->row, grid->col); + grid->row = -1; } -static void tui_resize(UI *ui, Integer width, Integer height) +static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height) { TUIData *data = ui->data; - ugrid_resize(&data->grid, (int)width, (int)height); + UGrid *grid = &data->grid; + ugrid_resize(grid, (int)width, (int)height); + + xfree(data->space_buf); + data->space_buf = xmalloc((size_t)width * sizeof(*data->space_buf)); + memset(data->space_buf, ' ', (size_t)width); + + // resize might not always be followed by a clear before flush + // so clip the invalid region + for (size_t i = 0; i < kv_size(data->invalid_regions); i++) { + Rect *r = &kv_A(data->invalid_regions, i); + r->bot = MIN(r->bot, grid->height); + r->right = MIN(r->right, grid->width); + } if (!got_winch) { // Try to resize the terminal window. UNIBI_SET_NUM_VAR(data->params[0], (int)height); @@ -802,33 +865,30 @@ static void tui_resize(UI *ui, Integer width, Integer height) unibi_out_ext(ui, data->unibi_ext.resize_screen); // DECSLPP does not reset the scroll region. if (data->scroll_region_is_full_screen) { - reset_scroll_region(ui); + reset_scroll_region(ui, ui->width == grid->width); } } else { // Already handled the SIGWINCH signal; avoid double-resize. got_winch = false; + grid->row = -1; } } -static void tui_clear(UI *ui) +static void tui_grid_clear(UI *ui, Integer g) { TUIData *data = ui->data; UGrid *grid = &data->grid; ugrid_clear(grid); kv_size(data->invalid_regions) = 0; - clear_region(ui, grid->top, grid->bot, grid->left, grid->right); + clear_region(ui, 0, grid->height, 0, grid->width, 0); } -static void tui_eol_clear(UI *ui) +static void tui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col) { TUIData *data = ui->data; - UGrid *grid = &data->grid; - ugrid_eol_clear(grid); - clear_region(ui, grid->row, grid->row, grid->col, grid->right); -} -static void tui_cursor_goto(UI *ui, Integer row, Integer col) -{ - cursor_goto(ui, (int)row, (int)col); + // cursor position is validated in tui_flush + data->row = (int)row; + data->col = (int)col; } CursorShape tui_cursor_decode_shape(const char *shape_str) @@ -861,7 +921,7 @@ static cursorentry_T decode_cursor_entry(Dictionary args) r.blinkon = (int)value.data.integer; } else if (strequal(key, "blinkoff")) { r.blinkoff = (int)value.data.integer; - } else if (strequal(key, "hl_id")) { + } else if (strequal(key, "attr_id")) { r.id = (int)value.data.integer; } } @@ -929,13 +989,20 @@ static void tui_set_mode(UI *ui, ModeShape mode) TUIData *data = ui->data; cursorentry_T c = data->cursor_shapes[mode]; - if (c.id != 0 && ui->rgb) { - int attr = syn_id2attr(c.id); - if (attr > 0) { - HlAttrs *aep = syn_cterm_attr2entry(attr); - UNIBI_SET_NUM_VAR(data->params[0], aep->rgb_bg_color); + if (c.id != 0 && c.id < (int)kv_size(data->attrs) && ui->rgb) { + HlAttrs aep = kv_A(data->attrs, c.id); + if (aep.rgb_ae_attr & HL_INVERSE) { + // We interpret "inverse" as "default" (no termcode for "inverse"...). + // Hopefully the user's default cursor color is inverse. + unibi_out_ext(ui, data->unibi_ext.reset_cursor_color); + } else { + UNIBI_SET_NUM_VAR(data->params[0], aep.rgb_bg_color); unibi_out_ext(ui, data->unibi_ext.set_cursor_color); + data->cursor_color_changed = true; } + } else if (c.id == 0) { + // No cursor color for this mode; reset to default. + unibi_out_ext(ui, data->unibi_ext.reset_cursor_color); } int shape; @@ -957,90 +1024,70 @@ static void tui_mode_change(UI *ui, String mode, Integer mode_idx) data->showing_mode = (ModeShape)mode_idx; } -static void tui_set_scroll_region(UI *ui, Integer top, Integer bot, - Integer left, Integer right) -{ - TUIData *data = ui->data; - ugrid_set_scroll_region(&data->grid, (int)top, (int)bot, - (int)left, (int)right); - data->scroll_region_is_full_screen = - left == 0 && right == ui->width - 1 - && top == 0 && bot == ui->height - 1; -} - -static void tui_scroll(UI *ui, Integer count) +static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow, + Integer startcol, Integer endcol, + Integer rows, Integer cols) { TUIData *data = ui->data; UGrid *grid = &data->grid; - int clear_top, clear_bot; - ugrid_scroll(grid, (int)count, &clear_top, &clear_bot); + int top = (int)startrow, bot = (int)endrow-1; + int left = (int)startcol, right = (int)endcol-1; + + bool fullwidth = left == 0 && right == ui->width-1; + data->scroll_region_is_full_screen = fullwidth + && top == 0 && bot == ui->height-1; + + ugrid_scroll(grid, top, bot, left, right, (int)rows); - if (can_use_scroll(ui)) { - int saved_row = grid->row; - int saved_col = grid->col; - bool scroll_clears_to_current_colour = - unibi_get_bool(data->ut, unibi_back_color_erase); + bool can_scroll = data->scroll_region_is_full_screen + || (data->can_change_scroll_region + && ((left == 0 && right == ui->width - 1) + || data->can_set_lr_margin + || data->can_set_left_right_margin)); + if (can_scroll) { // Change terminal scroll region and move cursor to the top if (!data->scroll_region_is_full_screen) { - set_scroll_region(ui); - } - cursor_goto(ui, grid->top, grid->left); - // also set default color attributes or some terminals can become funny - if (scroll_clears_to_current_colour) { - update_attrs(ui, grid->clear_attrs); + set_scroll_region(ui, top, bot, left, right); } + cursor_goto(ui, top, left); - if (count > 0) { - if (count == 1) { + if (rows > 0) { + if (rows == 1) { unibi_out(ui, unibi_delete_line); } else { - UNIBI_SET_NUM_VAR(data->params[0], (int)count); + UNIBI_SET_NUM_VAR(data->params[0], (int)rows); unibi_out(ui, unibi_parm_delete_line); } } else { - if (count == -1) { + if (rows == -1) { unibi_out(ui, unibi_insert_line); } else { - UNIBI_SET_NUM_VAR(data->params[0], -(int)count); + UNIBI_SET_NUM_VAR(data->params[0], -(int)rows); unibi_out(ui, unibi_parm_insert_line); } } // Restore terminal scroll region and cursor if (!data->scroll_region_is_full_screen) { - reset_scroll_region(ui); - } - cursor_goto(ui, saved_row, saved_col); - - if (!scroll_clears_to_current_colour) { - // Scrolling will leave wrong background in the cleared area on non-BCE - // terminals. Update the cleared area. - clear_region(ui, clear_top, clear_bot, grid->left, grid->right); + reset_scroll_region(ui, fullwidth); } } else { - // Mark the entire scroll region as invalid for redrawing later - invalidate(ui, grid->top, grid->bot, grid->left, grid->right); + // Mark the moved region as invalid for redrawing later + if (rows > 0) { + endrow = endrow - rows; + } else { + startrow = startrow - rows; + } + invalidate(ui, (int)startrow, (int)endrow, (int)startcol, (int)endcol); } } -static void tui_highlight_set(UI *ui, HlAttrs attrs) -{ - ((TUIData *)ui->data)->grid.attrs = attrs; -} - -static void tui_put(UI *ui, String text) +static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, + HlAttrs cterm_attrs, Array info) { TUIData *data = ui->data; - UGrid *grid = &data->grid; - UCell *cell; - - cell = ugrid_put(&data->grid, (uint8_t *)text.data, text.size); - // ugrid_put does not advance the cursor correctly, as the actual terminal - // will when we print. Its cursor motion model is simplistic and wrong. So - // we have to undo what it has just done before doing it right. - grid->col--; - print_cell(ui, cell); + kv_a(data->attrs, (size_t)id) = attrs; } static void tui_bell(UI *ui) @@ -1057,12 +1104,16 @@ static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp, Integer cterm_fg, Integer cterm_bg) { - UGrid *grid = &((TUIData *)ui->data)->grid; - grid->clear_attrs.rgb_fg_color = (int)rgb_fg; - grid->clear_attrs.rgb_bg_color = (int)rgb_bg; - grid->clear_attrs.rgb_sp_color = (int)rgb_sp; - grid->clear_attrs.cterm_fg_color = (int)cterm_fg; - grid->clear_attrs.cterm_bg_color = (int)cterm_bg; + TUIData *data = ui->data; + + data->clear_attrs.rgb_fg_color = (int)rgb_fg; + data->clear_attrs.rgb_bg_color = (int)rgb_bg; + data->clear_attrs.rgb_sp_color = (int)rgb_sp; + data->clear_attrs.cterm_fg_color = (int)cterm_fg; + data->clear_attrs.cterm_bg_color = (int)cterm_bg; + + data->print_attr_id = -1; + invalidate(ui, 0, data->grid.height, 0, data->grid.width); } static void tui_flush(UI *ui) @@ -1082,19 +1133,32 @@ static void tui_flush(UI *ui) tui_busy_stop(ui); // avoid hidden cursor } - int saved_row = grid->row; - int saved_col = grid->col; - while (kv_size(data->invalid_regions)) { Rect r = kv_pop(data->invalid_regions); - assert(r.bot < grid->height && r.right < grid->width); - UGRID_FOREACH_CELL(grid, r.top, r.bot, r.left, r.right, { - cursor_goto(ui, row, col); - print_cell(ui, cell); - }); + assert(r.bot <= grid->height && r.right <= grid->width); + + for (int row = r.top; row < r.bot; row++) { + int clear_attr = grid->cells[row][r.right-1].attr; + int clear_col; + for (clear_col = r.right; clear_col > 0; clear_col--) { + UCell *cell = &grid->cells[row][clear_col-1]; + if (!(cell->data[0] == ' ' && cell->data[1] == NUL + && cell->attr == clear_attr)) { + break; + } + } + + UGRID_FOREACH_CELL(grid, row, r.left, clear_col, { + cursor_goto(ui, row, col); + print_cell(ui, cell); + }); + if (clear_col < r.right) { + clear_region(ui, row, row+1, clear_col, r.right, clear_attr); + } + } } - cursor_goto(ui, saved_row, saved_col); + cursor_goto(ui, data->row, data->col); flush_buf(ui); } @@ -1175,7 +1239,49 @@ static void tui_option_set(UI *ui, String name, Object value) TUIData *data = ui->data; if (strequal(name.data, "termguicolors")) { ui->rgb = value.data.boolean; - invalidate(ui, 0, data->grid.height-1, 0, data->grid.width-1); + + data->print_attr_id = -1; + invalidate(ui, 0, data->grid.height, 0, data->grid.width); + } +} + +static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, + Integer endcol, Integer clearcol, Integer clearattr, + Boolean wrap, const schar_T *chunk, + const sattr_T *attrs) +{ + TUIData *data = ui->data; + UGrid *grid = &data->grid; + for (Integer c = startcol; c < endcol; c++) { + memcpy(grid->cells[linerow][c].data, chunk[c-startcol], sizeof(schar_T)); + assert((size_t)attrs[c-startcol] < kv_size(data->attrs)); + grid->cells[linerow][c].attr = attrs[c-startcol]; + } + UGRID_FOREACH_CELL(grid, (int)linerow, (int)startcol, (int)endcol, { + cursor_goto(ui, (int)linerow, col); + print_cell(ui, cell); + }); + + if (clearcol > endcol) { + ugrid_clear_chunk(grid, (int)linerow, (int)endcol, (int)clearcol, + (sattr_T)clearattr); + clear_region(ui, (int)linerow, (int)linerow+1, (int)endcol, (int)clearcol, + (int)clearattr); + } + + if (wrap && ui->width == grid->width && linerow + 1 < grid->height) { + // Only do line wrapping if the grid width is equal to the terminal + // width and the line continuation is within the grid. + + if (endcol != grid->width) { + // Print the last cell of the row, if we haven't already done so. + cursor_goto(ui, (int)linerow, grid->width - 1); + print_cell(ui, &grid->cells[linerow][grid->width - 1]); + } + + // Wrap the cursor over to the next line. The next line will be + // printed immediately without an intervening newline. + final_column_wrap(ui); } } @@ -1183,27 +1289,17 @@ static void invalidate(UI *ui, int top, int bot, int left, int right) { TUIData *data = ui->data; Rect *intersects = NULL; - // Increase dimensions before comparing to ensure adjacent regions are - // treated as intersecting - --top; - ++bot; - --left; - ++right; for (size_t i = 0; i < kv_size(data->invalid_regions); i++) { Rect *r = &kv_A(data->invalid_regions, i); - if (!(top > r->bot || bot < r->top - || left > r->right || right < r->left)) { + // adjacent regions are treated as overlapping + if (!(top > r->bot || bot < r->top) + && !(left > r->right || right < r->left)) { intersects = r; break; } } - ++top; - --bot; - ++left; - --right; - if (intersects) { // If top/bot/left/right intersects with a invalid rect, we replace it // by the union @@ -1346,6 +1442,18 @@ static int unibi_find_ext_str(unibi_term *ut, const char *name) return -1; } +static int unibi_find_ext_bool(unibi_term *ut, const char *name) +{ + size_t max = unibi_count_ext_bool(ut); + for (size_t i = 0; i < max; i++) { + const char * n = unibi_get_ext_bool_name(ut, i); + if (n && 0 == strcmp(n, name)) { + return (int)i; + } + } + return -1; +} + /// Patches the terminfo records after loading from system or built-in db. /// Several entries in terminfo are known to be deficient or outright wrong; /// and several terminal emulators falsely announce incorrect terminal types. @@ -1359,6 +1467,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool roxterm = !!os_getenv("ROXTERM_ID"); #endif bool xterm = terminfo_is_term_family(term, "xterm"); + bool kitty = terminfo_is_term_family(term, "xterm-kitty"); bool linuxvt = terminfo_is_term_family(term, "linux"); bool rxvt = terminfo_is_term_family(term, "rxvt"); bool teraterm = terminfo_is_term_family(term, "teraterm"); @@ -1372,6 +1481,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, || terminfo_is_term_family(term, "iterm2") || terminfo_is_term_family(term, "iTerm.app") || terminfo_is_term_family(term, "iTerm2.app"); + bool alacritty = terminfo_is_term_family(term, "alacritty"); // None of the following work over SSH; see :help TERM . bool iterm_pretending_xterm = xterm && iterm_env; bool konsole_pretending_xterm = xterm && konsole; @@ -1414,8 +1524,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, } } - if (!true_xterm) { - // Cannot trust terminfo; safer to disable BCE. #7624 + if (tmux || screen || kitty) { + // Disable BCE in some cases we know it is not working. #8806 unibi_set_bool(ut, unibi_back_color_erase, false); } @@ -1566,6 +1676,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // per analysis of VT100Terminal.m || iterm || iterm_pretending_xterm || teraterm // per TeraTerm "Supported Control Functions" doco + || alacritty // https://github.com/jwilm/alacritty/pull/608 // Some linux-type terminals implement the xterm extension. // Example: console-terminal-emulator from the nosh toolset. || (linuxvt @@ -1713,11 +1824,15 @@ static void augment_terminfo(TUIData *data, const char *term, // would use a tmux control sequence and an extra if(screen) test. data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\")); - } else if (xterm || (vte_version != 0) || rxvt) { - // This seems to be supported for a long time in VTE - // urxvt also supports this + } else if ((xterm || rxvt) && (vte_version == 0 || vte_version >= 3900)) { + // Supported in urxvt, newer VTE. data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( - ut, NULL, "\033]12;#%p1%06x\007"); + ut, "ext.set_cursor_color", "\033]12;#%p1%06x\007"); + } + + if (-1 != data->unibi_ext.set_cursor_color) { + data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str( + ut, "ext.reset_cursor_color", "\x1b]112\x07"); } /// Terminals usually ignore unrecognized private modes, and there is no @@ -1741,6 +1856,22 @@ static void augment_terminfo(TUIData *data, const char *term, ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h"); data->unibi_ext.disable_mouse = (int)unibi_add_ext_str( ut, "ext.disable_mouse", "\x1b[?1002l\x1b[?1006l"); + + int ext_bool_Su = unibi_find_ext_bool(ut, "Su"); // used by kitty + if (vte_version >= 5102 + || (ext_bool_Su != -1 && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))) { + data->unibi_ext.enter_undercurl_mode = (int)unibi_add_ext_str( + ut, "ext.enter_undercurl_mode", "\x1b[4:3m"); + data->unibi_ext.exit_undercurl_mode = (int)unibi_add_ext_str( + ut, "ext.exit_undercurl_mode", "\x1b[4:0m"); + if (has_colon_rgb) { + data->unibi_ext.set_underline_color = (int)unibi_add_ext_str( + ut, "ext.set_underline_color", "\x1b[58:2:%p1%d:%p2%d:%p3%dm"); + } else { + data->unibi_ext.set_underline_color = (int)unibi_add_ext_str( + ut, "ext.set_underline_color", "\x1b[58;2;%p1%d;%p2%d;%p3%dm"); + } + } } static void flush_buf(UI *ui) @@ -1795,7 +1926,7 @@ static void flush_buf(UI *ui) static const char *tui_get_stty_erase(void) { static char stty_erase[2] = { 0 }; -#if defined(ECHOE) && defined(ICANON) && defined(HAVE_TERMIOS_H) +#if defined(HAVE_TERMIOS_H) struct termios t; if (tcgetattr(input_global_fd(), &t) != -1) { stty_erase[0] = (char)t.c_cc[VERASE]; diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c index 6d420ef2f8..f5bd35a48e 100644 --- a/src/nvim/ugrid.c +++ b/src/nvim/ugrid.c @@ -16,8 +16,6 @@ void ugrid_init(UGrid *grid) { - grid->attrs = HLATTRS_INIT; - grid->clear_attrs = HLATTRS_INIT; grid->cells = NULL; } @@ -34,23 +32,18 @@ void ugrid_resize(UGrid *grid, int width, int height) grid->cells[i] = xcalloc((size_t)width, sizeof(UCell)); } - grid->top = 0; - grid->bot = height - 1; - grid->left = 0; - grid->right = width - 1; - grid->row = grid->col = 0; grid->width = width; grid->height = height; } void ugrid_clear(UGrid *grid) { - clear_region(grid, grid->top, grid->bot, grid->left, grid->right); + clear_region(grid, 0, grid->height-1, 0, grid->width-1, 0); } -void ugrid_eol_clear(UGrid *grid) +void ugrid_clear_chunk(UGrid *grid, int row, int col, int endcol, sattr_T attr) { - clear_region(grid, grid->row, grid->row, grid->col, grid->right); + clear_region(grid, row, row, col, endcol-1, attr); } void ugrid_goto(UGrid *grid, int row, int col) @@ -59,25 +52,17 @@ void ugrid_goto(UGrid *grid, int row, int col) grid->col = col; } -void ugrid_set_scroll_region(UGrid *grid, int top, int bot, int left, int right) -{ - grid->top = top; - grid->bot = bot; - grid->left = left; - grid->right = right; -} - -void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot) +void ugrid_scroll(UGrid *grid, int top, int bot, int left, int right, int count) { // Compute start/stop/step for the loop below int start, stop, step; if (count > 0) { - start = grid->top; - stop = grid->bot - count + 1; + start = top; + stop = bot - count + 1; step = 1; } else { - start = grid->bot; - stop = grid->top - count - 1; + start = bot; + stop = top - count - 1; step = -1; } @@ -85,46 +70,23 @@ void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot) // Copy cell data for (i = start; i != stop; i += step) { - UCell *target_row = grid->cells[i] + grid->left; - UCell *source_row = grid->cells[i + count] + grid->left; + UCell *target_row = grid->cells[i] + left; + UCell *source_row = grid->cells[i + count] + left; memcpy(target_row, source_row, - sizeof(UCell) * (size_t)(grid->right - grid->left + 1)); - } - - // clear cells in the emptied region, - if (count > 0) { - *clear_top = stop; - *clear_bot = stop + count - 1; - } else { - *clear_bot = stop; - *clear_top = stop + count + 1; + sizeof(UCell) * (size_t)(right - left + 1)); } - clear_region(grid, *clear_top, *clear_bot, grid->left, grid->right); } -UCell *ugrid_put(UGrid *grid, uint8_t *text, size_t size) +static void clear_region(UGrid *grid, int top, int bot, int left, int right, + sattr_T attr) { - UCell *cell = grid->cells[grid->row] + grid->col; - cell->data[size] = 0; - cell->attrs = grid->attrs; - assert(size <= CELLBYTES); - - if (text) { - memcpy(cell->data, text, size); + for (int row = top; row <= bot; row++) { + UGRID_FOREACH_CELL(grid, row, left, right+1, { + cell->data[0] = ' '; + cell->data[1] = 0; + cell->attr = attr; + }); } - - grid->col += 1; - return cell; -} - -static void clear_region(UGrid *grid, int top, int bot, int left, int right) -{ - HlAttrs clear_attrs = grid->clear_attrs; - UGRID_FOREACH_CELL(grid, top, bot, left, right, { - cell->data[0] = ' '; - cell->data[1] = 0; - cell->attrs = clear_attrs; - }); } static void destroy_cells(UGrid *grid) diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h index 035074846e..33a706b8c0 100644 --- a/src/nvim/ugrid.h +++ b/src/nvim/ugrid.h @@ -7,33 +7,28 @@ typedef struct ucell UCell; typedef struct ugrid UGrid; -#define CELLBYTES (4 * (MAX_MCO+1)) +#define CELLBYTES (sizeof(schar_T)) struct ucell { char data[CELLBYTES + 1]; - HlAttrs attrs; + sattr_T attr; }; struct ugrid { - int top, bot, left, right; int row, col; - HlAttrs clear_attrs; int width, height; - HlAttrs attrs; UCell **cells; }; // -V:UGRID_FOREACH_CELL:625 -#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \ +#define UGRID_FOREACH_CELL(grid, row, startcol, endcol, code) \ do { \ - for (int row = top; row <= bot; row++) { \ - UCell *row_cells = (grid)->cells[row]; \ - for (int col = left; col <= right; col++) { \ - UCell *cell = row_cells + col; \ - (void)(cell); \ - code; \ - } \ + UCell *row_cells = (grid)->cells[row]; \ + for (int col = startcol; col < endcol; col++) { \ + UCell *cell = row_cells + col; \ + (void)(cell); \ + code; \ } \ } while (0) diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 3b632ace41..0c69e94e5d 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -32,7 +32,7 @@ #include "nvim/os/signal.h" #include "nvim/popupmnu.h" #include "nvim/screen.h" -#include "nvim/syntax.h" +#include "nvim/highlight.h" #include "nvim/window.h" #include "nvim/cursor_shape.h" #ifdef FEAT_TUI @@ -52,14 +52,11 @@ static UI *uis[MAX_UI_COUNT]; static bool ui_ext[kUIExtCount] = { 0 }; static size_t ui_count = 0; static int row = 0, col = 0; -static struct { - int top, bot, left, right; -} sr; -static int current_attr_code = -1; static bool pending_cursor_update = false; static int busy = 0; -static int height, width; -static int old_mode_idx = -1; +static int mode_idx = SHAPE_IDX_N; +static bool pending_mode_info_update = false; +static bool pending_mode_update = false; #if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL # define UI_LOG(funname, ...) @@ -72,10 +69,10 @@ static char uilog_last_event[1024] = { 0 }; uilog_seen++; \ } else { \ if (uilog_seen > 0) { \ - do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, \ + logmsg(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, \ "%s (+%zu times...)", uilog_last_event, uilog_seen); \ } \ - do_log(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, STR(funname)); \ + logmsg(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, STR(funname)); \ uilog_seen = 0; \ xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \ } \ @@ -83,13 +80,12 @@ static char uilog_last_event[1024] = { 0 }; #endif // UI_CALL invokes a function on all registered UI instances. The functions can -// have 0-5 arguments (configurable by SELECT_NTH). +// have 0-10 arguments (configurable by SELECT_NTH). // // See http://stackoverflow.com/a/11172679 for how it works. #ifdef _MSC_VER # define UI_CALL(funname, ...) \ do { \ - flush_cursor_update(); \ UI_LOG(funname, 0); \ for (size_t i = 0; i < ui_count; i++) { \ UI *ui = uis[i]; \ @@ -99,7 +95,6 @@ static char uilog_last_event[1024] = { 0 }; #else # define UI_CALL(...) \ do { \ - flush_cursor_update(); \ UI_LOG(__VA_ARGS__, 0); \ for (size_t i = 0; i < ui_count; i++) { \ UI *ui = uis[i]; \ @@ -107,9 +102,9 @@ static char uilog_last_event[1024] = { 0 }; } \ } while (0) #endif -#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, \ - MORE, MORE, ZERO, ignore) -#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, ...) a7 +#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, MORE, \ + MORE, MORE, MORE, MORE, ZERO, ignore) +#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 #define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__) // Resolves to UI_CALL_MORE or UI_CALL_ZERO. #define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__) @@ -172,66 +167,6 @@ void ui_event(char *name, Array args) } -/// Converts an HlAttrs into Dictionary -/// -/// @param[in] aep data to convert -/// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*' -Dictionary hlattrs2dict(const HlAttrs *aep, bool use_rgb) -{ - assert(aep); - Dictionary hl = ARRAY_DICT_INIT; - int mask = use_rgb ? aep->rgb_ae_attr : aep->cterm_ae_attr; - - if (mask & HL_BOLD) { - PUT(hl, "bold", BOOLEAN_OBJ(true)); - } - - if (mask & HL_STANDOUT) { - PUT(hl, "standout", BOOLEAN_OBJ(true)); - } - - if (mask & HL_UNDERLINE) { - PUT(hl, "underline", BOOLEAN_OBJ(true)); - } - - if (mask & HL_UNDERCURL) { - PUT(hl, "undercurl", BOOLEAN_OBJ(true)); - } - - if (mask & HL_ITALIC) { - PUT(hl, "italic", BOOLEAN_OBJ(true)); - } - - if (mask & HL_INVERSE) { - PUT(hl, "reverse", BOOLEAN_OBJ(true)); - } - - - if (use_rgb) { - if (aep->rgb_fg_color != -1) { - PUT(hl, "foreground", INTEGER_OBJ(aep->rgb_fg_color)); - } - - if (aep->rgb_bg_color != -1) { - PUT(hl, "background", INTEGER_OBJ(aep->rgb_bg_color)); - } - - if (aep->rgb_sp_color != -1) { - PUT(hl, "special", INTEGER_OBJ(aep->rgb_sp_color)); - } - } else { - if (cterm_normal_fg_color != aep->cterm_fg_color) { - PUT(hl, "foreground", INTEGER_OBJ(aep->cterm_fg_color - 1)); - } - - if (cterm_normal_bg_color != aep->cterm_bg_color) { - PUT(hl, "background", INTEGER_OBJ(aep->cterm_bg_color - 1)); - } - } - - return hl; -} - void ui_refresh(void) { if (!ui_active()) { @@ -259,6 +194,9 @@ void ui_refresh(void) } row = col = 0; + pending_cursor_update = true; + + ui_default_colors_set(); int save_p_lz = p_lz; p_lz = false; // convince redrawing() to return true ... @@ -267,13 +205,14 @@ void ui_refresh(void) for (UIExtension i = 0; (int)i < kUIExtCount; i++) { ui_ext[i] = ext_widgets[i]; - ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]), - BOOLEAN_OBJ(ext_widgets[i])); + if (i < kUIGlobalCount) { + ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]), + BOOLEAN_OBJ(ext_widgets[i])); + } } ui_mode_info_set(); - old_mode_idx = -1; + pending_mode_update = true; ui_cursor_shape(); - current_attr_code = -1; } static void ui_refresh_event(void **argv) @@ -286,25 +225,15 @@ void ui_schedule_refresh(void) loop_schedule(&main_loop, event_create(ui_refresh_event, 0)); } -void ui_resize(int new_width, int new_height) +void ui_resize(int width, int height) { - width = new_width; - height = new_height; + ui_call_grid_resize(1, width, height); +} - // TODO(bfredl): update default colors when they changed, NOT on resize. +void ui_default_colors_set(void) +{ ui_call_default_colors_set(normal_fg, normal_bg, normal_sp, cterm_normal_fg_color, cterm_normal_bg_color); - - // Deprecated: - UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1)); - UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1)); - UI_CALL(update_sp, (ui->rgb ? normal_sp : -1)); - - sr.top = 0; - sr.bot = height - 1; - sr.left = 0; - sr.right = width - 1; - ui_call_resize(width, height); } void ui_busy_start(void) @@ -329,6 +258,18 @@ void ui_attach_impl(UI *ui) uis[ui_count++] = ui; ui_refresh_options(); + + for (UIExtension i = kUIGlobalCount; (int)i < kUIExtCount; i++) { + ui_set_ext_option(ui, i, ui->ui_ext[i]); + } + + bool sent = false; + if (ui->ui_ext[kUIHlState]) { + sent = highlight_use_hlstate(); + } + if (!sent) { + ui_send_all_hls(ui); + } ui_refresh(); } @@ -362,97 +303,35 @@ void ui_detach_impl(UI *ui) } } -// Set scrolling region for window 'wp'. -// The region starts 'off' lines from the start of the window. -// Also set the vertical scroll region for a vertically split window. Always -// the full width of the window, excluding the vertical separator. -void ui_set_scroll_region(win_T *wp, int off) +void ui_set_ext_option(UI *ui, UIExtension ext, bool active) { - sr.top = wp->w_winrow + off; - sr.bot = wp->w_winrow + wp->w_height - 1; - - if (wp->w_width != Columns) { - sr.left = wp->w_wincol; - sr.right = wp->w_wincol + wp->w_width - 1; - } - - ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right); -} - -// Reset scrolling region to the whole screen. -void ui_reset_scroll_region(void) -{ - sr.top = 0; - sr.bot = (int)Rows - 1; - sr.left = 0; - sr.right = (int)Columns - 1; - ui_call_set_scroll_region(sr.top, sr.bot, sr.left, sr.right); -} - -void ui_set_highlight(int attr_code) -{ - if (current_attr_code == attr_code) { + if (ext < kUIGlobalCount) { + ui_refresh(); return; } - current_attr_code = attr_code; - - HlAttrs attrs = HLATTRS_INIT; - - if (attr_code != 0) { - HlAttrs *aep = syn_cterm_attr2entry(attr_code); - if (aep) { - attrs = *aep; - } + if (ui->option_set) { + ui->option_set(ui, cstr_as_string((char *)ui_ext_names[ext]), + BOOLEAN_OBJ(active)); } - - UI_CALL(highlight_set, attrs); } -void ui_clear_highlight(void) +void ui_line(int row, int startcol, int endcol, int clearcol, int clearattr, + bool wrap) { - ui_set_highlight(0); -} - -void ui_puts(uint8_t *str) -{ - uint8_t *p = str; - uint8_t c; - - while ((c = *p)) { - if (c < 0x20) { - abort(); - } - - size_t clen = (size_t)mb_ptr2len(p); - ui_call_put((String){ .data = (char *)p, .size = clen }); - col++; - if (mb_ptr2cells(p) > 1) { - // double cell character, blank the next cell - ui_call_put((String)STRING_INIT); - col++; - } - if (utf_ambiguous_width(utf_ptr2char(p))) { - pending_cursor_update = true; - } - if (col >= width) { - ui_linefeed(); - } - p += clen; - - if (p_wd) { // 'writedelay': flush & delay each time. - ui_flush(); - uint64_t wd = (uint64_t)labs(p_wd); - os_microdelay(wd * 1000u, true); - } + size_t off = LineOffset[row]+(size_t)startcol; + UI_CALL(raw_line, 1, row, startcol, endcol, clearcol, clearattr, wrap, + (const schar_T *)ScreenLines+off, (const sattr_T *)ScreenAttrs+off); + if (p_wd) { // 'writedelay': flush & delay each time. + int old_row = row, old_col = col; + // If'writedelay is active, we set the cursor to highlight what was drawn + ui_cursor_goto(row, MIN(clearcol, (int)Columns-1)); + ui_flush(); + uint64_t wd = (uint64_t)labs(p_wd); + os_microdelay(wd * 1000u, true); + ui_cursor_goto(old_row, old_col); } } -void ui_putc(uint8_t c) -{ - uint8_t buf[2] = {c, 0}; - ui_puts(buf); -} - void ui_cursor_goto(int new_row, int new_col) { if (new_row == row && new_col == col) { @@ -465,10 +344,7 @@ void ui_cursor_goto(int new_row, int new_col) void ui_mode_info_set(void) { - Array style = mode_style_array(); - bool enabled = (*p_guicursor != NUL); - ui_call_mode_info_set(enabled, style); - api_free_array(style); + pending_mode_info_update = true; } int ui_current_row(void) @@ -484,30 +360,26 @@ int ui_current_col(void) void ui_flush(void) { cmdline_ui_flush(); - ui_call_flush(); -} - - -void ui_linefeed(void) -{ - int new_col = 0; - int new_row = row; - if (new_row < sr.bot) { - new_row++; - } else { - ui_call_scroll(1); - } - ui_cursor_goto(new_row, new_col); -} - -static void flush_cursor_update(void) -{ if (pending_cursor_update) { + ui_call_grid_cursor_goto(1, row, col); pending_cursor_update = false; - ui_call_cursor_goto(row, col); } + if (pending_mode_info_update) { + Array style = mode_style_array(); + bool enabled = (*p_guicursor != NUL); + ui_call_mode_info_set(enabled, style); + api_free_array(style); + pending_mode_info_update = false; + } + if (pending_mode_update) { + char *full_name = shape_table[mode_idx].full_name; + ui_call_mode_change(cstr_as_string(full_name), mode_idx); + pending_mode_update = false; + } + ui_call_flush(); } + /// Check if current mode has changed. /// May update the shape of the cursor. void ui_cursor_shape(void) @@ -515,14 +387,13 @@ void ui_cursor_shape(void) if (!full_screen) { return; } - int mode_idx = cursor_get_mode_idx(); + int new_mode_idx = cursor_get_mode_idx(); - if (old_mode_idx != mode_idx) { - old_mode_idx = mode_idx; - char *full_name = shape_table[mode_idx].full_name; - ui_call_mode_change(cstr_as_string(full_name), mode_idx); + if (new_mode_idx != mode_idx) { + mode_idx = new_mode_idx; + pending_mode_update = true; } - conceal_check_cursur_line(); + conceal_check_cursor_line(); } /// Returns true if `widget` is externalized. diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 6b04e9c67a..d89ad60ce7 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -5,14 +5,18 @@ #include <stdbool.h> #include <stdint.h> -#include "api/private/defs.h" -#include "nvim/buffer_defs.h" +#include "nvim/globals.h" +#include "nvim/api/private/defs.h" +#include "nvim/highlight_defs.h" typedef enum { kUICmdline = 0, kUIPopupmenu, kUITabline, kUIWildmenu, +#define kUIGlobalCount (kUIWildmenu+1) + kUILinegrid, + kUIHlState, kUIExtCount, } UIExtension; @@ -20,7 +24,9 @@ EXTERN const char *ui_ext_names[] INIT(= { "ext_cmdline", "ext_popupmenu", "ext_tabline", - "ext_wildmenu" + "ext_wildmenu", + "ext_linegrid", + "ext_hlstate", }); @@ -31,9 +37,17 @@ struct ui_t { bool ui_ext[kUIExtCount]; ///< Externalized widgets int width, height; void *data; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ui_events.generated.h" #endif + + // For perfomance and simplicity, we use the dense screen representation + // in the bridge and the TUI. The remote_ui module will translate this + // in to the public grid_line format. + void (*raw_line)(UI *ui, Integer grid, Integer row, Integer startcol, + Integer endcol, Integer clearcol, Integer clearattr, + Boolean wrap, const schar_T *chunk, const sattr_T *attrs); void (*event)(UI *ui, char *name, Array args, bool *args_consumed); void (*stop)(UI *ui); void (*inspect)(UI *ui, Dictionary *info); diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 56db124a46..ebd4651f4d 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -42,10 +42,9 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->ui = ui; rv->bridge.rgb = ui->rgb; rv->bridge.stop = ui_bridge_stop; - rv->bridge.resize = ui_bridge_resize; - rv->bridge.clear = ui_bridge_clear; - rv->bridge.eol_clear = ui_bridge_eol_clear; - rv->bridge.cursor_goto = ui_bridge_cursor_goto; + rv->bridge.grid_resize = ui_bridge_grid_resize; + rv->bridge.grid_clear = ui_bridge_grid_clear; + rv->bridge.grid_cursor_goto = ui_bridge_grid_cursor_goto; rv->bridge.mode_info_set = ui_bridge_mode_info_set; rv->bridge.update_menu = ui_bridge_update_menu; rv->bridge.busy_start = ui_bridge_busy_start; @@ -53,10 +52,8 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.mouse_on = ui_bridge_mouse_on; rv->bridge.mouse_off = ui_bridge_mouse_off; rv->bridge.mode_change = ui_bridge_mode_change; - rv->bridge.set_scroll_region = ui_bridge_set_scroll_region; - rv->bridge.scroll = ui_bridge_scroll; - rv->bridge.highlight_set = ui_bridge_highlight_set; - rv->bridge.put = ui_bridge_put; + rv->bridge.grid_scroll = ui_bridge_grid_scroll; + rv->bridge.hl_attr_define = ui_bridge_hl_attr_define; rv->bridge.bell = ui_bridge_bell; rv->bridge.visual_bell = ui_bridge_visual_bell; rv->bridge.default_colors_set = ui_bridge_default_colors_set; @@ -65,6 +62,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.set_title = ui_bridge_set_title; rv->bridge.set_icon = ui_bridge_set_icon; rv->bridge.option_set = ui_bridge_option_set; + rv->bridge.raw_line = ui_bridge_raw_line; rv->scheduler = scheduler; for (UIExtension i = 0; (int)i < kUIExtCount; i++) { @@ -133,17 +131,43 @@ static void ui_bridge_stop_event(void **argv) ui->stop(ui); } -static void ui_bridge_highlight_set(UI *b, HlAttrs attrs) +static void ui_bridge_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, + HlAttrs cterm_attrs, Array info) { HlAttrs *a = xmalloc(sizeof(HlAttrs)); *a = attrs; - UI_BRIDGE_CALL(b, highlight_set, 2, b, a); + UI_BRIDGE_CALL(ui, hl_attr_define, 3, ui, INT2PTR(id), a); } -static void ui_bridge_highlight_set_event(void **argv) +static void ui_bridge_hl_attr_define_event(void **argv) { UI *ui = UI(argv[0]); - ui->highlight_set(ui, *((HlAttrs *)argv[1])); - xfree(argv[1]); + Array info = ARRAY_DICT_INIT; + ui->hl_attr_define(ui, PTR2INT(argv[1]), *((HlAttrs *)argv[2]), + *((HlAttrs *)argv[2]), info); + xfree(argv[2]); +} + +static void ui_bridge_raw_line_event(void **argv) +{ + UI *ui = UI(argv[0]); + ui->raw_line(ui, PTR2INT(argv[1]), PTR2INT(argv[2]), PTR2INT(argv[3]), + PTR2INT(argv[4]), PTR2INT(argv[5]), PTR2INT(argv[6]), + PTR2INT(argv[7]), argv[8], argv[9]); + xfree(argv[8]); + xfree(argv[9]); +} +static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row, + Integer startcol, Integer endcol, + Integer clearcol, Integer clearattr, + Boolean wrap, const schar_T *chunk, + const sattr_T *attrs) +{ + size_t ncol = (size_t)(endcol-startcol); + schar_T *c = xmemdup(chunk, ncol * sizeof(schar_T)); + sattr_T *hl = xmemdup(attrs, ncol * sizeof(sattr_T)); + UI_BRIDGE_CALL(ui, raw_line, 10, ui, INT2PTR(grid), INT2PTR(row), + INT2PTR(startcol), INT2PTR(endcol), INT2PTR(clearcol), + INT2PTR(clearattr), INT2PTR(wrap), c, hl); } static void ui_bridge_suspend(UI *b) diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 2055b4879e..df0507ed41 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -122,7 +122,7 @@ static long u_newcount, u_oldcount; * When 'u' flag included in 'cpoptions', we behave like vi. Need to remember * the action that "u" should do. */ -static int undo_undoes = FALSE; +static bool undo_undoes = false; static int lastmark = 0; @@ -591,7 +591,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) uep->ue_next = curbuf->b_u_newhead->uh_entry; curbuf->b_u_newhead->uh_entry = uep; curbuf->b_u_synced = false; - undo_undoes = FALSE; + undo_undoes = false; #ifdef U_DEBUG u_check(FALSE); @@ -891,7 +891,7 @@ static u_header_T *unserialize_uhp(bufinfo_T *bi, for (;; ) { int len = undo_read_byte(bi); - if (len == 0) { + if (len == 0 || len == EOF) { break; } int what = undo_read_byte(bi); @@ -1675,10 +1675,11 @@ void u_undo(int count) count = 1; } - if (vim_strchr(p_cpo, CPO_UNDO) == NULL) - undo_undoes = TRUE; - else + if (vim_strchr(p_cpo, CPO_UNDO) == NULL) { + undo_undoes = true; + } else { undo_undoes = !undo_undoes; + } u_doit(count, false, true); } @@ -1804,31 +1805,29 @@ static void u_doit(int startcount, bool quiet, bool do_buf_event) u_undo_end(undo_undoes, false, quiet); } -/* - * Undo or redo over the timeline. - * When "step" is negative go back in time, otherwise goes forward in time. - * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as - * seconds. - * When "file" is TRUE use "step" as a number of file writes. - * When "absolute" is TRUE use "step" as the sequence number to jump to. - * "sec" must be FALSE then. - */ -void undo_time(long step, int sec, int file, int absolute) +// Undo or redo over the timeline. +// When "step" is negative go back in time, otherwise goes forward in time. +// When "sec" is false make "step" steps, when "sec" is true use "step" as +// seconds. +// When "file" is true use "step" as a number of file writes. +// When "absolute" is true use "step" as the sequence number to jump to. +// "sec" must be false then. +void undo_time(long step, bool sec, bool file, bool absolute) { long target; long closest; long closest_start; long closest_seq = 0; long val; - u_header_T *uhp; + u_header_T *uhp = NULL; u_header_T *last; int mark; int nomark; int round; - int dosec = sec; - int dofile = file; - int above = FALSE; - int did_undo = TRUE; + bool dosec = sec; + bool dofile = file; + bool above = false; + bool did_undo = true; /* First make sure the current undoable change is synced. */ if (curbuf->b_u_synced == false) @@ -1842,13 +1841,7 @@ void undo_time(long step, int sec, int file, int absolute) /* "target" is the node below which we want to be. * Init "closest" to a value we can't reach. */ if (absolute) { - if (step == 0) { - // target 0 does not exist, got to 1 and above it. - target = 1; - above = true; - } else { - target = step; - } + target = step; closest = -1; } else { if (dosec) { @@ -1873,7 +1866,7 @@ void undo_time(long step, int sec, int file, int absolute) if (target <= 0) /* Go to before first write: before the oldest change. Use * the sequence number for that. */ - dofile = FALSE; + dofile = false; } else { /* Moving forward to a newer write. */ target = curbuf->b_u_save_nr_cur + step; @@ -1881,7 +1874,7 @@ void undo_time(long step, int sec, int file, int absolute) /* Go to after last write: after the latest change. Use * the sequence number for that. */ target = curbuf->b_u_seq_last + 1; - dofile = FALSE; + dofile = false; } } } else @@ -1906,6 +1899,12 @@ void undo_time(long step, int sec, int file, int absolute) closest_start = closest; closest_seq = curbuf->b_u_seq_cur; + // When "target" is 0; Back to origin. + if (target == 0) { + mark = lastmark; // avoid that GCC complains + goto target_zero; + } + /* * May do this twice: * 1. Search for "target", update "closest" to the best match found. @@ -2015,17 +2014,17 @@ void undo_time(long step, int sec, int file, int absolute) } target = closest_seq; - dosec = FALSE; - dofile = FALSE; - if (step < 0) - above = TRUE; /* stop above the header */ + dosec = false; + dofile = false; + if (step < 0) { + above = true; // stop above the header + } } - /* If we found it: Follow the path to go to where we want to be. */ - if (uhp != NULL) { - /* - * First go up the tree as much as needed. - */ +target_zero: + // If we found it: Follow the path to go to where we want to be. + if (uhp != NULL || target == 0) { + // First go up the tree as much as needed. while (!got_int) { /* Do the change warning now, for the same reason as above. */ change_warning(0); @@ -2035,83 +2034,97 @@ void undo_time(long step, int sec, int file, int absolute) uhp = curbuf->b_u_newhead; else uhp = uhp->uh_next.ptr; - if (uhp == NULL || uhp->uh_walk != mark - || (uhp->uh_seq == target && !above)) + if (uhp == NULL + || (target > 0 && uhp->uh_walk != mark) + || (uhp->uh_seq == target && !above)) { break; + } curbuf->b_u_curhead = uhp; u_undoredo(true, true); - uhp->uh_walk = nomark; // don't go back down here + if (target > 0) { + uhp->uh_walk = nomark; // don't go back down here + } } - /* - * And now go down the tree (redo), branching off where needed. - */ - while (!got_int) { - /* Do the change warning now, for the same reason as above. */ - change_warning(0); - - uhp = curbuf->b_u_curhead; - if (uhp == NULL) - break; + // When back to origin, redo is not needed. + if (target > 0) { + // And now go down the tree (redo), branching off where needed. + while (!got_int) { + // Do the change warning now, for the same reason as above. + change_warning(0); - /* Go back to the first branch with a mark. */ - while (uhp->uh_alt_prev.ptr != NULL - && uhp->uh_alt_prev.ptr->uh_walk == mark) - uhp = uhp->uh_alt_prev.ptr; + uhp = curbuf->b_u_curhead; + if (uhp == NULL) { + break; + } - /* Find the last branch with a mark, that's the one. */ - last = uhp; - while (last->uh_alt_next.ptr != NULL - && last->uh_alt_next.ptr->uh_walk == mark) - last = last->uh_alt_next.ptr; - if (last != uhp) { - /* Make the used branch the first entry in the list of - * alternatives to make "u" and CTRL-R take this branch. */ - while (uhp->uh_alt_prev.ptr != NULL) + // Go back to the first branch with a mark. + while (uhp->uh_alt_prev.ptr != NULL + && uhp->uh_alt_prev.ptr->uh_walk == mark) { uhp = uhp->uh_alt_prev.ptr; - if (last->uh_alt_next.ptr != NULL) - last->uh_alt_next.ptr->uh_alt_prev.ptr = - last->uh_alt_prev.ptr; - last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr; - last->uh_alt_prev.ptr = NULL; - last->uh_alt_next.ptr = uhp; - uhp->uh_alt_prev.ptr = last; - - if (curbuf->b_u_oldhead == uhp) - curbuf->b_u_oldhead = last; - uhp = last; - if (uhp->uh_next.ptr != NULL) - uhp->uh_next.ptr->uh_prev.ptr = uhp; - } - curbuf->b_u_curhead = uhp; + } - if (uhp->uh_walk != mark) - break; /* must have reached the target */ + // Find the last branch with a mark, that's the one. + last = uhp; + while (last->uh_alt_next.ptr != NULL + && last->uh_alt_next.ptr->uh_walk == mark) { + last = last->uh_alt_next.ptr; + } + if (last != uhp) { + // Make the used branch the first entry in the list of + // alternatives to make "u" and CTRL-R take this branch. + while (uhp->uh_alt_prev.ptr != NULL) { + uhp = uhp->uh_alt_prev.ptr; + } + if (last->uh_alt_next.ptr != NULL) { + last->uh_alt_next.ptr->uh_alt_prev.ptr = last->uh_alt_prev.ptr; + } + last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr; + last->uh_alt_prev.ptr = NULL; + last->uh_alt_next.ptr = uhp; + uhp->uh_alt_prev.ptr = last; - /* Stop when going backwards in time and didn't find the exact - * header we were looking for. */ - if (uhp->uh_seq == target && above) { - curbuf->b_u_seq_cur = target - 1; - break; - } + if (curbuf->b_u_oldhead == uhp) { + curbuf->b_u_oldhead = last; + } + uhp = last; + if (uhp->uh_next.ptr != NULL) { + uhp->uh_next.ptr->uh_prev.ptr = uhp; + } + } + curbuf->b_u_curhead = uhp; - u_undoredo(false, true); + if (uhp->uh_walk != mark) { + break; // must have reached the target + } - /* Advance "curhead" to below the header we last used. If it - * becomes NULL then we need to set "newhead" to this leaf. */ - if (uhp->uh_prev.ptr == NULL) - curbuf->b_u_newhead = uhp; - curbuf->b_u_curhead = uhp->uh_prev.ptr; - did_undo = FALSE; + // Stop when going backwards in time and didn't find the exact + // header we were looking for. + if (uhp->uh_seq == target && above) { + curbuf->b_u_seq_cur = target - 1; + break; + } - if (uhp->uh_seq == target) /* found it! */ - break; + u_undoredo(false, true); - uhp = uhp->uh_prev.ptr; - if (uhp == NULL || uhp->uh_walk != mark) { - // Need to redo more but can't find it... - internal_error("undo_time()"); - break; + // Advance "curhead" to below the header we last used. If it + // becomes NULL then we need to set "newhead" to this leaf. + if (uhp->uh_prev.ptr == NULL) { + curbuf->b_u_newhead = uhp; + } + curbuf->b_u_curhead = uhp->uh_prev.ptr; + did_undo = false; + + if (uhp->uh_seq == target) { // found it! + break; + } + + uhp = uhp->uh_prev.ptr; + if (uhp == NULL || uhp->uh_walk != mark) { + // Need to redo more but can't find it... + internal_error("undo_time()"); + break; + } } } } @@ -2233,10 +2246,11 @@ static void u_undoredo(int undo, bool do_buf_event) * If the file is empty, there is an empty line 1 that we * should get rid of, by replacing it with the new line */ - if (empty_buffer && lnum == 0) - ml_replace((linenr_T)1, uep->ue_array[i], TRUE); - else + if (empty_buffer && lnum == 0) { + ml_replace((linenr_T)1, uep->ue_array[i], true); + } else { ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE); + } xfree(uep->ue_array[i]); } xfree((char_u *)uep->ue_array); @@ -2374,8 +2388,8 @@ static void u_undoredo(int undo, bool do_buf_event) /// Otherwise, report the number of changes (this may be incorrect /// in some cases, but it's better than nothing). static void u_undo_end( - int did_undo, ///< just did an undo - int absolute, ///< used ":undo N" + bool did_undo, ///< just did an undo + bool absolute, ///< used ":undo N" bool quiet) { char *msgstr; @@ -2415,13 +2429,15 @@ static void u_undo_end( /* For ":undo N" we prefer a "after #N" message. */ if (absolute && curbuf->b_u_curhead->uh_next.ptr != NULL) { uhp = curbuf->b_u_curhead->uh_next.ptr; - did_undo = FALSE; - } else if (did_undo) + did_undo = false; + } else if (did_undo) { uhp = curbuf->b_u_curhead; - else + } else { uhp = curbuf->b_u_curhead->uh_next.ptr; - } else + } + } else { uhp = curbuf->b_u_newhead; + } if (uhp == NULL) *msgbuf = NUL; @@ -2487,8 +2503,8 @@ void ex_undolist(exarg_T *eap) while (uhp != NULL) { if (uhp->uh_prev.ptr == NULL && uhp->uh_walk != nomark && uhp->uh_walk != mark) { - vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld ", - uhp->uh_seq, changes); + vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ", + uhp->uh_seq, changes); u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff), uhp->uh_time); if (uhp->uh_save_nr > 0) { @@ -2902,7 +2918,7 @@ void u_undoline(void) curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL) return; oldp = u_save_line(curbuf->b_u_line_lnum); - ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE); + ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true); changed_bytes(curbuf->b_u_line_lnum, 0); xfree(curbuf->b_u_line_ptr); curbuf->b_u_line_ptr = oldp; diff --git a/src/nvim/version.c b/src/nvim/version.c index 203b53472c..beb65a8bfd 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -78,38 +78,324 @@ NULL // clang-format off static const int included_patches[] = { + 1847, + // 1846, + // 1845, + // 1844, + 1843, + // 1842, + // 1841, + 1840, + 1839, + // 1838, + 1837, + 1836, + // 1835, + 1834, + 1833, + 1832, + // 1831, + // 1830, + // 1829, + 1828, + // 1827, + 1826, + 1825, + // 1824, + // 1823, + 1822, + // 1821, + // 1820, + 1819, + // 1818, + // 1817, + 1816, + // 1815, + // 1814, + 1813, + // 1812, + 1811, + // 1810, + 1809, + 1808, + 1807, + // 1806, + // 1805, + // 1804, + // 1803, + // 1802, + // 1801, + 1800, + 1799, + // 1798, + // 1797, + // 1796, + // 1795, + // 1794, + // 1793, + 1792, + 1791, + 1790, + // 1789, + 1788, + 1787, + // 1786, + 1785, + // 1784, + // 1783, + // 1782, + 1781, + // 1780, + 1779, + 1778, + 1777, + // 1776, + // 1775, + // 1774, + // 1773, + // 1772, + // 1771, + // 1770, + // 1769, + // 1768, + // 1767, + // 1766, + 1765, + 1764, + // 1763, + // 1762, + // 1761, + 1760, + // 1759, + // 1758, + 1757, + // 1756, + 1755, + // 1754, + // 1753, + // 1752, + 1751, + // 1750, + 1749, + // 1748, + // 1747, + // 1746, + // 1745, + // 1744, + // 1743, + // 1742, + 1741, + // 1740, + 1739, + // 1738, + 1737, + 1736, + // 1735, + // 1734, + // 1733, + // 1732, + // 1731, + 1730, + // 1729, + // 1728, + // 1727, + // 1726, + // 1725, + // 1724, + // 1723, + // 1722, + // 1721, + // 1720, + 1719, + // 1718, + 1717, + // 1716, + // 1715, + // 1714, + // 1713, + // 1712, + // 1711, + 1710, + // 1709, + // 1708, + 1707, + // 1706, + 1705, + // 1704, + // 1703, + // 1702, + 1701, + 1700, + 1699, + 1698, + // 1697, + 1696, + // 1695, + // 1694, + // 1693, + 1692, + // 1691, + // 1690, + // 1689, + // 1688, + // 1687, + 1686, + // 1685, + // 1684, + 1683, + 1682, + // 1681, + // 1680, + 1679, + // 1678, + // 1677, + // 1676, + 1675, + 1674, + // 1673, + 1672, + // 1671, + // 1670, + // 1669, + // 1668, + // 1667, + // 1666, + // 1665, + // 1664, + 1663, + // 1662, + // 1661, + // 1660, + 1659, + // 1658, + // 1657, + // 1656, + // 1655, + // 1654, + // 1653, + // 1652, + // 1651, + 1650, + 1649, + // 1648, + // 1647, + 1646, + // 1645, + // 1644, + // 1643, + // 1642, + // 1641, + // 1640, + 1639, + // 1638, + // 1637, + // 1636, + 1635, + // 1634, + 1633, + // 1632, + // 1631, + 1630, + // 1629, + // 1628, + 1627, + // 1626, + 1625, + // 1624, + // 1623, + 1622, + // 1621, + // 1620, + // 1619, + 1618, + // 1617, + // 1616, + // 1615, + 1614, + 1613, + // 1612, + // 1611, + 1610, + // 1609, + 1608, + // 1607, + 1606, + // 1605, + // 1604, + 1603, + 1602, + 1601, + 1600, + // 1599, + // 1598, + 1597, + // 1596, + 1595, + // 1594, + // 1593, + // 1592, + // 1591, + 1590, + // 1589, + // 1588, + // 1587, + 1586, + 1585, + 1584, + 1583, + // 1582, + 1581, + 1580, + 1579, + // 1578, + 1577, + // 1576, + 1575, + // 1574, + 1573, + // 1572, + 1571, + // 1570, + // 1569, + // 1568, + 1567, + 1566, + 1565, + 1564, + // 1563, + // 1562, 1561, - // 1560, - // 1559, + 1560, + 1559, // 1558, - // 1557, - // 1556, - // 1555, + 1557, + 1556, + 1555, // 1554, // 1553, // 1552, // 1551, // 1550, // 1549, - // 1548, - // 1547, + 1548, + 1547, // 1546, // 1545, // 1544, // 1543, // 1542, - // 1541, + 1541, // 1540, // 1539, // 1538, // 1537, - // 1536, + 1536, // 1535, // 1534, // 1533, - // 1532, + 1532, // 1531, - // 1530, + 1530, // 1529, // 1528, // 1527, @@ -122,22 +408,22 @@ static const int included_patches[] = { // 1520, // 1519, // 1518, - // 1517, + 1517, // 1516, // 1515, // 1514, // 1513, - // 1512, + 1512, // 1511, // 1510, - // 1509, - // 1508, - // 1507, - // 1506, + 1509, + 1508, + 1507, + 1506, // 1505, - // 1504, - // 1503, - // 1502, + 1504, + 1503, + 1502, // 1501, // 1500, // 1499, @@ -149,33 +435,33 @@ static const int included_patches[] = { 1493, // 1492, // 1491, - // 1490, - // 1489, - // 1488, - // 1487, - // 1486, - // 1485, + 1490, + 1489, + 1488, + 1487, + 1486, + 1485, // 1484, 1483, // 1482, // 1481, // 1480, // 1479, - // 1478, + 1478, // 1477, // 1476, 1475, - // 1474, - // 1473, + 1474, + 1473, 1472, - // 1471, - // 1470, + 1471, + 1470, // 1469, - // 1468, - // 1467, - // 1466, + 1468, + 1467, + 1466, // 1465, - // 1464, + 1464, // 1463, // 1462, // 1461, @@ -183,102 +469,102 @@ static const int included_patches[] = { // 1459, // 1458, // 1457, - // 1456, + 1456, // 1455, // 1454, // 1453, // 1452, // 1451, - // 1450, + 1450, // 1449, // 1448, // 1447, - // 1446, + 1446, // 1445, - // 1444, - // 1443, + 1444, + 1443, 1442, - // 1441, + 1441, // 1440, 1439, // 1438, - // 1437, + 1437, // 1436, 1435, 1434, - // 1433, + 1433, // 1432, - // 1431, + 1431, // 1430, // 1429, - // 1428, + 1428, // 1427, - // 1426, + 1426, // 1425, - // 1424, - // 1423, + 1424, + 1423, // 1422, - // 1421, + 1421, // 1420, 1419, - // 1418, - // 1417, - // 1416, - // 1415, + 1418, + 1417, + 1416, + 1415, // 1414, - // 1413, + 1413, // 1412, // 1411, - // 1410, - // 1409, + 1410, + 1409, // 1408, - // 1407, + 1407, // 1406, // 1405, - // 1404, + 1404, 1403, 1402, - // 1401, - // 1400, - // 1399, - // 1398, - // 1397, + 1401, + 1400, + 1399, + 1398, + 1397, 1396, - // 1395, - // 1394, + 1395, + 1394, 1393, - // 1392, - // 1391, - // 1390, + 1392, + 1391, + 1390, // 1389, // 1388, - // 1387, + 1387, // 1386, - // 1385, + 1385, // 1384, - // 1383, + 1383, // 1382, // 1381, - // 1380, - // 1379, - // 1378, - // 1377, + 1380, + 1379, + 1378, + 1377, // 1376, // 1375, - // 1374, - // 1373, + 1374, + 1373, // 1372, // 1371, 1370, - // 1369, + 1369, // 1368, // 1367, // 1366, 1365, - // 1364, - // 1363, + 1364, + 1363, // 1362, - // 1361, + 1361, // 1360, // 1359, // 1358, @@ -288,7 +574,7 @@ static const int included_patches[] = { // 1354, // 1353, // 1352, - // 1351, + 1351, // 1350, // 1349, // 1348, @@ -302,22 +588,22 @@ static const int included_patches[] = { // 1340, // 1339, // 1338, - // 1337, + 1337, // 1336, // 1335, // 1334, 1333, // 1332, - // 1331, + 1331, // 1330, 1329, // 1328, - // 1327, - // 1326, - // 1325, - // 1324, + 1327, + 1326, + 1325, + 1324, // 1323, - // 1322, + 1322, // 1321, // 1320, // 1319, @@ -325,33 +611,33 @@ static const int included_patches[] = { // 1317, // 1316, // 1315, - // 1314, - // 1313, + 1314, + 1313, // 1312, 1311, - // 1310, + 1310, // 1309, // 1308, // 1307, - // 1306, + 1306, // 1305, 1304, - // 1303, + 1303, 1302, - // 1301, + 1301, // 1300, // 1299, // 1298, // 1297, // 1296, // 1295, - // 1294, + 1294, // 1293, // 1292, - // 1291, - // 1290, + 1291, + 1290, 1289, - // 1288, + 1288, // 1287, // 1286, 1285, @@ -364,14 +650,14 @@ static const int included_patches[] = { // 1278, // 1277, // 1276, - // 1275, + 1275, // 1274, - // 1273, - // 1272, + 1273, + 1272, 1271, // 1270, - // 1269, - // 1268, + 1269, + 1268, // 1267, // 1266, // 1265, @@ -381,38 +667,38 @@ static const int included_patches[] = { // 1261, // 1260, // 1259, - // 1258, - // 1257, - // 1256, - // 1255, - // 1254, - // 1253, - // 1252, - // 1251, + 1258, + 1257, + 1256, + 1255, + 1254, + 1253, + 1252, + 1251, 1250, // 1249, - // 1248, - // 1247, + 1248, + 1247, // 1246, // 1245, // 1244, - // 1243, - // 1242, + 1243, + 1242, // 1241, // 1240, // 1239, 1238, - // 1237, + 1237, // 1236, - // 1235, + 1235, 1234, - // 1233, + 1233, 1232, - // 1231, + 1231, 1230, 1229, - // 1228, - // 1227, + 1228, + 1227, 1226, 1225, 1224, @@ -421,16 +707,16 @@ static const int included_patches[] = { 1221, // 1220, 1219, - // 1218, + 1218, // 1217, - // 1216, - // 1215, - // 1214, + 1216, + 1215, + 1214, // 1213, - // 1212, - // 1211, + 1212, + 1211, 1210, - // 1209, + 1209, // 1208, 1207, 1206, @@ -438,72 +724,72 @@ static const int included_patches[] = { 1204, // 1203, // 1202, - // 1201, + 1201, 1200, // 1199, - // 1198, + 1198, 1197, - // 1196, - // 1195, + 1196, + 1195, // 1194, // 1193, - // 1192, + 1192, 1191, - // 1190, + 1190, 1189, 1188, - // 1187, + 1187, 1186, - // 1185, - // 1184, - // 1183, + 1185, + 1184, + 1183, // 1182, 1181, 1180, // 1179, - // 1178, + 1178, // 1177, // 1176, - // 1175, + 1175, // 1174, // 1173, - // 1172, + 1172, // 1171, // 1170, - // 1169, - // 1168, + 1169, + 1168, // 1167, - // 1166, + 1166, // 1165, // 1164, // 1163, // 1162, - // 1161, - // 1160, - // 1159, + 1161, + 1160, + 1159, 1158, - // 1157, - // 1156, - // 1155, - // 1154, + 1157, + 1156, + 1155, + 1154, // 1153, - // 1152, - // 1151, + 1152, + 1151, 1150, // 1149, - // 1148, - // 1147, + 1148, + 1147, // 1146, // 1145, // 1144, // 1143, // 1142, 1141, - // 1140, + 1140, // 1139, // 1138, // 1137, - // 1136, + 1136, // 1135, // 1134, // 1133, @@ -515,151 +801,151 @@ static const int included_patches[] = { // 1127, // 1126, // 1125, - // 1124, + 1124, // 1123, - // 1122, + 1122, 1121, // 1120, // 1119, - // 1118, + 1118, // 1117, // 1116, - // 1115, + 1115, // 1114, // 1113, // 1112, - // 1111, - // 1110, + 1111, + 1110, // 1109, 1108, // 1107, // 1106, - // 1105, + 1105, // 1104, // 1103, // 1102, // 1101, // 1100, - // 1099, - // 1098, + 1099, + 1098, // 1097, // 1096, // 1095, - // 1094, + 1094, // 1093, // 1092, - // 1091, - // 1090, - // 1089, - // 1088, + 1091, + 1090, + 1089, + 1088, // 1087, - // 1086, + 1086, // 1085, - // 1084, + 1084, // 1083, // 1082, // 1081, // 1080, // 1079, - // 1078, + 1078, // 1077, // 1076, // 1075, // 1074, // 1073, - // 1072, - // 1071, + 1072, + 1071, // 1070, - // 1069, - // 1068, - // 1067, - // 1066, - // 1065, + 1069, + 1068, + 1067, + 1066, + 1065, // 1064, // 1063, - // 1062, + 1062, // 1061, // 1060, - // 1059, + 1059, // 1058, // 1057, - // 1056, + 1056, // 1055, // 1054, // 1053, // 1052, // 1051, - // 1050, + 1050, // 1049, - // 1048, - // 1047, - // 1046, + 1048, + 1047, + 1046, // 1045, - // 1044, - // 1043, - // 1042, - // 1041, - // 1040, + 1044, + 1043, + 1042, + 1041, + 1040, // 1039, // 1038, - // 1037, + 1037, // 1036, // 1035, // 1034, - // 1033, - // 1032, - // 1031, - // 1030, - // 1029, + 1033, + 1032, + 1031, + 1030, + 1029, // 1028, - // 1027, - // 1026, + 1027, + 1026, 1025, 1024, - // 1023, - // 1022, - // 1021, - // 1020, + 1023, + 1022, + 1021, + 1020, 1019, // 1018, - // 1017, - // 1016, + 1017, + 1016, // 1015, - // 1014, + 1014, // 1013, - // 1012, + 1012, // 1011, - // 1010, + 1010, // 1009, - // 1008, + 1008, 1007, - // 1006, + 1006, // 1005, - // 1004, + 1004, // 1003, // 1002, - // 1001, + 1001, // 1000, - // 999, - // 998, - // 997, - // 996, + 999, + 998, + 997, + 996, // 995, // 994, - // 993, + 993, // 992, // 991, // 990, - // 989, - // 988, + 989, + 988, // 987, - // 986, + 986, // 985, // 984, - // 983, + 983, // 982, // 981, - // 980, + 980, // 979, // 978, // 977, @@ -667,33 +953,33 @@ static const int included_patches[] = { 975, 974, // 973, - // 972, - // 971, + 972, + 971, // 970, // 969, // 968, - // 967, - // 966, + 967, + 966, // 965, // 964, // 963, 962, - // 961, + 961, // 960, // 959, // 958, // 957, // 956, 955, - // 954, + 954, // 953, // 952, // 951, // 950, // 949, - // 948, + 948, // 947, - // 946, + 946, // 945, 944, // 943, @@ -717,10 +1003,10 @@ static const int included_patches[] = { 925, // 924, // 923, - // 922, - // 921, + 922, + 921, // 920, - // 919, + 919, // 918, // 917, // 916, @@ -735,11 +1021,11 @@ static const int included_patches[] = { // 907, 906, // 905, - // 904, + 904, // 903, // 902, - // 901, - // 900, + 901, + 900, // 899, // 898, // 897, @@ -749,22 +1035,22 @@ static const int included_patches[] = { // 893, // 892, // 891, - // 890, + 890, // 889, // 888, // 887, // 886, // 885, // 884, - // 883, + 883, // 882, 881, - // 880, - // 879, - // 878, + 880, + 879, + 878, // 877, // 876, - // 875, + 875, // 874, // 873, // 872, @@ -773,8 +1059,8 @@ static const int included_patches[] = { // 869, // 868, // 867, - // 866, - // 865, + 866, + 865, // 864, // 863, 862, @@ -788,7 +1074,7 @@ static const int included_patches[] = { // 854, // 853, // 852, - // 851, + 851, // 850, // 849, // 848, @@ -802,22 +1088,22 @@ static const int included_patches[] = { // 840, // 839, // 838, - // 837, + 837, // 836, - // 835, - // 834, + 835, + 834, // 833, // 832, - // 831, - // 830, + 831, + 830, // 829, - // 828, + 828, // 827, // 826, // 825, // 824, // 823, - // 822, + 822, // 821, // 820, // 819, @@ -825,16 +1111,16 @@ static const int included_patches[] = { // 817, // 816, // 815, - // 814, + 814, // 813, // 812, - // 811, - // 810, - // 809, - // 808, + 811, + 810, + 809, + 808, // 807, - // 806, - // 805, + 806, + 805, // 804, // 803, // 802, @@ -843,54 +1129,54 @@ static const int included_patches[] = { // 799, // 798, // 797, - // 796, - // 795, - // 794, + 796, + 795, + 794, // 793, 792, - // 791, - // 790, + 791, + 790, // 789, // 788, // 787, - // 786, + 786, // 785, // 784, // 783, - // 782, + 782, // 781, - // 780, + 780, // 779, // 778, // 777, // 776, // 775, - // 774, - // 773, - // 772, + 774, + 773, + 772, // 771, - // 770, + 770, // 769, // 768, - // 767, + 767, // 766, - // 765, + 765, // 764, - // 763, - // 762, + 763, + 762, // 761, // 760, // 759, // 758, - // 757, - // 756, + 757, + 756, // 755, // 754, // 753, - // 752, - // 751, - // 750, - // 749, + 752, + 751, + 750, + 749, // 748, // 747, // 746, @@ -898,29 +1184,29 @@ static const int included_patches[] = { // 744, // 743, // 742, - // 741, + 741, // 740, // 739, // 738, // 737, 736, - // 735, - // 734, - // 733, + 735, + 734, + 733, // 732, - // 731, + 731, // 730, - // 729, + 729, // 728, - // 727, - // 726, + 727, + 726, // 725, - // 724, + 724, 723, - // 722, + 722, 721, // 720, - // 719, + 719, // 718, // 717, // 716, @@ -928,55 +1214,55 @@ static const int included_patches[] = { // 714, // 713, // 712, - // 711, + 711, 710, // 709, - // 708, - // 707, - // 706, + 708, + 707, + 706, // 705, - // 704, + 704, 703, // 702, 701, 700, 699, // 698, - // 697, - // 696, - // 695, + 697, + 696, + 695, // 694, // 693, 692, - // 691, - // 690, + 691, + 690, 689, - // 688, - // 687, - // 686, - // 685, + 688, + 687, + 686, + 685, 684, // 683, - // 682, + 682, // 681, 680, 679, 678, - // 677, + 677, 676, - // 675, + 675, 674, 673, 672, - // 671, - // 670, - // 669, + 671, + 670, + 669, 668, 667, 666, 665, 664, - // 663, + 663, 662, 661, 660, @@ -986,140 +1272,140 @@ static const int included_patches[] = { 656, 655, 654, - // 653, + 653, 652, - // 651, + 651, 650, - // 649, - // 648, + 649, + 648, // 647, // 646, // 645, // 644, // 643, - // 642, + 642, 641, - // 640, - // 639, - // 638, - // 637, - // 636, + 640, + 639, + 638, + 637, + 636, 635, 634, - // 633, - // 632, - // 631, - // 630, + 633, + 632, + 631, + 630, // 629, - // 628, - // 627, - // 626, - // 625, - // 624, - // 623, + 628, + 627, + 626, + 625, + 624, + 623, 622, - // 621, - // 620, - // 619, + 621, + 620, + 619, 618, - // 617, - // 616, - // 615, + 617, + 616, + 615, 614, 613, 612, - // 611, - // 610, - // 609, + 611, + 610, + 609, 608, 607, 606, 605, - // 604, - // 603, - // 602, + 604, + 603, + 602, 601, 600, 599, - // 598, + 598, 597, - // 596, + 596, 595, - // 594, - // 593, + 594, + 593, // 592, 591, 590, - // 589, - // 588, - // 587, - // 586, + 589, + 588, + 587, + 586, // 585, 584, - // 583, + 583, 582, - // 581, + 581, 580, 579, - // 578, - // 577, - // 576, - // 575, + 578, + 577, + 576, + 575, 574, - // 573, + 573, // 572, 571, - // 570, - // 569, - // 568, - // 567, - // 566, + 570, + 569, + 568, + 567, + 566, 565, 564, - // 563, + 563, 562, 561, - // 560, + 560, 559, 558, - // 557, - // 556, + 557, + 556, 555, 554, 553, 552, - // 551, + 551, 550, - // 549, - // 548, - // 547, - // 546, - // 545, - // 544, - // 543, - // 542, - // 541, - // 540, - // 539, - // 538, - // 537, + 549, + 548, + 547, + 546, + 545, + 544, + 543, + 542, + 541, + 540, + 539, + 538, + 537, 536, - // 535, - // 534, - // 533, - // 532, - // 531, - // 530, - // 529, + 535, + 534, + 533, + 532, + 531, + 530, + 529, 528, - // 527, - // 526, - // 525, + 527, + 526, + 525, 524, - // 523, - // 522, - // 521, - // 520, + 523, + 522, + 521, + 520, 519, 518, 517, @@ -1127,27 +1413,27 @@ static const int included_patches[] = { 515, // 514, 513, - // 512, + 512, 511, - // 510, - // 509, - // 508, + 510, + 509, + 508, 507, // 506, 505, // 504, 503, 502, - // 501, + 501, 500, 499, 498, 497, 496, 495, - // 494, - // 493, - // 492, + 494, + 493, + 492, 491, 490, 489, @@ -1158,43 +1444,43 @@ static const int included_patches[] = { 484, 483, 482, - // 481, + 481, 480, 479, 478, 477, - // 476, - // 475, - // 474, + 476, + 475, + 474, 473, 472, 471, 470, - // 469, - // 468, - // 467, - // 466, + 469, + 468, + 467, + 466, 465, 464, 463, - // 462, + 462, 461, 460, 459, 458, 457, 456, - // 455, + 455, 454, 453, - // 452, - // 451, + 452, + 451, 450, - // 449, + 449, 448, 447, 446, - // 445, + 445, 444, 443, 442, @@ -1207,29 +1493,29 @@ static const int included_patches[] = { 435, 434, 433, - // 432, + 432, 431, // 430, // 429, // 428, 427, 426, - // 425, + 425, 424, 423, - // 422, + 422, 421, 420, 419, - // 418, + 418, 417, 416, 415, - // 414, + 414, // 413, // 412, // 411, - // 410, + 410, 409, 408, 407, @@ -1238,22 +1524,22 @@ static const int included_patches[] = { 404, 403, 402, - // 401, + 401, 400, - // 399, + 399, 398, - // 397, + 397, // 396, - // 395, + 395, 394, 393, - // 392, + 392, 391, 390, 389, 388, 387, - // 386, + 386, 385, 384, 383, @@ -1266,40 +1552,40 @@ static const int included_patches[] = { 376, 375, 374, - // 373, - // 372, + 373, + 372, 371, - // 370, - // 369, - // 368, - // 367, - // 366, - // 365, + 370, + 369, + 368, + 367, + 366, + 365, 364, - // 363, + 363, 362, - // 361, + 361, 360, 359, 358, 357, 356, - // 355, + 355, 354, 353, 352, 351, // 350, - // 349, + 349, 348, 347, - // 346, + 346, 345, 344, 343, 342, 341, - // 340, + 340, 339, 338, 337, @@ -1374,8 +1660,8 @@ static const int included_patches[] = { 268, 267, 266, - // 265, - // 264, + 265, + 264, 263, 262, 261, @@ -1383,11 +1669,11 @@ static const int included_patches[] = { 259, 258, 257, - // 256, - // 255, - // 254, + 256, + 255, + 254, 253, - // 252, + 252, // 251, 250, 249, @@ -1423,7 +1709,7 @@ static const int included_patches[] = { 219, 218, 217, - // 216, + 216, 215, 214, 213, diff --git a/src/nvim/vim.h b/src/nvim/vim.h index 1fe4e53faf..767936ecee 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -155,6 +155,8 @@ enum { EXPAND_USER_ADDR_TYPE, EXPAND_PACKADD, EXPAND_MESSAGES, + EXPAND_MAPCLEAR, + EXPAND_ARGLIST, EXPAND_CHECKHEALTH, }; @@ -207,7 +209,7 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() // defines to avoid typecasts from (char_u *) to (char *) and back -// (vim_strchr() and vim_strrchr() are now in alloc.c) +// (vim_strchr() is now in strings.c) #define STRLEN(s) strlen((char *)(s)) #define STRCPY(d, s) strcpy((char *)(d), (char *)(s)) @@ -238,6 +240,8 @@ enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext() # endif #endif +#define STRRCHR(s, c) (char_u *)strrchr((const char *)(s), (c)) + #define STRCAT(d, s) strcat((char *)(d), (char *)(s)) #define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n)) #define STRLCAT(d, s, n) xstrlcat((char *)(d), (char *)(s), (size_t)(n)) diff --git a/src/nvim/window.c b/src/nvim/window.c index 274bf72f3b..8be79f0cff 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -367,7 +367,7 @@ newwindow: g_do_tagpreview = Prenum; else g_do_tagpreview = p_pvh; - /*FALLTHROUGH*/ + FALLTHROUGH; case ']': case Ctrl_RSB: CHECK_CMDWIN @@ -420,8 +420,8 @@ wingotofile: case 'i': /* Go to any match */ case Ctrl_I: type = FIND_ANY; - /* FALLTHROUGH */ - case 'd': /* Go to definition, using 'define' */ + FALLTHROUGH; + case 'd': // Go to definition, using 'define' case Ctrl_D: CHECK_CMDWIN if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) @@ -465,7 +465,7 @@ wingotofile: g_do_tagpreview = Prenum; else g_do_tagpreview = p_pvh; - /*FALLTHROUGH*/ + FALLTHROUGH; case ']': case Ctrl_RSB: // Keep visual mode, can select words to use as a tag. @@ -565,6 +565,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) int before; int minheight; int wmh1; + bool did_set_fraction = false; if (flags & WSP_TOP) oldwin = firstwin; @@ -729,6 +730,11 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) * 'winfixheight' window. Take them from a window above or below * instead, if possible. */ if (oldwin->w_p_wfh) { + // Set w_fraction now so that the cursor keeps the same relative + // vertical position using the old height. + set_fraction(oldwin); + did_set_fraction = true; + win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT, oldwin); oldwin_height = oldwin->w_height; @@ -843,8 +849,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) /* Set w_fraction now so that the cursor keeps the same relative * vertical position. */ - if (oldwin->w_height > 0) + if (!did_set_fraction) { set_fraction(oldwin); + } wp->w_fraction = oldwin->w_fraction; if (flags & WSP_VERT) { @@ -1258,7 +1265,8 @@ static void win_exchange(long Prenum) (void)win_comp_pos(); /* recompute window positions */ win_enter(wp, true); - redraw_later(CLEAR); + redraw_later(NOT_VALID); + redraw_win_later(wp, NOT_VALID); } /* @@ -1333,7 +1341,7 @@ static void win_rotate(int upwards, int count) (void)win_comp_pos(); } - redraw_later(CLEAR); + redraw_all_later(NOT_VALID); } /* @@ -1470,10 +1478,10 @@ static void win_equal_rec( || topfr->fr_width != width || topfr->fr_win->w_wincol != col ) { topfr->fr_win->w_winrow = row; - frame_new_height(topfr, height, FALSE, FALSE); + frame_new_height(topfr, height, false, false); topfr->fr_win->w_wincol = col; - frame_new_width(topfr, width, FALSE, FALSE); - redraw_all_later(CLEAR); + frame_new_width(topfr, width, false, false); + redraw_all_later(NOT_VALID); } } else if (topfr->fr_layout == FR_ROW) { topfr->fr_width = width; @@ -1852,20 +1860,18 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, return true; } -/* - * Close window "win". Only works for the current tab page. - * If "free_buf" is TRUE related buffer may be unloaded. - * - * Called by :quit, :close, :xit, :wq and findtag(). - * Returns FAIL when the window was not closed. - */ -int win_close(win_T *win, int free_buf) +// Close window "win". Only works for the current tab page. +// If "free_buf" is true related buffer may be unloaded. +// +// Called by :quit, :close, :xit, :wq and findtag(). +// Returns FAIL when the window was not closed. +int win_close(win_T *win, bool free_buf) { win_T *wp; int other_buffer = FALSE; int close_curwin = FALSE; int dir; - int help_window = FALSE; + bool help_window = false; tabpage_T *prev_curtab = curtab; frame_T *win_frame = win->w_frame->fr_parent; @@ -1895,10 +1901,11 @@ int win_close(win_T *win, int free_buf) /* When closing the help window, try restoring a snapshot after closing * the window. Otherwise clear the snapshot, it's now invalid. */ - if (win->w_buffer != NULL && win->w_buffer->b_help) - help_window = TRUE; - else + if (bt_help(win->w_buffer)) { + help_window = true; + } else { clear_snapshot(curtab, SNAP_HELP_IDX); + } if (win == curwin) { /* @@ -1960,10 +1967,11 @@ int win_close(win_T *win, int free_buf) if (only_one_window() && win_valid(win) && win->w_buffer == NULL && (last_window() || curtab != prev_curtab || close_last_window_tabpage(win, free_buf, prev_curtab))) { - /* Autocommands have close all windows, quit now. Restore - * curwin->w_buffer, otherwise writing ShaDa file may fail. */ - if (curwin->w_buffer == NULL) + // Autocommands have closed all windows, quit now. Restore + // curwin->w_buffer, otherwise writing ShaDa file may fail. + if (curwin->w_buffer == NULL) { curwin->w_buffer = curbuf; + } getout(0); } // Autocommands may have moved to another tab page. @@ -2296,6 +2304,9 @@ winframe_remove ( if (frp2->fr_win != NULL) frp2->fr_win->w_frame = frp2->fr_parent; frp = frp2->fr_parent; + if (topframe->fr_child == frp2) { + topframe->fr_child = frp; + } xfree(frp2); frp2 = frp->fr_parent; @@ -2317,6 +2328,9 @@ winframe_remove ( break; } } + if (topframe->fr_child == frp) { + topframe->fr_child = frp2; + } xfree(frp); } } @@ -2324,14 +2338,14 @@ winframe_remove ( return wp; } -/* - * Find out which frame is going to get the freed up space when "win" is - * closed. - * if 'splitbelow'/'splitleft' the space goes to the window above/left. - * if 'nosplitbelow'/'nosplitleft' the space goes to the window below/right. - * This makes opening a window and closing it immediately keep the same window - * layout. - */ +// Return a pointer to the frame that will receive the empty screen space that +// is left over after "win" is closed. +// +// If 'splitbelow' or 'splitright' is set, the space goes above or to the left +// by default. Otherwise, the free space goes below or to the right. The +// result is that opening a window and then immediately closing it will +// preserve the initial window layout. The 'wfh' and 'wfw' settings are +// respected when possible. static frame_T * win_altframe ( win_T *win, @@ -2339,20 +2353,40 @@ win_altframe ( ) { frame_T *frp; - int b; - if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) - /* Last window in this tab page, will go to next tab page. */ + if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) { return alt_tabpage()->tp_curwin->w_frame; + } frp = win->w_frame; - if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW) - b = p_spr; - else - b = p_sb; - if ((!b && frp->fr_next != NULL) || frp->fr_prev == NULL) + + if (frp->fr_prev == NULL) { return frp->fr_next; - return frp->fr_prev; + } + if (frp->fr_next == NULL) { + return frp->fr_prev; + } + + frame_T *target_fr = frp->fr_next; + frame_T *other_fr = frp->fr_prev; + if (p_spr || p_sb) { + target_fr = frp->fr_prev; + other_fr = frp->fr_next; + } + + // If 'wfh' or 'wfw' is set for the target and not for the alternate + // window, reverse the selection. + if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW) { + if (frame_fixed_width(target_fr) && !frame_fixed_width(other_fr)) { + target_fr = other_fr; + } + } else { + if (frame_fixed_height(target_fr) && !frame_fixed_height(other_fr)) { + target_fr = other_fr; + } + } + + return target_fr; } /* @@ -2849,8 +2883,8 @@ close_others ( } if (!r) { if (message && (p_confirm || cmdmod.confirm) && p_write) { - dialog_changed(wp->w_buffer, FALSE); - if (!win_valid(wp)) { /* autocommands messed wp up */ + dialog_changed(wp->w_buffer, false); + if (!win_valid(wp)) { // autocommands messed wp up nextwp = firstwin; continue; } @@ -2959,7 +2993,6 @@ static int win_alloc_firstwin(win_T *oldwin) topframe = curwin->w_frame; topframe->fr_width = Columns; topframe->fr_height = Rows - p_ch; - topframe->fr_win = curwin; return OK; } @@ -3073,7 +3106,7 @@ int win_new_tabpage(int after, char_u *filename) newtp->tp_topframe = topframe; last_status(FALSE); - redraw_all_later(CLEAR); + redraw_all_later(NOT_VALID); apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf); apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf); @@ -3278,10 +3311,9 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au trigger_enter_autocmds, trigger_leave_autocmds); prevwin = next_prevwin; - last_status(FALSE); /* status line may appear or disappear */ - (void)win_comp_pos(); /* recompute w_winrow for all windows */ - must_redraw = CLEAR; /* need to redraw everything */ - diff_need_scrollbind = TRUE; + last_status(false); // status line may appear or disappear + (void)win_comp_pos(); // recompute w_winrow for all windows + diff_need_scrollbind = true; /* The tabpage line may have appeared or disappeared, may need to resize * the frames for that. When the Vim window was resized need to update @@ -3303,7 +3335,8 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); } - redraw_all_later(CLEAR); + redraw_all_later(NOT_VALID); + must_redraw = NOT_VALID; } /* @@ -3970,18 +4003,20 @@ win_remove ( tabpage_T *tp /* tab page "win" is in, NULL for current */ ) { - if (wp->w_prev != NULL) + if (wp->w_prev != NULL) { wp->w_prev->w_next = wp->w_next; - else if (tp == NULL) - firstwin = wp->w_next; - else + } else if (tp == NULL) { + firstwin = curtab->tp_firstwin = wp->w_next; + } else { tp->tp_firstwin = wp->w_next; - if (wp->w_next != NULL) + } + if (wp->w_next != NULL) { wp->w_next->w_prev = wp->w_prev; - else if (tp == NULL) - lastwin = wp->w_prev; - else + } else if (tp == NULL) { + lastwin = curtab->tp_lastwin = wp->w_prev; + } else { tp->tp_lastwin = wp->w_prev; + } } /* @@ -4015,12 +4050,18 @@ static void frame_insert(frame_T *before, frame_T *frp) */ static void frame_remove(frame_T *frp) { - if (frp->fr_prev != NULL) + if (frp->fr_prev != NULL) { frp->fr_prev->fr_next = frp->fr_next; - else + } else { frp->fr_parent->fr_child = frp->fr_next; - if (frp->fr_next != NULL) + // special case: topframe->fr_child == frp + if (topframe->fr_child == frp) { + topframe->fr_child = frp->fr_next; + } + } + if (frp->fr_next != NULL) { frp->fr_next->fr_prev = frp->fr_prev; + } } @@ -4778,10 +4819,13 @@ void win_drag_vsep_line(win_T *dragwin, int offset) #define FRACTION_MULT 16384L // Set wp->w_fraction for the current w_wrow and w_height. +// Has no effect when the window is less than two lines. void set_fraction(win_T *wp) { - wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2) + if (wp->w_height > 1) { + wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2) / (long)wp->w_height; + } } /* @@ -4848,8 +4892,8 @@ void scroll_to_fraction(win_T *wp, int prev_height) sline = wp->w_wrow - line_size; if (sline >= 0) { - /* Make sure the whole cursor line is visible, if possible. */ - int rows = plines_win(wp, lnum, FALSE); + // Make sure the whole cursor line is visible, if possible. + const int rows = plines_win(wp, lnum, false); if (sline > wp->w_height - rows) { sline = wp->w_height - rows; @@ -4884,12 +4928,13 @@ void scroll_to_fraction(win_T *wp, int prev_height) --sline; break; } - --lnum; - if (lnum == wp->w_topline) - line_size = plines_win_nofill(wp, lnum, TRUE) + lnum--; + if (lnum == wp->w_topline) { + line_size = plines_win_nofill(wp, lnum, true) + wp->w_topfill; - else - line_size = plines_win(wp, lnum, TRUE); + } else { + line_size = plines_win(wp, lnum, true); + } sline -= line_size; } @@ -5096,6 +5141,8 @@ file_name_in_line ( { char_u *ptr; size_t len; + bool in_type = true; + bool is_url = false; /* * search forward for what could be the start of a file name @@ -5116,13 +5163,14 @@ file_name_in_line ( * Go one char back to ":" before "//" even when ':' is not in 'isfname'. */ while (ptr > line) { - if (has_mbyte && (len = (size_t)((*mb_head_off)(line, ptr - 1))) > 0) + if ((len = (size_t)(utf_head_off(line, ptr - 1))) > 0) { ptr -= len + 1; - else if (vim_isfilec(ptr[-1]) - || ((options & FNAME_HYP) && path_is_url((char *)ptr - 1))) - --ptr; - else + } else if (vim_isfilec(ptr[-1]) + || ((options & FNAME_HYP) && path_is_url((char *)ptr - 1))) { + ptr--; + } else { break; + } } /* @@ -5131,7 +5179,19 @@ file_name_in_line ( */ len = 0; while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') - || ((options & FNAME_HYP) && path_is_url((char *)ptr + len))) { + || ((options & FNAME_HYP) && path_is_url((char *)ptr + len)) + || (is_url && vim_strchr((char_u *)"?&=", ptr[len]) != NULL)) { + // After type:// we also include ?, & and = as valid characters, so that + // http://google.com?q=this&that=ok works. + if ((ptr[len] >= 'A' && ptr[len] <= 'Z') + || (ptr[len] >= 'a' && ptr[len] <= 'z')) { + if (in_type && path_is_url((char *)ptr + len + 1)) { + is_url = true; + } + } else { + in_type = false; + } + if (ptr[len] == '\\' && ptr[len + 1] == ' ') { // Skip over the "\" in "\ ". ++len; @@ -5282,7 +5342,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT int count = 0; FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_buffer != NULL - && (!((wp->w_buffer->b_help && !curbuf->b_help) + && (!((bt_help(wp->w_buffer) && !bt_help(curbuf)) || wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) { count++; } @@ -5384,7 +5444,7 @@ restore_snapshot ( win_comp_pos(); if (wp != NULL && close_curwin) win_goto(wp); - redraw_all_later(CLEAR); + redraw_all_later(NOT_VALID); } clear_snapshot(curtab, idx); } @@ -5488,12 +5548,10 @@ int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage return OK; } -/* - * Restore current tabpage and window saved by switch_win(), if still valid. - * When "no_display" is TRUE the display won't be affected, no redraw is - * triggered. - */ -void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display) +// Restore current tabpage and window saved by switch_win(), if still valid. +// When "no_display" is true the display won't be affected, no redraw is +// triggered. +void restore_win(win_T *save_curwin, tabpage_T *save_curtab, bool no_display) { if (save_curtab != NULL && valid_tabpage(save_curtab)) { if (no_display) { @@ -5608,7 +5666,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, m->match.rmm_maxcol = 0; m->conceal_char = 0; if (conceal_char != NULL) { - m->conceal_char = (*mb_ptr2char)((const char_u *)conceal_char); + m->conceal_char = utf_ptr2char((const char_u *)conceal_char); } // Set up position matches |