diff options
Diffstat (limited to 'src')
105 files changed, 9733 insertions, 6973 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 878ffdf06f..3808f601d9 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -1232,7 +1232,7 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict) return rv; } -/// Returns position for a given extmark id +/// Gets the position (0-indexed) of an extmark. /// /// @param buffer Buffer handle, or 0 for current buffer /// @param ns_id Namespace id from |nvim_create_namespace()| @@ -1240,7 +1240,8 @@ static Array extmark_to_array(ExtmarkInfo extmark, bool id, bool add_dict) /// @param opts Optional parameters. Keys: /// - details: Whether to include the details dict /// @param[out] err Error details, if any -/// @return (row, col) tuple or empty list () if extmark id was absent +/// @return 0-indexed (row, col) tuple or empty list () if extmark id was +/// absent ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, Integer id, Dictionary opts, Error *err) @@ -1320,10 +1321,10 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, /// /// @param buffer Buffer handle, or 0 for current buffer /// @param ns_id Namespace id from |nvim_create_namespace()| -/// @param start Start of range, given as (row, col) or valid extmark id -/// (whose position defines the bound) -/// @param end End of range, given as (row, col) or valid extmark id -/// (whose position defines the bound) +/// @param start Start of range: a 0-indexed (row, col) or valid extmark id +/// (whose position defines the bound). |api-indexing| +/// @param end End of range (inclusive): a 0-indexed (row, col) or valid +/// extmark id (whose position defines the bound). |api-indexing| /// @param opts Optional parameters. Keys: /// - limit: Maximum number of marks to return /// - details Whether to include the details dict @@ -1424,8 +1425,8 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, /// /// @param buffer Buffer handle, or 0 for current buffer /// @param ns_id Namespace id from |nvim_create_namespace()| -/// @param line Line where to place the mark, 0-based -/// @param col Column where to place the mark, 0-based +/// @param line Line where to place the mark, 0-based. |api-indexing| +/// @param col Column where to place the mark, 0-based. |api-indexing| /// @param opts Optional parameters. /// - id : id of the extmark to edit. /// - end_line : ending line of the mark, 0-based inclusive. diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 0ed5e6408b..ecbd4e13a3 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -444,6 +444,16 @@ void set_option_to(uint64_t channel_id, void *to, int type, #define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \ TYPVAL_ENCODE_CONV_NIL(tv) +#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ + do { \ + const size_t len_ = (size_t)(len); \ + const blob_T *const blob_ = (blob); \ + kvi_push(edata->stack, STRING_OBJ(((String) { \ + .data = len_ != 0 ? xmemdup(blob_->bv_ga.ga_data, len_) : NULL, \ + .size = len_ \ + }))); \ + } while (0) + #define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \ do { \ TYPVAL_ENCODE_CONV_NIL(tv); \ @@ -584,6 +594,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata) #undef TYPVAL_ENCODE_CONV_STRING #undef TYPVAL_ENCODE_CONV_STR_STRING #undef TYPVAL_ENCODE_CONV_EXT_STRING +#undef TYPVAL_ENCODE_CONV_BLOB #undef TYPVAL_ENCODE_CONV_NUMBER #undef TYPVAL_ENCODE_CONV_FLOAT #undef TYPVAL_ENCODE_CONV_FUNC_START diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 35d39a34d7..03fe5c5058 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -119,7 +119,8 @@ void msg_set_pos(Integer grid, Integer row, Boolean scrolled, String sep_char) FUNC_API_SINCE(6) FUNC_API_BRIDGE_IMPL FUNC_API_COMPOSITOR_IMPL; void win_viewport(Integer grid, Window win, Integer topline, - Integer botline, Integer curline, Integer curcol) + Integer botline, Integer curline, Integer curcol, + Integer line_count) FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY; void popupmenu_show(Array items, Integer selected, diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 5f48a26a29..f65d5cc185 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -275,9 +275,9 @@ static void on_redraw_event(void **argv) /// /// On execution error: does not fail, but updates v:errmsg. /// -/// If you need to input sequences like <C-o> use |nvim_replace_termcodes| to -/// replace the termcodes and then pass the resulting string to nvim_feedkeys. -/// You'll also want to enable escape_csi. +/// To input sequences like <C-o> use |nvim_replace_termcodes()| (typically +/// with escape_csi=true) to replace |keycodes|, then pass the result to +/// nvim_feedkeys(). /// /// Example: /// <pre> @@ -1551,7 +1551,7 @@ void nvim_set_current_tabpage(Tabpage tabpage, Error *err) } } -/// Creates a new namespace, or gets an existing one. +/// Creates a new *namespace*, or gets an existing one. /// /// Namespaces are used for buffer highlights and virtual text, see /// |nvim_buf_add_highlight()| and |nvim_buf_set_extmark()|. diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index f41068ea70..7b5e82cd3f 100644 --- a/src/nvim/ascii.h +++ b/src/nvim/ascii.h @@ -169,6 +169,14 @@ static inline bool ascii_isbdigit(int c) return (c == '0' || c == '1'); } +/// Checks if `c` is an octal digit, that is, 0-7. +/// +/// @see {ascii_isdigit} +static inline bool ascii_isodigit(int c) +{ + return (c >= '0' && c <= '7'); +} + /// Checks if `c` is a white-space character, that is, /// one of \f, \n, \r, \t, \v. /// diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 0ae8dd3664..89f7448188 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -230,6 +230,8 @@ typedef struct { # define w_p_culopt w_onebuf_opt.wo_culopt // 'cursorlineopt' char_u *wo_cc; # define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn' + char_u *wo_sbr; +# define w_p_sbr w_onebuf_opt.wo_sbr // 'showbreak' char_u *wo_stl; #define w_p_stl w_onebuf_opt.wo_stl // 'statusline' int wo_scb; diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 94db7fb3b9..54a59f6cc1 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -516,6 +516,7 @@ uint64_t channel_from_stdio(bool rpc, CallbackReader on_output, /// @param data will be consumed size_t channel_send(uint64_t id, char *data, size_t len, bool data_owned, const char **error) + FUNC_ATTR_NONNULL_ALL { Channel *chan = find_channel(id); size_t written = 0; diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 0252ef4e9c..e029973386 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -941,7 +941,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, // Also use this when 'list' is set but tabs take their normal size. if ((!wp->w_p_list || (wp->w_p_lcs_chars.tab1 != NUL)) && !wp->w_p_lbr - && (*p_sbr == NUL) + && *get_showbreak_value(wp) == NUL && !wp->w_p_bri ) { for (;;) { head = 0; @@ -1150,15 +1150,29 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, /// skipwhite: skip over ' ' and '\t'. /// -/// @param[in] q String to skip in. +/// @param[in] p String to skip in. /// /// @return Pointer to character after the skipped whitespace. -char_u *skipwhite(const char_u *q) +char_u *skipwhite(const char_u *const p) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { - const char_u *p = q; - while (ascii_iswhite(*p)) { + return skipwhite_len(p, STRLEN(p)); +} + +/// Like `skipwhite`, but skip up to `len` characters. +/// @see skipwhite +/// +/// @param[in] p String to skip in. +/// @param[in] len Max length to skip. +/// +/// @return Pointer to character after the skipped whitespace, or the `len`-th +/// character in the string. +char_u *skipwhite_len(const char_u *p, size_t len) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_RET +{ + for (; len > 0 && ascii_iswhite(*p); len--) { p++; } return (char_u *)p; @@ -1304,6 +1318,18 @@ char_u* skiptowhite_esc(char_u *p) { return p; } +/// Skip over text until '\n' or NUL. +/// +/// @param[in] p Text to skip over. +/// +/// @return Pointer to the next '\n' or NUL character. +char_u *skip_to_newline(const char_u *const p) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL + FUNC_ATTR_NONNULL_RET +{ + return (char_u *)xstrchrnul((const char *)p, NL); +} + /// Gets a number from a string and skips over it, signalling overflow. /// /// @param[out] pp A pointer to a pointer to char_u. @@ -1385,6 +1411,8 @@ bool vim_isblankline(char_u *lbuf) /// If "prep" is not NULL, returns a flag to indicate the type of the number: /// 0 decimal /// '0' octal +/// 'O' octal +/// 'o' octal /// 'B' bin /// 'b' bin /// 'X' hex @@ -1396,20 +1424,25 @@ bool vim_isblankline(char_u *lbuf) /// If "what" contains STR2NR_OCT recognize octal numbers. /// If "what" contains STR2NR_HEX recognize hex numbers. /// If "what" contains STR2NR_FORCE always assume bin/oct/hex. +/// If "what" contains STR2NR_QUOTE ignore embedded single quotes /// If maxlen > 0, check at a maximum maxlen chars. +/// If strict is true, check the number strictly. return *len = 0 if fail. /// /// @param start /// @param prep Returns guessed type of number 0 = decimal, 'x' or 'X' is -/// hexadecimal, '0' = octal, 'b' or 'B' is binary. When using -/// STR2NR_FORCE is always zero. +/// hexadecimal, '0', 'o' or 'O' is octal, 'b' or 'B' is binary. +/// When using STR2NR_FORCE is always zero. /// @param len Returns the detected length of number. /// @param what Recognizes what number passed, @see ChStr2NrFlags. /// @param nptr Returns the signed result. /// @param unptr Returns the unsigned result. /// @param maxlen Max length of string to check. +/// @param strict If true, fail if the number has unexpected trailing +/// alpha-numeric chars: *len is set to 0 and nothing else is +/// returned. void vim_str2nr(const char_u *const start, int *const prep, int *const len, const int what, varnumber_T *const nptr, - uvarnumber_T *const unptr, const int maxlen) + uvarnumber_T *const unptr, const int maxlen, const bool strict) FUNC_ATTR_NONNULL_ARG(1) { const char *ptr = (const char *)start; @@ -1419,14 +1452,18 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, const bool negative = (ptr[0] == '-'); uvarnumber_T un = 0; + if (len != NULL) { + *len = 0; + } + if (negative) { ptr++; } if (what & STR2NR_FORCE) { - // When forcing main consideration is skipping the prefix. Octal and decimal - // numbers have no prefixes to skip. pre is not set. - switch ((unsigned)what & (~(unsigned)STR2NR_FORCE)) { + // When forcing main consideration is skipping the prefix. Decimal numbers + // have no prefixes to skip. pre is not set. + switch (what & ~(STR2NR_FORCE | STR2NR_QUOTE)) { case STR2NR_HEX: { if (!STRING_ENDED(ptr + 2) && ptr[0] == '0' @@ -1445,7 +1482,16 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, } goto vim_str2nr_bin; } - case STR2NR_OCT: { + // Make STR2NR_OOCT work the same as STR2NR_OCT when forcing. + case STR2NR_OCT: + case STR2NR_OOCT: + case STR2NR_OCT | STR2NR_OOCT: { + if (!STRING_ENDED(ptr + 2) + && ptr[0] == '0' + && (ptr[1] == 'o' || ptr[1] == 'O') + && ascii_isodigit(ptr[2])) { + ptr += 2; + } goto vim_str2nr_oct; } case 0: { @@ -1455,9 +1501,9 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, abort(); } } - } else if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN)) - && !STRING_ENDED(ptr + 1) - && ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') { + } else if ((what & (STR2NR_HEX | STR2NR_OCT | STR2NR_OOCT | STR2NR_BIN)) + && !STRING_ENDED(ptr + 1) && ptr[0] == '0' && ptr[1] != '8' + && ptr[1] != '9') { pre = ptr[1]; // Detect hexadecimal: 0x or 0X followed by hex digit. if ((what & STR2NR_HEX) @@ -1475,10 +1521,18 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, ptr += 2; goto vim_str2nr_bin; } - // Detect octal number: zero followed by octal digits without '8' or '9'. + // Detect octal: 0o or 0O followed by octal digits (without '8' or '9'). + if ((what & STR2NR_OOCT) + && !STRING_ENDED(ptr + 2) + && (pre == 'O' || pre == 'o') + && ascii_isodigit(ptr[2])) { + ptr += 2; + goto vim_str2nr_oct; + } + // Detect old octal format: 0 followed by octal digits. pre = 0; if (!(what & STR2NR_OCT) - || !('0' <= ptr[1] && ptr[1] <= '7')) { + || !ascii_isodigit(ptr[1])) { goto vim_str2nr_dec; } for (int i = 2; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) { @@ -1492,11 +1546,22 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len, goto vim_str2nr_dec; } - // Do the string-to-numeric conversion "manually" to avoid sscanf quirks. + // Do the conversion manually to avoid sscanf() quirks. abort(); // Should’ve used goto earlier. #define PARSE_NUMBER(base, cond, conv) \ do { \ - while (!STRING_ENDED(ptr) && (cond)) { \ + const char *const after_prefix = ptr; \ + while (!STRING_ENDED(ptr)) { \ + if ((what & STR2NR_QUOTE) && ptr > after_prefix && *ptr == '\'') { \ + ptr++; \ + if (!STRING_ENDED(ptr) && (cond)) { \ + continue; \ + } \ + ptr--; \ + } \ + if (!(cond)) { \ + break; \ + } \ const uvarnumber_T digit = (uvarnumber_T)(conv); \ /* avoid ubsan error for overflow */ \ if (un < UVARNUMBER_MAX / base \ @@ -1513,7 +1578,7 @@ vim_str2nr_bin: PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0')); goto vim_str2nr_proceed; vim_str2nr_oct: - PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0')); + PARSE_NUMBER(8, (ascii_isodigit(*ptr)), (*ptr - '0')); goto vim_str2nr_proceed; vim_str2nr_dec: PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0')); @@ -1524,6 +1589,12 @@ vim_str2nr_hex: #undef PARSE_NUMBER vim_str2nr_proceed: + // Check for an alpha-numeric character immediately following, that is + // most likely a typo. + if (strict && ptr - (const char *)start != maxlen && ASCII_ISALNUM(*ptr)) { + return; + } + if (prep != NULL) { *prep = pre; } diff --git a/src/nvim/charset.h b/src/nvim/charset.h index e657ce19b6..2fef4d78a2 100644 --- a/src/nvim/charset.h +++ b/src/nvim/charset.h @@ -23,13 +23,20 @@ typedef enum { STR2NR_BIN = (1 << 0), ///< Allow binary numbers. STR2NR_OCT = (1 << 1), ///< Allow octal numbers. STR2NR_HEX = (1 << 2), ///< Allow hexadecimal numbers. + STR2NR_OOCT = (1 << 3), ///< Octal with prefix "0o": 0o777 /// Force one of the above variants. /// /// STR2NR_FORCE|STR2NR_DEC is actually not different from supplying zero /// as flags, but still present for completeness. - STR2NR_FORCE = (1 << 3), + /// + /// STR2NR_FORCE|STR2NR_OCT|STR2NR_OOCT is the same as STR2NR_FORCE|STR2NR_OCT + /// or STR2NR_FORCE|STR2NR_OOCT. + STR2NR_FORCE = (1 << 7), /// Recognize all formats vim_str2nr() can recognize. - STR2NR_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX, + STR2NR_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX | STR2NR_OOCT, + /// Disallow octals numbers without the 0o prefix. + STR2NR_NO_OCT = STR2NR_BIN | STR2NR_HEX | STR2NR_OOCT, + STR2NR_QUOTE = (1 << 4), ///< Ignore embedded single quotes. } ChStr2NrFlags; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c new file mode 100644 index 0000000000..73665009ff --- /dev/null +++ b/src/nvim/debugger.c @@ -0,0 +1,833 @@ +// 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 + +/// @file debugger.c +/// +/// Vim script debugger functions + +#include "nvim/ascii.h" +#include "nvim/charset.h" +#include "nvim/debugger.h" +#include "nvim/eval.h" +#include "nvim/ex_docmd.h" +#include "nvim/ex_getln.h" +#include "nvim/fileio.h" +#include "nvim/getchar.h" +#include "nvim/globals.h" +#include "nvim/os/os.h" +#include "nvim/pos.h" +#include "nvim/regexp.h" +#include "nvim/screen.h" +#include "nvim/types.h" +#include "nvim/vim.h" + +/// batch mode debugging: don't save and restore typeahead. +static bool debug_greedy = false; + +static char *debug_oldval = NULL; // old and newval for debug expressions +static char *debug_newval = NULL; + +/// The list of breakpoints: dbg_breakp. +/// This is a grow-array of structs. +struct debuggy { + int dbg_nr; ///< breakpoint number + int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR + char_u *dbg_name; ///< function, expression or file name + regprog_T *dbg_prog; ///< regexp program + linenr_T dbg_lnum; ///< line number in function or file + int dbg_forceit; ///< ! used + typval_T *dbg_val; ///< last result of watchexpression + int dbg_level; ///< stored nested level for expr +}; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "debugger.c.generated.h" +#endif + +/// Debug mode. Repeatedly get Ex commands, until told to continue normal +/// execution. +void do_debug(char_u *cmd) +{ + int save_msg_scroll = msg_scroll; + int save_State = State; + int save_did_emsg = did_emsg; + const bool save_cmd_silent = cmd_silent; + int save_msg_silent = msg_silent; + int save_emsg_silent = emsg_silent; + bool save_redir_off = redir_off; + tasave_T typeaheadbuf; + bool typeahead_saved = false; + int save_ignore_script = 0; + int save_ex_normal_busy; + int n; + char_u *cmdline = NULL; + char_u *p; + char *tail = NULL; + static int last_cmd = 0; +#define CMD_CONT 1 +#define CMD_NEXT 2 +#define CMD_STEP 3 +#define CMD_FINISH 4 +#define CMD_QUIT 5 +#define CMD_INTERRUPT 6 +#define CMD_BACKTRACE 7 +#define CMD_FRAME 8 +#define CMD_UP 9 +#define CMD_DOWN 10 + + + RedrawingDisabled++; // don't redisplay the window + no_wait_return++; // don't wait for return + did_emsg = false; // don't use error from debugged stuff + cmd_silent = false; // display commands + msg_silent = false; // display messages + emsg_silent = false; // display error messages + redir_off = true; // don't redirect debug commands + + State = NORMAL; + debug_mode = true; + + if (!debug_did_msg) { + MSG(_("Entering Debug mode. Type \"cont\" to continue.")); + } + if (debug_oldval != NULL) { + smsg(_("Oldval = \"%s\""), debug_oldval); + xfree(debug_oldval); + debug_oldval = NULL; + } + if (debug_newval != NULL) { + smsg(_("Newval = \"%s\""), debug_newval); + xfree(debug_newval); + debug_newval = NULL; + } + if (sourcing_name != NULL) { + msg(sourcing_name); + } + if (sourcing_lnum != 0) { + smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd); + } else { + smsg(_("cmd: %s"), cmd); + } + // Repeat getting a command and executing it. + for (;; ) { + msg_scroll = true; + need_wait_return = false; + // Save the current typeahead buffer and replace it with an empty one. + // This makes sure we get input from the user here and don't interfere + // with the commands being executed. Reset "ex_normal_busy" to avoid + // the side effects of using ":normal". Save the stuff buffer and make + // it empty. Set ignore_script to avoid reading from script input. + save_ex_normal_busy = ex_normal_busy; + ex_normal_busy = 0; + if (!debug_greedy) { + save_typeahead(&typeaheadbuf); + typeahead_saved = true; + save_ignore_script = ignore_script; + ignore_script = true; + } + + xfree(cmdline); + cmdline = (char_u *)getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL, + CALLBACK_NONE); + + if (typeahead_saved) { + restore_typeahead(&typeaheadbuf); + ignore_script = save_ignore_script; + } + ex_normal_busy = save_ex_normal_busy; + + cmdline_row = msg_row; + msg_starthere(); + if (cmdline != NULL) { + // If this is a debug command, set "last_cmd". + // If not, reset "last_cmd". + // For a blank line use previous command. + p = skipwhite(cmdline); + if (*p != NUL) { + switch (*p) { + case 'c': last_cmd = CMD_CONT; + tail = "ont"; + break; + case 'n': last_cmd = CMD_NEXT; + tail = "ext"; + break; + case 's': last_cmd = CMD_STEP; + tail = "tep"; + break; + case 'f': + last_cmd = 0; + if (p[1] == 'r') { + last_cmd = CMD_FRAME; + tail = "rame"; + } else { + last_cmd = CMD_FINISH; + tail = "inish"; + } + break; + case 'q': last_cmd = CMD_QUIT; + tail = "uit"; + break; + case 'i': last_cmd = CMD_INTERRUPT; + tail = "nterrupt"; + break; + case 'b': + last_cmd = CMD_BACKTRACE; + if (p[1] == 't') { + tail = "t"; + } else { + tail = "acktrace"; + } + break; + case 'w': + last_cmd = CMD_BACKTRACE; + tail = "here"; + break; + case 'u': + last_cmd = CMD_UP; + tail = "p"; + break; + case 'd': + last_cmd = CMD_DOWN; + tail = "own"; + break; + default: last_cmd = 0; + } + if (last_cmd != 0) { + // Check that the tail matches. + p++; + while (*p != NUL && *p == *tail) { + p++; + tail++; + } + if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) { + last_cmd = 0; + } + } + } + + if (last_cmd != 0) { + // Execute debug command: decided where to break next and return. + switch (last_cmd) { + case CMD_CONT: + debug_break_level = -1; + break; + case CMD_NEXT: + debug_break_level = ex_nesting_level; + break; + case CMD_STEP: + debug_break_level = 9999; + break; + case CMD_FINISH: + debug_break_level = ex_nesting_level - 1; + break; + case CMD_QUIT: + got_int = true; + debug_break_level = -1; + break; + case CMD_INTERRUPT: + got_int = true; + debug_break_level = 9999; + // Do not repeat ">interrupt" cmd, continue stepping. + last_cmd = CMD_STEP; + break; + case CMD_BACKTRACE: + do_showbacktrace(cmd); + continue; + case CMD_FRAME: + if (*p == NUL) { + do_showbacktrace(cmd); + } else { + p = skipwhite(p); + do_setdebugtracelevel(p); + } + continue; + case CMD_UP: + debug_backtrace_level++; + do_checkbacktracelevel(); + continue; + case CMD_DOWN: + debug_backtrace_level--; + do_checkbacktracelevel(); + continue; + } + // Going out reset backtrace_level + debug_backtrace_level = 0; + break; + } + + // don't debug this command + n = debug_break_level; + debug_break_level = -1; + (void)do_cmdline(cmdline, getexline, NULL, + DOCMD_VERBOSE|DOCMD_EXCRESET); + debug_break_level = n; + } + lines_left = (int)(Rows - 1); + } + xfree(cmdline); + + RedrawingDisabled--; + no_wait_return--; + redraw_all_later(NOT_VALID); + need_wait_return = false; + msg_scroll = save_msg_scroll; + lines_left = (int)(Rows - 1); + State = save_State; + debug_mode = false; + did_emsg = save_did_emsg; + cmd_silent = save_cmd_silent; + msg_silent = save_msg_silent; + emsg_silent = save_emsg_silent; + redir_off = save_redir_off; + + // Only print the message again when typing a command before coming back here. + debug_did_msg = true; +} + +static int get_maxbacktrace_level(void) +{ + int maxbacktrace = 0; + + if (sourcing_name != NULL) { + char *p = (char *)sourcing_name; + char *q; + while ((q = strstr(p, "..")) != NULL) { + p = q + 2; + maxbacktrace++; + } + } + return maxbacktrace; +} + +static void do_setdebugtracelevel(char_u *arg) +{ + int level = atoi((char *)arg); + if (*arg == '+' || level < 0) { + debug_backtrace_level += level; + } else { + debug_backtrace_level = level; + } + + do_checkbacktracelevel(); +} + +static void do_checkbacktracelevel(void) +{ + if (debug_backtrace_level < 0) { + debug_backtrace_level = 0; + MSG(_("frame is zero")); + } else { + int max = get_maxbacktrace_level(); + if (debug_backtrace_level > max) { + debug_backtrace_level = max; + smsg(_("frame at highest level: %d"), max); + } + } +} + +static void do_showbacktrace(char_u *cmd) +{ + if (sourcing_name != NULL) { + int i = 0; + int max = get_maxbacktrace_level(); + char *cur = (char *)sourcing_name; + while (!got_int) { + char *next = strstr(cur, ".."); + if (next != NULL) { + *next = NUL; + } + if (i == max - debug_backtrace_level) { + smsg("->%d %s", max - i, cur); + } else { + smsg(" %d %s", max - i, cur); + } + i++; + if (next == NULL) { + break; + } + *next = '.'; + cur = next + 2; + } + } + if (sourcing_lnum != 0) { + smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd); + } else { + smsg(_("cmd: %s"), cmd); + } +} + +/// ":debug". +void ex_debug(exarg_T *eap) +{ + int debug_break_level_save = debug_break_level; + + debug_break_level = 9999; + do_cmdline_cmd((char *)eap->arg); + debug_break_level = debug_break_level_save; +} + +static char_u *debug_breakpoint_name = NULL; +static linenr_T debug_breakpoint_lnum; + +/// When debugging or a breakpoint is set on a skipped command, no debug prompt +/// is shown by do_one_cmd(). This situation is indicated by debug_skipped, and +/// debug_skipped_name is then set to the source name in the breakpoint case. If +/// a skipped command decides itself that a debug prompt should be displayed, it +/// can do so by calling dbg_check_skipped(). +static int debug_skipped; +static char_u *debug_skipped_name; + +/// Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is +/// at or below the break level. But only when the line is actually +/// executed. Return true and set breakpoint_name for skipped commands that +/// decide to execute something themselves. +/// Called from do_one_cmd() before executing a command. +void dbg_check_breakpoint(exarg_T *eap) +{ + char_u *p; + + debug_skipped = false; + if (debug_breakpoint_name != NULL) { + if (!eap->skip) { + // replace K_SNR with "<SNR>" + if (debug_breakpoint_name[0] == K_SPECIAL + && debug_breakpoint_name[1] == KS_EXTRA + && debug_breakpoint_name[2] == (int)KE_SNR) { + p = (char_u *)"<SNR>"; + } else { + p = (char_u *)""; + } + smsg(_("Breakpoint in \"%s%s\" line %" PRId64), + p, + debug_breakpoint_name + (*p == NUL ? 0 : 3), + (int64_t)debug_breakpoint_lnum); + debug_breakpoint_name = NULL; + do_debug(eap->cmd); + } else { + debug_skipped = true; + debug_skipped_name = debug_breakpoint_name; + debug_breakpoint_name = NULL; + } + } else if (ex_nesting_level <= debug_break_level) { + if (!eap->skip) { + do_debug(eap->cmd); + } else { + debug_skipped = true; + debug_skipped_name = NULL; + } + } +} + +/// Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was +/// set. +/// +/// @return true when the debug mode is entered this time. +bool dbg_check_skipped(exarg_T *eap) +{ + int prev_got_int; + + if (debug_skipped) { + // Save the value of got_int and reset it. We don't want a previous + // interruption cause flushing the input buffer. + prev_got_int = got_int; + got_int = false; + debug_breakpoint_name = debug_skipped_name; + // eap->skip is true + eap->skip = false; + dbg_check_breakpoint(eap); + eap->skip = true; + got_int |= prev_got_int; + return true; + } + return false; +} + +static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL }; +#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx]) +#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx]) +static int last_breakp = 0; // nr of last defined breakpoint + +// Profiling uses file and func names similar to breakpoints. +static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL }; +#define DBG_FUNC 1 +#define DBG_FILE 2 +#define DBG_EXPR 3 + +/// Evaluate the "bp->dbg_name" expression and return the result. +/// Disables error messages. +static typval_T *eval_expr_no_emsg(struct debuggy *const bp) + FUNC_ATTR_NONNULL_ALL +{ + // Disable error messages, a bad expression would make Vim unusable. + emsg_off++; + typval_T *const tv = eval_expr(bp->dbg_name); + emsg_off--; + return tv; +} + +/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them +/// in the entry just after the last one in dbg_breakp. Note that "dbg_name" +/// is allocated. +/// Returns FAIL for failure. +/// +/// @param arg +/// @param gap either &dbg_breakp or &prof_ga +static int dbg_parsearg(char_u *arg, garray_T *gap) +{ + char_u *p = arg; + char_u *q; + struct debuggy *bp; + bool here = false; + + ga_grow(gap, 1); + + bp = &DEBUGGY(gap, gap->ga_len); + + // Find "func" or "file". + if (STRNCMP(p, "func", 4) == 0) { + bp->dbg_type = DBG_FUNC; + } else if (STRNCMP(p, "file", 4) == 0) { + bp->dbg_type = DBG_FILE; + } else if (gap != &prof_ga && STRNCMP(p, "here", 4) == 0) { + if (curbuf->b_ffname == NULL) { + EMSG(_(e_noname)); + return FAIL; + } + bp->dbg_type = DBG_FILE; + here = true; + } else if (gap != &prof_ga && STRNCMP(p, "expr", 4) == 0) { + bp->dbg_type = DBG_EXPR; + } else { + EMSG2(_(e_invarg2), p); + return FAIL; + } + p = skipwhite(p + 4); + + // Find optional line number. + if (here) { + bp->dbg_lnum = curwin->w_cursor.lnum; + } else if (gap != &prof_ga && ascii_isdigit(*p)) { + bp->dbg_lnum = getdigits_long(&p, true, 0); + p = skipwhite(p); + } else { + bp->dbg_lnum = 0; + } + + // Find the function or file name. Don't accept a function name with (). + if ((!here && *p == NUL) + || (here && *p != NUL) + || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) { + EMSG2(_(e_invarg2), arg); + return FAIL; + } + + if (bp->dbg_type == DBG_FUNC) { + bp->dbg_name = vim_strsave(p); + } else if (here) { + bp->dbg_name = vim_strsave(curbuf->b_ffname); + } else if (bp->dbg_type == DBG_EXPR) { + bp->dbg_name = vim_strsave(p); + bp->dbg_val = eval_expr_no_emsg(bp); + } else { + // Expand the file name in the same way as do_source(). This means + // doing it twice, so that $DIR/file gets expanded when $DIR is + // "~/dir". + q = expand_env_save(p); + if (q == NULL) { + return FAIL; + } + p = expand_env_save(q); + xfree(q); + if (p == NULL) { + return FAIL; + } + if (*p != '*') { + bp->dbg_name = (char_u *)fix_fname((char *)p); + xfree(p); + } else { + bp->dbg_name = p; + } + } + + if (bp->dbg_name == NULL) { + return FAIL; + } + return OK; +} + +/// ":breakadd". Also used for ":profile". +void ex_breakadd(exarg_T *eap) +{ + struct debuggy *bp; + garray_T *gap; + + gap = &dbg_breakp; + if (eap->cmdidx == CMD_profile) { + gap = &prof_ga; + } + + if (dbg_parsearg(eap->arg, gap) == OK) { + bp = &DEBUGGY(gap, gap->ga_len); + bp->dbg_forceit = eap->forceit; + + if (bp->dbg_type != DBG_EXPR) { + char_u *pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, false); + if (pat != NULL) { + bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING); + xfree(pat); + } + if (pat == NULL || bp->dbg_prog == NULL) { + xfree(bp->dbg_name); + } else { + if (bp->dbg_lnum == 0) { // default line number is 1 + bp->dbg_lnum = 1; + } + if (eap->cmdidx != CMD_profile) { + DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp; + debug_tick++; + } + gap->ga_len++; + } + } else { + // DBG_EXPR + DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp; + debug_tick++; + } + } +} + +/// ":debuggreedy". +void ex_debuggreedy(exarg_T *eap) +{ + if (eap->addr_count == 0 || eap->line2 != 0) { + debug_greedy = true; + } else { + debug_greedy = false; + } +} + +/// ":breakdel" and ":profdel". +void ex_breakdel(exarg_T *eap) +{ + struct debuggy *bp, *bpi; + int nr; + int todel = -1; + bool del_all = false; + linenr_T best_lnum = 0; + garray_T *gap; + + gap = &dbg_breakp; + if (eap->cmdidx == CMD_profdel) { + gap = &prof_ga; + } + + if (ascii_isdigit(*eap->arg)) { + // ":breakdel {nr}" + nr = atoi((char *)eap->arg); + for (int i = 0; i < gap->ga_len; i++) { + if (DEBUGGY(gap, i).dbg_nr == nr) { + todel = i; + break; + } + } + } else if (*eap->arg == '*') { + todel = 0; + del_all = true; + } else { + // ":breakdel {func|file|expr} [lnum] {name}" + if (dbg_parsearg(eap->arg, gap) == FAIL) { + return; + } + bp = &DEBUGGY(gap, gap->ga_len); + for (int i = 0; i < gap->ga_len; i++) { + bpi = &DEBUGGY(gap, i); + if (bp->dbg_type == bpi->dbg_type + && STRCMP(bp->dbg_name, bpi->dbg_name) == 0 + && (bp->dbg_lnum == bpi->dbg_lnum + || (bp->dbg_lnum == 0 + && (best_lnum == 0 + || bpi->dbg_lnum < best_lnum)))) { + todel = i; + best_lnum = bpi->dbg_lnum; + } + } + xfree(bp->dbg_name); + } + + if (todel < 0) { + EMSG2(_("E161: Breakpoint not found: %s"), eap->arg); + } else { + while (!GA_EMPTY(gap)) { + xfree(DEBUGGY(gap, todel).dbg_name); + if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR + && DEBUGGY(gap, todel).dbg_val != NULL) { + tv_free(DEBUGGY(gap, todel).dbg_val); + } + vim_regfree(DEBUGGY(gap, todel).dbg_prog); + gap->ga_len--; + if (todel < gap->ga_len) { + memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1), + (size_t)(gap->ga_len - todel) * sizeof(struct debuggy)); + } + if (eap->cmdidx == CMD_breakdel) { + debug_tick++; + } + if (!del_all) { + break; + } + } + + // If all breakpoints were removed clear the array. + if (GA_EMPTY(gap)) { + ga_clear(gap); + } + } +} + +/// ":breaklist". +void ex_breaklist(exarg_T *eap) +{ + struct debuggy *bp; + + if (GA_EMPTY(&dbg_breakp)) { + MSG(_("No breakpoints defined")); + } else { + for (int i = 0; i < dbg_breakp.ga_len; i++) { + bp = &BREAKP(i); + if (bp->dbg_type == DBG_FILE) { + home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true); + } + if (bp->dbg_type != DBG_EXPR) { + smsg(_("%3d %s %s line %" PRId64), + bp->dbg_nr, + bp->dbg_type == DBG_FUNC ? "func" : "file", + bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff, + (int64_t)bp->dbg_lnum); + } else { + smsg(_("%3d expr %s"), bp->dbg_nr, bp->dbg_name); + } + } + } +} + +/// Find a breakpoint for a function or sourced file. +/// Returns line number at which to break; zero when no matching breakpoint. +linenr_T +dbg_find_breakpoint( + bool file, // true for a file, false for a function + char_u *fname, // file or function name + linenr_T after // after this line number +) +{ + return debuggy_find(file, fname, after, &dbg_breakp, NULL); +} + +/// @param file true for a file, false for a function +/// @param fname file or function name +/// @param fp[out] forceit +/// +/// @returns true if profiling is on for a function or sourced file. +bool has_profiling(bool file, char_u *fname, bool *fp) +{ + return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp) + != (linenr_T)0; +} + +/// Common code for dbg_find_breakpoint() and has_profiling(). +static linenr_T +debuggy_find( + bool file, // true for a file, false for a function + char_u *fname, // file or function name + linenr_T after, // after this line number + garray_T *gap, // either &dbg_breakp or &prof_ga + bool *fp // if not NULL: return forceit +) +{ + struct debuggy *bp; + linenr_T lnum = 0; + char_u *name = fname; + int prev_got_int; + + // Return quickly when there are no breakpoints. + if (GA_EMPTY(gap)) { + return (linenr_T)0; + } + + // Replace K_SNR in function name with "<SNR>". + if (!file && fname[0] == K_SPECIAL) { + name = xmalloc(STRLEN(fname) + 3); + STRCPY(name, "<SNR>"); + STRCPY(name + 5, fname + 3); + } + + for (int i = 0; i < gap->ga_len; i++) { + // Skip entries that are not useful or are for a line that is beyond + // an already found breakpoint. + bp = &DEBUGGY(gap, i); + if ((bp->dbg_type == DBG_FILE) == file + && bp->dbg_type != DBG_EXPR + && (gap == &prof_ga + || (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))) { + // Save the value of got_int and reset it. We don't want a + // previous interruption cancel matching, only hitting CTRL-C + // while matching should abort it. + prev_got_int = got_int; + got_int = false; + if (vim_regexec_prog(&bp->dbg_prog, false, name, (colnr_T)0)) { + lnum = bp->dbg_lnum; + if (fp != NULL) { + *fp = bp->dbg_forceit; + } + } + got_int |= prev_got_int; + } else if (bp->dbg_type == DBG_EXPR) { + bool line = false; + + typval_T *const tv = eval_expr_no_emsg(bp); + if (tv != NULL) { + if (bp->dbg_val == NULL) { + debug_oldval = typval_tostring(NULL); + bp->dbg_val = tv; + debug_newval = typval_tostring(bp->dbg_val); + line = true; + } else { + if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK + && tv->vval.v_number == false) { + line = true; + debug_oldval = typval_tostring(bp->dbg_val); + // Need to evaluate again, typval_compare() overwrites "tv". + typval_T *const v = eval_expr_no_emsg(bp); + debug_newval = typval_tostring(v); + tv_free(bp->dbg_val); + bp->dbg_val = v; + } + tv_free(tv); + } + } else if (bp->dbg_val != NULL) { + debug_oldval = typval_tostring(bp->dbg_val); + debug_newval = typval_tostring(NULL); + tv_free(bp->dbg_val); + bp->dbg_val = NULL; + line = true; + } + + if (line) { + lnum = after > 0 ? after : 1; + break; + } + } + } + if (name != fname) { + xfree(name); + } + + return lnum; +} + +/// Called when a breakpoint was encountered. +void dbg_breakpoint(char_u *name, linenr_T lnum) +{ + // We need to check if this line is actually executed in do_one_cmd() + debug_breakpoint_name = name; + debug_breakpoint_lnum = lnum; +} diff --git a/src/nvim/debugger.h b/src/nvim/debugger.h new file mode 100644 index 0000000000..1f1139b3bc --- /dev/null +++ b/src/nvim/debugger.h @@ -0,0 +1,11 @@ +#ifndef NVIM_DEBUGGER_H +#define NVIM_DEBUGGER_H + +#include <stdbool.h> + +#include "nvim/ex_cmds_defs.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "debugger.h.generated.h" +#endif +#endif // NVIM_DEBUGGER_H diff --git a/src/nvim/edit.c b/src/nvim/edit.c index ffe60ab043..a19adca942 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -6,60 +6,60 @@ */ #include <assert.h> -#include <string.h> #include <inttypes.h> #include <stdbool.h> +#include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/edit.h" #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" #include "nvim/digraph.h" +#include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/event/loop.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" +#include "nvim/extmark.h" #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/getchar.h" #include "nvim/indent.h" #include "nvim/indent_c.h" +#include "nvim/keymap.h" #include "nvim/main.h" -#include "nvim/extmark.h" +#include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/keymap.h" +#include "nvim/mouse.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/time.h" #include "nvim/path.h" -#include "nvim/popupmnu.h" #include "nvim/plines.h" +#include "nvim/popupmnu.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/spell.h" -#include "nvim/strings.h" #include "nvim/state.h" +#include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/tag.h" -#include "nvim/ui.h" -#include "nvim/mouse.h" #include "nvim/terminal.h" +#include "nvim/ui.h" #include "nvim/undo.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/event/loop.h" -#include "nvim/mark.h" -#include "nvim/os/input.h" -#include "nvim/os/time.h" // Definitions used for CTRL-X submode. // Note: If you change CTRL-X submode, you must also maintain ctrl_x_msgs[] @@ -84,6 +84,7 @@ #define CTRL_X_SPELL 14 #define CTRL_X_LOCAL_MSG 15 ///< only used in "ctrl_x_msgs" #define CTRL_X_EVAL 16 ///< for builtin function complete() +#define CTRL_X_CMDLINE_CTRL_X 17 ///< CTRL-X typed in CTRL_X_CMDLINE #define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT] #define CTRL_X_MODE_LINE_OR_EVAL(m) \ @@ -109,6 +110,7 @@ static char *ctrl_x_msgs[] = N_(" Spelling suggestion (s^N^P)"), N_(" Keyword Local completion (^N^P)"), NULL, // CTRL_X_EVAL doesn't use msg. + N_(" Command-line completion (^V^N^P)"), }; static char *ctrl_x_mode_names[] = { @@ -128,7 +130,8 @@ static char *ctrl_x_mode_names[] = { "omni", "spell", NULL, // CTRL_X_LOCAL_MSG only used in "ctrl_x_msgs" - "eval" + "eval", + "cmdline", }; static char e_hitend[] = N_("Hit end of paragraph"); @@ -140,13 +143,13 @@ static char e_compldel[] = N_("E840: Completion function deleted text"); */ typedef struct compl_S compl_T; struct compl_S { - compl_T *cp_next; - compl_T *cp_prev; - char_u *cp_str; // matched text - char_u *(cp_text[CPT_COUNT]); // text for the menu + compl_T *cp_next; + compl_T *cp_prev; + char_u *cp_str; // matched text + char_u *(cp_text[CPT_COUNT]); // text for the menu typval_T cp_user_data; - char_u *cp_fname; // file containing the match, allocated when - // cp_flags has CP_FREE_FNAME + char_u *cp_fname; // file containing the match, allocated when + // cp_flags has CP_FREE_FNAME int cp_flags; // CP_ values int cp_number; // sequence number }; @@ -158,10 +161,10 @@ struct compl_S { * "compl_shown_match" is different from compl_curr_match during * ins_compl_get_exp(). */ -static compl_T *compl_first_match = NULL; -static compl_T *compl_curr_match = NULL; -static compl_T *compl_shown_match = NULL; -static compl_T *compl_old_match = NULL; +static compl_T *compl_first_match = NULL; +static compl_T *compl_curr_match = NULL; +static compl_T *compl_shown_match = NULL; +static compl_T *compl_old_match = NULL; /* After using a cursor key <Enter> selects a match in the popup menu, * otherwise it inserts a line break. */ @@ -169,10 +172,9 @@ static int compl_enter_selects = FALSE; /* When "compl_leader" is not NULL only matches that start with this string * are used. */ -static char_u *compl_leader = NULL; +static char_u *compl_leader = NULL; -static int compl_get_longest = FALSE; /* put longest common string - in compl_leader */ +static bool compl_get_longest = false; // put longest common string in compl_leader static int compl_no_insert = FALSE; /* FALSE: select & insert TRUE: noinsert */ @@ -196,19 +198,19 @@ static bool compl_started = false; static int ctrl_x_mode = CTRL_X_NORMAL; static int compl_matches = 0; -static char_u *compl_pattern = NULL; +static char_u *compl_pattern = NULL; static Direction compl_direction = FORWARD; static Direction compl_shows_dir = FORWARD; static int compl_pending = 0; // > 1 for postponed CTRL-N static pos_T compl_startpos; static colnr_T compl_col = 0; /* column where the text starts * that is being completed */ -static char_u *compl_orig_text = NULL; /* text as it was before - * completion started */ +static char_u *compl_orig_text = NULL; /* text as it was before + * completion started */ static int compl_cont_mode = 0; static expand_T compl_xp; -static int compl_opt_refresh_always = FALSE; +static bool compl_opt_refresh_always = false; static int pum_selected_item = -1; @@ -257,8 +259,8 @@ static colnr_T Insstart_textlen; // length of line when insert started static colnr_T Insstart_blank_vcol; // vcol for first inserted blank static bool update_Insstart_orig = true; // set Insstart_orig to Insstart -static char_u *last_insert = NULL; // the text of the previous insert, - // K_SPECIAL and CSI are escaped +static char_u *last_insert = NULL; // the text of the previous insert, + // K_SPECIAL and CSI are escaped 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() @@ -310,7 +312,7 @@ static void insert_enter(InsertState *s) s->ptr = (char_u *)"i"; } - set_vim_var_string(VV_INSERTMODE, (char *) s->ptr, 1); + set_vim_var_string(VV_INSERTMODE, (char *)s->ptr, 1); set_vim_var_string(VV_CHAR, NULL, -1); ins_apply_autocmds(EVENT_INSERTENTER); @@ -762,7 +764,8 @@ static int insert_execute(VimState *state, int key) s->c = do_digraph(s->c); - if ((s->c == Ctrl_V || s->c == Ctrl_Q) && ctrl_x_mode == CTRL_X_CMDLINE) { + if ((s->c == Ctrl_V || s->c == Ctrl_Q) + && (ctrl_x_mode == CTRL_X_CMDLINE || ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X)) { insert_do_complete(s); return 1; } @@ -791,15 +794,22 @@ static int insert_execute(VimState *state, int key) } } - if (curwin->w_p_rl) + if (curwin->w_p_rl) { switch (s->c) { - case K_LEFT: s->c = K_RIGHT; break; - case K_S_LEFT: s->c = K_S_RIGHT; break; - case K_C_LEFT: s->c = K_C_RIGHT; break; - case K_RIGHT: s->c = K_LEFT; break; - case K_S_RIGHT: s->c = K_S_LEFT; break; - case K_C_RIGHT: s->c = K_C_LEFT; break; + case K_LEFT: + s->c = K_RIGHT; break; + case K_S_LEFT: + s->c = K_S_RIGHT; break; + case K_C_LEFT: + s->c = K_C_RIGHT; break; + case K_RIGHT: + s->c = K_LEFT; break; + case K_S_RIGHT: + s->c = K_S_LEFT; break; + case K_C_RIGHT: + s->c = K_C_LEFT; break; } + } // If 'keymodel' contains "startsel", may start selection. If it // does, a CTRL-O and c will be stuffed, we need to get these @@ -1288,8 +1298,9 @@ normalchar: // If the new value is already inserted or an empty string // then don't insert any character. - if (s->c == NUL) + if (s->c == NUL) { break; + } } // Try to perform smart-indenting. ins_try_si(s->c); @@ -1309,8 +1320,8 @@ normalchar: // special character. Let CTRL-] expand abbreviations without // inserting it. if (vim_iswordc(s->c) - // Add ABBR_OFF for characters above 0x100, this is - // what check_abbr() expects. + // Add ABBR_OFF for characters above 0x100, this is + // what check_abbr() expects. || (!echeck_abbr((s->c >= 0x100) ? (s->c + ABBR_OFF) : s->c) && s->c != Ctrl_RSB)) { insert_special(s->c, false, false); @@ -1415,21 +1426,20 @@ bool edit(int cmdchar, bool startln, long count) return s->c == Ctrl_O; } -/* - * Redraw for Insert mode. - * This is postponed until getting the next character to make '$' in the 'cpo' - * option work correctly. - * Only redraw when there are no characters available. This speeds up - * inserting sequences of characters (e.g., for CTRL-R). - */ -static void ins_redraw( - bool ready // not busy with something -) +/// Redraw for Insert mode. +/// This is postponed until getting the next character to make '$' in the 'cpo' +/// option work correctly. +/// Only redraw when there are no characters available. This speeds up +/// inserting sequences of characters (e.g., for CTRL-R). +/// +/// @param ready not busy with something +static void ins_redraw(bool ready) { bool conceal_cursor_moved = false; - if (char_avail()) + if (char_avail()) { return; + } // Trigger CursorMoved if the cursor moved. Not when the popup menu is // visible, the command might delete it. @@ -1655,8 +1665,8 @@ static void init_prompt(int cmdchar_todo) /// @return true if the cursor is in the editable position of the prompt line. bool prompt_curpos_editable(void) { - return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count - && curwin->w_cursor.col >= (int)STRLEN(prompt_text()); + return curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count + && curwin->w_cursor.col >= (int)STRLEN(prompt_text()); } /* @@ -1685,8 +1695,9 @@ void display_dollar(colnr_T col) { colnr_T save_col; - if (!redrawing()) + if (!redrawing()) { return; + } save_col = curwin->w_cursor.col; curwin->w_cursor.col = col; @@ -1714,34 +1725,28 @@ static void undisplay_dollar(void) } } -/* - * Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D). - * Keep the cursor on the same character. - * type == INDENT_INC increase indent (for CTRL-T or <Tab>) - * type == INDENT_DEC decrease indent (for CTRL-D) - * type == INDENT_SET set indent to "amount" - * if round is TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec). - */ -void -change_indent ( - int type, - int amount, - int round, - int replaced, // replaced character, put on replace stack - int call_changed_bytes // call changed_bytes() -) +/// Insert an indent (for <Tab> or CTRL-T) or delete an indent (for CTRL-D). +/// Keep the cursor on the same character. +/// type == INDENT_INC increase indent (for CTRL-T or <Tab>) +/// type == INDENT_DEC decrease indent (for CTRL-D) +/// type == INDENT_SET set indent to "amount" +/// +/// @param round if TRUE, round the indent to 'shiftwidth' (only with _INC and _Dec). +/// @param replaced replaced character, put on replace stack +/// @param call_changed_bytes call changed_bytes() +void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes) { int vcol; int last_vcol; int insstart_less; // reduction for Insstart.col int new_cursor_col; int i; - char_u *ptr; + char_u *ptr; int save_p_list; int start_col; colnr_T vc; colnr_T orig_col = 0; // init for GCC - char_u *new_line, *orig_line = NULL; // init for GCC + char_u *new_line, *orig_line = NULL; // init for GCC // VREPLACE mode needs to know what the line was like before changing if (State & VREPLACE_FLAG) { @@ -1773,8 +1778,9 @@ change_indent ( * If the cursor is in the indent, compute how many screen columns the * cursor is to the left of the first non-blank. */ - if (new_cursor_col < 0) + if (new_cursor_col < 0) { vcol = get_indent() - vcol; + } if (new_cursor_col > 0) { // can't fix replace stack start_col = -1; @@ -1783,9 +1789,9 @@ change_indent ( /* * Set the new indent. The cursor will be put on the first non-blank. */ - if (type == INDENT_SET) + if (type == INDENT_SET) { (void)set_indent(amount, call_changed_bytes ? SIN_CHANGED : 0); - else { + } else { int save_State = State; // Avoid being called recursively. @@ -1811,12 +1817,13 @@ change_indent ( * When changing the indent while the cursor is touching it, reset * Insstart_col to 0. */ - if (new_cursor_col == 0) + if (new_cursor_col == 0) { insstart_less = MAXCOL; + } new_cursor_col += curwin->w_cursor.col; - } else if (!(State & INSERT)) + } else if (!(State & INSERT)) { new_cursor_col = curwin->w_cursor.col; - else { + } else { /* * Compute the screen column where the cursor should be. */ @@ -1863,10 +1870,11 @@ change_indent ( curwin->w_p_list = save_p_list; - if (new_cursor_col <= 0) + if (new_cursor_col <= 0) { curwin->w_cursor.col = 0; - else + } else { curwin->w_cursor.col = (colnr_T)new_cursor_col; + } curwin->w_set_curswant = TRUE; changed_cline_bef_curs(); @@ -1875,15 +1883,17 @@ change_indent ( */ if (State & INSERT) { if (curwin->w_cursor.lnum == Insstart.lnum && Insstart.col != 0) { - if ((int)Insstart.col <= insstart_less) + if ((int)Insstart.col <= insstart_less) { Insstart.col = 0; - else + } else { Insstart.col -= insstart_less; + } } - if ((int)ai_col <= insstart_less) + if ((int)ai_col <= insstart_less) { ai_col = 0; - else + } else { ai_col -= insstart_less; + } } /* @@ -1975,10 +1985,11 @@ void backspace_until_column(int col) { while ((int)curwin->w_cursor.col > col) { curwin->w_cursor.col--; - if (State & REPLACE_FLAG) + if (State & REPLACE_FLAG) { replace_do_bs(col); - else if (!del_char_after_col(col)) + } else if (!del_char_after_col(col)) { break; + } } } @@ -2020,20 +2031,22 @@ static bool del_char_after_col(int limit_col) */ static void ins_ctrl_x(void) { - /* CTRL-X after CTRL-X CTRL-V doesn't do anything, so that CTRL-X - * CTRL-V works like CTRL-N */ - if (ctrl_x_mode != CTRL_X_CMDLINE) { - /* if the next ^X<> won't ADD nothing, then reset - * compl_cont_status */ - if (compl_cont_status & CONT_N_ADDS) + if (ctrl_x_mode != CTRL_X_CMDLINE && ctrl_x_mode != CTRL_X_CMDLINE_CTRL_X) { + // if the next ^X<> won't ADD nothing, then reset compl_cont_status + if (compl_cont_status & CONT_N_ADDS) { compl_cont_status |= CONT_INTRPT; - else + } else { compl_cont_status = 0; + } // We're not sure which CTRL-X mode it will be yet ctrl_x_mode = CTRL_X_NOT_DEFINED_YET; edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); edit_submode_pre = NULL; showmode(); + } else { + // CTRL-X in CTRL-X CTRL-V mode behaves differently to make CTRL-X + // CTRL-V look like CTRL-N + ctrl_x_mode = CTRL_X_CMDLINE_CTRL_X; } } @@ -2043,7 +2056,8 @@ bool ctrl_x_mode_not_default(void) return ctrl_x_mode != CTRL_X_NORMAL; } -// Whether CTRL-X was typed without a following character. +// Whether CTRL-X was typed without a following character, +// not including when in CTRL-X CTRL-V mode. bool ctrl_x_mode_not_defined_yet(void) { return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET; @@ -2095,12 +2109,14 @@ bool vim_is_ctrl_x_key(int c) case 0: // Not in any CTRL-X mode return c == Ctrl_N || c == Ctrl_P || c == Ctrl_X; case CTRL_X_NOT_DEFINED_YET: + case CTRL_X_CMDLINE_CTRL_X: return c == Ctrl_X || c == Ctrl_Y || c == Ctrl_E || c == Ctrl_L || c == Ctrl_F || c == Ctrl_RSB || c == Ctrl_I || c == Ctrl_D || c == Ctrl_P || c == Ctrl_N || c == Ctrl_T || c == Ctrl_V || c == Ctrl_Q || c == Ctrl_U || c == Ctrl_O - || c == Ctrl_S || c == Ctrl_K || c == 's'; + || c == Ctrl_S || c == Ctrl_K || c == 's' + || c == Ctrl_Z; case CTRL_X_SCROLL: return c == Ctrl_Y || c == Ctrl_E; case CTRL_X_WHOLE_LINE: @@ -2154,6 +2170,7 @@ static bool ins_compl_accept_char(int c) return vim_isfilec(c) && !vim_ispathsep(c); case CTRL_X_CMDLINE: + case CTRL_X_CMDLINE_CTRL_X: case CTRL_X_OMNI: // Command line and Omni completion can work with just about any // printable character, but do stop at white space. @@ -2172,8 +2189,8 @@ static bool ins_compl_accept_char(int c) /// the rest of the word to be in -- webb /// /// @param[in] cont_s_ipos next ^X<> will set initial_pos -int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname, - Direction dir, bool cont_s_ipos) +int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname, Direction dir, + bool cont_s_ipos) FUNC_ATTR_NONNULL_ARG(1) { char_u *str = str_arg; @@ -2316,15 +2333,12 @@ int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname, /// @return NOTDONE if the given string is already in the list of completions, /// otherwise it is added to the list and OK is returned. FAIL will be /// returned in case of error. -static int ins_compl_add(char_u *const str, int len, - char_u *const fname, - char_u *const *const cptext, - const bool cptext_allocated, - typval_T *user_data, - const Direction cdir, int flags_arg, const bool adup) +static int ins_compl_add(char_u *const str, int len, char_u *const fname, + char_u *const *const cptext, const bool cptext_allocated, + typval_T *user_data, const Direction cdir, int flags_arg, const bool adup) FUNC_ATTR_NONNULL_ARG(1) { - compl_T *match; + compl_T *match; const Direction dir = (cdir == kDirectionNotSet ? compl_direction : cdir); int flags = flags_arg; @@ -2420,9 +2434,9 @@ static int ins_compl_add(char_u *const str, int len, /* * Link the new match structure in the list of matches. */ - if (compl_first_match == NULL) + if (compl_first_match == NULL) { match->cp_next = match->cp_prev = NULL; - else if (dir == FORWARD) { + } else if (dir == FORWARD) { match->cp_next = compl_curr_match->cp_next; match->cp_prev = compl_curr_match; } else { // BACKWARD @@ -2472,7 +2486,7 @@ static bool ins_compl_equal(compl_T *match, char_u *str, size_t len) */ static void ins_compl_longest_match(compl_T *match) { - char_u *p, *s; + char_u *p, *s; int c1, c2; int had_match; @@ -2486,8 +2500,9 @@ static void ins_compl_longest_match(compl_T *match) /* When the match isn't there (to avoid matching itself) remove it * again after redrawing. */ - if (!had_match) + if (!had_match) { ins_compl_delete(); + } compl_used_match = false; } else { // Reduce the text if this match differs from compl_leader. @@ -2516,8 +2531,9 @@ static void ins_compl_longest_match(compl_T *match) /* When the match isn't there (to avoid matching itself) remove it * again after redrawing. */ - if (!had_match) + if (!had_match) { ins_compl_delete(); + } } compl_used_match = false; @@ -2601,8 +2617,9 @@ void set_completion(colnr_T startcol, list_T *list) ins_compl_free(); compl_direction = FORWARD; - if (startcol > curwin->w_cursor.col) + if (startcol > curwin->w_cursor.col) { startcol = curwin->w_cursor.col; + } compl_col = startcol; compl_length = (int)curwin->w_cursor.col - (int)startcol; // compl_pattern doesn't need to be set @@ -2725,8 +2742,8 @@ static void trigger_complete_changed_event(int cur) /// Also adjusts "compl_shown_match" to an entry that is actually displayed. void ins_compl_show_pum(void) { - compl_T *compl; - compl_T *shown_compl = NULL; + compl_T *compl; + compl_T *shown_compl = NULL; bool did_find_shown_match = false; bool shown_match_ok = false; int i; @@ -2735,8 +2752,9 @@ void ins_compl_show_pum(void) int lead_len = 0; bool array_changed = false; - if (!pum_wanted() || !pum_enough_matches()) + if (!pum_wanted() || !pum_enough_matches()) { return; + } // Dirty hard-coded hack: remove any matchparen highlighting. do_cmdline_cmd("if exists('g:loaded_matchparen')|3match none|endif"); @@ -2767,8 +2785,9 @@ void ins_compl_show_pum(void) } compl = compl->cp_next; } while (compl != NULL && compl != compl_first_match); - if (compl_match_arraysize == 0) + if (compl_match_arraysize == 0) { return; + } assert(compl_match_arraysize >= 0); compl_match_array = xcalloc(compl_match_arraysize, sizeof(pumitem_T)); @@ -2799,18 +2818,20 @@ void ins_compl_show_pum(void) cur = i; } - if (compl->cp_text[CPT_ABBR] != NULL) + if (compl->cp_text[CPT_ABBR] != NULL) { compl_match_array[i].pum_text = compl->cp_text[CPT_ABBR]; - else + } else { compl_match_array[i].pum_text = compl->cp_str; + } compl_match_array[i].pum_kind = compl->cp_text[CPT_KIND]; compl_match_array[i].pum_info = compl->cp_text[CPT_INFO]; - if (compl->cp_text[CPT_MENU] != NULL) + if (compl->cp_text[CPT_MENU] != NULL) { compl_match_array[i++].pum_extra = compl->cp_text[CPT_MENU]; - else + } else { compl_match_array[i++].pum_extra = compl->cp_fname; + } } if (compl == compl_shown_match) { @@ -2867,23 +2888,18 @@ void ins_compl_show_pum(void) #define DICT_FIRST (1) // use just first element in "dict" #define DICT_EXACT (2) // "dict" is the exact name of a file -/* - * Add any identifiers that match the given pattern in the list of dictionary - * files "dict_start" to the list of completions. - */ -static void -ins_compl_dictionaries ( - char_u *dict_start, - char_u *pat, - int flags, // DICT_FIRST and/or DICT_EXACT - int thesaurus // Thesaurus completion -) -{ - char_u *dict = dict_start; - char_u *ptr; - char_u *buf; +/// Add any identifiers that match the given pattern in the list of dictionary +/// files "dict_start" to the list of completions. +/// +/// @param flags DICT_FIRST and/or DICT_EXACT +/// @param thesaurus Thesaurus completion +static void ins_compl_dictionaries(char_u *dict_start, char_u *pat, int flags, int thesaurus) +{ + char_u *dict = dict_start; + char_u *ptr; + char_u *buf; regmatch_T regmatch; - char_u **files; + char_u **files; int count; int save_p_scs; Direction dir = compl_direction; @@ -2891,10 +2907,11 @@ ins_compl_dictionaries ( if (*dict == NUL) { /* When 'dictionary' is empty and spell checking is enabled use * "spell". */ - if (!thesaurus && curwin->w_p_spell) + if (!thesaurus && curwin->w_p_spell) { dict = (char_u *)"spell"; - else + } else { return; + } } buf = xmalloc(LSIZE); @@ -2902,8 +2919,9 @@ ins_compl_dictionaries ( // If 'infercase' is set, don't use 'smartcase' here save_p_scs = p_scs; - if (curbuf->b_p_inf) + if (curbuf->b_p_inf) { p_scs = FALSE; + } /* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern * to only match at the start of a line. Otherwise just match the @@ -2919,8 +2937,9 @@ ins_compl_dictionaries ( xfree(ptr); } else { regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); - if (regmatch.regprog == NULL) + if (regmatch.regprog == NULL) { goto theend; + } } // ignore case depends on 'ignorecase', 'smartcase' and "pat" @@ -2935,30 +2954,34 @@ ins_compl_dictionaries ( * backticks (for security, the 'dict' option may have been set in * a modeline). */ copy_option_part(&dict, buf, LSIZE, ","); - if (!thesaurus && STRCMP(buf, "spell") == 0) + if (!thesaurus && STRCMP(buf, "spell") == 0) { count = -1; - else if (vim_strchr(buf, '`') != NULL - || expand_wildcards(1, &buf, &count, &files, - EW_FILE|EW_SILENT) != OK) + } else if (vim_strchr(buf, '`') != NULL + || expand_wildcards(1, &buf, &count, &files, + EW_FILE|EW_SILENT) != OK) { count = 0; + } } if (count == -1) { /* Complete from active spelling. Skip "\<" in the pattern, we * don't use it as a RE. */ - if (pat[0] == '\\' && pat[1] == '<') + if (pat[0] == '\\' && pat[1] == '<') { ptr = pat + 2; - else + } else { ptr = pat; + } spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0); } else if (count > 0) { // avoid warning for using "files" uninit ins_compl_files(count, files, thesaurus, flags, - ®match, buf, &dir); - if (flags != DICT_EXACT) + ®match, buf, &dir); + if (flags != DICT_EXACT) { FreeWild(count, files); + } } - if (flags != 0) + if (flags != 0) { break; + } } theend: @@ -2967,14 +2990,13 @@ theend: xfree(buf); } -static void ins_compl_files(int count, char_u **files, int thesaurus, - int flags, regmatch_T *regmatch, char_u *buf, - Direction *dir) +static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, + regmatch_T *regmatch, char_u *buf, Direction *dir) FUNC_ATTR_NONNULL_ARG(2, 7) { - char_u *ptr; + char_u *ptr; int i; - FILE *fp; + FILE *fp; int add_r; for (i = 0; i < count && !got_int && !compl_interrupted; i++) { @@ -3017,8 +3039,9 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, /* Find start of the next word. Skip white * space and punctuation. */ ptr = find_word_start(ptr); - if (*ptr == NUL || *ptr == NL) + if (*ptr == NUL || *ptr == NL) { break; + } wstart = ptr; // Find end of the word. @@ -3096,11 +3119,12 @@ char_u *find_word_end(char_u *ptr) */ static char_u *find_line_end(char_u *ptr) { - char_u *s; + char_u *s; s = ptr + STRLEN(ptr); - while (s > ptr && (s[-1] == CAR || s[-1] == NL)) + while (s > ptr && (s[-1] == CAR || s[-1] == NL)) { --s; + } return s; } @@ -3114,8 +3138,9 @@ static void ins_compl_free(void) XFREE_CLEAR(compl_pattern); XFREE_CLEAR(compl_leader); - if (compl_first_match == NULL) + if (compl_first_match == NULL) { return; + } ins_compl_del_pum(); pum_clear(); @@ -3277,9 +3302,9 @@ void get_complete_info(list_T *what_list, dict_T *retdict) tv_dict_add_str(di, S_LEN("info"), (char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO])); if (match->cp_user_data.v_type == VAR_UNKNOWN) { - tv_dict_add_str(di, S_LEN("user_data"), ""); + tv_dict_add_str(di, S_LEN("user_data"), ""); } else { - tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data); + tv_dict_add_tv(di, S_LEN("user_data"), &match->cp_user_data); } } match = match->cp_next; @@ -3319,8 +3344,8 @@ static char_u * ins_compl_mode(void) */ static int ins_compl_bs(void) { - char_u *line; - char_u *p; + char_u *line; + char_u *p; line = get_cursor_line_ptr(); p = line + curwin->w_cursor.col; @@ -3340,8 +3365,9 @@ static int ins_compl_bs(void) /* Deleted more than what was used to find matches or didn't finish * finding all matches: need to look for matches all over again. */ if (curwin->w_cursor.col <= compl_col + compl_length - || ins_compl_need_restart()) + || ins_compl_need_restart()) { ins_compl_restart(); + } xfree(compl_leader); compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); @@ -3398,8 +3424,9 @@ static void ins_compl_new_leader(void) /* Don't let Enter select the original text when there is no popup menu. * Don't let Enter select when use user function and refresh_always is set */ - if (compl_match_array == NULL || ins_compl_need_restart()) + if (compl_match_array == NULL || ins_compl_need_restart()) { compl_enter_selects = FALSE; + } } /* @@ -3410,8 +3437,9 @@ static int ins_compl_len(void) { int off = (int)curwin->w_cursor.col - (int)compl_col; - if (off < 0) + if (off < 0) { return 0; + } return off; } @@ -3424,7 +3452,7 @@ static void ins_compl_addleader(int c) int cc; if (stop_arrow() == FAIL) { - return; + return; } if ((cc = utf_char2len(c)) > 1) { char_u buf[MB_MAXBYTES + 1]; @@ -3489,10 +3517,10 @@ static void ins_compl_set_original_text(char_u *str) */ static void ins_compl_addfrommatch(void) { - char_u *p; + char_u *p; int len = (int)curwin->w_cursor.col - (int)compl_col; int c; - compl_T *cp; + compl_T *cp; assert(compl_shown_match != NULL); p = compl_shown_match->cp_str; if ((int)STRLEN(p) <= len) { // the match is too short @@ -3504,15 +3532,17 @@ static void ins_compl_addfrommatch(void) && cp != compl_first_match; cp = cp->cp_next) { if (compl_leader == NULL || ins_compl_equal(cp, compl_leader, - (int)STRLEN(compl_leader))) { + (int)STRLEN(compl_leader))) { p = cp->cp_str; break; } } - if (p == NULL || (int)STRLEN(p) <= len) + if (p == NULL || (int)STRLEN(p) <= len) { return; - } else + } + } else { return; + } } p += len; c = PTR2CHAR(p); @@ -3534,8 +3564,9 @@ static bool ins_compl_prep(int c) /* Forget any previous 'special' messages if this is actually * a ^X mode key - bar ^R, in which case we wait to see what it gives us. */ - if (c != Ctrl_R && vim_is_ctrl_x_key(c)) + if (c != Ctrl_R && vim_is_ctrl_x_key(c)) { edit_submode_extra = NULL; + } // Ignore end of Select mode mapping and mouse scroll buttons. if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP @@ -3544,6 +3575,26 @@ static bool ins_compl_prep(int c) return retval; } + if (ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X && c != Ctrl_X) { + if (c == Ctrl_V || c == Ctrl_Q || c == Ctrl_Z || ins_compl_pum_key(c) + || !vim_is_ctrl_x_key(c)) { + // Not starting another completion mode. + ctrl_x_mode = CTRL_X_CMDLINE; + + // CTRL-X CTRL-Z should stop completion without inserting anything + if (c == Ctrl_Z) { + retval = true; + } + } else { + ctrl_x_mode = CTRL_X_CMDLINE; + + // Other CTRL-X keys first stop completion, then start another + // completion mode. + ins_compl_prep(' '); + ctrl_x_mode = CTRL_X_NOT_DEFINED_YET; + } + } + // Set "compl_get_longest" when finding the first matches. if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) { @@ -3560,10 +3611,11 @@ static bool ins_compl_prep(int c) case Ctrl_E: case Ctrl_Y: ctrl_x_mode = CTRL_X_SCROLL; - if (!(State & REPLACE_FLAG)) + if (!(State & REPLACE_FLAG)) { edit_submode = (char_u *)_(" (insert) Scroll (^E/^Y)"); - else + } else { edit_submode = (char_u *)_(" (replace) Scroll (^E/^Y)"); + } edit_submode_pre = NULL; showmode(); break; @@ -3609,6 +3661,12 @@ static bool ins_compl_prep(int c) case Ctrl_Q: ctrl_x_mode = CTRL_X_CMDLINE; break; + case Ctrl_Z: + ctrl_x_mode = CTRL_X_NORMAL; + edit_submode = NULL; + showmode(); + retval = true; + break; case Ctrl_P: case Ctrl_N: /* ^X^P means LOCAL expansion if nothing interrupted (eg we @@ -3618,10 +3676,11 @@ static bool ins_compl_prep(int c) * ^X^F^X^P or ^P^X^X^P, see below) * nothing changes if interrupting mode 0, (eg, the flag * doesn't change when going to ADDING mode -- Acevedo */ - if (!(compl_cont_status & CONT_INTRPT)) + if (!(compl_cont_status & CONT_INTRPT)) { compl_cont_status |= CONT_LOCAL; - else if (compl_cont_mode != 0) + } else if (compl_cont_mode != 0) { compl_cont_status &= ~CONT_LOCAL; + } FALLTHROUGH; default: /* If we have typed at least 2 ^X's... for modes != 0, we set @@ -3635,10 +3694,11 @@ static bool ins_compl_prep(int c) * In mode 0 an extra ^X is needed since ^X^P goes to ADDING * mode -- Acevedo */ if (c == Ctrl_X) { - if (compl_cont_mode != 0) + if (compl_cont_mode != 0) { compl_cont_status = 0; - else + } else { compl_cont_mode = CTRL_X_NOT_DEFINED_YET; + } } ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; @@ -3681,10 +3741,11 @@ static bool ins_compl_prep(int c) * When using the longest match, edited the match or used * CTRL-E then don't use the current match. */ - if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E) + if (compl_curr_match != NULL && compl_used_match && c != Ctrl_E) { ptr = compl_curr_match->cp_str; - else + } else { ptr = NULL; + } ins_compl_fixRedoBufForLeader(ptr); } @@ -3766,16 +3827,18 @@ static bool ins_compl_prep(int c) /* * Indent now if a key was typed that is in 'cinkeys'. */ - if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) + if (want_cindent && in_cinkeys(KEY_COMPLETE, ' ', inindent(0))) { do_c_expr_indent(); + } // Trigger the CompleteDone event to give scripts a chance to act // upon the end of completion. ins_apply_autocmds(EVENT_COMPLETEDONE); } - } else if (ctrl_x_mode == CTRL_X_LOCAL_MSG) + } 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. */ ins_apply_autocmds(EVENT_COMPLETEDONE); + } /* reset continue_* if we left expansion-mode, if we stay they'll be * (re)set properly in ins_complete() */ @@ -3795,8 +3858,8 @@ static bool ins_compl_prep(int c) static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg) { int len; - char_u *p; - char_u *ptr = ptr_arg; + char_u *p; + char_u *ptr = ptr_arg; if (ptr == NULL) { if (compl_leader != NULL) { @@ -3823,7 +3886,7 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg) /* * Loops through the list of windows, loaded-buffers or non-loaded-buffers * (depending on flag) starting from buf and looking for a non-scanned - * buffer (other than curbuf). curbuf is special, if it is called with + * buffer (other than curbuf). curbuf is special, if it is called with * buf=curbuf then it has to be the first call for a given flag/expansion. * * Returns the buffer to scan, if any, otherwise returns curbuf -- Acevedo @@ -3838,10 +3901,11 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag) } assert(wp); while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin - && wp->w_buffer->b_scanned) + && wp->w_buffer->b_scanned) { ; + } buf = wp->w_buffer; - } else + } else { /* 'b' (just loaded buffers), 'u' (just non-loaded buffers) or 'U' * (unlisted buffers) * When completing whole lines skip unloaded buffers. */ @@ -3850,19 +3914,19 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag) ? buf->b_p_bl : (!buf->b_p_bl || (buf->b_ml.ml_mfp == NULL) != (flag == 'u'))) - || buf->b_scanned)) + || buf->b_scanned)) { ; + } + } return buf; } -// Execute user defined complete function 'completefunc' or 'omnifunc', and -// get matches in "matches". -static void -expand_by_function( - int type, // CTRL_X_OMNI or CTRL_X_FUNCTION - char_u *base -) +/// Execute user defined complete function 'completefunc' or 'omnifunc', and +/// get matches in "matches". +/// +/// @param type CTRL_X_OMNI or CTRL_X_FUNCTION +static void expand_by_function(int type, char_u *base) { list_T *matchlist = NULL; dict_T *matchdict = NULL; @@ -3920,10 +3984,11 @@ expand_by_function( goto theend; } - if (matchlist != NULL) + if (matchlist != NULL) { ins_compl_add_list(matchlist); - else if (matchdict != NULL) + } else if (matchdict != NULL) { ins_compl_add_dict(matchdict); + } theend: // Restore State, it might have been changed. @@ -3960,8 +4025,8 @@ static void ins_compl_add_list(list_T *const list) */ static void ins_compl_add_dict(dict_T *dict) { - dictitem_T *di_refresh; - dictitem_T *di_words; + dictitem_T *di_refresh; + dictitem_T *di_words; // Check for optional "refresh" item. compl_opt_refresh_always = false; @@ -4019,7 +4084,7 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir, bool fast) flags |= CP_EQUAL; } } else { - word = (const char *)tv_get_string_chk(tv); + word = tv_get_string_chk(tv); memset(cptext, 0, sizeof(cptext)); } if (word == NULL || (!empty && *word == NUL)) { @@ -4044,7 +4109,7 @@ static int ins_compl_get_exp(pos_T *ini) static pos_T first_match_pos; static pos_T last_match_pos; static char_u *e_cpt = (char_u *)""; // curr. entry in 'complete' - static int found_all = false; // Found all matches of a + static bool found_all = false; // Found all matches of a // certain type. static buf_T *ins_buf = NULL; // buffer being scanned @@ -4061,7 +4126,7 @@ static int ins_compl_get_exp(pos_T *ini) char_u *ptr; char_u *dict = NULL; int dict_f = 0; - int set_match_pos; + bool set_match_pos; int l_ctrl_x_mode = ctrl_x_mode; assert(curbuf != NULL); @@ -4070,7 +4135,7 @@ static int ins_compl_get_exp(pos_T *ini) FOR_ALL_BUFFERS(buf) { buf->b_scanned = false; } - found_all = FALSE; + found_all = false; ins_buf = curbuf; e_cpt = (compl_cont_status & CONT_LOCAL) ? (char_u *)"." : curbuf->b_p_cpt; @@ -4085,7 +4150,7 @@ static int ins_compl_get_exp(pos_T *ini) // For ^N/^P loop over all the flags/windows/buffers in 'complete' for (;; ) { found_new_match = FAIL; - set_match_pos = FALSE; + set_match_pos = false; assert(l_ctrl_x_mode == ctrl_x_mode); @@ -4095,9 +4160,10 @@ static int ins_compl_get_exp(pos_T *ini) if ((l_ctrl_x_mode == CTRL_X_NORMAL || CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) && (!compl_started || found_all)) { - found_all = FALSE; - while (*e_cpt == ',' || *e_cpt == ' ') + found_all = false; + while (*e_cpt == ',' || *e_cpt == ' ') { e_cpt++; + } if (*e_cpt == '.' && !curbuf->b_scanned) { ins_buf = curbuf; first_match_pos = *ini; @@ -4118,7 +4184,7 @@ static int ins_compl_get_exp(pos_T *ini) set_match_pos = true; } else if (vim_strchr((char_u *)"buwU", *e_cpt) != NULL && (ins_buf = - ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) { + ins_compl_next_buf(ins_buf, *e_cpt)) != curbuf) { // Scan a buffer, but not the current one. if (ins_buf->b_ml.ml_mfp != NULL) { // loaded buffer compl_started = true; @@ -4149,10 +4215,11 @@ static int ins_compl_get_exp(pos_T *ini) if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) { type = -1; } else if (*e_cpt == 'k' || *e_cpt == 's') { - if (*e_cpt == 'k') + if (*e_cpt == 'k') { type = CTRL_X_DICTIONARY; - else + } else { type = CTRL_X_THESAURUS; + } if (*++e_cpt != ',' && *e_cpt != NUL) { dict = e_cpt; dict_f = DICT_FIRST; @@ -4173,9 +4240,10 @@ static int ins_compl_get_exp(pos_T *ini) // in any case e_cpt is advanced to the next entry (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ","); - found_all = TRUE; - if (type == -1) + found_all = true; + if (type == -1) { continue; + } } } @@ -4201,18 +4269,17 @@ static int ins_compl_get_exp(pos_T *ini) case CTRL_X_DICTIONARY: case CTRL_X_THESAURUS: - ins_compl_dictionaries( - dict != NULL ? dict - : (type == CTRL_X_THESAURUS + ins_compl_dictionaries(dict != NULL ? dict + : (type == CTRL_X_THESAURUS ? (*curbuf->b_p_tsr == NUL ? p_tsr : curbuf->b_p_tsr) - : (*curbuf->b_p_dict == NUL + : (*curbuf->b_p_dict == NUL ? p_dict : curbuf->b_p_dict)), - compl_pattern, - dict != NULL ? dict_f - : 0, type == CTRL_X_THESAURUS); + compl_pattern, + dict != NULL ? dict_f + : 0, type == CTRL_X_THESAURUS); dict = NULL; break; @@ -4242,7 +4309,7 @@ static int ins_compl_get_exp(pos_T *ini) #ifdef BACKSLASH_IN_FILENAME if (curbuf->b_p_csl[0] != NUL) { for (int i = 0; i < num_matches; i++) { - char_u *ptr = matches[i]; + char_u *ptr = matches[i]; while (*ptr != NUL) { if (curbuf->b_p_csl[0] == 's' && *ptr == '\\') { *ptr = '/'; @@ -4259,10 +4326,12 @@ static int ins_compl_get_exp(pos_T *ini) break; case CTRL_X_CMDLINE: + case CTRL_X_CMDLINE_CTRL_X: if (expand_cmdline(&compl_xp, compl_pattern, - (int)STRLEN(compl_pattern), - &num_matches, &matches) == EXPAND_OK) - ins_compl_add_matches(num_matches, matches, FALSE); + (int)STRLEN(compl_pattern), + &num_matches, &matches) == EXPAND_OK) { + ins_compl_add_matches(num_matches, matches, false); + } break; case CTRL_X_FUNCTION: @@ -4272,27 +4341,30 @@ static int ins_compl_get_exp(pos_T *ini) case CTRL_X_SPELL: num_matches = expand_spelling(first_match_pos.lnum, - compl_pattern, &matches); - if (num_matches > 0) + compl_pattern, &matches); + if (num_matches > 0) { ins_compl_add_matches(num_matches, matches, p_ic); + } break; default: // normal ^P/^N and ^X^L // If 'infercase' is set, don't use 'smartcase' here save_p_scs = p_scs; assert(ins_buf); - if (ins_buf->b_p_inf) + if (ins_buf->b_p_inf) { p_scs = FALSE; + } // Buffers other than curbuf are scanned from the beginning or the // end but never from the middle, thus setting nowrapscan in this // buffers is a good idea, on the other hand, we always set // wrapscan for curbuf to avoid missing matches -- Acevedo,Webb save_p_ws = p_ws; - if (ins_buf != curbuf) + if (ins_buf != curbuf) { p_ws = false; - else if (*e_cpt == '.') + } else if (*e_cpt == '.') { p_ws = true; + } for (;; ) { bool cont_s_ipos = false; @@ -4323,8 +4395,9 @@ static int ins_compl_get_exp(pos_T *ini) found_new_match = FAIL; } if (found_new_match == FAIL) { - if (ins_buf == curbuf) - found_all = TRUE; + if (ins_buf == curbuf) { + found_all = true; + } break; } @@ -4399,13 +4472,13 @@ static int ins_compl_get_exp(pos_T *ini) IObuff[len] = NUL; ptr = IObuff; } - if (len == compl_length) + if (len == compl_length) { continue; + } } } - if (ins_compl_add_infercase( - ptr, len, p_ic, ins_buf == curbuf ? NULL : ins_buf->b_sfname, - 0, cont_s_ipos) != NOTDONE) { + if (ins_compl_add_infercase(ptr, len, p_ic, ins_buf == curbuf ? NULL : ins_buf->b_sfname, + 0, cont_s_ipos) != NOTDONE) { found_new_match = OK; break; } @@ -4425,8 +4498,9 @@ static int ins_compl_get_exp(pos_T *ini) if ((l_ctrl_x_mode != CTRL_X_NORMAL && !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) || found_new_match != FAIL) { - if (got_int) + if (got_int) { break; + } // Fill the popup menu as soon as possible. if (type != -1) { ins_compl_check_keys(0, false); @@ -4518,21 +4592,16 @@ static dict_T *ins_compl_dict_alloc(compl_T *match) { // { word, abbr, menu, kind, info } dict_T *dict = tv_dict_alloc_lock(VAR_FIXED); - tv_dict_add_str( - dict, S_LEN("word"), - (const char *)EMPTY_IF_NULL(match->cp_str)); - tv_dict_add_str( - dict, S_LEN("abbr"), - (const char *)EMPTY_IF_NULL(match->cp_text[CPT_ABBR])); - tv_dict_add_str( - dict, S_LEN("menu"), - (const char *)EMPTY_IF_NULL(match->cp_text[CPT_MENU])); - tv_dict_add_str( - dict, S_LEN("kind"), - (const char *)EMPTY_IF_NULL(match->cp_text[CPT_KIND])); - tv_dict_add_str( - dict, S_LEN("info"), - (const char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO])); + tv_dict_add_str(dict, S_LEN("word"), + (const char *)EMPTY_IF_NULL(match->cp_str)); + tv_dict_add_str(dict, S_LEN("abbr"), + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_ABBR])); + tv_dict_add_str(dict, S_LEN("menu"), + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_MENU])); + tv_dict_add_str(dict, S_LEN("kind"), + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_KIND])); + tv_dict_add_str(dict, S_LEN("info"), + (const char *)EMPTY_IF_NULL(match->cp_text[CPT_INFO])); if (match->cp_user_data.v_type == VAR_UNKNOWN) { tv_dict_add_str(dict, S_LEN("user_data"), ""); } else { @@ -4541,30 +4610,25 @@ static dict_T *ins_compl_dict_alloc(compl_T *match) return dict; } -/* - * Fill in the next completion in the current direction. - * If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to - * get more completions. If it is FALSE, then we just do nothing when there - * are no more completions in a given direction. The latter case is used when - * we are still in the middle of finding completions, to allow browsing - * through the ones found so far. - * Return the total number of matches, or -1 if still unknown -- webb. - * - * compl_curr_match is currently being used by ins_compl_get_exp(), so we use - * compl_shown_match here. - * - * Note that this function may be called recursively once only. First with - * "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn - * calls this function with "allow_get_expansion" FALSE. - */ -static int -ins_compl_next ( - int allow_get_expansion, - int count, // Repeat completion this many times; should - // be at least 1 - int insert_match, // Insert the newly selected match - int in_compl_func // Called from complete_check() -) +/// Fill in the next completion in the current direction. +/// If "allow_get_expansion" is TRUE, then we may call ins_compl_get_exp() to +/// get more completions. If it is FALSE, then we just do nothing when there +/// are no more completions in a given direction. The latter case is used when +/// we are still in the middle of finding completions, to allow browsing +/// through the ones found so far. +/// @return the total number of matches, or -1 if still unknown -- webb. +/// +/// compl_curr_match is currently being used by ins_compl_get_exp(), so we use +/// compl_shown_match here. +/// +/// Note that this function may be called recursively once only. First with +/// "allow_get_expansion" TRUE, which calls ins_compl_get_exp(), which in turn +/// calls this function with "allow_get_expansion" FALSE. +/// +/// @param count Repeat completion this many times; should be at least 1 +/// @param insert_match Insert the newly selected match +/// @param in_compl_func Called from complete_check() +static int ins_compl_next(int allow_get_expansion, int count, int insert_match, int in_compl_func) { int num_matches = -1; int todo = count; @@ -4574,8 +4638,9 @@ ins_compl_next ( /* When user complete function return -1 for findstart which is next * time of 'always', compl_shown_match become NULL. */ - if (compl_shown_match == NULL) + if (compl_shown_match == NULL) { return -1; + } if (compl_leader != NULL && (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0) { @@ -4592,21 +4657,23 @@ ins_compl_next ( * backward, find the last match. */ if (compl_shows_dir == BACKWARD && !ins_compl_equal(compl_shown_match, - compl_leader, (int)STRLEN(compl_leader)) + compl_leader, (int)STRLEN(compl_leader)) && (compl_shown_match->cp_next == NULL || compl_shown_match->cp_next == compl_first_match)) { while (!ins_compl_equal(compl_shown_match, - compl_leader, (int)STRLEN(compl_leader)) + compl_leader, (int)STRLEN(compl_leader)) && compl_shown_match->cp_prev != NULL - && compl_shown_match->cp_prev != compl_first_match) + && compl_shown_match->cp_prev != compl_first_match) { compl_shown_match = compl_shown_match->cp_prev; + } } } if (allow_get_expansion && insert_match - && (!(compl_get_longest || compl_restarting) || compl_used_match)) + && (!(compl_get_longest || compl_restarting) || compl_used_match)) { // Delete old text to be replaced ins_compl_delete(); + } // When finding the longest common text we stick at the original text, // don't let CTRL-N or CTRL-P move to the first match. @@ -4634,19 +4701,21 @@ ins_compl_next ( } else { if (!allow_get_expansion) { if (advance) { - if (compl_shows_dir == BACKWARD) + if (compl_shows_dir == BACKWARD) { compl_pending -= todo + 1; - else + } else { compl_pending += todo + 1; + } } return -1; } if (!compl_no_select && advance) { - if (compl_shows_dir == BACKWARD) + if (compl_shows_dir == BACKWARD) { --compl_pending; - else + } else { ++compl_pending; + } } // Find matches. @@ -4662,8 +4731,9 @@ ins_compl_next ( if (compl_pending < 0 && compl_shown_match->cp_prev != NULL) { compl_shown_match = compl_shown_match->cp_prev; ++compl_pending; - } else + } else { break; + } } found_end = false; } @@ -4728,8 +4798,8 @@ ins_compl_next ( if (compl_shown_match->cp_fname != NULL) { char *lead = _("match in file"); int space = sc_col - vim_strsize((char_u *)lead) - 2; - char_u *s; - char_u *e; + char_u *s; + char_u *e; if (space > 0) { // We need the tail that fits. With double-byte encoding going @@ -4797,7 +4867,7 @@ void ins_compl_check_keys(int frequency, int in_compl_func) c = safe_vgetc(); // Eat the character compl_shows_dir = ins_compl_key2dir(c); (void)ins_compl_next(false, ins_compl_key2count(c), - c != K_UP && c != K_DOWN, in_compl_func); + c != K_UP && c != K_DOWN, in_compl_func); } else { /* Need to get the character to have KeyTyped set. We'll put it * back with vungetc() below. But skip K_IGNORE. */ @@ -4805,8 +4875,9 @@ void ins_compl_check_keys(int frequency, int in_compl_func) if (c != K_IGNORE) { /* Don't interrupt completion when the character wasn't typed, * e.g., when doing @q to replay keys. */ - if (c != Ctrl_R && KeyTyped) + if (c != Ctrl_R && KeyTyped) { compl_interrupted = TRUE; + } vungetc(c); } @@ -4902,7 +4973,7 @@ static bool ins_compl_use_match(int c) */ static int ins_complete(int c, bool enable_pum) { - char_u *line; + char_u *line; int startcol = 0; // column where searched text starts colnr_T curs_col; // cursor column int n; @@ -4961,9 +5032,8 @@ static int ins_complete(int c, bool enable_pum) * mode but first we need to redefine compl_startpos */ if (compl_cont_status & CONT_S_IPOS) { compl_cont_status |= CONT_SOL; - compl_startpos.col = (colnr_T)(skipwhite( - line + compl_length - + compl_startpos.col) - line); + compl_startpos.col = (colnr_T)(skipwhite(line + compl_length + + compl_startpos.col) - line); } compl_col = compl_startpos.col; } @@ -4977,14 +5047,17 @@ static int ins_complete(int c, bool enable_pum) compl_col = curwin->w_cursor.col - compl_length; } compl_cont_status |= CONT_ADDING | CONT_N_ADDS; - if (compl_length < 1) + if (compl_length < 1) { compl_cont_status &= CONT_LOCAL; + } } else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { compl_cont_status = CONT_ADDING | CONT_N_ADDS; - } else + } else { compl_cont_status = 0; - } else + } + } else { compl_cont_status &= CONT_LOCAL; + } if (!(compl_cont_status & CONT_ADDING)) { // normal expansion compl_cont_mode = ctrl_x_mode; @@ -5003,27 +5076,30 @@ static int ins_complete(int c, bool enable_pum) if ((compl_cont_status & CONT_SOL) || ctrl_x_mode == CTRL_X_PATH_DEFINES) { if (!(compl_cont_status & CONT_ADDING)) { - while (--startcol >= 0 && vim_isIDc(line[startcol])) + while (--startcol >= 0 && vim_isIDc(line[startcol])) { ; + } compl_col += ++startcol; compl_length = curs_col - startcol; } - if (p_ic) + if (p_ic) { compl_pattern = str_foldcase(line + compl_col, compl_length, NULL, 0); - else + } else { compl_pattern = vim_strnsave(line + compl_col, compl_length); + } } else if (compl_cont_status & CONT_ADDING) { - char_u *prefix = (char_u *)"\\<"; + char_u *prefix = (char_u *)"\\<"; // we need up to 2 extra chars for the prefix compl_pattern = xmalloc(quote_meta(NULL, line + compl_col, - compl_length) + 2); + compl_length) + 2); if (!vim_iswordp(line + compl_col) || (compl_col > 0 && ( - vim_iswordp(mb_prevptr(line, line + compl_col)) - ))) + vim_iswordp(mb_prevptr(line, line + compl_col)) + ))) { prefix = (char_u *)""; + } STRCPY((char *)compl_pattern, prefix); (void)quote_meta(compl_pattern + STRLEN(prefix), line + compl_col, compl_length); @@ -5058,10 +5134,10 @@ static int ins_complete(int c, bool enable_pum) STRCAT((char *)compl_pattern, "\\k"); } else { compl_pattern = xmalloc(quote_meta(NULL, line + compl_col, - compl_length) + 2); + compl_length) + 2); STRCPY((char *)compl_pattern, "\\<"); (void)quote_meta(compl_pattern + 2, line + compl_col, - compl_length); + compl_length); } } } else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { @@ -5078,7 +5154,7 @@ static int ins_complete(int c, bool enable_pum) } else if (ctrl_x_mode == CTRL_X_FILES) { // Go back to just before the first filename character. if (startcol > 0) { - char_u *p = line + startcol; + char_u *p = line + startcol; MB_PTR_BACK(line, p); while (p > line && vim_isfilec(PTR2CHAR(p))) { @@ -5094,7 +5170,7 @@ static int ins_complete(int c, bool enable_pum) compl_col += startcol; compl_length = (int)curs_col - startcol; compl_pattern = addstar(line + compl_col, compl_length, EXPAND_FILES); - } else if (ctrl_x_mode == CTRL_X_CMDLINE) { + } else if (ctrl_x_mode == CTRL_X_CMDLINE || ctrl_x_mode == CTRL_X_CMDLINE_CTRL_X) { compl_pattern = vim_strnsave(line, curs_col); set_cmd_context(&compl_xp, compl_pattern, (int)STRLEN(compl_pattern), curs_col, false); @@ -5113,10 +5189,10 @@ static int ins_complete(int c, bool enable_pum) * Call user defined function 'completefunc' with "a:findstart" * set to 1 to obtain the length of text to use for completion. */ - char_u *funcname; + char_u *funcname; pos_T pos; - win_T *curwin_save; - buf_T *curbuf_save; + win_T *curwin_save; + buf_T *curbuf_save; const int save_State = State; /* Call 'completefunc' or 'omnifunc' and get pattern length as a @@ -5158,8 +5234,9 @@ static int ins_complete(int c, bool enable_pum) /* Return value -2 means the user complete function wants to * cancel the complete without an error. * Return value -3 does the same as -2 and leaves CTRL-X mode.*/ - if (col == -2) + if (col == -2) { return FAIL; + } if (col == -3) { ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; @@ -5169,17 +5246,17 @@ static int ins_complete(int c, bool enable_pum) return FAIL; } - /* - * Reset extended parameters of completion, when start new - * completion. - */ - compl_opt_refresh_always = FALSE; + // Reset extended parameters of completion, when start new + // completion. + compl_opt_refresh_always = false; - if (col < 0) + if (col < 0) { col = curs_col; + } compl_col = col; - if (compl_col > curs_col) + if (compl_col > curs_col) { compl_col = curs_col; + } /* Setup variables for completion. Need to obtain "line" again, * it may have become invalid. */ @@ -5190,9 +5267,9 @@ static int ins_complete(int c, bool enable_pum) if (spell_bad_len > 0) { assert(spell_bad_len <= INT_MAX); compl_col = curs_col - (int)spell_bad_len; - } - else + } else { compl_col = spell_word_start(startcol); + } if (compl_col >= (colnr_T)startcol) { compl_length = 0; compl_col = curs_col; @@ -5227,10 +5304,11 @@ static int ins_complete(int c, bool enable_pum) compl_startpos.col = compl_col; } - if (compl_cont_status & CONT_LOCAL) + if (compl_cont_status & CONT_LOCAL) { edit_submode = (char_u *)_(ctrl_x_msgs[CTRL_X_LOCAL_MSG]); - else + } else { edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); + } /* If any of the original typed text has been changed we need to fix * the redo buffer. */ @@ -5335,14 +5413,15 @@ static int ins_complete(int c, bool enable_pum) * Translations may need more than twice that. */ static char_u match_ref[81]; - if (compl_matches > 0) + if (compl_matches > 0) { vim_snprintf((char *)match_ref, sizeof(match_ref), - _("match %d of %d"), - compl_curr_match->cp_number, compl_matches); - else + _("match %d of %d"), + compl_curr_match->cp_number, compl_matches); + } else { vim_snprintf((char *)match_ref, sizeof(match_ref), - _("match %d"), - compl_curr_match->cp_number); + _("match %d"), + compl_curr_match->cp_number); + } edit_submode_extra = match_ref; edit_submode_highl = HLF_R; if (dollar_vcol >= 0) { @@ -5394,8 +5473,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len) case '*': case '[': if (ctrl_x_mode == CTRL_X_DICTIONARY - || ctrl_x_mode == CTRL_X_THESAURUS) + || ctrl_x_mode == CTRL_X_THESAURUS) { break; + } FALLTHROUGH; case '~': if (!p_magic) { // quote these only if magic is set @@ -5404,8 +5484,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len) FALLTHROUGH; case '\\': if (ctrl_x_mode == CTRL_X_DICTIONARY - || ctrl_x_mode == CTRL_X_THESAURUS) + || ctrl_x_mode == CTRL_X_THESAURUS) { break; + } FALLTHROUGH; case '^': // currently it's not needed. case '$': @@ -5430,8 +5511,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len) } } } - if (dest != NULL) + if (dest != NULL) { *dest = NUL; + } return m; } @@ -5447,12 +5529,13 @@ int get_literal(void) int cc; int nc; int i; - int hex = FALSE; - int octal = FALSE; + bool hex = false; + bool octal = false; int unicode = 0; - if (got_int) + if (got_int) { return Ctrl_C; + } no_mapping++; // don't map the next key hits cc = 0; @@ -5460,29 +5543,31 @@ int get_literal(void) for (;; ) { nc = plain_vgetc(); if (!(State & CMDLINE) - && MB_BYTE2LEN_CHECK(nc) == 1 - ) + && MB_BYTE2LEN_CHECK(nc) == 1) { add_to_showcmd(nc); - if (nc == 'x' || nc == 'X') - hex = TRUE; - else if (nc == 'o' || nc == 'O') - octal = TRUE; - else if (nc == 'u' || nc == 'U') + } + if (nc == 'x' || nc == 'X') { + hex = true; + } else if (nc == 'o' || nc == 'O') { + octal = true; + } else if (nc == 'u' || nc == 'U') { unicode = nc; - else { + } else { if (hex - || unicode != 0 - ) { - if (!ascii_isxdigit(nc)) + || unicode != 0) { + if (!ascii_isxdigit(nc)) { break; + } cc = cc * 16 + hex2nr(nc); } else if (octal) { - if (nc < '0' || nc > '7') + if (nc < '0' || nc > '7') { break; + } cc = cc * 8 + nc - '0'; } else { - if (!ascii_isdigit(nc)) + if (!ascii_isdigit(nc)) { break; + } cc = cc * 10 + nc - '0'; } @@ -5490,9 +5575,9 @@ int get_literal(void) } if (cc > 255 - && unicode == 0 - ) + && unicode == 0) { cc = 255; // limit range to 0-255 + } nc = 0; if (hex) { // hex: up to two chars @@ -5522,8 +5607,9 @@ int get_literal(void) } --no_mapping; - if (nc) + if (nc) { vungetc(nc); + } got_int = false; // CTRL-C typed after CTRL-V is not an interrupt return cc; } @@ -5533,7 +5619,7 @@ int get_literal(void) /// @param ctrlv `c` was typed after CTRL-V static void insert_special(int c, int allow_modmask, int ctrlv) { - char_u *p; + char_u *p; int len; // Special function key, translate into "<Key>". Up to the last '>' is @@ -5549,16 +5635,18 @@ static void insert_special(int c, int allow_modmask, int ctrlv) len = (int)STRLEN(p); c = p[len - 1]; if (len > 2) { - if (stop_arrow() == FAIL) + if (stop_arrow() == FAIL) { return; + } p[len - 1] = NUL; ins_str(p); AppendToRedobuffLit(p, -1); ctrlv = FALSE; } } - if (stop_arrow() == OK) + if (stop_arrow() == OK) { insertchar(c, ctrlv ? INSCHAR_CTRLV : 0, -1); + } } /* @@ -5573,26 +5661,25 @@ static void insert_special(int c, int allow_modmask, int ctrlv) # define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL || (c) == '0' || (c) == '^') #define WHITECHAR(cc) ( \ - ascii_iswhite(cc) \ - && !utf_iscomposing(utf_ptr2char(get_cursor_pos_ptr() + 1))) + ascii_iswhite(cc) \ + && !utf_iscomposing(utf_ptr2char(get_cursor_pos_ptr() + 1))) -/* - * "flags": INSCHAR_FORMAT - force formatting - * INSCHAR_CTRLV - char typed just after CTRL-V - * INSCHAR_NO_FEX - don't use 'formatexpr' - * - * NOTE: passes the flags value straight through to internal_format() which, - * beside INSCHAR_FORMAT (above), is also looking for these: - * INSCHAR_DO_COM - format comments - * INSCHAR_COM_LIST - format comments with num list or 2nd line indent - */ -void insertchar( - int c, // character to insert or NUL - int flags, // INSCHAR_FORMAT, etc. - int second_indent // indent for second line if >= 0 -) +/// +/// "flags": INSCHAR_FORMAT - force formatting +/// INSCHAR_CTRLV - char typed just after CTRL-V +/// INSCHAR_NO_FEX - don't use 'formatexpr' +/// +/// NOTE: passes the flags value straight through to internal_format() which, +/// beside INSCHAR_FORMAT (above), is also looking for these: +/// INSCHAR_DO_COM - format comments +/// INSCHAR_COM_LIST - format comments with num list or 2nd line indent +/// +/// @param c character to insert or NUL +/// @param flags INSCHAR_FORMAT, etc. +/// @param second_indent indent for second line if >= 0 +void insertchar(int c, int flags, int second_indent) { - char_u *p; + char_u *p; int force_format = flags & INSCHAR_FORMAT; const int textwidth = comp_textwidth(force_format); @@ -5604,14 +5691,14 @@ void insertchar( * - Always do this when 'formatoptions' has the 'a' flag and the line * ends in white space. * - Otherwise: - * - Don't do this if inserting a blank - * - Don't do this if an existing character is being replaced, unless - * we're in VREPLACE mode. - * - Do this if the cursor is not on the line where insert started - * or - 'formatoptions' doesn't have 'l' or the line was not too long - * before the insert. - * - 'formatoptions' doesn't have 'b' or a blank was inserted at or - * before 'textwidth' + * - Don't do this if inserting a blank + * - Don't do this if an existing character is being replaced, unless + * we're in VREPLACE mode. + * - Do this if the cursor is not on the line where insert started + * or - 'formatoptions' doesn't have 'l' or the line was not too long + * before the insert. + * - 'formatoptions' doesn't have 'b' or a blank was inserted at or + * before 'textwidth' */ if (textwidth > 0 && (force_format @@ -5628,7 +5715,7 @@ void insertchar( // when 'formatexpr' isn't set or it returns non-zero. bool do_internal = true; colnr_T virtcol = get_nolist_virtcol() - + char2cells(c != NUL ? c : gchar_cursor()); + + char2cells(c != NUL ? c : gchar_cursor()); if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0 && (force_format || virtcol > (colnr_T)textwidth)) { @@ -5637,8 +5724,9 @@ void insertchar( // was called. ins_need_undo = true; } - if (do_internal) + if (do_internal) { internal_format(textwidth, second_indent, flags, c == NUL, c); + } } if (c == NUL) { // only formatting was wanted @@ -5647,7 +5735,7 @@ void insertchar( // Check whether this character should end a comment. if (did_ai && c == end_comment_pending) { - char_u *line; + char_u *line; char_u lead_end[COM_MAX_LEN]; // end-comment string int middle_len, end_len; int i; @@ -5676,8 +5764,9 @@ void insertchar( // Skip white space before the cursor i = curwin->w_cursor.col; - while (--i >= 0 && ascii_iswhite(line[i])) + while (--i >= 0 && ascii_iswhite(line[i])) { ; + } i++; // Skip to before the middle leader @@ -5754,10 +5843,12 @@ void insertchar( if (flags & INSCHAR_CTRLV) { redo_literal(*buf); i = 1; - } else + } else { i = 0; - if (buf[i] != NUL) + } + if (buf[i] != NUL) { AppendToRedobuffLit(buf + i, -1); + } } else { int cc; @@ -5779,20 +5870,13 @@ void insertchar( } } -/* - * Format text at the current insert position. - * - * If the INSCHAR_COM_LIST flag is present, then the value of second_indent - * will be the comment leader length sent to open_line(). - */ -static void -internal_format ( - int textwidth, - int second_indent, - int flags, - int format_only, - int c // character to be inserted (can be NUL) -) +/// Format text at the current insert position. +/// +/// If the INSCHAR_COM_LIST flag is present, then the value of second_indent +/// will be the comment leader length sent to open_line(). +/// +/// @param c character to be inserted (can be NUL) +static void internal_format(int textwidth, int second_indent, int flags, int format_only, int c) { int cc; int save_char = NUL; @@ -5815,8 +5899,7 @@ internal_format ( * deleted. Replace it with an 'x' temporarily. */ if (!curbuf->b_p_ai - && !(State & VREPLACE_FLAG) - ) { + && !(State & VREPLACE_FLAG)) { cc = gchar_cursor(); if (ascii_iswhite(cc)) { save_char = cc; @@ -5835,14 +5918,15 @@ internal_format ( colnr_T len; colnr_T virtcol; int orig_col = 0; - char_u *saved_text = NULL; + char_u *saved_text = NULL; colnr_T col; colnr_T end_col; virtcol = get_nolist_virtcol() + char2cells(c != NUL ? c : gchar_cursor()); - if (virtcol <= (colnr_T)textwidth) + if (virtcol <= (colnr_T)textwidth) { break; + } if (no_leader) { do_comments = false; @@ -5890,10 +5974,11 @@ internal_format ( || (flags & INSCHAR_FORMAT) || curwin->w_cursor.lnum != Insstart.lnum || curwin->w_cursor.col >= Insstart.col) { - if (curwin->w_cursor.col == startcol && c != NUL) + if (curwin->w_cursor.col == startcol && c != NUL) { cc = c; - else + } else { cc = gchar_cursor(); + } if (WHITECHAR(cc)) { // remember position of blank just before text end_col = curwin->w_cursor.col; @@ -5948,8 +6033,9 @@ internal_format ( end_foundcol = end_col + 1; foundcol = curwin->w_cursor.col; - if (curwin->w_cursor.col <= (colnr_T)wantcol) + if (curwin->w_cursor.col <= (colnr_T)wantcol) { break; + } } else if ((cc >= 0x100 || !utf_allow_break_before(cc)) && fo_multibyte) { int ncc; @@ -5970,14 +6056,16 @@ internal_format ( if (curwin->w_cursor.col != skip_pos && allow_break) { foundcol = curwin->w_cursor.col; end_foundcol = foundcol; - if (curwin->w_cursor.col <= (colnr_T)wantcol) + if (curwin->w_cursor.col <= (colnr_T)wantcol) { break; + } } curwin->w_cursor.col = col; } - if (curwin->w_cursor.col == 0) + if (curwin->w_cursor.col == 0) { break; + } ncc = cc; col = curwin->w_cursor.col; @@ -6039,8 +6127,9 @@ internal_format ( } } } - if (curwin->w_cursor.col == 0) + if (curwin->w_cursor.col == 0) { break; + } dec_cursor(); } @@ -6069,11 +6158,13 @@ internal_format ( */ curwin->w_cursor.col = foundcol; while ((cc = gchar_cursor(), WHITECHAR(cc)) - && (!fo_white_par || curwin->w_cursor.col < startcol)) + && (!fo_white_par || curwin->w_cursor.col < startcol)) { inc_cursor(); + } startcol -= curwin->w_cursor.col; - if (startcol < 0) + if (startcol < 0) { startcol = 0; + } if (State & VREPLACE_FLAG) { /* @@ -6100,12 +6191,13 @@ internal_format ( * Only insert/delete lines, but don't really redraw the window. */ open_line(FORWARD, OPENLINE_DELSPACES + OPENLINE_MARKFIX - + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) - + (do_comments ? OPENLINE_DO_COM : 0) - + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0) - , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); - if (!(flags & INSCHAR_COM_LIST)) + + (fo_white_par ? OPENLINE_KEEPTRAIL : 0) + + (do_comments ? OPENLINE_DO_COM : 0) + + ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0) + , ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent)); + if (!(flags & INSCHAR_COM_LIST)) { old_indent = 0; + } replace_offset = 0; if (first_line) { @@ -6156,8 +6248,9 @@ internal_format ( */ curwin->w_cursor.col += startcol; len = (colnr_T)STRLEN(get_cursor_line_ptr()); - if (curwin->w_cursor.col > len) + if (curwin->w_cursor.col > len) { curwin->w_cursor.col = len; + } } haveto_redraw = true; @@ -6182,27 +6275,26 @@ internal_format ( } } -/* - * Called after inserting or deleting text: When 'formatoptions' includes the - * 'a' flag format from the current line until the end of the paragraph. - * Keep the cursor at the same position relative to the text. - * The caller must have saved the cursor line for undo, following ones will be - * saved here. - */ -void auto_format( - bool trailblank, // when true also format with trailing blank - bool prev_line // may start in previous line -) +/// Called after inserting or deleting text: When 'formatoptions' includes the +/// 'a' flag format from the current line until the end of the paragraph. +/// Keep the cursor at the same position relative to the text. +/// The caller must have saved the cursor line for undo, following ones will be +/// saved here. +/// +/// @param trailblank when true also format with trailing blank +/// @param prev_line may start in previous line +void auto_format(bool trailblank, bool prev_line) { pos_T pos; colnr_T len; - char_u *old; - char_u *new, *pnew; + char_u *old; + char_u *new, *pnew; int wasatend; int cc; - if (!has_format_option(FO_AUTO)) + if (!has_format_option(FO_AUTO)) { return; + } pos = curwin->w_cursor; old = get_cursor_line_ptr(); @@ -6220,8 +6312,9 @@ void auto_format( dec_cursor(); cc = gchar_cursor(); if (!WHITECHAR(cc) && curwin->w_cursor.col > 0 - && has_format_option(FO_ONE_LETTER)) + && has_format_option(FO_ONE_LETTER)) { dec_cursor(); + } cc = gchar_cursor(); if (WHITECHAR(cc)) { curwin->w_cursor = pos; @@ -6233,8 +6326,9 @@ void auto_format( /* With the 'c' flag in 'formatoptions' and 't' missing: only format * comments. */ if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) - && get_leader_len(old, NULL, FALSE, TRUE) == 0) + && get_leader_len(old, NULL, false, true) == 0) { return; + } /* * May start formatting in a previous line, so that after "x" a word is @@ -6243,8 +6337,9 @@ void auto_format( */ if (prev_line && !paragraph_start(curwin->w_cursor.lnum)) { --curwin->w_cursor.lnum; - if (u_save_cursor() == FAIL) + if (u_save_cursor() == FAIL) { return; + } } /* @@ -6287,14 +6382,12 @@ void auto_format( check_cursor(); } -/* - * When an extra space was added to continue a paragraph for auto-formatting, - * delete it now. The space must be under the cursor, just after the insert - * position. - */ -static void check_auto_format( - bool end_insert // true when ending Insert mode -) +/// When an extra space was added to continue a paragraph for auto-formatting, +/// delete it now. The space must be under the cursor, just after the insert +/// position. +/// +/// @param end_insert true when ending Insert mode +static void check_auto_format(bool end_insert) { int c = ' '; int cc; @@ -6319,16 +6412,14 @@ static void check_auto_format( } } -/* - * Find out textwidth to be used for formatting: - * if 'textwidth' option is set, use it - * else if 'wrapmargin' option is set, use curwin->w_width_inner-'wrapmargin' - * if invalid value, use 0. - * Set default to window width (maximum 79) for "gq" operator. - */ -int comp_textwidth( - bool ff // force formatting (for "gq" command) -) +/// Find out textwidth to be used for formatting: +/// if 'textwidth' option is set, use it +/// else if 'wrapmargin' option is set, use curwin->w_width_inner-'wrapmargin' +/// if invalid value, use 0. +/// Set default to window width (maximum 79) for "gq" operator. +/// +/// @param ff force formatting (for "gq" command) +int comp_textwidth(bool ff) { int textwidth = curbuf->b_p_tw; if (textwidth == 0 && curbuf->b_p_wm) { @@ -6341,11 +6432,13 @@ int comp_textwidth( textwidth -= win_fdccol_count(curwin); textwidth -= win_signcol_count(curwin); - if (curwin->w_p_nu || curwin->w_p_rnu) + if (curwin->w_p_nu || curwin->w_p_rnu) { textwidth -= 8; + } } - if (textwidth < 0) + if (textwidth < 0) { textwidth = 0; + } if (ff && textwidth == 0) { textwidth = curwin->w_width_inner - 1; if (textwidth > 79) { @@ -6372,17 +6465,18 @@ static void redo_literal(int c) } } -// start_arrow() is called when an arrow key is used in insert mode. -// For undo/redo it resembles hitting the <ESC> key. -static void start_arrow( - pos_T *end_insert_pos // can be NULL -) +/// start_arrow() is called when an arrow key is used in insert mode. +/// For undo/redo it resembles hitting the <ESC> key. +/// +/// @param end_insert_pos can be NULL +static void start_arrow(pos_T *end_insert_pos) { start_arrow_common(end_insert_pos, true); } /// Like start_arrow() but with end_change argument. -/// Will prepare for redo of CTRL-G U if "end_change" is FALSE. +/// Will prepare for redo of CTRL-G U if "end_change" is false. +/// /// @param end_insert_pos can be NULL /// @param end_change end undoable change static void start_arrow_with_change(pos_T *end_insert_pos, bool end_change) @@ -6427,9 +6521,10 @@ static void check_spell_redraw(void) static void spell_back_to_badword(void) { pos_T tpos = curwin->w_cursor; - spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL); - if (curwin->w_cursor.col != tpos.col) + spell_bad_len = spell_move_to(curwin, BACKWARD, true, true, NULL); + if (curwin->w_cursor.col != tpos.col) { start_arrow(&tpos); + } } /* @@ -6444,7 +6539,7 @@ int stop_arrow(void) if (Insstart.col > Insstart_orig.col && !ins_need_undo) { // Don't update the original insert position when moved to the // right, except when nothing was inserted yet. - update_Insstart_orig = FALSE; + update_Insstart_orig = false; } Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr()); @@ -6472,20 +6567,16 @@ int stop_arrow(void) return arrow_used || ins_need_undo ? FAIL : OK; } -/* - * Do a few things to stop inserting. - * "end_insert_pos" is where insert ended. It is NULL when we already jumped - * to another window/buffer. - */ -static void -stop_insert ( - pos_T *end_insert_pos, - int esc, // called by ins_esc() - int nomove // <c-\><c-o>, don't move cursor -) +/// Do a few things to stop inserting. +/// "end_insert_pos" is where insert ended. It is NULL when we already jumped +/// to another window/buffer. +/// +/// @param esc called by ins_esc() +/// @param nomove <c-\><c-o>, don't move cursor +static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) { int cc; - char_u *ptr; + char_u *ptr; stop_redo_ins(); replace_flush(); // abandon replace stack @@ -6501,8 +6592,9 @@ stop_insert ( xfree(last_insert); last_insert = ptr; last_insert_skip = new_insert_skip; - } else + } else { xfree(ptr); + } if (!arrow_used && end_insert_pos != NULL) { // Auto-format now. It may seem strange to do this when stopping an @@ -6519,21 +6611,24 @@ stop_insert ( if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) { dec_cursor(); cc = gchar_cursor(); - if (!ascii_iswhite(cc)) + if (!ascii_iswhite(cc)) { curwin->w_cursor = tpos; + } } auto_format(true, false); if (ascii_iswhite(cc)) { - if (gchar_cursor() != NUL) + if (gchar_cursor() != NUL) { inc_cursor(); + } /* If the cursor is still at the same character, also keep * the "coladd". */ if (gchar_cursor() == NUL && curwin->w_cursor.lnum == tpos.lnum - && curwin->w_cursor.col == tpos.col) + && curwin->w_cursor.col == tpos.col) { curwin->w_cursor.coladd = tpos.coladd; + } } } @@ -6554,8 +6649,9 @@ stop_insert ( curwin->w_cursor = *end_insert_pos; check_cursor_col(); // make sure it is not past the line for (;; ) { - if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) + if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) { --curwin->w_cursor.col; + } cc = gchar_cursor(); if (!ascii_iswhite(cc)) { break; @@ -6607,7 +6703,7 @@ stop_insert ( */ void set_last_insert(int c) { - char_u *s; + char_u *s; xfree(last_insert); last_insert = xmalloc(MB_MAXBYTES * 3 + 5); @@ -6661,25 +6757,26 @@ char_u *add_char2buf(int c, char_u *s) /* * move cursor to start of line - * if flags & BL_WHITE move to first non-white - * if flags & BL_SOL move to first non-white if startofline is set, - * otherwise keep "curswant" column - * if flags & BL_FIX don't leave the cursor on a NUL. + * if flags & BL_WHITE move to first non-white + * if flags & BL_SOL move to first non-white if startofline is set, + * otherwise keep "curswant" column + * if flags & BL_FIX don't leave the cursor on a NUL. */ void beginline(int flags) { - if ((flags & BL_SOL) && !p_sol) + if ((flags & BL_SOL) && !p_sol) { coladvance(curwin->w_curswant); - else { + } else { curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; if (flags & (BL_WHITE | BL_SOL)) { - char_u *ptr; + char_u *ptr; for (ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr) - && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr) + && !((flags & BL_FIX) && ptr[1] == NUL); ++ptr) { ++curwin->w_cursor.col; + } } curwin->w_set_curswant = TRUE; } @@ -6695,7 +6792,7 @@ void beginline(int flags) int oneright(void) { - char_u *ptr; + char_u *ptr; int l; if (virtual_active()) { @@ -6736,8 +6833,9 @@ int oneleft(void) int width; int v = getviscol(); - if (v == 0) + if (v == 0) { return FAIL; + } // We might get stuck on 'showbreak', skip over it. width = 1; @@ -6767,8 +6865,9 @@ int oneleft(void) return OK; } - if (curwin->w_cursor.col == 0) + if (curwin->w_cursor.col == 0) { return FAIL; + } curwin->w_set_curswant = TRUE; --curwin->w_cursor.col; @@ -6779,11 +6878,8 @@ int oneleft(void) return OK; } -int -cursor_up ( - long n, - int upd_topline // When TRUE: update topline -) +/// @oaram upd_topline When TRUE: update topline +int cursor_up(long n, int upd_topline) { linenr_T lnum; @@ -6794,9 +6890,9 @@ cursor_up ( if (lnum <= 1) { return FAIL; } - if (n >= lnum) + if (n >= lnum) { lnum = 1; - else if (hasAnyFolding(curwin)) { + } else if (hasAnyFolding(curwin)) { /* * Count each sequence of folded lines as one logical line. */ @@ -6816,10 +6912,12 @@ cursor_up ( (void)hasFolding(lnum, &lnum, NULL); } } - if (lnum < 1) + if (lnum < 1) { lnum = 1; - } else + } + } else { lnum -= n; + } curwin->w_cursor.lnum = lnum; } @@ -6833,14 +6931,10 @@ cursor_up ( return OK; } -/* - * Cursor down a number of logical lines. - */ -int -cursor_down ( - long n, - int upd_topline // When TRUE: update topline -) +/// Cursor down a number of logical lines. +/// +/// @param upd_topline When TRUE: update topline +int cursor_down(long n, int upd_topline) { linenr_T lnum; @@ -6853,24 +6947,28 @@ cursor_down ( if (lnum >= curbuf->b_ml.ml_line_count) { return FAIL; } - if (lnum + n >= curbuf->b_ml.ml_line_count) + if (lnum + n >= curbuf->b_ml.ml_line_count) { lnum = curbuf->b_ml.ml_line_count; - else if (hasAnyFolding(curwin)) { + } else if (hasAnyFolding(curwin)) { linenr_T last; // count each sequence of folded lines as one logical line while (n--) { - if (hasFolding(lnum, NULL, &last)) + if (hasFolding(lnum, NULL, &last)) { lnum = last + 1; - else + } else { ++lnum; - if (lnum >= curbuf->b_ml.ml_line_count) + } + if (lnum >= curbuf->b_ml.ml_line_count) { break; + } } - if (lnum > curbuf->b_ml.ml_line_count) + if (lnum > curbuf->b_ml.ml_line_count) { lnum = curbuf->b_ml.ml_line_count; - } else + } + } else { lnum += n; + } curwin->w_cursor.lnum = lnum; } @@ -6884,20 +6982,18 @@ cursor_down ( return OK; } -/* - * Stuff the last inserted text in the read buffer. - * Last_insert actually is a copy of the redo buffer, so we - * first have to remove the command. - */ -int stuff_inserted( - int c, // Command character to be inserted - long count, // Repeat this many times - int no_esc // Don't add an ESC at the end -) -{ - char_u *esc_ptr; - char_u *ptr; - char_u *last_ptr; +/// Stuff the last inserted text in the read buffer. +/// Last_insert actually is a copy of the redo buffer, so we +/// first have to remove the command. +/// +/// @param c Command character to be inserted +/// @param count Repeat this many times +/// @param no_esc Don't add an ESC at the end +int stuff_inserted(int c, long count, int no_esc) +{ + char_u *esc_ptr; + char_u *ptr; + char_u *last_ptr; char_u last = NUL; ptr = get_last_insert(); @@ -6935,8 +7031,9 @@ int stuff_inserted( } } while (--count > 0); - if (last) + if (last) { *last_ptr = last; + } if (esc_ptr != NULL) { *esc_ptr = ESC; // put the ESC back @@ -6952,8 +7049,9 @@ int stuff_inserted( char_u *get_last_insert(void) { - if (last_insert == NULL) + if (last_insert == NULL) { return NULL; + } return last_insert + last_insert_skip; } @@ -6963,11 +7061,12 @@ char_u *get_last_insert(void) */ char_u *get_last_insert_save(void) { - char_u *s; + char_u *s; int len; - if (last_insert == NULL) + if (last_insert == NULL) { return NULL; + } s = vim_strsave(last_insert + last_insert_skip); len = (int)STRLEN(s); if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC @@ -6995,7 +7094,7 @@ static bool echeck_abbr(int c) } return check_abbr(c, get_cursor_line_ptr(), curwin->w_cursor.col, - curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0); + curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0); } /* @@ -7013,7 +7112,7 @@ static bool echeck_abbr(int c) * that were deleted (always white space). */ -static char_u *replace_stack = NULL; +static char_u *replace_stack = NULL; static ssize_t replace_stack_nr = 0; // next entry in replace stack static ssize_t replace_stack_len = 0; // max. number of entries @@ -7052,8 +7151,9 @@ int replace_push_mb(char_u *p) int l = (*mb_ptr2len)(p); int j; - for (j = l - 1; j >= 0; --j) + for (j = l - 1; j >= 0; --j) { replace_push(p[j]); + } return l; } @@ -7065,23 +7165,22 @@ static int replace_pop(void) return (replace_stack_nr == 0) ? -1 : (int)replace_stack[--replace_stack_nr]; } -/* - * Join the top two items on the replace stack. This removes to "off"'th NUL - * encountered. - */ -static void replace_join( - int off // offset for which NUL to remove -) +/// Join the top two items on the replace stack. This removes to "off"'th NUL +/// encountered. +/// +/// @param off offset for which NUL to remove +static void replace_join(int off) { int i; - for (i = replace_stack_nr; --i >= 0; ) + for (i = replace_stack_nr; --i >= 0; ) { if (replace_stack[i] == NUL && off-- <= 0) { --replace_stack_nr; memmove(replace_stack + i, replace_stack + i + 1, - (size_t)(replace_stack_nr - i)); + (size_t)(replace_stack_nr - i)); return; } + } } /* @@ -7114,8 +7213,9 @@ static void mb_replace_pop_ins(int cc) if ((n = MB_BYTE2LEN(cc)) > 1) { buf[0] = cc; - for (i = 1; i < n; ++i) + for (i = 1; i < n; ++i) { buf[i] = replace_pop(); + } ins_bytes_len(buf, n); } else { ins_char(cc); @@ -7177,7 +7277,7 @@ static void replace_do_bs(int limit_col) int ins_len; int orig_vcols = 0; colnr_T start_vcol; - char_u *p; + char_u *p; int i; int vcol; const int l_State = State; @@ -7220,8 +7320,9 @@ static void replace_do_bs(int limit_col) // mark the buffer as changed and prepare for displaying changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); - } else if (cc == 0) + } else if (cc == 0) { (void)del_char_after_col(limit_col); + } } /// Check that C-indenting is on. @@ -7239,23 +7340,25 @@ static bool cindent_on(void) */ void fixthisline(IndentGetter get_the_indent) { - int amount = get_the_indent(); + int amount = get_the_indent(); - if (amount >= 0) { - change_indent(INDENT_SET, amount, false, 0, true); - if (linewhite(curwin->w_cursor.lnum)) { - did_ai = true; // delete the indent if the line stays empty - } + if (amount >= 0) { + change_indent(INDENT_SET, amount, false, 0, true); + if (linewhite(curwin->w_cursor.lnum)) { + did_ai = true; // delete the indent if the line stays empty } + } } void fix_indent(void) { - if (p_paste) + if (p_paste) { return; - if (curbuf->b_p_lisp && curbuf->b_p_ai) + } + if (curbuf->b_p_lisp && curbuf->b_p_ai) { fixthisline(get_lisp_indent); - else if (cindent_on()) + } else if (cindent_on()) { do_c_expr_indent(); + } } /// Check that "cinkeys" contains the key "keytyped", @@ -7278,7 +7381,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) int try_match_word; char_u *p; char_u *line; - int icase; + bool icase; if (keytyped == NUL) { // Can happen with CTRL-Y and CTRL-E on a short line. @@ -7296,9 +7399,12 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) * 'when' and a '*' or '!' before the key. */ switch (when) { - case '*': try_match = (*look == '*'); break; - case '!': try_match = (*look == '!'); break; - default: try_match = (*look != '*'); break; + case '*': + try_match = (*look == '*'); break; + case '!': + try_match = (*look == '!'); break; + default: + try_match = (*look != '*'); break; } if (*look == '*' || *look == '!') { look++; @@ -7323,8 +7429,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) } look += 2; - // 'o' means "o" command, open forward. - // 'O' means "O" command, open backward. + // 'o' means "o" command, open forward. + // 'O' means "O" command, open backward. } else if (*look == 'o') { if (try_match && keytyped == KEY_OPEN_FORW) { return true; @@ -7336,8 +7442,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) } look++; - // 'e' means to check for "else" at start of line and just before the - // cursor. + // 'e' means to check for "else" at start of line and just before the + // cursor. } else if (*look == 'e') { if (try_match && keytyped == 'e' && curwin->w_cursor.col >= 4) { p = get_cursor_line_ptr(); @@ -7348,9 +7454,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) } look++; - // ':' only causes an indent if it is at the end of a label or case - // statement, or when it was before typing the ':' (to fix - // class::method for C++). + // ':' only causes an indent if it is at the end of a label or case + // statement, or when it was before typing the ':' (to fix + // class::method for C++). } else if (*look == ':') { if (try_match && keytyped == ':') { p = get_cursor_line_ptr(); @@ -7364,8 +7470,8 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) && p[curwin->w_cursor.col - 2] == ':') { p[curwin->w_cursor.col - 1] = ' '; const bool i = cin_iscase(p, false) - || cin_isscopedecl(p) - || cin_islabel(); + || cin_isscopedecl(p) + || cin_islabel(); p = get_cursor_line_ptr(); p[curwin->w_cursor.col - 1] = ':'; if (i) { @@ -7375,7 +7481,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) } look++; - // Is it a key in <>, maybe? + // Is it a key in <>, maybe? } else if (*look == '<') { if (try_match) { // make up some named keys <o>, <O>, <e>, <0>, <>>, <<>, <*>, @@ -7390,10 +7496,12 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) return true; } } - while (*look && *look != '>') + while (*look && *look != '>') { look++; - while (*look == '>') + } + while (*look == '>') { look++; + } } /* * Is it a word: "=word"? @@ -7401,13 +7509,15 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) else if (*look == '=' && look[1] != ',' && look[1] != NUL) { ++look; if (*look == '~') { - icase = TRUE; - ++look; - } else - icase = FALSE; + icase = true; + look++; + } else { + icase = false; + } p = vim_strchr(look, ','); - if (p == NULL) + if (p == NULL) { p = look + STRLEN(look); + } if ((try_match || try_match_word) && curwin->w_cursor.col >= (colnr_T)(p - look)) { bool match = false; @@ -7428,8 +7538,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) if (s + (p - look) <= line + curwin->w_cursor.col && (icase ? mb_strnicmp(s, look, (size_t)(p - look)) - : STRNCMP(s, look, p - look)) == 0) + : STRNCMP(s, look, p - look)) == 0) { match = true; + } } else { // TODO(@brammool): multi-byte if (keytyped == (int)p[-1] @@ -7460,7 +7571,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) } look = p; - // Ok, it's a boring generic character. + // Ok, it's a boring generic character. } else { if (try_match && *look == keytyped) { return true; @@ -7490,15 +7601,15 @@ int hkmap(int c) PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV }; static char_u map[26] = - {(char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/, - (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/, - (char_u)GIMEL /*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/, - (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/, - (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/, - (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/, - (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/, - (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/, - (char_u)AIN /*y*/, (char_u)ZADI /*z*/}; + { (char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/, + (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/, + (char_u)GIMEL /*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/, + (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/, + (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/, + (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/, + (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/, + (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/, + (char_u)AIN /*y*/, (char_u)ZADI /*z*/ }; if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') { return (int)(map[CharOrd(c)] - 1 + p_aleph); @@ -7523,24 +7634,33 @@ int hkmap(int c) } } else { switch (c) { - case '`': return ';'; - case '/': return '.'; - case '\'': return ','; - case 'q': return '/'; - case 'w': return '\''; + case '`': + return ';'; + case '/': + return '.'; + case '\'': + return ','; + case 'q': + return '/'; + case 'w': + return '\''; // Hebrew letters - set offset from 'a' - case ',': c = '{'; break; - case '.': c = 'v'; break; - case ';': c = 't'; break; + case ',': + c = '{'; break; + case '.': + c = 'v'; break; + case ';': + c = 't'; break; default: { - static char str[] = "zqbcxlsjphmkwonu ydafe rig"; + static char str[] = "zqbcxlsjphmkwonu ydafe rig"; - if (c < 'a' || c > 'z') - return c; - c = str[CharOrdLow(c)]; - break; - } + if (c < 'a' || c > 'z') { + return c; + } + c = str[CharOrdLow(c)]; + break; + } } return (int)(CharOrdLow(c) + p_aleph); @@ -7549,7 +7669,7 @@ int hkmap(int c) static void ins_reg(void) { - int need_redraw = FALSE; + bool need_redraw = false; int regname; int literally = 0; int vis_active = VIsual_active; @@ -7660,13 +7780,15 @@ static void ins_ctrl_g(void) // CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col case K_UP: case Ctrl_K: - case 'k': ins_up(TRUE); + case 'k': + ins_up(true); break; // CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col case K_DOWN: case Ctrl_J: - case 'j': ins_down(TRUE); + case 'j': + ins_down(true); break; // CTRL-G u: start new undoable edit @@ -7688,7 +7810,8 @@ static void ins_ctrl_g(void) break; // Unknown CTRL-G command, reserved for future expansion. - default: vim_beep(BO_CTRLG); + default: + vim_beep(BO_CTRLG); } } @@ -7746,8 +7869,9 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) */ if (*count > 0) { line_breakcheck(); - if (got_int) + if (got_int) { *count = 0; + } } if (--*count > 0) { // repeat what was typed @@ -7796,8 +7920,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) || (gchar_cursor() == NUL && !VIsual_active )) - && !revins_on - ) { + && !revins_on) { if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) { oneleft(); if (restart_edit != NUL) { @@ -7836,8 +7959,9 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) static void ins_ctrl_(void) { if (revins_on && revins_chars && revins_scol >= 0) { - while (gchar_cursor() != NUL && revins_chars--) + while (gchar_cursor() != NUL && revins_chars--) { ++curwin->w_cursor.col; + } } p_ri = !p_ri; revins_on = (State == INSERT && p_ri); @@ -7846,8 +7970,9 @@ static void ins_ctrl_(void) revins_legal++; revins_chars = 0; undisplay_dollar(); - } else + } else { revins_scol = -1; + } p_hkmap = curwin->w_p_rl ^ p_ri; // be consistent! showmode(); } @@ -7870,8 +7995,9 @@ static bool ins_start_select(int c) case K_KPAGEUP: case K_PAGEDOWN: case K_KPAGEDOWN: - if (!(mod_mask & MOD_MASK_SHIFT)) + if (!(mod_mask & MOD_MASK_SHIFT)) { break; + } FALLTHROUGH; case K_S_LEFT: case K_S_RIGHT: @@ -7920,12 +8046,13 @@ static void ins_insert(int replaceState) */ static void ins_ctrl_o(void) { - if (State & VREPLACE_FLAG) + if (State & VREPLACE_FLAG) { restart_edit = 'V'; - else if (State & REPLACE_FLAG) + } else if (State & REPLACE_FLAG) { restart_edit = 'R'; - else + } else { restart_edit = 'I'; + } if (virtual_active()) { ins_at_eol = false; // cursor always keeps its column } else { @@ -7935,15 +8062,16 @@ static void ins_ctrl_o(void) /* * If the cursor is on an indent, ^T/^D insert/delete one - * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>". + * shiftwidth. Otherwise ^T/^D behave like a "<<" or ">>". * Always round the indent to 'shiftwidth', this is compatible * with vi. But vi only supports ^T and ^D after an * autoindent, we support it everywhere. */ static void ins_shift(int c, int lastc) { - if (stop_arrow() == FAIL) + if (stop_arrow() == FAIL) { return; + } AppendCharToRedobuff(c); /* @@ -7961,8 +8089,9 @@ static void ins_shift(int c, int lastc) old_indent = get_indent(); // remember curr. indent } change_indent(INDENT_SET, 0, TRUE, 0, TRUE); - } else + } 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; @@ -8124,19 +8253,22 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // again when auto-formatting. if (has_format_option(FO_AUTO) && has_format_option(FO_WHITE_PAR)) { - char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true); + char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true); int len; len = (int)STRLEN(ptr); - if (len > 0 && ptr[len - 1] == ' ') + if (len > 0 && ptr[len - 1] == ' ') { ptr[len - 1] = NUL; + } } do_join(2, FALSE, FALSE, FALSE, false); - if (temp == NUL && gchar_cursor() != NUL) + if (temp == NUL && gchar_cursor() != NUL) { inc_cursor(); - } else + } + } else { dec_cursor(); + } /* * In REPLACE mode we have to put back the text that was replaced @@ -8178,12 +8310,12 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) && (curbuf->b_p_ai || cindent_on() ) - && !revins_on - ) { + && !revins_on) { save_col = curwin->w_cursor.col; beginline(BL_WHITE); - if (curwin->w_cursor.col < save_col) + if (curwin->w_cursor.col < save_col) { mincol = curwin->w_cursor.col; + } curwin->w_cursor.col = save_col; } @@ -8213,7 +8345,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol); inc_cursor(); if (p_sta && in_indent) { - ts = (int)get_sw_value(curbuf); + ts = get_sw_value(curbuf); want_vcol = (want_vcol / ts) * ts; } else { want_vcol = tabstop_start(want_vcol, @@ -8239,8 +8371,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) ins_char(' '); } else { ins_str((char_u *)" "); - if ((State & REPLACE_FLAG)) + if ((State & REPLACE_FLAG)) { replace_push(NUL); + } } getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); } @@ -8294,8 +8427,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) revins_chars--; revins_legal++; } - if (revins_on && gchar_cursor() == NUL) + if (revins_on && gchar_cursor() == NUL) { break; + } } // Just a single backspace?: if (mode == BACKSPACE_CHAR) { @@ -8349,12 +8483,12 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) static void ins_mouse(int c) { pos_T tpos; - win_T *old_curwin = curwin; + win_T *old_curwin = curwin; undisplay_dollar(); tpos = curwin->w_cursor; if (do_mouse(NULL, c, BACKWARD, 1, 0)) { - win_T *new_curwin = curwin; + win_T *new_curwin = curwin; if (curwin != old_curwin && win_valid(old_curwin)) { // Mouse took us to another window. We need to go back to the @@ -8394,21 +8528,22 @@ static void ins_mousescroll(int dir) curwin = wp; curbuf = curwin->w_buffer; } - if (curwin == old_curwin) + if (curwin == old_curwin) { undisplay_dollar(); + } // Don't scroll the window in which completion is being done. if (!pum_visible() - || curwin != old_curwin - ) { + || curwin != old_curwin) { if (dir == MSCR_DOWN || dir == MSCR_UP) { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) { scroll_redraw(dir, - (long)(curwin->w_botline - curwin->w_topline)); - else + (curwin->w_botline - curwin->w_topline)); + } else { scroll_redraw(dir, 3L); + } } else { - mouse_scroll_horiz(dir); + mouse_scroll_horiz(dir); } } @@ -8430,8 +8565,9 @@ static void ins_left(void) pos_T tpos; const bool end_change = dont_sync_undo == kFalse; // end undoable change - if ((fdo_flags & FDO_HOR) && KeyTyped) + if ((fdo_flags & FDO_HOR) && KeyTyped) { foldOpenCursor(); + } undisplay_dollar(); tpos = curwin->w_cursor; if (oneleft() == OK) { @@ -8461,12 +8597,14 @@ static void ins_home(int c) { pos_T tpos; - if ((fdo_flags & FDO_HOR) && KeyTyped) + if ((fdo_flags & FDO_HOR) && KeyTyped) { foldOpenCursor(); + } undisplay_dollar(); tpos = curwin->w_cursor; - if (c == K_C_HOME) + if (c == K_C_HOME) { curwin->w_cursor.lnum = 1; + } curwin->w_cursor.col = 0; curwin->w_cursor.coladd = 0; curwin->w_curswant = 0; @@ -8477,12 +8615,14 @@ static void ins_end(int c) { pos_T tpos; - if ((fdo_flags & FDO_HOR) && KeyTyped) + if ((fdo_flags & FDO_HOR) && KeyTyped) { foldOpenCursor(); + } undisplay_dollar(); tpos = curwin->w_cursor; - if (c == K_C_END) + if (c == K_C_END) { curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; + } coladvance(MAXCOL); curwin->w_curswant = MAXCOL; @@ -8530,8 +8670,9 @@ static void ins_right(void) } revins_legal++; - if (revins_chars) + if (revins_chars) { revins_chars--; + } } else if (vim_strchr(p_ww, ']') != NULL && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { // if 'whichwrap' set for cursor in insert mode, may move the @@ -8567,9 +8708,8 @@ static void ins_s_right(void) dont_sync_undo = kFalse; } -static void ins_up( - bool startcol // when true move to Insstart.col -) +/// @param startcol when true move to Insstart.col +static void ins_up(bool startcol) { pos_T tpos; linenr_T old_topline = curwin->w_topline; @@ -8578,12 +8718,13 @@ static void ins_up( undisplay_dollar(); tpos = curwin->w_cursor; if (cursor_up(1L, TRUE) == OK) { - if (startcol) + if (startcol) { coladvance(getvcol_nolist(&Insstart)); + } if (old_topline != curwin->w_topline - || old_topfill != curwin->w_topfill - ) + || old_topfill != curwin->w_topfill) { redraw_later(curwin, VALID); + } start_arrow(&tpos); can_cindent = true; } else { @@ -8615,9 +8756,8 @@ static void ins_pageup(void) } } -static void ins_down( - bool startcol // when true move to Insstart.col -) +/// @param startcol when true move to Insstart.col +static void ins_down(bool startcol) { pos_T tpos; linenr_T old_topline = curwin->w_topline; @@ -8626,12 +8766,13 @@ static void ins_down( undisplay_dollar(); tpos = curwin->w_cursor; if (cursor_down(1L, TRUE) == OK) { - if (startcol) + if (startcol) { coladvance(getvcol_nolist(&Insstart)); + } if (old_topline != curwin->w_topline - || old_topfill != curwin->w_topfill - ) + || old_topfill != curwin->w_topfill) { redraw_later(curwin, VALID); + } start_arrow(&tpos); can_cindent = true; } else { @@ -8687,15 +8828,15 @@ static bool ins_tab(void) // When nothing special, insert TAB like a normal character. if (!curbuf->b_p_et && !( - p_sta - && ind - // These five lines mean 'tabstop' != 'shiftwidth' - && ((tabstop_count(curbuf->b_p_vts_array) > 1) - || (tabstop_count(curbuf->b_p_vts_array) == 1 - && tabstop_first(curbuf->b_p_vts_array) - != get_sw_value(curbuf)) - || (tabstop_count(curbuf->b_p_vts_array) == 0 - && curbuf->b_p_ts != get_sw_value(curbuf)))) + p_sta + && ind + // These five lines mean 'tabstop' != 'shiftwidth' + && ((tabstop_count(curbuf->b_p_vts_array) > 1) + || (tabstop_count(curbuf->b_p_vts_array) == 1 + && tabstop_first(curbuf->b_p_vts_array) + != get_sw_value(curbuf)) + || (tabstop_count(curbuf->b_p_vts_array) == 0 + && curbuf->b_p_ts != get_sw_value(curbuf)))) && tabstop_count(curbuf->b_p_vsts_array) == 0 && get_sts_value() == 0) { return true; } @@ -8711,7 +8852,7 @@ static bool ins_tab(void) AppendToRedobuff("\t"); if (p_sta && ind) { // insert tab in indent, use 'shiftwidth' - temp = (int)get_sw_value(curbuf); + temp = get_sw_value(curbuf); temp -= get_nolist_virtcol() % temp; } else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts != 0) { @@ -8727,7 +8868,7 @@ static bool ins_tab(void) } /* - * Insert the first space with ins_char(). It will delete one char in + * Insert the first space with ins_char(). It will delete one char in * replace mode. Insert the rest with ins_str(); it will not delete any * chars. For VREPLACE mode, we use ins_char() for all characters. */ @@ -8749,11 +8890,11 @@ static bool ins_tab(void) if (!curbuf->b_p_et && (tabstop_count(curbuf->b_p_vsts_array) > 0 || get_sts_value() > 0 || (p_sta && ind))) { - char_u *ptr; - char_u *saved_line = NULL; // init for GCC + char_u *ptr; + char_u *saved_line = NULL; // init for GCC pos_T pos; pos_T fpos; - pos_T *cursor; + pos_T *cursor; colnr_T want_vcol, vcol; int change_col = -1; int save_list = curwin->w_p_list; @@ -8800,8 +8941,9 @@ static bool ins_tab(void) // and 'linebreak' adding extra virtual columns. while (ascii_iswhite(*ptr)) { i = lbr_chartabsize(NULL, (char_u *)"\t", vcol); - if (vcol + i > want_vcol) + if (vcol + i > want_vcol) { break; + } if (*ptr != TAB) { *ptr = TAB; if (change_col < 0) { @@ -8865,12 +9007,13 @@ static bool ins_tab(void) // Insert each char in saved_line from changed_col to // ptr-cursor ins_bytes_len(saved_line + change_col, - cursor->col - change_col); + cursor->col - change_col); } } - if (State & VREPLACE_FLAG) + if (State & VREPLACE_FLAG) { xfree(saved_line); + } curwin->w_p_list = save_list; } @@ -8896,9 +9039,9 @@ static bool ins_eol(int c) * nothing to put back when the NL is deleted. */ if ((State & REPLACE_FLAG) - && !(State & VREPLACE_FLAG) - ) + && !(State & VREPLACE_FLAG)) { replace_push(NUL); + } /* * In VREPLACE mode, a NL replaces the rest of the line, and starts @@ -9008,8 +9151,8 @@ int ins_copychar(linenr_T lnum) { int c; int temp; - char_u *ptr, *prev_ptr; - char_u *line; + char_u *ptr, *prev_ptr; + char_u *line; if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) { vim_beep(BO_COPY); @@ -9025,8 +9168,9 @@ int ins_copychar(linenr_T lnum) prev_ptr = ptr; temp += lbr_chartabsize_adv(line, &ptr, (colnr_T)temp); } - if ((colnr_T)temp > curwin->w_virtcol) + if ((colnr_T)temp > curwin->w_virtcol) { ptr = prev_ptr; + } c = utf_ptr2char(ptr); if (c == NUL) { @@ -9043,10 +9187,11 @@ static int ins_ctrl_ey(int tc) int c = tc; if (ctrl_x_mode == CTRL_X_SCROLL) { - if (c == Ctrl_Y) + if (c == Ctrl_Y) { scrolldown_clamp(); - else + } else { scrollup_clamp(); + } redraw_later(curwin, VALID); } else { c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1)); @@ -9079,10 +9224,10 @@ static int ins_ctrl_ey(int tc) */ static void ins_try_si(int c) { - pos_T *pos, old_pos; - char_u *ptr; + pos_T *pos, old_pos; + char_u *ptr; int i; - int temp; + bool temp; /* * do some very smart indenting when entering '{' or '}' @@ -9108,20 +9253,20 @@ static void ins_try_si(int c) } curwin->w_cursor.lnum = pos->lnum; curwin->w_cursor.col = i; - if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) + if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) { curwin->w_cursor = *pos; + } i = get_indent(); curwin->w_cursor = old_pos; - if (State & VREPLACE_FLAG) + if (State & VREPLACE_FLAG) { change_indent(INDENT_SET, i, FALSE, NUL, TRUE); - else + } else { (void)set_indent(i, SIN_CHANGED); + } } else if (curwin->w_cursor.col > 0) { - /* - * when inserting '{' after "O" reduce indent, but not - * more than indent of previous line - */ - temp = TRUE; + // when inserting '{' after "O" reduce indent, but not + // more than indent of previous line + temp = true; if (c == '{' && can_si_back && curwin->w_cursor.lnum > 1) { old_pos = curwin->w_cursor; i = get_indent(); @@ -9133,12 +9278,14 @@ static void ins_try_si(int c) break; } } - if (get_indent() >= i) - temp = FALSE; + if (get_indent() >= i) { + temp = false; + } curwin->w_cursor = old_pos; } - if (temp) + if (temp) { shift_line(TRUE, FALSE, 1, TRUE); + } } } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 5603fbb082..5607de3cc1 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -69,6 +69,7 @@ static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); static char *e_invalwindow = N_("E957: Invalid window number"); static char *e_lock_unlock = N_("E940: Cannot lock or unlock variable %s"); +static char *e_write2 = N_("E80: Error while writing: %s"); // TODO(ZyX-I): move to eval/executor static char *e_letwrong = N_("E734: Wrong variable type for %s="); @@ -113,6 +114,8 @@ typedef struct { int fi_varcount; // nr of variables in the list listwatch_T fi_lw; // keep an eye on the item used. list_T *fi_list; // list being used + int fi_bi; // index of blob + blob_T *fi_blob; // blob being used } forinfo_T; // values for vv_flags: @@ -227,6 +230,7 @@ static struct vimvar { VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO), VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO), VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO), + VV(VV_TYPE_BLOB, "t_blob", VAR_NUMBER, VV_RO), VV(VV_EVENT, "event", VAR_DICT, VV_RO), VV(VV_ECHOSPACE, "echospace", VAR_NUMBER, VV_RO), VV(VV_ARGV, "argv", VAR_LIST, VV_RO), @@ -238,6 +242,7 @@ static struct vimvar { VV(VV__NULL_STRING, "_null_string", VAR_STRING, VV_RO), VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO), VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO), + VV(VV__NULL_BLOB, "_null_blob", VAR_BLOB, VV_RO), VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO), }; #undef VV @@ -251,6 +256,7 @@ static struct vimvar { #define vv_str vv_di.di_tv.vval.v_string #define vv_list vv_di.di_tv.vval.v_list #define vv_dict vv_di.di_tv.vval.v_dict +#define vv_blob vv_di.di_tv.vval.v_blob #define vv_partial vv_di.di_tv.vval.v_partial #define vv_tv vv_di.di_tv @@ -393,6 +399,7 @@ void eval_init(void) set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT); set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT); set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL); + set_vim_var_nr(VV_TYPE_BLOB, VAR_TYPE_BLOB); set_vim_var_bool(VV_FALSE, kBoolVarFalse); set_vim_var_bool(VV_TRUE, kBoolVarTrue); @@ -1456,21 +1463,18 @@ static void ex_let_const(exarg_T *eap, const bool is_const) /* * Assign the typevalue "tv" to the variable or variables at "arg_start". * Handles both "var" with any type and "[var, var; var]" with a list type. - * When "nextchars" is not NULL it points to a string with characters that + * When "op" is not NULL it points to a string with characters that * must appear after the variable(s). Use "+", "-" or "." for add, subtract * or concatenate. * Returns OK or FAIL; */ -static int -ex_let_vars( - char_u *arg_start, - typval_T *tv, - int copy, // copy values from "tv", don't move - int semicolon, // from skip_var_list() - int var_count, // from skip_var_list() - int is_const, // lock variables for :const - char_u *nextchars -) +static int ex_let_vars(char_u *arg_start, + typval_T *tv, + int copy, // copy values from "tv", don't move + int semicolon, // from skip_var_list() + int var_count, // from skip_var_list() + int is_const, // lock variables for :const + char_u *op) { char_u *arg = arg_start; typval_T ltv; @@ -1479,7 +1483,7 @@ ex_let_vars( /* * ":let var = expr" or ":for var in list" */ - if (ex_let_one(arg, tv, copy, is_const, nextchars, nextchars) == NULL) { + if (ex_let_one(arg, tv, copy, is_const, op, op) == NULL) { return FAIL; } return OK; @@ -1510,7 +1514,7 @@ ex_let_vars( while (*arg != ']') { arg = skipwhite(arg + 1); arg = ex_let_one(arg, TV_LIST_ITEM_TV(item), true, is_const, - (const char_u *)",;]", nextchars); + (const char_u *)",;]", op); if (arg == NULL) { return FAIL; } @@ -1532,8 +1536,8 @@ ex_let_vars( ltv.vval.v_list = rest_list; tv_list_ref(rest_list); - arg = ex_let_one(skipwhite(arg + 1), <v, false, is_const, - (char_u *)"]", nextchars); + arg = ex_let_one(skipwhite(arg + 1), <v, false, is_const, (char_u *)"]", + op); tv_clear(<v); if (arg == NULL) { return FAIL; @@ -2062,18 +2066,17 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, return NULL; } - /* - * Loop until no more [idx] or .key is following. - */ + // Loop until no more [idx] or .key is following. lp->ll_tv = &v->di_tv; var1.v_type = VAR_UNKNOWN; var2.v_type = VAR_UNKNOWN; while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) { if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) - && !(lp->ll_tv->v_type == VAR_DICT - && lp->ll_tv->vval.v_dict != NULL)) { - if (!quiet) - EMSG(_("E689: Can only index a List or Dictionary")); + && !(lp->ll_tv->v_type == VAR_DICT && lp->ll_tv->vval.v_dict != NULL) + && !(lp->ll_tv->v_type == VAR_BLOB && lp->ll_tv->vval.v_blob != NULL)) { + if (!quiet) { + EMSG(_("E689: Can only index a List, Dictionary or Blob")); + } return NULL; } if (lp->ll_range) { @@ -2122,10 +2125,11 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, tv_clear(&var1); return NULL; } - if (rettv != NULL && (rettv->v_type != VAR_LIST - || rettv->vval.v_list == NULL)) { + if (rettv != NULL + && !(rettv->v_type == VAR_LIST && rettv->vval.v_list != NULL) + && !(rettv->v_type == VAR_BLOB && rettv->vval.v_blob != NULL)) { if (!quiet) { - EMSG(_("E709: [:] requires a List value")); + EMSG(_("E709: [:] requires a List or Blob value")); } tv_clear(&var1); return NULL; @@ -2239,6 +2243,38 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, tv_clear(&var1); lp->ll_tv = &lp->ll_di->di_tv; + } else if (lp->ll_tv->v_type == VAR_BLOB) { + // Get the number and item for the only or first index of the List. + if (empty1) { + lp->ll_n1 = 0; + } else { + // Is number or string. + lp->ll_n1 = (long)tv_get_number(&var1); + } + tv_clear(&var1); + + const int bloblen = tv_blob_len(lp->ll_tv->vval.v_blob); + if (lp->ll_n1 < 0 || lp->ll_n1 > bloblen + || (lp->ll_range && lp->ll_n1 == bloblen)) { + if (!quiet) { + EMSGN(_(e_blobidx), lp->ll_n1); + } + tv_clear(&var2); + return NULL; + } + if (lp->ll_range && !lp->ll_empty2) { + lp->ll_n2 = (long)tv_get_number(&var2); + tv_clear(&var2); + if (lp->ll_n2 < 0 || lp->ll_n2 >= bloblen || lp->ll_n2 < lp->ll_n1) { + if (!quiet) { + EMSGN(_(e_blobidx), lp->ll_n2); + } + return NULL; + } + } + lp->ll_blob = lp->ll_tv->vval.v_blob; + lp->ll_tv = NULL; + break; } else { // Get the number and item for the only or first index of the List. if (empty1) { @@ -2332,7 +2368,50 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, if (lp->ll_tv == NULL) { cc = *endp; *endp = NUL; - if (op != NULL && *op != '=') { + if (lp->ll_blob != NULL) { + if (op != NULL && *op != '=') { + EMSG2(_(e_letwrong), op); + return; + } + if (var_check_lock(lp->ll_blob->bv_lock, lp->ll_name, TV_CSTRING)) { + return; + } + + if (lp->ll_range && rettv->v_type == VAR_BLOB) { + if (lp->ll_empty2) { + lp->ll_n2 = tv_blob_len(lp->ll_blob) - 1; + } + + if (lp->ll_n2 - lp->ll_n1 + 1 != tv_blob_len(rettv->vval.v_blob)) { + EMSG(_("E972: Blob value does not have the right number of bytes")); + return; + } + if (lp->ll_empty2) { + lp->ll_n2 = tv_blob_len(lp->ll_blob); + } + + for (int il = lp->ll_n1, ir = 0; il <= lp->ll_n2; il++) { + tv_blob_set(lp->ll_blob, il, tv_blob_get(rettv->vval.v_blob, ir++)); + } + } else { + bool error = false; + const char_u val = tv_get_number_chk(rettv, &error); + if (!error) { + garray_T *const gap = &lp->ll_blob->bv_ga; + + // Allow for appending a byte. Setting a byte beyond + // the end is an error otherwise. + if (lp->ll_n1 < gap->ga_len || lp->ll_n1 == gap->ga_len) { + ga_grow(&lp->ll_blob->bv_ga, 1); + tv_blob_set(lp->ll_blob, lp->ll_n1, val); + if (lp->ll_n1 == gap->ga_len) { + gap->ga_len++; + } + } + // error for invalid range was already given in get_lval() + } + } + } else if (op != NULL && *op != '=') { typval_T tv; if (is_const) { @@ -2511,19 +2590,32 @@ void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip) if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) { *errp = false; if (!skip) { - l = tv.vval.v_list; - if (tv.v_type != VAR_LIST) { - EMSG(_(e_listreq)); - tv_clear(&tv); - } else if (l == NULL) { - // a null list is like an empty list: do nothing + if (tv.v_type == VAR_LIST) { + l = tv.vval.v_list; + if (l == NULL) { + // a null list is like an empty list: do nothing + tv_clear(&tv); + } else { + // No need to increment the refcount, it's already set for + // the list being used in "tv". + fi->fi_list = l; + tv_list_watch_add(l, &fi->fi_lw); + fi->fi_lw.lw_item = tv_list_first(l); + } + } else if (tv.v_type == VAR_BLOB) { + fi->fi_bi = 0; + if (tv.vval.v_blob != NULL) { + typval_T btv; + + // Make a copy, so that the iteration still works when the + // blob is changed. + tv_blob_copy(&tv, &btv); + fi->fi_blob = btv.vval.v_blob; + } tv_clear(&tv); } else { - /* No need to increment the refcount, it's already set for the - * list being used in "tv". */ - fi->fi_list = l; - tv_list_watch_add(l, &fi->fi_lw); - fi->fi_lw.lw_item = tv_list_first(l); + EMSG(_(e_listblobreq)); + tv_clear(&tv); } } } @@ -2545,6 +2637,19 @@ bool next_for_item(void *fi_void, char_u *arg) { forinfo_T *fi = (forinfo_T *)fi_void; + if (fi->fi_blob != NULL) { + if (fi->fi_bi >= tv_blob_len(fi->fi_blob)) { + return false; + } + typval_T tv; + tv.v_type = VAR_NUMBER; + tv.v_lock = VAR_FIXED; + tv.vval.v_number = tv_blob_get(fi->fi_blob, fi->fi_bi); + fi->fi_bi++; + return ex_let_vars(arg, &tv, true, + fi->fi_semicolon, fi->fi_varcount, false, NULL) == OK; + } + listitem_T *item = fi->fi_lw.lw_item; if (item == NULL) { return false; @@ -2568,6 +2673,9 @@ void free_for_info(void *fi_void) tv_list_watch_remove(fi->fi_list, &fi->fi_lw); tv_list_unref(fi->fi_list); } + if (fi != NULL && fi->fi_blob != NULL) { + tv_blob_unref(fi->fi_blob); + } xfree(fi); } @@ -2977,7 +3085,7 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, } else { di->di_flags &= ~DI_FLAGS_LOCK; } - tv_item_lock(&di->di_tv, deep, lock); + tv_item_lock(&di->di_tv, deep, lock, false); } } } else if (lp->ll_range) { @@ -2985,16 +3093,16 @@ static int do_lock_var(lval_T *lp, char_u *name_end FUNC_ATTR_UNUSED, // (un)lock a range of List items. while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) { - tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock); + tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock, false); li = TV_LIST_ITEM_NEXT(lp->ll_list, li); lp->ll_n1++; } } else if (lp->ll_list != NULL) { // (un)lock a List item. - tv_item_lock(TV_LIST_ITEM_TV(lp->ll_li), deep, lock); + tv_item_lock(TV_LIST_ITEM_TV(lp->ll_li), deep, lock, false); } else { // (un)lock a Dictionary item. - tv_item_lock(&lp->ll_di->di_tv, deep, lock); + tv_item_lock(&lp->ll_di->di_tv, deep, lock, false); } return ret; @@ -3610,7 +3718,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) if (op != '+' && op != '-' && op != '.') break; - if ((op != '+' || rettv->v_type != VAR_LIST) + if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB)) && (op == '.' || rettv->v_type != VAR_FLOAT)) { // For "list + ...", an illegal use of the first operand as // a number cannot be determined before evaluating the 2nd @@ -3656,6 +3764,21 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) tv_clear(rettv); rettv->v_type = VAR_STRING; rettv->vval.v_string = p; + } else if (op == '+' && rettv->v_type == VAR_BLOB + && var2.v_type == VAR_BLOB) { + const blob_T *const b1 = rettv->vval.v_blob; + const blob_T *const b2 = var2.vval.v_blob; + blob_T *const b = tv_blob_alloc(); + + for (int i = 0; i < tv_blob_len(b1); i++) { + ga_append(&b->bv_ga, tv_blob_get(b1, i)); + } + for (int i = 0; i < tv_blob_len(b2); i++) { + ga_append(&b->bv_ga, tv_blob_get(b2, i)); + } + + tv_clear(rettv); + tv_blob_set_ret(rettv, b); } else if (op == '+' && rettv->v_type == VAR_LIST && var2.v_type == VAR_LIST) { // Concatenate Lists. @@ -3676,10 +3799,12 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) } else { n1 = tv_get_number_chk(rettv, &error); if (error) { - /* This can only happen for "list + non-list". For - * "non-list + ..." or "something - ...", we returned - * before evaluating the 2nd operand. */ + // This can only happen for "list + non-list" or + // "blob + non-blob". For "non-list + ..." or + // "something - ...", we returned before evaluating the + // 2nd operand. tv_clear(rettv); + tv_clear(&var2); return FAIL; } if (var2.v_type == VAR_FLOAT) @@ -3853,6 +3978,7 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string) // Handle sixth level expression: // number number constant +// 0zFFFFFFFF Blob constant // "string" string constant // 'string' literal string constant // &option-name option value @@ -3949,8 +4075,43 @@ static int eval7( rettv->v_type = VAR_FLOAT; rettv->vval.v_float = f; } + } else if (**arg == '0' && ((*arg)[1] == 'z' || (*arg)[1] == 'Z')) { + blob_T *blob = NULL; + // Blob constant: 0z0123456789abcdef + if (evaluate) { + blob = tv_blob_alloc(); + } + char_u *bp; + for (bp = *arg + 2; ascii_isxdigit(bp[0]); bp += 2) { + if (!ascii_isxdigit(bp[1])) { + if (blob != NULL) { + EMSG(_("E973: Blob literal should have an even number of hex " + "characters")); + ga_clear(&blob->bv_ga); + XFREE_CLEAR(blob); + } + ret = FAIL; + break; + } + if (blob != NULL) { + ga_append(&blob->bv_ga, (hex2nr(*bp) << 4) + hex2nr(*(bp + 1))); + } + if (bp[2] == '.' && ascii_isxdigit(bp[3])) { + bp++; + } + } + if (blob != NULL) { + tv_blob_set_ret(rettv, blob); + } + *arg = bp; } else { - vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0); + // decimal, hex or octal number + vim_str2nr(*arg, NULL, &len, STR2NR_ALL, &n, NULL, 0, true); + if (len == 0) { + EMSG2(_(e_invexpr2), *arg); + ret = FAIL; + break; + } *arg += len; if (evaluate) { rettv->v_type = VAR_NUMBER; @@ -4334,7 +4495,8 @@ eval_index( case VAR_STRING: case VAR_NUMBER: case VAR_LIST: - case VAR_DICT: { + case VAR_DICT: + case VAR_BLOB: { break; } } @@ -4460,6 +4622,53 @@ eval_index( rettv->vval.v_string = (char_u *)v; break; } + case VAR_BLOB: { + len = tv_blob_len(rettv->vval.v_blob); + if (range) { + // The resulting variable is a sub-blob. If the indexes + // are out of range the result is empty. + if (n1 < 0) { + n1 = len + n1; + if (n1 < 0) { + n1 = 0; + } + } + if (n2 < 0) { + n2 = len + n2; + } else if (n2 >= len) { + n2 = len - 1; + } + if (n1 >= len || n2 < 0 || n1 > n2) { + tv_clear(rettv); + rettv->v_type = VAR_BLOB; + rettv->vval.v_blob = NULL; + } else { + blob_T *const blob = tv_blob_alloc(); + ga_grow(&blob->bv_ga, n2 - n1 + 1); + blob->bv_ga.ga_len = n2 - n1 + 1; + for (long i = n1; i <= n2; i++) { + tv_blob_set(blob, i - n1, tv_blob_get(rettv->vval.v_blob, i)); + } + tv_clear(rettv); + tv_blob_set_ret(rettv, blob); + } + } else { + // The resulting variable is a byte value. + // If the index is too big or negative that is an error. + if (n1 < 0) { + n1 = len + n1; + } + if (n1 < len && n1 >= 0) { + const int v = (int)tv_blob_get(rettv->vval.v_blob, n1); + tv_clear(rettv); + rettv->v_type = VAR_NUMBER; + rettv->vval.v_number = v; + } else { + EMSGN(_(e_blobidx), n1); + } + } + break; + } case VAR_LIST: { len = tv_list_len(rettv->vval.v_list); if (n1 < 0) { @@ -5396,7 +5605,8 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, case VAR_SPECIAL: case VAR_FLOAT: case VAR_NUMBER: - case VAR_STRING: { + case VAR_STRING: + case VAR_BLOB: { break; } } @@ -6159,6 +6369,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) dict_T *d = NULL; typval_T save_val; typval_T save_key; + blob_T *b = NULL; int rem = false; int todo; char_u *ermsg = (char_u *)(map ? "map()" : "filter()"); @@ -6168,7 +6379,12 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) int save_did_emsg; int idx = 0; - if (argvars[0].v_type == VAR_LIST) { + if (argvars[0].v_type == VAR_BLOB) { + tv_copy(&argvars[0], rettv); + if ((b = argvars[0].vval.v_blob) == NULL) { + return; + } + } else if (argvars[0].v_type == VAR_LIST) { tv_copy(&argvars[0], rettv); if ((l = argvars[0].vval.v_list) == NULL || (!map @@ -6182,7 +6398,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) return; } } else { - EMSG2(_(e_listdictarg), ermsg); + EMSG2(_(e_listdictblobarg), ermsg); return; } @@ -6232,6 +6448,34 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map) } } hash_unlock(ht); + } else if (argvars[0].v_type == VAR_BLOB) { + vimvars[VV_KEY].vv_type = VAR_NUMBER; + + for (int i = 0; i < b->bv_ga.ga_len; i++) { + typval_T tv; + tv.v_type = VAR_NUMBER; + const varnumber_T val = tv_blob_get(b, i); + tv.vval.v_number = val; + vimvars[VV_KEY].vv_nr = idx; + if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg) { + break; + } + if (tv.v_type != VAR_NUMBER) { + EMSG(_(e_invalblob)); + return; + } + if (map) { + if (tv.vval.v_number != val) { + tv_blob_set(b, i, tv.vval.v_number); + } + } else if (rem) { + char_u *const p = (char_u *)argvars[0].vval.v_blob->bv_ga.ga_data; + memmove(p + i, p + i + 1, (size_t)b->bv_ga.ga_len - i - 1); + b->bv_ga.ga_len--; + i--; + } + idx++; + } } else { assert(argvars[0].v_type == VAR_LIST); vimvars[VV_KEY].vv_type = VAR_NUMBER; @@ -7726,10 +7970,61 @@ bool write_list(FileDescriptor *const fp, const list_T *const list, } return true; write_list_error: - emsgf(_("E80: Error while writing: %s"), os_strerror(error)); + emsgf(_(e_write2), os_strerror(error)); return false; } +/// Write a blob to file with descriptor `fp`. +/// +/// @param[in] fp File to write to. +/// @param[in] blob Blob to write. +/// +/// @return true on success, or false on failure. +bool write_blob(FileDescriptor *const fp, const blob_T *const blob) + FUNC_ATTR_NONNULL_ARG(1) +{ + int error = 0; + const int len = tv_blob_len(blob); + if (len > 0) { + const ptrdiff_t written = file_write(fp, blob->bv_ga.ga_data, (size_t)len); + if (written < (ptrdiff_t)len) { + error = (int)written; + goto write_blob_error; + } + } + error = file_flush(fp); + if (error != 0) { + goto write_blob_error; + } + return true; +write_blob_error: + EMSG2(_(e_write2), os_strerror(error)); + return false; +} + +/// Read a blob from a file `fd`. +/// +/// @param[in] fd File to read from. +/// @param[in,out] blob Blob to write to. +/// +/// @return true on success, or false on failure. +bool read_blob(FILE *const fd, blob_T *const blob) + FUNC_ATTR_NONNULL_ALL +{ + FileInfo file_info; + if (!os_fileinfo_fd(fileno(fd), &file_info)) { + return false; + } + const int size = (int)os_fileinfo_size(&file_info); + ga_grow(&blob->bv_ga, size); + blob->bv_ga.ga_len = size; + if (fread(blob->bv_ga.ga_data, 1, blob->bv_ga.ga_len, fd) + < (size_t)blob->bv_ga.ga_len) { + return false; + } + return true; +} + /// Saves a typval_T as a string. /// /// For lists or buffers, replaces NLs with NUL and separates items with NLs. @@ -8670,6 +8965,7 @@ handle_subscript( } } + // "." is ".name" lookup when we found a dict. while (ret == OK && (((**arg == '[' || (**arg == '.' && rettv->v_type == VAR_DICT) || (**arg == '(' && (!evaluate || tv_is_func(*rettv)))) @@ -9245,7 +9541,10 @@ static void set_var_const(const char *name, const size_t name_len, } if (is_const) { - tv_item_lock(&v->di_tv, 1, true); + // Like :lockvar! name: lock the value and what it contains, but only + // if the reference count is up to one. That locks only literal + // values. + tv_item_lock(&v->di_tv, DICT_MAXNEST, true, true); } } @@ -9453,6 +9752,9 @@ int var_item_copy(const vimconv_T *const conv, ret = FAIL; } break; + case VAR_BLOB: + tv_blob_copy(from, to); + break; case VAR_DICT: to->v_type = VAR_DICT; to->v_lock = VAR_UNLOCKED; @@ -10812,6 +11114,29 @@ int typval_compare( // For "is" a different type always means false, for "notis" // it means true. n1 = type == EXPR_ISNOT; + } else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) { + if (type_is) { + n1 = typ1->v_type == typ2->v_type + && typ1->vval.v_blob == typ2->vval.v_blob; + if (type == EXPR_ISNOT) { + n1 = !n1; + } + } else if (typ1->v_type != typ2->v_type + || (type != EXPR_EQUAL && type != EXPR_NEQUAL)) { + if (typ1->v_type != typ2->v_type) { + EMSG(_("E977: Can only compare Blob with Blob")); + } else { + EMSG(_(e_invalblob)); + } + tv_clear(typ1); + return FAIL; + } else { + // Compare two Blobs for being equal or unequal. + n1 = tv_blob_equal(typ1->vval.v_blob, typ2->vval.v_blob); + if (type == EXPR_NEQUAL) { + n1 = !n1; + } + } } else if (typ1->v_type == VAR_LIST || typ2->v_type == VAR_LIST) { if (type_is) { n1 = typ1->v_type == typ2->v_type diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 41120b3c78..2452a0a8c8 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -63,6 +63,7 @@ typedef struct lval_S { dict_T *ll_dict; ///< The Dictionary or NULL. dictitem_T *ll_di; ///< The dictitem or NULL. char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL. + blob_T *ll_blob; ///< The Blob or NULL. } lval_T; /// enum used by var_flavour() @@ -154,6 +155,7 @@ typedef enum { VV_TYPE_DICT, VV_TYPE_FLOAT, VV_TYPE_BOOL, + VV_TYPE_BLOB, VV_EVENT, VV_ECHOSPACE, VV_ARGV, @@ -165,6 +167,7 @@ typedef enum { VV__NULL_STRING, // String with NULL value. For test purposes only. VV__NULL_LIST, // List with NULL value. For test purposes only. VV__NULL_DICT, // Dictionary with NULL value. For test purposes only. + VV__NULL_BLOB, // Blob with NULL value. For test purposes only. VV_LUA, } VimVarIndex; diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index faff29b268..5f355abe3c 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -250,7 +250,7 @@ return { min={args=1, base=1}, mkdir={args={1, 3}}, mode={args={0, 1}}, - msgpackdump={args=1}, + msgpackdump={args={1, 2}}, msgpackparse={args=1}, nextnonblank={args=1}, nr2char={args={1, 2}}, @@ -344,7 +344,7 @@ return { stdpath={args=1}, str2float={args=1, base=1}, str2list={args={1, 2}, base=1}, - str2nr={args={1, 2}}, + str2nr={args={1, 3}}, strcharpart={args={2, 3}}, strchars={args={1,2}}, strdisplaywidth={args={1, 2}}, diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c index bd4dc87d31..5c03f55621 100644 --- a/src/nvim/eval/decode.c +++ b/src/nvim/eval/decode.c @@ -246,14 +246,15 @@ list_T *decode_create_map_special_dict(typval_T *const ret_tv, /// Convert char* string to typval_T /// /// Depending on whether string has (no) NUL bytes, it may use a special -/// dictionary or decode string to VAR_STRING. +/// dictionary, VAR_BLOB, or decode string to VAR_STRING. /// /// @param[in] s String to decode. /// @param[in] len String length. /// @param[in] hasnul Whether string has NUL byte, not or it was not yet /// determined. -/// @param[in] binary If true, save special string type as kMPBinary, -/// otherwise kMPString. +/// @param[in] binary Determines decode type if string has NUL bytes. +/// If true convert string to VAR_BLOB, otherwise to the +/// kMPString special type. /// @param[in] s_allocated If true, then `s` was allocated and can be saved in /// a returned structure. If it is not saved there, it /// will be freed. @@ -269,21 +270,28 @@ typval_T decode_string(const char *const s, const size_t len, ? ((s != NULL) && (memchr(s, NUL, len) != NULL)) : (bool)hasnul); if (really_hasnul) { - list_T *const list = tv_list_alloc(kListLenMayKnow); - tv_list_ref(list); typval_T tv; - create_special_dict(&tv, binary ? kMPBinary : kMPString, ((typval_T) { - .v_type = VAR_LIST, - .v_lock = VAR_UNLOCKED, - .vval = { .v_list = list }, - })); - const int elw_ret = encode_list_write((void *)list, s, len); - if (s_allocated) { - xfree((void *)s); - } - if (elw_ret == -1) { - tv_clear(&tv); - return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED }; + tv.v_lock = VAR_UNLOCKED; + if (binary) { + tv_blob_alloc_ret(&tv); + ga_concat_len(&tv.vval.v_blob->bv_ga, s, len); + } else { + list_T *const list = tv_list_alloc(kListLenMayKnow); + tv_list_ref(list); + create_special_dict(&tv, kMPString, + ((typval_T){ + .v_type = VAR_LIST, + .v_lock = VAR_UNLOCKED, + .vval = { .v_list = list }, + })); + const int elw_ret = encode_list_write((void *)list, s, len); + if (s_allocated) { + xfree((void *)s); + } + if (elw_ret == -1) { + tv_clear(&tv); + return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED }; + } } return tv; } else { @@ -437,7 +445,7 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len, t += 4; uvarnumber_T ch; vim_str2nr((char_u *)ubuf, NULL, NULL, - STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4); + STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4, true); if (ch == 0) { hasnul = true; } @@ -611,8 +619,8 @@ parse_json_number_check: // Convert integer varnumber_T nr; int num_len; - vim_str2nr((char_u *) s, NULL, &num_len, 0, &nr, NULL, (int) (p - s)); - if ((int) exp_num_len != num_len) { + vim_str2nr((char_u *)s, NULL, &num_len, 0, &nr, NULL, (int)(p - s), true); + if ((int)exp_num_len != num_len) { emsgf(_("E685: internal error: while converting number \"%.*s\" " "to integer vim_str2nr consumed %i bytes in place of %zu"), (int) exp_num_len, s, num_len, exp_num_len); diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index a4d7af7971..b5e50e7ef5 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -47,6 +47,14 @@ const char *const encode_special_var_names[] = { # include "eval/encode.c.generated.h" #endif +/// Msgpack callback for writing to a Blob +int encode_blob_write(void *const data, const char *const buf, const size_t len) + FUNC_ATTR_NONNULL_ARG(1) +{ + ga_concat_len(&((blob_T *)data)->bv_ga, buf, len); + return (int)len; +} + /// Msgpack callback for writing to readfile()-style list int encode_list_write(void *const data, const char *const buf, const size_t len) FUNC_ATTR_NONNULL_ARG(1) @@ -319,6 +327,30 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, #define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) +#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ + do { \ + const blob_T *const blob_ = (blob); \ + const int len_ = (len); \ + if (len_ == 0) { \ + ga_concat(gap, "0z"); \ + } else { \ + /* Allocate space for "0z", the two hex chars per byte, and a */ \ + /* "." separator after every eight hex chars. */ \ + /* Example: "0z00112233.44556677.8899" */ \ + ga_grow(gap, 2 + 2 * len_ + (len_ - 1) / 4); \ + ga_concat(gap, "0z"); \ + char numbuf[NUMBUFLEN]; \ + for (int i_ = 0; i_ < len_; i_++) { \ + if (i_ > 0 && (i_ & 3) == 0) { \ + ga_append(gap, '.'); \ + } \ + vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%02X", \ + (int)tv_blob_get(blob_, i_)); \ + ga_concat(gap, numbuf); \ + } \ + } \ + } while (0) + #define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \ do { \ char numbuf[NUMBUFLEN]; \ @@ -705,6 +737,28 @@ static inline int convert_to_json_string(garray_T *const gap, return FAIL; \ } while (0) +#undef TYPVAL_ENCODE_CONV_BLOB +#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ + do { \ + const blob_T *const blob_ = (blob); \ + const int len_ = (len); \ + if (len_ == 0) { \ + ga_concat(gap, "[]"); \ + } else { \ + ga_append(gap, '['); \ + char numbuf[NUMBUFLEN]; \ + for (int i_ = 0; i_ < len_; i_++) { \ + if (i_ > 0) { \ + ga_concat(gap, ", "); \ + } \ + vim_snprintf((char *)numbuf, ARRAY_SIZE(numbuf), "%d", \ + (int)tv_blob_get(blob_, i_)); \ + ga_concat(gap, numbuf); \ + } \ + ga_append(gap, ']'); \ + } \ + } while (0) + #undef TYPVAL_ENCODE_CONV_FUNC_START #define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \ return conv_error(_("E474: Error while dumping %s, %s: " \ @@ -770,6 +824,7 @@ bool encode_check_json_key(const typval_T *const tv) #undef TYPVAL_ENCODE_CONV_STRING #undef TYPVAL_ENCODE_CONV_STR_STRING #undef TYPVAL_ENCODE_CONV_EXT_STRING +#undef TYPVAL_ENCODE_CONV_BLOB #undef TYPVAL_ENCODE_CONV_NUMBER #undef TYPVAL_ENCODE_CONV_FLOAT #undef TYPVAL_ENCODE_CONV_FUNC_START @@ -904,6 +959,15 @@ char *encode_tv2json(typval_T *tv, size_t *len) } \ } while (0) +#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ + do { \ + const size_t len_ = (size_t)(len); \ + msgpack_pack_bin(packer, len_); \ + if (len_ > 0) { \ + msgpack_pack_bin_body(packer, (blob)->bv_ga.ga_data, len_); \ + } \ + } while (0) + #define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \ msgpack_pack_int64(packer, (int64_t)(num)) @@ -982,6 +1046,7 @@ char *encode_tv2json(typval_T *tv, size_t *len) #undef TYPVAL_ENCODE_CONV_STRING #undef TYPVAL_ENCODE_CONV_STR_STRING #undef TYPVAL_ENCODE_CONV_EXT_STRING +#undef TYPVAL_ENCODE_CONV_BLOB #undef TYPVAL_ENCODE_CONV_NUMBER #undef TYPVAL_ENCODE_CONV_FLOAT #undef TYPVAL_ENCODE_CONV_FUNC_START diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index 8ac2c3b8eb..5ced2a0535 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -38,6 +38,20 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2, case VAR_SPECIAL: { break; } + case VAR_BLOB: { + if (*op != '+' || tv2->v_type != VAR_BLOB) { + break; + } + // Blob += Blob + if (tv1->vval.v_blob != NULL && tv2->vval.v_blob != NULL) { + blob_T *const b1 = tv1->vval.v_blob; + blob_T *const b2 = tv2->vval.v_blob; + for (int i = 0; i < tv_blob_len(b2); i++) { + ga_append(&b1->bv_ga, (char)tv_blob_get(b2, i)); + } + } + return OK; + } case VAR_LIST: { if (*op != '+' || tv2->v_type != VAR_LIST) { break; diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 99f9f17e0a..bcbd2266d3 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -96,6 +96,7 @@ PRAGMA_DIAG_POP static char *e_listarg = N_("E686: Argument of %s must be a List"); +static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); static char *e_invalwindow = N_("E957: Invalid window number"); /// Dummy va_list for passing to vim_snprintf @@ -321,8 +322,20 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_list_append_tv(l, &argvars[1]); tv_copy(&argvars[0], rettv); } + } else if (argvars[0].v_type == VAR_BLOB) { + blob_T *const b = argvars[0].vval.v_blob; + if (b != NULL + && !var_check_lock(b->bv_lock, N_("add() argument"), TV_TRANSLATE)) { + bool error = false; + const varnumber_T n = tv_get_number_chk(&argvars[1], &error); + + if (!error) { + ga_append(&b->bv_ga, (int)n); + tv_copy(&argvars[0], rettv); + } + } } else { - EMSG(_(e_listreq)); + EMSG(_(e_listblobreq)); } } @@ -959,7 +972,17 @@ static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr) } ptrdiff_t input_len = 0; - char *input = save_tv_as_string(&argvars[1], &input_len, false); + char *input = NULL; + if (argvars[1].v_type == VAR_BLOB) { + const blob_T *const b = argvars[1].vval.v_blob; + input_len = tv_blob_len(b); + if (input_len > 0) { + input = xmemdup(b->bv_ga.ga_data, input_len); + } + } else { + input = save_tv_as_string(&argvars[1], &input_len, false); + } + if (!input) { // Either the error has been handled by save_tv_as_string(), // or there is no input to send. @@ -1874,6 +1897,10 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr) n = argvars[0].vval.v_special == kSpecialVarNull; break; } + case VAR_BLOB: { + n = (tv_blob_len(argvars[0].vval.v_blob) == 0); + break; + } case VAR_UNKNOWN: { internal_error("f_empty(UNKNOWN)"); break; @@ -2791,7 +2818,23 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) typval_T *tv = NULL; bool what_is_dict = false; - if (argvars[0].v_type == VAR_LIST) { + if (argvars[0].v_type == VAR_BLOB) { + bool error = false; + int idx = tv_get_number_chk(&argvars[1], &error); + + if (!error) { + rettv->v_type = VAR_NUMBER; + if (idx < 0) { + idx = tv_blob_len(argvars[0].vval.v_blob) + idx; + } + if (idx < 0 || idx >= tv_blob_len(argvars[0].vval.v_blob)) { + rettv->vval.v_number = -1; + } else { + rettv->vval.v_number = tv_blob_get(argvars[0].vval.v_blob, idx); + tv = rettv; + } + } + } else if (argvars[0].v_type == VAR_LIST) { if ((l = argvars[0].vval.v_list) != NULL) { bool error = false; @@ -2852,7 +2895,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } else { - EMSG2(_(e_listdictarg), "get()"); + EMSG2(_(e_listdictblobarg), "get()"); } if (tv == NULL) { @@ -4403,6 +4446,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) "user_commands", "vartabs", "vertsplit", + "vimscript-1", "virtualedit", "visual", "visualextra", @@ -4790,8 +4834,38 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool ic = false; rettv->vval.v_number = -1; - if (argvars[0].v_type != VAR_LIST) { - EMSG(_(e_listreq)); + if (argvars[0].v_type == VAR_BLOB) { + bool error = false; + int start = 0; + + if (argvars[2].v_type != VAR_UNKNOWN) { + start = tv_get_number_chk(&argvars[2], &error); + if (error) { + return; + } + } + blob_T *const b = argvars[0].vval.v_blob; + if (b == NULL) { + return; + } + if (start < 0) { + start = tv_blob_len(b) + start; + if (start < 0) { + start = 0; + } + } + for (idx = start; idx < tv_blob_len(b); idx++) { + typval_T tv; + tv.v_type = VAR_NUMBER; + tv.vval.v_number = tv_blob_get(b, idx); + if (tv_equal(&tv, &argvars[1], ic, false)) { + rettv->vval.v_number = idx; + return; + } + } + return; + } else if (argvars[0].v_type != VAR_LIST) { + EMSG(_(e_listblobreq)); return; } list_T *const l = argvars[0].vval.v_list; @@ -4920,8 +4994,46 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr) list_T *l; bool error = false; - if (argvars[0].v_type != VAR_LIST) { - EMSG2(_(e_listarg), "insert()"); + if (argvars[0].v_type == VAR_BLOB) { + blob_T *const b = argvars[0].vval.v_blob; + + if (b == NULL + || var_check_lock(b->bv_lock, N_("insert() argument"), + TV_TRANSLATE)) { + return; + } + + long before = 0; + const int len = tv_blob_len(b); + + if (argvars[2].v_type != VAR_UNKNOWN) { + before = (long)tv_get_number_chk(&argvars[2], &error); + if (error) { + return; // type error; errmsg already given + } + if (before < 0 || before > len) { + EMSG2(_(e_invarg2), tv_get_string(&argvars[2])); + return; + } + } + const int val = tv_get_number_chk(&argvars[1], &error); + if (error) { + return; + } + if (val < 0 || val > 255) { + EMSG2(_(e_invarg2), tv_get_string(&argvars[1])); + return; + } + + ga_grow(&b->bv_ga, 1); + char_u *const p = (char_u *)b->bv_ga.ga_data; + memmove(p + before + 1, p + before, (size_t)len - before); + *(p + before) = val; + b->bv_ga.ga_len++; + + tv_copy(&argvars[0], rettv); + } else if (argvars[0].v_type != VAR_LIST) { + EMSG2(_(e_listblobarg), "insert()"); } else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), N_("insert() argument"), TV_TRANSLATE)) { long before = 0; @@ -5581,6 +5693,10 @@ static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr) tv_get_string(&argvars[0])); break; } + case VAR_BLOB: { + rettv->vval.v_number = tv_blob_len(argvars[0].vval.v_blob); + break; + } case VAR_LIST: { rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list); break; @@ -6391,9 +6507,16 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG2(_(e_listarg), "msgpackdump()"); return; } - list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow); list_T *const list = argvars[0].vval.v_list; - msgpack_packer *lpacker = msgpack_packer_new(ret_list, &encode_list_write); + msgpack_packer *packer; + if (argvars[1].v_type != VAR_UNKNOWN + && strequal(tv_get_string(&argvars[1]), "B")) { + tv_blob_alloc_ret(rettv); + packer = msgpack_packer_new(rettv->vval.v_blob, &encode_blob_write); + } else { + packer = msgpack_packer_new(tv_list_alloc_ret(rettv, kListLenMayKnow), + &encode_list_write); + } const char *const msg = _("msgpackdump() argument, index %i"); // Assume that translation will not take more then 4 times more space char msgbuf[sizeof("msgpackdump() argument, index ") * 4 + NUMBUFLEN]; @@ -6401,23 +6524,50 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr) TV_LIST_ITER(list, li, { vim_snprintf(msgbuf, sizeof(msgbuf), (char *)msg, idx); idx++; - if (encode_vim_to_msgpack(lpacker, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) { + if (encode_vim_to_msgpack(packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) { break; } }); - msgpack_packer_free(lpacker); + msgpack_packer_free(packer); } -/// "msgpackparse" function -static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr) +static int msgpackparse_convert_item(const msgpack_object data, + const msgpack_unpack_return result, + list_T *const ret_list, + const bool fail_if_incomplete) FUNC_ATTR_NONNULL_ALL { - if (argvars[0].v_type != VAR_LIST) { - EMSG2(_(e_listarg), "msgpackparse()"); - return; + switch (result) { + case MSGPACK_UNPACK_PARSE_ERROR: + EMSG2(_(e_invarg2), "Failed to parse msgpack string"); + return FAIL; + case MSGPACK_UNPACK_NOMEM_ERROR: + EMSG(_(e_outofmem)); + return FAIL; + case MSGPACK_UNPACK_CONTINUE: + if (fail_if_incomplete) { + EMSG2(_(e_invarg2), "Incomplete msgpack string"); + return FAIL; + } + return NOTDONE; + case MSGPACK_UNPACK_SUCCESS: { + typval_T tv = { .v_type = VAR_UNKNOWN }; + if (msgpack_to_vim(data, &tv) == FAIL) { + EMSG2(_(e_invarg2), "Failed to convert msgpack string"); + return FAIL; + } + tv_list_append_owned_tv(ret_list, tv); + return OK; + } + default: + abort(); } - list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow); - const list_T *const list = argvars[0].vval.v_list; +} + +static void msgpackparse_unpack_list(const list_T *const list, + list_T *const ret_list) + FUNC_ATTR_NONNULL_ARG(2) +{ if (tv_list_len(list) == 0) { return; } @@ -6436,43 +6586,28 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr) do { if (!msgpack_unpacker_reserve_buffer(unpacker, IOSIZE)) { EMSG(_(e_outofmem)); - goto f_msgpackparse_exit; + goto end; } size_t read_bytes; const int rlret = encode_read_from_list( &lrstate, msgpack_unpacker_buffer(unpacker), IOSIZE, &read_bytes); if (rlret == FAIL) { EMSG2(_(e_invarg2), "List item is not a string"); - goto f_msgpackparse_exit; + goto end; } msgpack_unpacker_buffer_consumed(unpacker, read_bytes); if (read_bytes == 0) { break; } while (unpacker->off < unpacker->used) { - const msgpack_unpack_return result = msgpack_unpacker_next(unpacker, - &unpacked); - if (result == MSGPACK_UNPACK_PARSE_ERROR) { - EMSG2(_(e_invarg2), "Failed to parse msgpack string"); - goto f_msgpackparse_exit; - } - if (result == MSGPACK_UNPACK_NOMEM_ERROR) { - EMSG(_(e_outofmem)); - goto f_msgpackparse_exit; - } - if (result == MSGPACK_UNPACK_SUCCESS) { - typval_T tv = { .v_type = VAR_UNKNOWN }; - if (msgpack_to_vim(unpacked.data, &tv) == FAIL) { - EMSG2(_(e_invarg2), "Failed to convert msgpack string"); - goto f_msgpackparse_exit; - } - tv_list_append_owned_tv(ret_list, tv); - } - if (result == MSGPACK_UNPACK_CONTINUE) { - if (rlret == OK) { - EMSG2(_(e_invarg2), "Incomplete msgpack string"); - } + const msgpack_unpack_return result + = msgpack_unpacker_next(unpacker, &unpacked); + const int conv_result = msgpackparse_convert_item(unpacked.data, result, + ret_list, rlret == OK); + if (conv_result == NOTDONE) { break; + } else if (conv_result == FAIL) { + goto end; } } if (rlret == OK) { @@ -6480,10 +6615,47 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } while (true); -f_msgpackparse_exit: - msgpack_unpacked_destroy(&unpacked); +end: msgpack_unpacker_free(unpacker); - return; + msgpack_unpacked_destroy(&unpacked); +} + +static void msgpackparse_unpack_blob(const blob_T *const blob, + list_T *const ret_list) + FUNC_ATTR_NONNULL_ARG(2) +{ + const int len = tv_blob_len(blob); + if (len == 0) { + return; + } + msgpack_unpacked unpacked; + msgpack_unpacked_init(&unpacked); + for (size_t offset = 0; offset < (size_t)len;) { + const msgpack_unpack_return result + = msgpack_unpack_next(&unpacked, blob->bv_ga.ga_data, len, &offset); + if (msgpackparse_convert_item(unpacked.data, result, ret_list, true) + != OK) { + break; + } + } + + msgpack_unpacked_destroy(&unpacked); +} + +/// "msgpackparse" function +static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr) + FUNC_ATTR_NONNULL_ALL +{ + if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) { + EMSG2(_(e_listblobarg), "msgpackparse()"); + return; + } + list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow); + if (argvars[0].v_type == VAR_LIST) { + msgpackparse_unpack_list(argvars[0].vval.v_list, ret_list); + } else { + msgpackparse_unpack_blob(argvars[0].vval.v_blob, ret_list); + } } /* @@ -6894,6 +7066,7 @@ static void f_readdir(typval_T *argvars, typval_T *rettv, FunPtr fptr) static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) { bool binary = false; + bool blob = false; FILE *fd; char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1 int io_size = sizeof(buf); @@ -6906,22 +7079,41 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (argvars[1].v_type != VAR_UNKNOWN) { if (strcmp(tv_get_string(&argvars[1]), "b") == 0) { binary = true; + } else if (strcmp(tv_get_string(&argvars[1]), "B") == 0) { + blob = true; } if (argvars[2].v_type != VAR_UNKNOWN) { maxline = tv_get_number(&argvars[2]); } } - list_T *const l = tv_list_alloc_ret(rettv, kListLenUnknown); - // Always open the file in binary mode, library functions have a mind of // their own about CR-LF conversion. const char *const fname = tv_get_string(&argvars[0]); + + if (os_isdir((const char_u *)fname)) { + EMSG2(_(e_isadir2), fname); + return; + } if (*fname == NUL || (fd = os_fopen(fname, READBIN)) == NULL) { EMSG2(_(e_notopen), *fname == NUL ? _("<empty>") : fname); return; } + if (blob) { + tv_blob_alloc_ret(rettv); + if (!read_blob(fd, rettv->vval.v_blob)) { + EMSG2(_(e_notread), fname); + // An empty blob is returned on error. + tv_blob_free(rettv->vval.v_blob); + rettv->vval.v_blob = NULL; + } + fclose(fd); + return; + } + + list_T *const l = tv_list_alloc_ret(rettv, kListLenUnknown); + while (maxline < 0 || tv_list_len(l) < maxline) { readlen = (int)fread(buf, 1, io_size, fd); @@ -7190,8 +7382,64 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } + } else if (argvars[0].v_type == VAR_BLOB) { + blob_T *const b = argvars[0].vval.v_blob; + + if (b != NULL && var_check_lock(b->bv_lock, arg_errmsg, TV_TRANSLATE)) { + return; + } + + bool error = false; + idx = (long)tv_get_number_chk(&argvars[1], &error); + + if (!error) { + const int len = tv_blob_len(b); + + if (idx < 0) { + // count from the end + idx = len + idx; + } + if (idx < 0 || idx >= len) { + EMSGN(_(e_blobidx), idx); + return; + } + if (argvars[2].v_type == VAR_UNKNOWN) { + // Remove one item, return its value. + char_u *const p = (char_u *)b->bv_ga.ga_data; + rettv->vval.v_number = (varnumber_T)(*(p + idx)); + memmove(p + idx, p + idx + 1, (size_t)len - idx - 1); + b->bv_ga.ga_len--; + } else { + // Remove range of items, return blob with values. + end = (long)tv_get_number_chk(&argvars[2], &error); + if (error) { + return; + } + if (end < 0) { + // count from the end + end = len + end; + } + if (end >= len || idx > end) { + EMSGN(_(e_blobidx), end); + return; + } + blob_T *const blob = tv_blob_alloc(); + blob->bv_ga.ga_len = end - idx + 1; + ga_grow(&blob->bv_ga, end - idx + 1); + + char_u *const p = (char_u *)b->bv_ga.ga_data; + memmove((char_u *)blob->bv_ga.ga_data, p + idx, + (size_t)(end - idx + 1)); + tv_blob_set_ret(rettv, blob); + + if (len - end - 1 > 0) { + memmove(p + idx, p + end + 1, (size_t)(len - end - 1)); + } + b->bv_ga.ga_len -= end - idx + 1; + } + } } else if (argvars[0].v_type != VAR_LIST) { - EMSG2(_(e_listdictarg), "remove()"); + EMSG2(_(e_listdictblobarg), "remove()"); } else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), arg_errmsg, TV_TRANSLATE)) { bool error = false; @@ -7465,13 +7713,25 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - list_T *l; - if (argvars[0].v_type != VAR_LIST) { - EMSG2(_(e_listarg), "reverse()"); - } else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), - N_("reverse() argument"), TV_TRANSLATE)) { - tv_list_reverse(l); - tv_list_set_ret(rettv, l); + if (argvars[0].v_type == VAR_BLOB) { + blob_T *const b = argvars[0].vval.v_blob; + const int len = tv_blob_len(b); + + for (int i = 0; i < len / 2; i++) { + const char_u tmp = tv_blob_get(b, i); + tv_blob_set(b, i, tv_blob_get(b, len - i - 1)); + tv_blob_set(b, len - i - 1, tmp); + } + tv_blob_set_ret(rettv, b); + } else if (argvars[0].v_type != VAR_LIST) { + EMSG2(_(e_listblobarg), "reverse()"); + } else { + list_T *const l = argvars[0].vval.v_list; + if (!var_check_lock(tv_list_locked(l), N_("reverse() argument"), + TV_TRANSLATE)) { + tv_list_reverse(l); + tv_list_set_ret(rettv, l); + } } } @@ -9998,7 +10258,7 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { int base = 10; varnumber_T n; - int what; + int what = 0; if (argvars[1].v_type != VAR_UNKNOWN) { base = tv_get_number(&argvars[1]); @@ -10006,6 +10266,9 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_invarg)); return; } + if (argvars[2].v_type != VAR_UNKNOWN && tv_get_number(&argvars[2])) { + what |= STR2NR_QUOTE; + } } char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0])); @@ -10015,22 +10278,20 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } switch (base) { case 2: { - what = STR2NR_BIN | STR2NR_FORCE; + what |= STR2NR_BIN | STR2NR_FORCE; break; } case 8: { - what = STR2NR_OCT | STR2NR_FORCE; + what |= STR2NR_OCT | STR2NR_OOCT | STR2NR_FORCE; break; } case 16: { - what = STR2NR_HEX | STR2NR_FORCE; + what |= STR2NR_HEX | STR2NR_FORCE; break; } - default: { - what = 0; - } } - vim_str2nr(p, NULL, NULL, what, &n, NULL, 0); + vim_str2nr(p, NULL, NULL, what, &n, NULL, 0, false); + // Text after the number is silently ignored. if (isneg) { rettv->vval.v_number = -n; } else { @@ -11290,15 +11551,16 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr) int n = -1; switch (argvars[0].v_type) { - case VAR_NUMBER: n = VAR_TYPE_NUMBER; break; - case VAR_STRING: n = VAR_TYPE_STRING; break; + case VAR_NUMBER: n = VAR_TYPE_NUMBER; break; + case VAR_STRING: n = VAR_TYPE_STRING; break; case VAR_PARTIAL: - case VAR_FUNC: n = VAR_TYPE_FUNC; break; - case VAR_LIST: n = VAR_TYPE_LIST; break; - case VAR_DICT: n = VAR_TYPE_DICT; break; - case VAR_FLOAT: n = VAR_TYPE_FLOAT; break; - case VAR_BOOL: n = VAR_TYPE_BOOL; break; - case VAR_SPECIAL:n = VAR_TYPE_SPECIAL; break; + case VAR_FUNC: n = VAR_TYPE_FUNC; break; + case VAR_LIST: n = VAR_TYPE_LIST; break; + case VAR_DICT: n = VAR_TYPE_DICT; break; + case VAR_FLOAT: n = VAR_TYPE_FLOAT; break; + case VAR_BOOL: n = VAR_TYPE_BOOL; break; + case VAR_SPECIAL: n = VAR_TYPE_SPECIAL; break; + case VAR_BLOB: n = VAR_TYPE_BLOB; break; case VAR_UNKNOWN: { internal_error("f_type(UNKNOWN)"); break; @@ -11677,16 +11939,17 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - if (argvars[0].v_type != VAR_LIST) { - EMSG2(_(e_listarg), "writefile()"); + if (argvars[0].v_type == VAR_LIST) { + TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, { + if (!tv_check_str_or_nr(TV_LIST_ITEM_TV(li))) { + return; + } + }); + } else if (argvars[0].v_type != VAR_BLOB) { + EMSG2(_(e_invarg2), + _("writefile() first argument must be a List or a Blob")); return; } - const list_T *const list = argvars[0].vval.v_list; - TV_LIST_ITER_CONST(list, li, { - if (!tv_check_str_or_nr(TV_LIST_ITEM_TV(li))) { - return; - } - }); bool binary = false; bool append = false; @@ -11726,7 +11989,13 @@ static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr) emsgf(_("E482: Can't open file %s for writing: %s"), fname, os_strerror(error)); } else { - if (write_list(&fp, list, binary)) { + bool write_ok; + if (argvars[0].v_type == VAR_BLOB) { + write_ok = write_blob(&fp, argvars[0].vval.v_blob); + } else { + write_ok = write_list(&fp, argvars[0].vval.v_list, binary); + } + if (write_ok) { rettv->vval.v_number = 0; } if ((error = file_close(&fp, do_fsync)) != 0) { diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index 5cb0058ec6..381d70ea1b 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -2125,6 +2125,77 @@ void tv_dict_set_keys_readonly(dict_T *const dict) }); } +//{{{1 Blobs +//{{{2 Alloc/free + +/// Allocate an empty blob. +/// +/// Caller should take care of the reference count. +/// +/// @return [allocated] new blob. +blob_T *tv_blob_alloc(void) + FUNC_ATTR_NONNULL_RET +{ + blob_T *const blob = xcalloc(1, sizeof(blob_T)); + ga_init(&blob->bv_ga, 1, 100); + return blob; +} + +/// Free a blob. Ignores the reference count. +/// +/// @param[in,out] b Blob to free. +void tv_blob_free(blob_T *const b) + FUNC_ATTR_NONNULL_ALL +{ + ga_clear(&b->bv_ga); + xfree(b); +} + +/// Unreference a blob. +/// +/// Decrements the reference count and frees blob when it becomes zero. +/// +/// @param[in,out] b Blob to operate on. +void tv_blob_unref(blob_T *const b) +{ + if (b != NULL && --b->bv_refcount <= 0) { + tv_blob_free(b); + } +} + +//{{{2 Operations on the whole blob + +/// Check whether two blobs are equal. +/// +/// @param[in] b1 First blob. +/// @param[in] b2 Second blob. +/// +/// @return true if blobs are equal, false otherwise. +bool tv_blob_equal(const blob_T *const b1, const blob_T *const b2) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + const int len1 = tv_blob_len(b1); + const int len2 = tv_blob_len(b2); + + // empty and NULL are considered the same + if (len1 == 0 && len2 == 0) { + return true; + } + if (b1 == b2) { + return true; + } + if (len1 != len2) { + return false; + } + + for (int i = 0; i < b1->bv_ga.ga_len; i++) { + if (tv_blob_get(b1, i) != tv_blob_get(b2, i)) { + return false; + } + } + return true; +} + //{{{1 Generic typval operations //{{{2 Init/alloc/clear //{{{3 Alloc @@ -2169,6 +2240,44 @@ void tv_dict_alloc_ret(typval_T *const ret_tv) tv_dict_set_ret(ret_tv, d); } +/// Allocate an empty blob for a return value. +/// +/// Also sets reference count. +/// +/// @param[out] ret_tv Structure where blob is saved. +void tv_blob_alloc_ret(typval_T *const ret_tv) + FUNC_ATTR_NONNULL_ALL +{ + blob_T *const b = tv_blob_alloc(); + tv_blob_set_ret(ret_tv, b); +} + +/// Copy a blob typval to a different typval. +/// +/// @param[in] from Blob object to copy from. +/// @param[out] to Blob object to copy to. +void tv_blob_copy(typval_T *const from, typval_T *const to) + FUNC_ATTR_NONNULL_ALL +{ + assert(from->v_type == VAR_BLOB); + + to->v_type = VAR_BLOB; + to->v_lock = VAR_UNLOCKED; + if (from->vval.v_blob == NULL) { + to->vval.v_blob = NULL; + } else { + tv_blob_alloc_ret(to); + int len = from->vval.v_blob->bv_ga.ga_len; + + if (len > 0) { + to->vval.v_blob->bv_ga.ga_data + = xmemdup(from->vval.v_blob->bv_ga.ga_data, (size_t)len); + } + to->vval.v_blob->bv_ga.ga_len = len; + to->vval.v_blob->bv_ga.ga_maxlen = len; + } +} + //{{{3 Clear #define TYPVAL_ENCODE_ALLOW_SPECIALS false @@ -2210,6 +2319,13 @@ void tv_dict_alloc_ret(typval_T *const ret_tv) #define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) +#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ + do { \ + tv_blob_unref(tv->vval.v_blob); \ + tv->vval.v_blob = NULL; \ + tv->v_lock = VAR_UNLOCKED; \ + } while (0) + static inline int _nothing_conv_func_start(typval_T *const tv, char_u *const fun) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1) @@ -2392,6 +2508,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, #undef TYPVAL_ENCODE_CONV_STRING #undef TYPVAL_ENCODE_CONV_STR_STRING #undef TYPVAL_ENCODE_CONV_EXT_STRING +#undef TYPVAL_ENCODE_CONV_BLOB #undef TYPVAL_ENCODE_CONV_FUNC_START #undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS #undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF @@ -2449,6 +2566,10 @@ void tv_free(typval_T *tv) xfree(tv->vval.v_string); break; } + case VAR_BLOB: { + tv_blob_unref(tv->vval.v_blob); + break; + } case VAR_LIST: { tv_list_unref(tv->vval.v_list); break; @@ -2509,6 +2630,12 @@ void tv_copy(const typval_T *const from, typval_T *const to) } break; } + case VAR_BLOB: { + if (from->vval.v_blob != NULL) { + to->vval.v_blob->bv_refcount++; + } + break; + } case VAR_LIST: { tv_list_ref(to->vval.v_list); break; @@ -2533,7 +2660,10 @@ void tv_copy(const typval_T *const from, typval_T *const to) /// @param[out] tv Item to (un)lock. /// @param[in] deep Levels to (un)lock, -1 to (un)lock everything. /// @param[in] lock True if it is needed to lock an item, false to unlock. -void tv_item_lock(typval_T *const tv, const int deep, const bool lock) +/// @param[in] check_refcount If true, do not lock a list or dict with a +/// reference count larger than 1. +void tv_item_lock(typval_T *const tv, const int deep, const bool lock, + const bool check_refcount) FUNC_ATTR_NONNULL_ALL { // TODO(ZyX-I): Make this not recursive @@ -2560,14 +2690,21 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock) CHANGE_LOCK(lock, tv->v_lock); switch (tv->v_type) { + case VAR_BLOB: { + blob_T *const b = tv->vval.v_blob; + if (b != NULL && !(check_refcount && b->bv_refcount > 1)) { + CHANGE_LOCK(lock, b->bv_lock); + } + break; + } case VAR_LIST: { list_T *const l = tv->vval.v_list; - if (l != NULL) { + if (l != NULL && !(check_refcount && l->lv_refcount > 1)) { CHANGE_LOCK(lock, l->lv_lock); if (deep < 0 || deep > 1) { // Recursive: lock/unlock the items the List contains. TV_LIST_ITER(l, li, { - tv_item_lock(TV_LIST_ITEM_TV(li), deep - 1, lock); + tv_item_lock(TV_LIST_ITEM_TV(li), deep - 1, lock, check_refcount); }); } } @@ -2575,12 +2712,12 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock) } case VAR_DICT: { dict_T *const d = tv->vval.v_dict; - if (d != NULL) { + if (d != NULL && !(check_refcount && d->dv_refcount > 1)) { CHANGE_LOCK(lock, d->dv_lock); if (deep < 0 || deep > 1) { // recursive: lock/unlock the items the List contains TV_DICT_ITER(d, di, { - tv_item_lock(&di->di_tv, deep - 1, lock); + tv_item_lock(&di->di_tv, deep - 1, lock, check_refcount); }); } } @@ -2646,10 +2783,11 @@ bool tv_check_lock(const typval_T *tv, const char *name, VarLockStatus lock = VAR_UNLOCKED; switch (tv->v_type) { - // case VAR_BLOB: - // if (tv->vval.v_blob != NULL) - // lock = tv->vval.v_blob->bv_lock; - // break; + case VAR_BLOB: + if (tv->vval.v_blob != NULL) { + lock = tv->vval.v_blob->bv_lock; + } + break; case VAR_LIST: if (tv->vval.v_list != NULL) { lock = tv->vval.v_list->lv_lock; @@ -2769,6 +2907,9 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic, recursive_cnt--; return r; } + case VAR_BLOB: { + return tv_blob_equal(tv1->vval.v_blob, tv2->vval.v_blob); + } case VAR_NUMBER: { return tv1->vval.v_number == tv2->vval.v_number; } @@ -2835,6 +2976,10 @@ bool tv_check_str_or_nr(const typval_T *const tv) EMSG(_("E728: Expected a Number or a String, Dictionary found")); return false; } + case VAR_BLOB: { + EMSG(_("E974: Expected a Number or a String, Blob found")); + return false; + } case VAR_BOOL: { EMSG(_("E5299: Expected a Number or a String, Boolean found")); return false; @@ -2860,6 +3005,7 @@ static const char *const num_errors[] = { [VAR_LIST]=N_("E745: Using a List as a Number"), [VAR_DICT]=N_("E728: Using a Dictionary as a Number"), [VAR_FLOAT]=N_("E805: Using a Float as a Number"), + [VAR_BLOB]=N_("E974: Using a Blob as a Number"), [VAR_UNKNOWN]=N_("E685: using an invalid value as a Number"), }; @@ -2888,6 +3034,7 @@ bool tv_check_num(const typval_T *const tv) case VAR_LIST: case VAR_DICT: case VAR_FLOAT: + case VAR_BLOB: case VAR_UNKNOWN: { EMSG(_(num_errors[tv->v_type])); return false; @@ -2905,6 +3052,7 @@ static const char *const str_errors[] = { [VAR_LIST]=N_("E730: using List as a String"), [VAR_DICT]=N_("E731: using Dictionary as a String"), [VAR_FLOAT]=((const char *)e_float_as_string), + [VAR_BLOB]=N_("E976: using Blob as a String"), [VAR_UNKNOWN]=N_("E908: using an invalid value as a String"), }; @@ -2933,6 +3081,7 @@ bool tv_check_str(const typval_T *const tv) case VAR_LIST: case VAR_DICT: case VAR_FLOAT: + case VAR_BLOB: case VAR_UNKNOWN: { EMSG(_(str_errors[tv->v_type])); return false; @@ -2980,6 +3129,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) case VAR_PARTIAL: case VAR_LIST: case VAR_DICT: + case VAR_BLOB: case VAR_FLOAT: { EMSG(_(num_errors[tv->v_type])); break; @@ -2990,7 +3140,8 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error) case VAR_STRING: { varnumber_T n = 0; if (tv->vval.v_string != NULL) { - vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0); + vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0, + false); } return n; } @@ -3074,6 +3225,10 @@ float_T tv_get_float(const typval_T *const tv) EMSG(_("E907: Using a special value as a Float")); break; } + case VAR_BLOB: { + EMSG(_("E975: Using a Blob as a Float")); + break; + } case VAR_UNKNOWN: { emsgf(_(e_intern2), "tv_get_float(UNKNOWN)"); break; @@ -3133,6 +3288,7 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf) case VAR_LIST: case VAR_DICT: case VAR_FLOAT: + case VAR_BLOB: case VAR_UNKNOWN: { EMSG(_(str_errors[tv->v_type])); return false; diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index ef49fa1de6..5aecaccee9 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -64,6 +64,7 @@ enum ListLenSpecials { typedef struct listvar_S list_T; typedef struct dictvar_S dict_T; typedef struct partial_S partial_T; +typedef struct blobvar_S blob_T; typedef struct ufunc ufunc_T; @@ -123,6 +124,7 @@ typedef enum { VAR_SPECIAL, ///< Special value (null), .v_special ///< is used. VAR_PARTIAL, ///< Partial, .v_partial is used. + VAR_BLOB, ///< Blob, .v_blob is used. } VarType; /// Structure that holds an internal variable value @@ -138,6 +140,7 @@ typedef struct { list_T *v_list; ///< List for VAR_LIST, can be NULL. dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL. partial_T *v_partial; ///< Closure: function with args. + blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL. } vval; ///< Actual value. } typval_T; @@ -252,6 +255,13 @@ struct dictvar_S { LuaRef lua_table_ref; }; +/// Structure to hold info about a Blob +struct blobvar_S { + garray_T bv_ga; ///< Growarray with the data. + int bv_refcount; ///< Reference count. + VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED. +}; + /// Type used for script ID typedef int scid_T; /// Format argument for scid_T @@ -711,6 +721,65 @@ static inline bool tv_dict_is_watched(const dict_T *const d) return d && !QUEUE_EMPTY(&d->watchers); } +static inline void tv_blob_set_ret(typval_T *const tv, blob_T *const b) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1); + +/// Set a blob as the return value. +/// +/// Increments the reference count. +/// +/// @param[out] tv Object to receive the blob. +/// @param[in,out] b Blob to pass to the object. +static inline void tv_blob_set_ret(typval_T *const tv, blob_T *const b) +{ + tv->v_type = VAR_BLOB; + tv->vval.v_blob = b; + if (b != NULL) { + b->bv_refcount++; + } +} + +static inline int tv_blob_len(const blob_T *const b) + REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; + +/// Get the length of the data in the blob, in bytes. +/// +/// @param[in] b Blob to check. +static inline int tv_blob_len(const blob_T *const b) +{ + if (b == NULL) { + return 0; + } + return b->bv_ga.ga_len; +} + +static inline char_u tv_blob_get(const blob_T *const b, int idx) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT; + +/// Get the byte at index `idx` in the blob. +/// +/// @param[in] b Blob to index. Cannot be NULL. +/// @param[in] idx Index in a blob. Must be valid. +/// +/// @return Byte value at the given index. +static inline char_u tv_blob_get(const blob_T *const b, int idx) +{ + return ((char_u *)b->bv_ga.ga_data)[idx]; +} + +static inline void tv_blob_set(blob_T *const b, int idx, char_u c) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL; + +/// Store the byte `c` at index `idx` in the blob. +/// +/// @param[in] b Blob to index. Cannot be NULL. +/// @param[in] idx Index in a blob. Must be valid. +/// @param[in] c Value to store. +static inline void tv_blob_set(blob_T *const b, int idx, char_u c) +{ + ((char_u *)b->bv_ga.ga_data)[idx] = c; +} + /// Initialize VimL object /// /// Initializes to unlocked VAR_UNKNOWN object. diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h index 91c948ce7e..cd1be1eecc 100644 --- a/src/nvim/eval/typval_encode.c.h +++ b/src/nvim/eval/typval_encode.c.h @@ -83,6 +83,13 @@ /// @param len String length. /// @param type EXT type. +/// @def TYPVAL_ENCODE_CONV_BLOB +/// @brief Macros used to convert a blob +/// +/// @param tv Pointer to typval where value is stored. May not be NULL. +/// @param blob Pointer to the blob to convert. +/// @param len Blob length. + /// @def TYPVAL_ENCODE_CONV_FUNC_START /// @brief Macros used when starting to convert a funcref or a partial /// @@ -330,6 +337,11 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE( TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float); break; } + case VAR_BLOB: { + TYPVAL_ENCODE_CONV_BLOB(tv, tv->vval.v_blob, + tv_blob_len(tv->vval.v_blob)); + break; + } case VAR_FUNC: { TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string); TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0); diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c index 4184e4d922..350c5ee1c2 100644 --- a/src/nvim/eval/userfunc.c +++ b/src/nvim/eval/userfunc.c @@ -5,6 +5,7 @@ #include "nvim/ascii.h" #include "nvim/charset.h" +#include "nvim/debugger.h" #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/encode.h" @@ -1547,7 +1548,7 @@ call_func( // Trigger FuncUndefined event, may load the function. if (fp == NULL - && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL) + && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, true, NULL) && !aborting()) { // executed an autocommand, search for the function again fp = find_func(rfname); diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c index c02f730431..0251ea9957 100644 --- a/src/nvim/event/libuv_process.c +++ b/src/nvim/event/libuv_process.c @@ -2,14 +2,13 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> - #include <uv.h> +#include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" +#include "nvim/event/process.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/event/process.h" -#include "nvim/event/libuv_process.h" #include "nvim/log.h" #include "nvim/macros.h" #include "nvim/os/os.h" @@ -68,7 +67,7 @@ int libuv_process_spawn(LibuvProcess *uvproc) #ifdef WIN32 // pipe must be readable for IOCP to work on Windows. uvproc->uvstdio[1].flags |= proc->overlapped ? - (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0; + (UV_READABLE_PIPE | UV_OVERLAPPED_PIPE) : 0; #endif uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t, &proc->out.uv.pipe); diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index e341513ae1..892c46dd04 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -3,7 +3,6 @@ #include <stdarg.h> #include <stdint.h> - #include <uv.h> #include "nvim/event/loop.h" diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index f534fc483f..a90cbc4e80 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -49,8 +49,6 @@ #include <stdarg.h> #include <stdbool.h> #include <stdint.h> - - #include <uv.h> #include "nvim/event/multiqueue.h" @@ -89,7 +87,7 @@ typedef struct { # include "event/multiqueue.c.generated.h" #endif -static Event NILEVENT = { .handler = NULL, .argv = {NULL} }; +static Event NILEVENT = { .handler = NULL, .argv = { NULL } }; MultiQueue *multiqueue_new_parent(PutCallback put_cb, void *data) { @@ -104,8 +102,7 @@ MultiQueue *multiqueue_new_child(MultiQueue *parent) return multiqueue_new(parent, NULL, NULL); } -static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb, - void *data) +static MultiQueue *multiqueue_new(MultiQueue *parent, PutCallback put_cb, void *data) { MultiQueue *rv = xmalloc(sizeof(MultiQueue)); QUEUE_INIT(&rv->headtail); diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 8b366d0f3c..dae4dad16d 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -3,20 +3,19 @@ #include <assert.h> #include <stdlib.h> - #include <uv.h> -#include "nvim/os/shell.h" +#include "nvim/event/libuv_process.h" #include "nvim/event/loop.h" +#include "nvim/event/process.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/event/process.h" -#include "nvim/event/libuv_process.h" -#include "nvim/os/process.h" -#include "nvim/os/pty_process.h" #include "nvim/globals.h" -#include "nvim/macros.h" #include "nvim/log.h" +#include "nvim/macros.h" +#include "nvim/os/process.h" +#include "nvim/os/pty_process.h" +#include "nvim/os/shell.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/process.c.generated.h" @@ -62,14 +61,14 @@ int process_spawn(Process *proc, bool in, bool out, bool err) int status; switch (proc->type) { - case kProcessTypeUv: - status = libuv_process_spawn((LibuvProcess *)proc); - break; - case kProcessTypePty: - status = pty_process_spawn((PtyProcess *)proc); - break; - default: - abort(); + case kProcessTypeUv: + status = libuv_process_spawn((LibuvProcess *)proc); + break; + case kProcessTypePty: + status = pty_process_spawn((PtyProcess *)proc); + break; + default: + abort(); } if (status) { @@ -139,9 +138,8 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL } // Wait until all children exit and all close events are processed. - LOOP_PROCESS_EVENTS_UNTIL( - loop, loop->events, -1, - kl_empty(loop->children) && multiqueue_empty(loop->events)); + LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, + kl_empty(loop->children) && multiqueue_empty(loop->events)); pty_process_teardown(loop); } @@ -189,7 +187,7 @@ int process_wait(Process *proc, int ms, MultiQueue *events) // We can only return if all streams/handles are closed and the job // exited. LOOP_PROCESS_EVENTS_UNTIL(proc->loop, events, -1, - proc->refcount == 1); + proc->refcount == 1); } else { LOOP_PROCESS_EVENTS(proc->loop, events, 0); } @@ -222,16 +220,16 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL proc->exit_signal = SIGTERM; switch (proc->type) { - case kProcessTypeUv: - os_proc_tree_kill(proc->pid, SIGTERM); - break; - case kProcessTypePty: - // close all streams for pty processes to send SIGHUP to the process - process_close_streams(proc); - pty_process_close_master((PtyProcess *)proc); - break; - default: - abort(); + case kProcessTypeUv: + os_proc_tree_kill(proc->pid, SIGTERM); + break; + case kProcessTypePty: + // close all streams for pty processes to send SIGHUP to the process + process_close_streams(proc); + pty_process_close_master((PtyProcess *)proc); + break; + default: + abort(); } // (Re)start timer to verify that stopped process(es) died. @@ -325,14 +323,14 @@ static void process_close(Process *proc) } switch (proc->type) { - case kProcessTypeUv: - libuv_process_close((LibuvProcess *)proc); - break; - case kProcessTypePty: - pty_process_close((PtyProcess *)proc); - break; - default: - abort(); + case kProcessTypeUv: + libuv_process_close((LibuvProcess *)proc); + break; + case kProcessTypePty: + pty_process_close((PtyProcess *)proc); + break; + default: + abort(); } } @@ -369,7 +367,7 @@ static void flush_stream(Process *proc, Stream *stream) // Poll for data and process the generated events. loop_poll_events(proc->loop, 0); if (stream->events) { - multiqueue_process_events(stream->events); + multiqueue_process_events(stream->events); } // Stream can be closed if it is empty. diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index efa56932d2..f070c8179f 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -2,19 +2,18 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> - #include <uv.h> -#include "nvim/event/rstream.h" #include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/memory.h" +#include "nvim/event/loop.h" +#include "nvim/event/rstream.h" #include "nvim/log.h" +#include "nvim/memory.h" #include "nvim/misc1.h" -#include "nvim/event/loop.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/rstream.c.generated.h" @@ -160,14 +159,13 @@ static void fread_idle_cb(uv_idle_t *handle) } // Synchronous read - uv_fs_read( - handle->loop, - &req, - stream->fd, - &stream->uvbuf, - 1, - (int64_t) stream->fpos, - NULL); + uv_fs_read(handle->loop, + &req, + stream->fd, + &stream->uvbuf, + 1, + (int64_t)stream->fpos, + NULL); uv_fs_req_cleanup(&req); @@ -178,7 +176,7 @@ static void fread_idle_cb(uv_idle_t *handle) } // no errors (req.result (ssize_t) is positive), it's safe to cast. - size_t nread = (size_t) req.result; + size_t nread = (size_t)req.result; rbuffer_produced(stream->buffer, nread); stream->fpos += nread; invoke_read_cb(stream, nread, false); diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 23228aa63a..7948a7be83 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -3,30 +3,28 @@ #include <assert.h> #include <stdint.h> - #include <uv.h> +#include "nvim/ascii.h" +#include "nvim/charset.h" #include "nvim/event/loop.h" -#include "nvim/event/socket.h" #include "nvim/event/rstream.h" +#include "nvim/event/socket.h" #include "nvim/event/wstream.h" -#include "nvim/os/os.h" -#include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/strings.h" -#include "nvim/path.h" +#include "nvim/log.h" +#include "nvim/macros.h" #include "nvim/main.h" #include "nvim/memory.h" -#include "nvim/macros.h" -#include "nvim/charset.h" -#include "nvim/log.h" +#include "nvim/os/os.h" +#include "nvim/path.h" +#include "nvim/strings.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "event/socket.c.generated.h" #endif -int socket_watcher_init(Loop *loop, SocketWatcher *watcher, - const char *endpoint) +int socket_watcher_init(Loop *loop, SocketWatcher *watcher, const char *endpoint) FUNC_ATTR_NONNULL_ALL { xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr)); @@ -56,9 +54,9 @@ int socket_watcher_init(Loop *loop, SocketWatcher *watcher, int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, port, &(struct addrinfo){ - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - }); + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + }); if (retval != 0) { ELOG("Host lookup failed: %s", endpoint); return retval; @@ -106,7 +104,7 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb) uv_tcp_getsockname(&watcher->uv.tcp.handle, (struct sockaddr *)&sas, &(int){ sizeof(sas) }); uint16_t port = (uint16_t)( - (sas.ss_family == AF_INET) + (sas.ss_family == AF_INET) ? (STRUCT_CAST(struct sockaddr_in, &sas))->sin_port : (STRUCT_CAST(struct sockaddr_in6, &sas))->sin6_port); // v:servername uses the string from watcher->addr @@ -183,7 +181,7 @@ static void connection_cb(uv_stream_t *handle, int status) { SocketWatcher *watcher = handle->data; CREATE_EVENT(watcher->events, connection_event, 2, watcher, - (void *)(uintptr_t)status); + (void *)(uintptr_t)status); } static void close_cb(uv_handle_t *handle) @@ -203,9 +201,8 @@ static void connect_cb(uv_connect_t *req, int status) } } -bool socket_connect(Loop *loop, Stream *stream, - bool is_tcp, const char *address, - int timeout, const char **error) +bool socket_connect(Loop *loop, Stream *stream, bool is_tcp, const char *address, int timeout, + const char **error) { bool success = false; int status; @@ -243,7 +240,6 @@ tcp_retry: uv_tcp_nodelay(tcp, true); uv_tcp_connect(&req, tcp, addrinfo->ai_addr, connect_cb); uv_stream = (uv_stream_t *)tcp; - } else { uv_pipe_t *pipe = &stream->uv.pipe; uv_pipe_init(&loop->uv, pipe, 0); diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index a8ded66ea5..8569b92d56 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -2,15 +2,14 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdio.h> #include <stdbool.h> - +#include <stdio.h> #include <uv.h> +#include "nvim/event/stream.h" #include "nvim/log.h" -#include "nvim/rbuffer.h" #include "nvim/macros.h" -#include "nvim/event/stream.h" +#include "nvim/rbuffer.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif @@ -77,7 +76,7 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream) uv_pipe_open(&stream->uv.pipe, fd); stream->uvstream = STRUCT_CAST(uv_stream_t, &stream->uv.pipe); #ifdef WIN32 - } + } #endif } } diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index b7e30e392b..aa7b9cf2a1 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -2,7 +2,6 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <stdint.h> - #include <uv.h> #include "nvim/event/loop.h" @@ -23,8 +22,7 @@ void time_watcher_init(Loop *loop, TimeWatcher *watcher, void *data) watcher->blockable = false; } -void time_watcher_start(TimeWatcher *watcher, time_cb cb, uint64_t timeout, - uint64_t repeat) +void time_watcher_start(TimeWatcher *watcher, time_cb cb, uint64_t timeout, uint64_t repeat) FUNC_ATTR_NONNULL_ALL { watcher->cb = cb; diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c index 2baa667e7d..d81ffa5c15 100644 --- a/src/nvim/event/wstream.c +++ b/src/nvim/event/wstream.c @@ -2,17 +2,16 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include <stdlib.h> - #include <uv.h> -#include "nvim/log.h" #include "nvim/event/loop.h" #include "nvim/event/wstream.h" -#include "nvim/vim.h" +#include "nvim/log.h" #include "nvim/memory.h" +#include "nvim/vim.h" #define DEFAULT_MAXMEM 1024 * 1024 * 2000 @@ -117,10 +116,7 @@ err: /// @param cb Pointer to function that will be responsible for freeing /// the buffer data(passing 'free' will work as expected). /// @return The allocated WBuffer instance -WBuffer *wstream_new_buffer(char *data, - size_t size, - size_t refcount, - wbuffer_data_finalizer cb) +WBuffer *wstream_new_buffer(char *data, size_t size, size_t refcount, wbuffer_data_finalizer cb) FUNC_ATTR_NONNULL_ARG(1) { WBuffer *rv = xmalloc(sizeof(WBuffer)); diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 87d9c312d9..f8186c000e 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -329,9 +329,9 @@ void ex_align(exarg_T *eap) */ static int linelen(int *has_tab) { - char_u *line; - char_u *first; - char_u *last; + char_u *line; + char_u *first; + char_u *last; int save; int len; @@ -363,8 +363,8 @@ static int linelen(int *has_tab) /* Buffer for two lines used during sorting. They are allocated to * contain the longest line being sorted. */ -static char_u *sortbuf1; -static char_u *sortbuf2; +static char_u *sortbuf1; +static char_u *sortbuf2; static int sort_lc; ///< sort using locale static int sort_ic; ///< ignore case @@ -461,9 +461,9 @@ void ex_sort(exarg_T *eap) long maxlen = 0; size_t count = (size_t)(eap->line2 - eap->line1 + 1); size_t i; - char_u *p; - char_u *s; - char_u *s2; + char_u *p; + char_u *s; + char_u *s2; char_u c; // temporary character storage bool unique = false; long deleted; @@ -609,7 +609,7 @@ void ex_sort(exarg_T *eap) } else { nrs[lnum - eap->line1].st_u.num.is_number = true; vim_str2nr(s, NULL, NULL, sort_what, - &nrs[lnum - eap->line1].st_u.num.value, NULL, 0); + &nrs[lnum - eap->line1].st_u.num.value, NULL, 0, false); } } else { s = skipwhite(p); @@ -738,9 +738,9 @@ void ex_retab(exarg_T *eap) long start_col = 0; // For start of white-space string long start_vcol = 0; // For start of white-space string long old_len; - char_u *ptr; - char_u *new_line = (char_u *)1; // init to non-NULL - int did_undo; // called u_save for current line + char_u *ptr; + char_u *new_line = (char_u *)1; // init to non-NULL + bool did_undo; // called u_save for current line long *new_vts_array = NULL; char_u *new_ts_str; // string value of tab argument @@ -772,7 +772,7 @@ void ex_retab(exarg_T *eap) ptr = ml_get(lnum); col = 0; vcol = 0; - did_undo = FALSE; + did_undo = false; for (;; ) { if (ascii_iswhite(ptr[col])) { if (!got_tab && num_spaces == 0) { @@ -906,7 +906,7 @@ void ex_retab(exarg_T *eap) */ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) { - char_u *str; + char_u *str; linenr_T l; linenr_T extra; // Num lines added before line1 linenr_T num_lines; // Num lines moved @@ -1058,7 +1058,7 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest) void ex_copy(linenr_T line1, linenr_T line2, linenr_T n) { linenr_T count; - char_u *p; + char_u *p; count = line2 - line1 + 1; curbuf->b_op_start.lnum = n + 1; @@ -1107,7 +1107,7 @@ void ex_copy(linenr_T line1, linenr_T line2, linenr_T n) msgmore((long)count); } -static char_u *prevcmd = NULL; // the previous command +static char_u *prevcmd = NULL; // the previous command #if defined(EXITFREE) void free_prev_shellcmd(void) @@ -1130,9 +1130,9 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out linenr_T line2 = eap->line2; // end of range char_u *newcmd = NULL; // the new command bool free_newcmd = false; // need to free() newcmd - char_u *t; - char_u *p; - char_u *trailarg; + char_u *t; + char_u *p; + char_u *trailarg; int len; int scroll_save = msg_scroll; @@ -1240,7 +1240,7 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out /* Careful: This may recursively call do_bang() again! (because of * autocommands) */ do_filter(line1, line2, eap, newcmd, do_in, do_out); - apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_SHELLFILTERPOST, NULL, NULL, false, curbuf); } if (free_newcmd) { xfree(newcmd); @@ -1265,13 +1265,13 @@ void do_bang(int addr_count, exarg_T *eap, bool forceit, bool do_in, bool do_out static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, bool do_in, bool do_out) { - char_u *itmp = NULL; - char_u *otmp = NULL; + char_u *itmp = NULL; + char_u *otmp = NULL; linenr_T linecount; linenr_T read_linecount; pos_T cursor_save; - char_u *cmd_buf; - buf_T *old_curbuf = curbuf; + char_u *cmd_buf; + buf_T *old_curbuf = curbuf; int shell_flags = 0; const int stmp = p_stmp; @@ -1353,7 +1353,7 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, ui_cursor_goto(Rows - 1, 0); if (do_out) { - if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL) { + if (u_save((line2), (linenr_T)(line2 + 1)) == FAIL) { xfree(cmd_buf); goto error; } @@ -1519,7 +1519,7 @@ void do_shell(char_u *cmd, int flags) msg_row = Rows - 1; msg_col = 0; - apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, false, curbuf); } #if !defined(UNIX) @@ -1684,11 +1684,11 @@ void print_line(linenr_T lnum, int use_number, int list) int rename_buffer(char_u *new_fname) { - char_u *fname, *sfname, *xfname; - buf_T *buf; + char_u *fname, *sfname, *xfname; + buf_T *buf; buf = curbuf; - apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf); // buffer changed, don't change name now if (buf != curbuf) { return FAIL; @@ -1722,7 +1722,7 @@ int rename_buffer(char_u *new_fname) } xfree(fname); xfree(sfname); - apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf); // Change directories when the 'acd' option is set. do_autochdir(); return OK; @@ -1795,11 +1795,11 @@ void ex_write(exarg_T *eap) int do_write(exarg_T *eap) { int other; - char_u *fname = NULL; // init to shut up gcc - char_u *ffname; + char_u *fname = NULL; // init to shut up gcc + char_u *ffname; int retval = FAIL; - char_u *free_fname = NULL; - buf_T *alt_buf = NULL; + char_u *free_fname = NULL; + buf_T *alt_buf = NULL; int name_was_missing; if (not_writing()) { // check 'write' option @@ -1879,10 +1879,10 @@ int do_write(exarg_T *eap) if (check_overwrite(eap, curbuf, fname, ffname, other) == OK) { if (eap->cmdidx == CMD_saveas && alt_buf != NULL) { - buf_T *was_curbuf = curbuf; + buf_T *was_curbuf = curbuf; - apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, curbuf); - apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, FALSE, alt_buf); + apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf); + apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, alt_buf); if (curbuf != was_curbuf || aborting()) { // buffer changed, don't change name now retval = FAIL; @@ -1903,8 +1903,8 @@ int do_write(exarg_T *eap) alt_buf->b_sfname = curbuf->b_sfname; curbuf->b_sfname = fname; buf_name_changed(curbuf); - apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, curbuf); - apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, FALSE, alt_buf); + apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf); + apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, alt_buf); if (!alt_buf->b_p_bl) { alt_buf->b_p_bl = TRUE; apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, alt_buf); @@ -1999,9 +1999,9 @@ int check_overwrite(exarg_T *eap, buf_T *buf, char_u *fname, char_u *ffname, int // For ":w! filename" check that no swap file exists for "filename". if (other && !emsg_silent) { - char_u *dir; - char_u *p; - char_u *swapname; + char_u *dir; + char_u *p; + char_u *swapname; /* We only try the first entry in 'directory', without checking if * it's writable. If the "." directory is not writable the write @@ -2196,7 +2196,7 @@ int getfile(int fnum, char_u *ffname_arg, char_u *sfname_arg, int setpm, linenr_ char_u *sfname = sfname_arg; int other; int retval; - char_u *free_me = NULL; + char_u *free_me = NULL; if (text_locked()) { return GETFILE_ERROR; @@ -2287,25 +2287,25 @@ theend: int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T newlnum, int flags, win_T *oldwin) { - int other_file; // TRUE if editing another file + bool other_file; // true if editing another file int oldbuf; // TRUE if using existing buffer - int auto_buf = FALSE; /* TRUE if autocommands brought us - into the buffer unexpectedly */ - char_u *new_name = NULL; - int did_set_swapcommand = FALSE; - buf_T *buf; + bool auto_buf = false; // true if autocommands brought us + // into the buffer unexpectedly + char_u *new_name = NULL; + bool did_set_swapcommand = false; + buf_T *buf; bufref_T bufref; bufref_T old_curbuf; - char_u *free_fname = NULL; + char_u *free_fname = NULL; int retval = FAIL; long n; pos_T orig_pos; linenr_T topline = 0; int newcol = -1; int solcol = -1; - pos_T *pos; - char_u *command = NULL; - int did_get_winopts = FALSE; + pos_T *pos; + char_u *command = NULL; + bool did_get_winopts = false; int readfile_flags = 0; bool did_inc_redrawing_disabled = false; long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; @@ -2320,7 +2320,7 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new if (fnum == curbuf->b_fnum) { // file is already being edited return OK; // nothing to do } - other_file = TRUE; + other_file = true; } else { // if no short name given, use ffname for short name if (sfname == NULL) { @@ -2338,11 +2338,9 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new } if (ffname == NULL) { - other_file = TRUE; - } - // there is no file name - else if (*ffname == NUL && curbuf->b_ffname == NULL) { - other_file = FALSE; + other_file = true; + } else if (*ffname == NUL && curbuf->b_ffname == NULL) { // there is no file name + other_file = false; } else { if (*ffname == NUL) { // re-edit with same file name ffname = curbuf->b_ffname; @@ -2397,7 +2395,7 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new vim_snprintf(p, len, "%" PRId64 "G", (int64_t)newlnum); } set_vim_var_string(VV_SWAPCOMMAND, p, -1); - did_set_swapcommand = TRUE; + did_set_swapcommand = true; xfree(p); } @@ -2584,7 +2582,7 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new * before, reset the local window options to the global * values. Also restores old folding stuff. */ get_winopts(curbuf); - did_get_winopts = TRUE; + did_get_winopts = true; } xfree(new_name); au_new_curbuf.br_buf = NULL; @@ -2836,17 +2834,17 @@ int do_ecmd(int fnum, char_u *ffname, char_u *sfname, exarg_T *eap, linenr_T new msg_scroll = FALSE; } if (!msg_scroll) { // wait a bit when overwriting an error msg - check_for_delay(FALSE); + check_for_delay(false); } msg_start(); msg_scroll = msg_scroll_save; - msg_scrolled_ign = TRUE; + msg_scrolled_ign = true; if (!shortmess(SHM_FILEINFO)) { fileinfo(false, true, false); } - msg_scrolled_ign = FALSE; + msg_scrolled_ign = false; } curbuf->b_last_used = time(NULL); @@ -2911,11 +2909,11 @@ static int append_indent = 0; // autoindent for first line */ void ex_append(exarg_T *eap) { - char_u *theline; + char_u *theline; bool did_undo = false; linenr_T lnum = eap->line2; int indent = 0; - char_u *p; + char_u *p; int vcol; int empty = (curbuf->b_ml.ml_flags & ML_EMPTY); @@ -3070,7 +3068,7 @@ void ex_change(exarg_T *eap) // make sure the cursor is not beyond the end of the file now check_cursor_lnum(); - deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum)); + deleted_lines_mark(eap->line1, (eap->line2 - lnum)); // ":append" on the line above the deleted lines. eap->line2 = eap->line1; @@ -3079,9 +3077,9 @@ void ex_change(exarg_T *eap) void ex_z(exarg_T *eap) { - char_u *x; + char_u *x; int64_t bigness; - char_u *kind; + char_u *kind; int minus = 0; linenr_T start, end, curs, i; int j; @@ -3459,8 +3457,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle int delimiter; bool has_second_delim = false; int sublen; - int got_quit = false; - int got_match = false; + bool got_quit = false; + bool got_match = false; int which_pat; char_u *cmd = eap->arg; linenr_T first_line = 0; // first changed line @@ -3648,9 +3646,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle colnr_T copycol; colnr_T matchcol; colnr_T prev_matchcol = MAXCOL; - char_u *new_end, *new_start = NULL; - char_u *p1; - int did_sub = FALSE; + char_u *new_end, *new_start = NULL; + char_u *p1; + bool did_sub = false; int lastone; long nmatch_tl = 0; // nr of lines matched below lnum int do_again; // do it again after joining lines @@ -3708,7 +3706,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle // At first match, remember current cursor position. if (!got_match) { setpcmark(); - got_match = TRUE; + got_match = true; } /* @@ -3798,9 +3796,9 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle skip_match = true; } sub_nsubs++; - did_sub = TRUE; - /* Skip the substitution, unless an expression is used, - * then it is evaluated in the sandbox. */ + did_sub = true; + // Skip the substitution, unless an expression is used, + // then it is evaluated in the sandbox. if (!(sub[0] == '\\' && sub[1] == '=')) { goto skip; } @@ -3831,8 +3829,8 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle */ while (subflags.do_ask) { if (exmode_active) { - char *prompt; - char_u *resp; + char *prompt; + char_u *resp; colnr_T sc, ec; print_line_no_prefix(lnum, subflags.do_number, subflags.do_list); @@ -4087,7 +4085,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle + copy_len + sublen + 1); // copy the text up to the part that matched - memmove(new_end, sub_firstline + copycol, (size_t)copy_len); + memmove(new_end, sub_firstline + copycol, copy_len); new_end += copy_len; // Finally, at this point we can know where the match actually will @@ -4435,7 +4433,7 @@ skip: /// /// @param count_only used 'n' flag for ":s" /// -/// @return TRUE if a message was given. +/// @return true if a message was given. bool do_sub_msg(bool count_only) { /* @@ -4513,10 +4511,10 @@ void ex_global(exarg_T *eap) linenr_T lnum; // line number according to old situation int ndone = 0; int type; // first char of cmd: 'v' or 'g' - char_u *cmd; // command argument + char_u *cmd; // command argument char_u delim; // delimiter, normally '/' - char_u *pat; + char_u *pat; regmmatch_T regmatch; int match; int which_pat; @@ -4683,7 +4681,7 @@ void free_old_sub(void) /// /// @param undo_sync sync undo when leaving the window /// -/// @return TRUE when it was created. +/// @return true when it was created. bool prepare_tagpreview(bool undo_sync) { /* @@ -4726,20 +4724,20 @@ bool prepare_tagpreview(bool undo_sync) */ void ex_help(exarg_T *eap) { - char_u *arg; - char_u *tag; - FILE *helpfd; // file descriptor of help file + char_u *arg; + char_u *tag; + FILE *helpfd; // file descriptor of help file int n; int i; - win_T *wp; + win_T *wp; int num_matches; - char_u **matches; - char_u *p; + char_u **matches; + char_u *p; int empty_fnum = 0; int alt_fnum = 0; - buf_T *buf; + buf_T *buf; int len; - char_u *lang; + char_u *lang; const bool old_KeyTyped = KeyTyped; if (eap != NULL) { @@ -4940,7 +4938,7 @@ char_u *check_help_lang(char_u *arg) int help_heuristic(char_u *matched_string, int offset, int wrong_case) { int num_letters; - char_u *p; + char_u *p; num_letters = 0; for (p = matched_string; *p; p++) { @@ -4982,8 +4980,8 @@ int help_heuristic(char_u *matched_string, int offset, int wrong_case) */ static int help_compare(const void *s1, const void *s2) { - char *p1; - char *p2; + char *p1; + char *p2; p1 = *(char **)s1 + strlen(*(char **)s1) + 1; p2 = *(char **)s2 + strlen(*(char **)s2) + 1; @@ -5274,7 +5272,7 @@ static void prepare_help_buffer(void) void fix_help_buffer(void) { linenr_T lnum; - char_u *line; + char_u *line; bool in_example = false; // Set filetype to "help". @@ -5338,10 +5336,10 @@ void fix_help_buffer(void) if (rt != NULL && path_full_compare(rt, NameBuff, false, true) != kEqualFiles) { int fcount; - char_u **fnames; - char_u *s; + char_u **fnames; + char_u *s; vimconv_T vc; - char_u *cp; + char_u *cp; // Find all "doc/ *.txt" files in this directory. if (!add_pathsep((char *)NameBuff) @@ -5498,9 +5496,9 @@ static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname, { garray_T ga; int filecount; - char_u **files; - char_u *p1, *p2; - char_u *s; + char_u **files; + char_u *p1, *p2; + char_u *s; TriState utf8 = kNone; bool mix = false; // detected mixed encodings @@ -6125,7 +6123,7 @@ char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags) /// List v:oldfiles in a nice way. void ex_oldfiles(exarg_T *eap) { - list_T *l = get_vim_var_list(VV_OLDFILES); + list_T *l = get_vim_var_list(VV_OLDFILES); long nr = 0; if (l == NULL) { diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index e06a62e0f6..6542ab41f5 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -20,14 +20,12 @@ #include "nvim/buffer.h" #include "nvim/change.h" #include "nvim/charset.h" +#include "nvim/debugger.h" #include "nvim/eval/userfunc.h" #include "nvim/ex_cmds.h" -#include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/getchar.h" -#include "nvim/globals.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -43,13 +41,11 @@ #include "nvim/path.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" -#include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/undo.h" #include "nvim/version.h" #include "nvim/window.h" #include "nvim/profile.h" -#include "nvim/os/os.h" #include "nvim/os/shell.h" #include "nvim/os/fs_defs.h" #include "nvim/api/private/helpers.h" @@ -119,808 +115,6 @@ struct source_cookie { # include "ex_cmds2.c.generated.h" #endif -/// batch mode debugging: don't save and restore typeahead. -static bool debug_greedy = false; - -static char *debug_oldval = NULL; // old and newval for debug expressions -static char *debug_newval = NULL; - -/// Debug mode. Repeatedly get Ex commands, until told to continue normal -/// execution. -void do_debug(char_u *cmd) -{ - int save_msg_scroll = msg_scroll; - int save_State = State; - int save_did_emsg = did_emsg; - const bool save_cmd_silent = cmd_silent; - int save_msg_silent = msg_silent; - int save_emsg_silent = emsg_silent; - bool save_redir_off = redir_off; - tasave_T typeaheadbuf; - bool typeahead_saved = false; - int save_ignore_script = 0; - int save_ex_normal_busy; - int n; - char_u *cmdline = NULL; - char_u *p; - char *tail = NULL; - static int last_cmd = 0; -#define CMD_CONT 1 -#define CMD_NEXT 2 -#define CMD_STEP 3 -#define CMD_FINISH 4 -#define CMD_QUIT 5 -#define CMD_INTERRUPT 6 -#define CMD_BACKTRACE 7 -#define CMD_FRAME 8 -#define CMD_UP 9 -#define CMD_DOWN 10 - - - RedrawingDisabled++; // don't redisplay the window - no_wait_return++; // don't wait for return - did_emsg = false; // don't use error from debugged stuff - cmd_silent = false; // display commands - msg_silent = false; // display messages - emsg_silent = false; // display error messages - redir_off = true; // don't redirect debug commands - - State = NORMAL; - debug_mode = true; - - if (!debug_did_msg) { - MSG(_("Entering Debug mode. Type \"cont\" to continue.")); - } - if (debug_oldval != NULL) { - smsg(_("Oldval = \"%s\""), debug_oldval); - xfree(debug_oldval); - debug_oldval = NULL; - } - if (debug_newval != NULL) { - smsg(_("Newval = \"%s\""), debug_newval); - xfree(debug_newval); - debug_newval = NULL; - } - if (sourcing_name != NULL) { - msg(sourcing_name); - } - if (sourcing_lnum != 0) { - smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd); - } else { - smsg(_("cmd: %s"), cmd); - } - // Repeat getting a command and executing it. - for (;; ) { - msg_scroll = true; - need_wait_return = false; - // Save the current typeahead buffer and replace it with an empty one. - // This makes sure we get input from the user here and don't interfere - // with the commands being executed. Reset "ex_normal_busy" to avoid - // the side effects of using ":normal". Save the stuff buffer and make - // it empty. Set ignore_script to avoid reading from script input. - save_ex_normal_busy = ex_normal_busy; - ex_normal_busy = 0; - if (!debug_greedy) { - save_typeahead(&typeaheadbuf); - typeahead_saved = true; - save_ignore_script = ignore_script; - ignore_script = true; - } - - xfree(cmdline); - cmdline = (char_u *)getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL, - CALLBACK_NONE); - - if (typeahead_saved) { - restore_typeahead(&typeaheadbuf); - ignore_script = save_ignore_script; - } - ex_normal_busy = save_ex_normal_busy; - - cmdline_row = msg_row; - msg_starthere(); - if (cmdline != NULL) { - // If this is a debug command, set "last_cmd". - // If not, reset "last_cmd". - // For a blank line use previous command. - p = skipwhite(cmdline); - if (*p != NUL) { - switch (*p) { - case 'c': last_cmd = CMD_CONT; - tail = "ont"; - break; - case 'n': last_cmd = CMD_NEXT; - tail = "ext"; - break; - case 's': last_cmd = CMD_STEP; - tail = "tep"; - break; - case 'f': - last_cmd = 0; - if (p[1] == 'r') { - last_cmd = CMD_FRAME; - tail = "rame"; - } else { - last_cmd = CMD_FINISH; - tail = "inish"; - } - break; - case 'q': last_cmd = CMD_QUIT; - tail = "uit"; - break; - case 'i': last_cmd = CMD_INTERRUPT; - tail = "nterrupt"; - break; - case 'b': - last_cmd = CMD_BACKTRACE; - if (p[1] == 't') { - tail = "t"; - } else { - tail = "acktrace"; - } - break; - case 'w': - last_cmd = CMD_BACKTRACE; - tail = "here"; - break; - case 'u': - last_cmd = CMD_UP; - tail = "p"; - break; - case 'd': - last_cmd = CMD_DOWN; - tail = "own"; - break; - default: last_cmd = 0; - } - if (last_cmd != 0) { - // Check that the tail matches. - p++; - while (*p != NUL && *p == *tail) { - p++; - tail++; - } - if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) { - last_cmd = 0; - } - } - } - - if (last_cmd != 0) { - // Execute debug command: decided where to break next and return. - switch (last_cmd) { - case CMD_CONT: - debug_break_level = -1; - break; - case CMD_NEXT: - debug_break_level = ex_nesting_level; - break; - case CMD_STEP: - debug_break_level = 9999; - break; - case CMD_FINISH: - debug_break_level = ex_nesting_level - 1; - break; - case CMD_QUIT: - got_int = true; - debug_break_level = -1; - break; - case CMD_INTERRUPT: - got_int = true; - debug_break_level = 9999; - // Do not repeat ">interrupt" cmd, continue stepping. - last_cmd = CMD_STEP; - break; - case CMD_BACKTRACE: - do_showbacktrace(cmd); - continue; - case CMD_FRAME: - if (*p == NUL) { - do_showbacktrace(cmd); - } else { - p = skipwhite(p); - do_setdebugtracelevel(p); - } - continue; - case CMD_UP: - debug_backtrace_level++; - do_checkbacktracelevel(); - continue; - case CMD_DOWN: - debug_backtrace_level--; - do_checkbacktracelevel(); - continue; - } - // Going out reset backtrace_level - debug_backtrace_level = 0; - break; - } - - // don't debug this command - n = debug_break_level; - debug_break_level = -1; - (void)do_cmdline(cmdline, getexline, NULL, - DOCMD_VERBOSE|DOCMD_EXCRESET); - debug_break_level = n; - } - lines_left = (int)(Rows - 1); - } - xfree(cmdline); - - RedrawingDisabled--; - no_wait_return--; - redraw_all_later(NOT_VALID); - need_wait_return = false; - msg_scroll = save_msg_scroll; - lines_left = (int)(Rows - 1); - State = save_State; - debug_mode = false; - did_emsg = save_did_emsg; - cmd_silent = save_cmd_silent; - msg_silent = save_msg_silent; - emsg_silent = save_emsg_silent; - redir_off = save_redir_off; - - // Only print the message again when typing a command before coming back here. - debug_did_msg = true; -} - -static int get_maxbacktrace_level(void) -{ - int maxbacktrace = 0; - - if (sourcing_name != NULL) { - char *p = (char *)sourcing_name; - char *q; - while ((q = strstr(p, "..")) != NULL) { - p = q + 2; - maxbacktrace++; - } - } - return maxbacktrace; -} - -static void do_setdebugtracelevel(char_u *arg) -{ - int level = atoi((char *)arg); - if (*arg == '+' || level < 0) { - debug_backtrace_level += level; - } else { - debug_backtrace_level = level; - } - - do_checkbacktracelevel(); -} - -static void do_checkbacktracelevel(void) -{ - if (debug_backtrace_level < 0) { - debug_backtrace_level = 0; - MSG(_("frame is zero")); - } else { - int max = get_maxbacktrace_level(); - if (debug_backtrace_level > max) { - debug_backtrace_level = max; - smsg(_("frame at highest level: %d"), max); - } - } -} - -static void do_showbacktrace(char_u *cmd) -{ - if (sourcing_name != NULL) { - int i = 0; - int max = get_maxbacktrace_level(); - char *cur = (char *)sourcing_name; - while (!got_int) { - char *next = strstr(cur, ".."); - if (next != NULL) { - *next = NUL; - } - if (i == max - debug_backtrace_level) { - smsg("->%d %s", max - i, cur); - } else { - smsg(" %d %s", max - i, cur); - } - i++; - if (next == NULL) { - break; - } - *next = '.'; - cur = next + 2; - } - } - if (sourcing_lnum != 0) { - smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd); - } else { - smsg(_("cmd: %s"), cmd); - } -} - - -/// ":debug". -void ex_debug(exarg_T *eap) -{ - int debug_break_level_save = debug_break_level; - - debug_break_level = 9999; - do_cmdline_cmd((char *)eap->arg); - debug_break_level = debug_break_level_save; -} - -static char_u *debug_breakpoint_name = NULL; -static linenr_T debug_breakpoint_lnum; - -/// When debugging or a breakpoint is set on a skipped command, no debug prompt -/// is shown by do_one_cmd(). This situation is indicated by debug_skipped, and -/// debug_skipped_name is then set to the source name in the breakpoint case. If -/// a skipped command decides itself that a debug prompt should be displayed, it -/// can do so by calling dbg_check_skipped(). -static int debug_skipped; -static char_u *debug_skipped_name; - -/// Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is -/// at or below the break level. But only when the line is actually -/// executed. Return true and set breakpoint_name for skipped commands that -/// decide to execute something themselves. -/// Called from do_one_cmd() before executing a command. -void dbg_check_breakpoint(exarg_T *eap) -{ - char_u *p; - - debug_skipped = false; - if (debug_breakpoint_name != NULL) { - if (!eap->skip) { - // replace K_SNR with "<SNR>" - if (debug_breakpoint_name[0] == K_SPECIAL - && debug_breakpoint_name[1] == KS_EXTRA - && debug_breakpoint_name[2] == (int)KE_SNR) { - p = (char_u *)"<SNR>"; - } else { - p = (char_u *)""; - } - smsg(_("Breakpoint in \"%s%s\" line %" PRId64), - p, - debug_breakpoint_name + (*p == NUL ? 0 : 3), - (int64_t)debug_breakpoint_lnum); - debug_breakpoint_name = NULL; - do_debug(eap->cmd); - } else { - debug_skipped = true; - debug_skipped_name = debug_breakpoint_name; - debug_breakpoint_name = NULL; - } - } else if (ex_nesting_level <= debug_break_level) { - if (!eap->skip) { - do_debug(eap->cmd); - } else { - debug_skipped = true; - debug_skipped_name = NULL; - } - } -} - -/// Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was -/// set. -/// -/// @return true when the debug mode is entered this time. -bool dbg_check_skipped(exarg_T *eap) -{ - int prev_got_int; - - if (debug_skipped) { - // Save the value of got_int and reset it. We don't want a previous - // interruption cause flushing the input buffer. - prev_got_int = got_int; - got_int = false; - debug_breakpoint_name = debug_skipped_name; - // eap->skip is true - eap->skip = false; - dbg_check_breakpoint(eap); - eap->skip = true; - got_int |= prev_got_int; - return true; - } - return false; -} - -/// The list of breakpoints: dbg_breakp. -/// This is a grow-array of structs. -struct debuggy { - int dbg_nr; ///< breakpoint number - int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR - char_u *dbg_name; ///< function, expression or file name - regprog_T *dbg_prog; ///< regexp program - linenr_T dbg_lnum; ///< line number in function or file - int dbg_forceit; ///< ! used - typval_T *dbg_val; ///< last result of watchexpression - int dbg_level; ///< stored nested level for expr -}; - -static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL }; -#define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx]) -#define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx]) -static int last_breakp = 0; // nr of last defined breakpoint - -// Profiling uses file and func names similar to breakpoints. -static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL }; -#define DBG_FUNC 1 -#define DBG_FILE 2 -#define DBG_EXPR 3 - - -/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them -/// in the entry just after the last one in dbg_breakp. Note that "dbg_name" -/// is allocated. -/// Returns FAIL for failure. -/// -/// @param arg -/// @param gap either &dbg_breakp or &prof_ga -static int dbg_parsearg(char_u *arg, garray_T *gap) -{ - char_u *p = arg; - char_u *q; - struct debuggy *bp; - bool here = false; - - ga_grow(gap, 1); - - bp = &DEBUGGY(gap, gap->ga_len); - - // Find "func" or "file". - if (STRNCMP(p, "func", 4) == 0) { - bp->dbg_type = DBG_FUNC; - } else if (STRNCMP(p, "file", 4) == 0) { - bp->dbg_type = DBG_FILE; - } else if (gap != &prof_ga && STRNCMP(p, "here", 4) == 0) { - if (curbuf->b_ffname == NULL) { - EMSG(_(e_noname)); - return FAIL; - } - bp->dbg_type = DBG_FILE; - here = true; - } else if (gap != &prof_ga && STRNCMP(p, "expr", 4) == 0) { - bp->dbg_type = DBG_EXPR; - } else { - EMSG2(_(e_invarg2), p); - return FAIL; - } - p = skipwhite(p + 4); - - // Find optional line number. - if (here) { - bp->dbg_lnum = curwin->w_cursor.lnum; - } else if (gap != &prof_ga && ascii_isdigit(*p)) { - bp->dbg_lnum = getdigits_long(&p, true, 0); - p = skipwhite(p); - } else { - bp->dbg_lnum = 0; - } - - // Find the function or file name. Don't accept a function name with (). - if ((!here && *p == NUL) - || (here && *p != NUL) - || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) { - EMSG2(_(e_invarg2), arg); - return FAIL; - } - - if (bp->dbg_type == DBG_FUNC) { - bp->dbg_name = vim_strsave(p); - } else if (here) { - bp->dbg_name = vim_strsave(curbuf->b_ffname); - } else if (bp->dbg_type == DBG_EXPR) { - bp->dbg_name = vim_strsave(p); - bp->dbg_val = eval_expr(bp->dbg_name); - } else { - // Expand the file name in the same way as do_source(). This means - // doing it twice, so that $DIR/file gets expanded when $DIR is - // "~/dir". - q = expand_env_save(p); - if (q == NULL) { - return FAIL; - } - p = expand_env_save(q); - xfree(q); - if (p == NULL) { - return FAIL; - } - if (*p != '*') { - bp->dbg_name = (char_u *)fix_fname((char *)p); - xfree(p); - } else { - bp->dbg_name = p; - } - } - - if (bp->dbg_name == NULL) { - return FAIL; - } - return OK; -} - -/// ":breakadd". Also used for ":profile". -void ex_breakadd(exarg_T *eap) -{ - struct debuggy *bp; - garray_T *gap; - - gap = &dbg_breakp; - if (eap->cmdidx == CMD_profile) { - gap = &prof_ga; - } - - if (dbg_parsearg(eap->arg, gap) == OK) { - bp = &DEBUGGY(gap, gap->ga_len); - bp->dbg_forceit = eap->forceit; - - if (bp->dbg_type != DBG_EXPR) { - char_u *pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, false); - if (pat != NULL) { - bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING); - xfree(pat); - } - if (pat == NULL || bp->dbg_prog == NULL) { - xfree(bp->dbg_name); - } else { - if (bp->dbg_lnum == 0) { // default line number is 1 - bp->dbg_lnum = 1; - } - if (eap->cmdidx != CMD_profile) { - DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp; - debug_tick++; - } - gap->ga_len++; - } - } else { - // DBG_EXPR - DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp; - debug_tick++; - } - } -} - -/// ":debuggreedy". -void ex_debuggreedy(exarg_T *eap) -{ - if (eap->addr_count == 0 || eap->line2 != 0) { - debug_greedy = true; - } else { - debug_greedy = false; - } -} - -/// ":breakdel" and ":profdel". -void ex_breakdel(exarg_T *eap) -{ - struct debuggy *bp, *bpi; - int nr; - int todel = -1; - bool del_all = false; - linenr_T best_lnum = 0; - garray_T *gap; - - gap = &dbg_breakp; - if (eap->cmdidx == CMD_profdel) { - gap = &prof_ga; - } - - if (ascii_isdigit(*eap->arg)) { - // ":breakdel {nr}" - nr = atoi((char *)eap->arg); - for (int i = 0; i < gap->ga_len; i++) { - if (DEBUGGY(gap, i).dbg_nr == nr) { - todel = i; - break; - } - } - } else if (*eap->arg == '*') { - todel = 0; - del_all = true; - } else { - // ":breakdel {func|file|expr} [lnum] {name}" - if (dbg_parsearg(eap->arg, gap) == FAIL) { - return; - } - bp = &DEBUGGY(gap, gap->ga_len); - for (int i = 0; i < gap->ga_len; i++) { - bpi = &DEBUGGY(gap, i); - if (bp->dbg_type == bpi->dbg_type - && STRCMP(bp->dbg_name, bpi->dbg_name) == 0 - && (bp->dbg_lnum == bpi->dbg_lnum - || (bp->dbg_lnum == 0 - && (best_lnum == 0 - || bpi->dbg_lnum < best_lnum)))) { - todel = i; - best_lnum = bpi->dbg_lnum; - } - } - xfree(bp->dbg_name); - } - - if (todel < 0) { - EMSG2(_("E161: Breakpoint not found: %s"), eap->arg); - } else { - while (!GA_EMPTY(gap)) { - xfree(DEBUGGY(gap, todel).dbg_name); - if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR - && DEBUGGY(gap, todel).dbg_val != NULL) { - tv_free(DEBUGGY(gap, todel).dbg_val); - } - vim_regfree(DEBUGGY(gap, todel).dbg_prog); - gap->ga_len--; - if (todel < gap->ga_len) { - memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1), - (size_t)(gap->ga_len - todel) * sizeof(struct debuggy)); - } - if (eap->cmdidx == CMD_breakdel) { - debug_tick++; - } - if (!del_all) { - break; - } - } - - // If all breakpoints were removed clear the array. - if (GA_EMPTY(gap)) { - ga_clear(gap); - } - } -} - -/// ":breaklist". -void ex_breaklist(exarg_T *eap) -{ - struct debuggy *bp; - - if (GA_EMPTY(&dbg_breakp)) { - MSG(_("No breakpoints defined")); - } else { - for (int i = 0; i < dbg_breakp.ga_len; i++) { - bp = &BREAKP(i); - if (bp->dbg_type == DBG_FILE) { - home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true); - } - if (bp->dbg_type != DBG_EXPR) { - smsg(_("%3d %s %s line %" PRId64), - bp->dbg_nr, - bp->dbg_type == DBG_FUNC ? "func" : "file", - bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff, - (int64_t)bp->dbg_lnum); - } else { - smsg(_("%3d expr %s"), bp->dbg_nr, bp->dbg_name); - } - } - } -} - -/// Find a breakpoint for a function or sourced file. -/// Returns line number at which to break; zero when no matching breakpoint. -linenr_T -dbg_find_breakpoint( - bool file, // true for a file, false for a function - char_u *fname, // file or function name - linenr_T after // after this line number -) -{ - return debuggy_find(file, fname, after, &dbg_breakp, NULL); -} - -/// @param file true for a file, false for a function -/// @param fname file or function name -/// @param fp[out] forceit -/// -/// @returns true if profiling is on for a function or sourced file. -bool has_profiling(bool file, char_u *fname, bool *fp) -{ - return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp) - != (linenr_T)0; -} - -/// Common code for dbg_find_breakpoint() and has_profiling(). -static linenr_T -debuggy_find( - bool file, // true for a file, false for a function - char_u *fname, // file or function name - linenr_T after, // after this line number - garray_T *gap, // either &dbg_breakp or &prof_ga - bool *fp // if not NULL: return forceit -) -{ - struct debuggy *bp; - linenr_T lnum = 0; - char_u *name = fname; - int prev_got_int; - - // Return quickly when there are no breakpoints. - if (GA_EMPTY(gap)) { - return (linenr_T)0; - } - - // Replace K_SNR in function name with "<SNR>". - if (!file && fname[0] == K_SPECIAL) { - name = xmalloc(STRLEN(fname) + 3); - STRCPY(name, "<SNR>"); - STRCPY(name + 5, fname + 3); - } - - for (int i = 0; i < gap->ga_len; i++) { - // Skip entries that are not useful or are for a line that is beyond - // an already found breakpoint. - bp = &DEBUGGY(gap, i); - if ((bp->dbg_type == DBG_FILE) == file - && bp->dbg_type != DBG_EXPR - && (gap == &prof_ga - || (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))) { - // Save the value of got_int and reset it. We don't want a - // previous interruption cancel matching, only hitting CTRL-C - // while matching should abort it. - prev_got_int = got_int; - got_int = false; - if (vim_regexec_prog(&bp->dbg_prog, false, name, (colnr_T)0)) { - lnum = bp->dbg_lnum; - if (fp != NULL) { - *fp = bp->dbg_forceit; - } - } - got_int |= prev_got_int; - } else if (bp->dbg_type == DBG_EXPR) { - bool line = false; - - prev_got_int = got_int; - got_int = false; - - typval_T *tv = eval_expr(bp->dbg_name); - if (tv != NULL) { - if (bp->dbg_val == NULL) { - debug_oldval = typval_tostring(NULL); - bp->dbg_val = tv; - debug_newval = typval_tostring(bp->dbg_val); - line = true; - } else { - if (typval_compare(tv, bp->dbg_val, EXPR_IS, false) == OK - && tv->vval.v_number == false) { - line = true; - debug_oldval = typval_tostring(bp->dbg_val); - // Need to evaluate again, typval_compare() overwrites "tv". - typval_T *v = eval_expr(bp->dbg_name); - debug_newval = typval_tostring(v); - tv_free(bp->dbg_val); - bp->dbg_val = v; - } - tv_free(tv); - } - } else if (bp->dbg_val != NULL) { - debug_oldval = typval_tostring(bp->dbg_val); - debug_newval = typval_tostring(NULL); - tv_free(bp->dbg_val); - bp->dbg_val = NULL; - line = true; - } - - if (line) { - lnum = after > 0 ? after : 1; - break; - } - - got_int |= prev_got_int; - } - } - if (name != fname) { - xfree(name); - } - - return lnum; -} - -/// Called when a breakpoint was encountered. -void dbg_breakpoint(char_u *name, linenr_T lnum) -{ - // We need to check if this line is actually executed in do_one_cmd() - debug_breakpoint_name = name; - debug_breakpoint_lnum = lnum; -} - static char_u *profile_fname = NULL; /// ":profile cmd args" @@ -2635,44 +1829,42 @@ static void cmd_source(char_u *fname, exarg_T *eap) } } -typedef struct { - linenr_T curr_lnum; - const linenr_T final_lnum; -} GetBufferLineCookie; - -/// Get one line from the current selection in the buffer. -/// Called by do_cmdline() when it's called from cmd_source_buffer(). +/// Concatenate VimL line if it starts with a line continuation into a growarray +/// (excluding the continuation chars and leading whitespace) /// -/// @return pointer to allocated line, or NULL for end-of-file or -/// some error. -static char_u *get_buffer_line(int c, void *cookie, int indent, bool do_concat) -{ - GetBufferLineCookie *p = cookie; - if (p->curr_lnum > p->final_lnum) { - return NULL; - } - char_u *curr_line = ml_get(p->curr_lnum); - p->curr_lnum++; - return (char_u *)xstrdup((const char *)curr_line); -} - -static void cmd_source_buffer(const exarg_T *eap) +/// @note Growsize of the growarray may be changed to speed up concatenations! +/// +/// @param ga the growarray to append to +/// @param init_growsize the starting growsize value of the growarray +/// @param p pointer to the beginning of the line to consider +/// @param len the length of this line +/// +/// @return true if this line did begin with a continuation (the next line +/// should also be considered, if it exists); false otherwise +static bool concat_continued_line(garray_T *const ga, const int init_growsize, + const char_u *const p, size_t len) FUNC_ATTR_NONNULL_ALL { - GetBufferLineCookie cookie = { - .curr_lnum = eap->line1, - .final_lnum = eap->line2, - }; - if (curbuf != NULL && curbuf->b_fname - && path_with_extension((const char *)curbuf->b_fname, "lua")) { - nlua_source_using_linegetter(get_buffer_line, (void *)&cookie, - ":source (no file)"); - } else { - source_using_linegetter((void *)&cookie, get_buffer_line, - ":source (no file)"); + const char_u *const line = skipwhite_len(p, len); + len -= (size_t)(line - p); + // Skip lines starting with '\" ', concat lines starting with '\' + if (len >= 3 && STRNCMP(line, "\"\\ ", 3) == 0) { + return true; + } else if (len == 0 || line[0] != '\\') { + return false; } + if (ga->ga_len > init_growsize) { + ga_set_growsize(ga, MAX(ga->ga_len, 8000)); + } + ga_concat_len(ga, (const char *)line + 1, len - 1); + return true; } +typedef struct { + linenr_T curr_lnum; + const linenr_T final_lnum; +} GetBufferLineCookie; + /// ":source" and associated commands. /// /// @return address holding the next breakpoint line for a source cookie @@ -2725,17 +1917,27 @@ typedef struct { static char_u *get_str_line(int c, void *cookie, int indent, bool do_concat) { GetStrLineCookie *p = cookie; - size_t i = p->offset; - if (strlen((char *)p->buf) <= p->offset) { + if (STRLEN(p->buf) <= p->offset) { return NULL; } - while (!(p->buf[i] == '\n' || p->buf[i] == '\0')) { - i++; + const char_u *line = p->buf + p->offset; + const char_u *eol = skip_to_newline(line); + garray_T ga; + ga_init(&ga, sizeof(char_u), 400); + ga_concat_len(&ga, (const char *)line, (size_t)(eol - line)); + if (do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL) { + while (eol[0] != NUL) { + line = eol + 1; + const char_u *const next_eol = skip_to_newline(line); + if (!concat_continued_line(&ga, 400, line, (size_t)(next_eol - line))) { + break; + } + eol = next_eol; + } } - size_t line_length = i - p->offset; - char_u *buf = xmemdupz(p->buf + p->offset, line_length); - p->offset = i + 1; - return buf; + ga_append(&ga, NUL); + p->offset = (size_t)(eol - p->buf) + 1; + return ga.ga_data; } static int source_using_linegetter(void *cookie, @@ -2770,6 +1972,40 @@ static int source_using_linegetter(void *cookie, return retval; } +static void cmd_source_buffer(const exarg_T *const eap) + FUNC_ATTR_NONNULL_ALL +{ + if (curbuf == NULL) { + return; + } + garray_T ga; + ga_init(&ga, sizeof(char_u), 400); + const linenr_T final_lnum = eap->line2; + // Copy the contents to be executed. + for (linenr_T curr_lnum = eap->line1; curr_lnum <= final_lnum; curr_lnum++) { + // Adjust growsize to current length to speed up concatenating many lines. + if (ga.ga_len > 400) { + ga_set_growsize(&ga, MAX(ga.ga_len, 8000)); + } + ga_concat(&ga, ml_get(curr_lnum)); + ga_append(&ga, NL); + } + ((char_u *)ga.ga_data)[ga.ga_len - 1] = NUL; + const GetStrLineCookie cookie = { + .buf = ga.ga_data, + .offset = 0, + }; + if (curbuf->b_fname + && path_with_extension((const char *)curbuf->b_fname, "lua")) { + nlua_source_using_linegetter(get_str_line, (void *)&cookie, + ":source (no file)"); + } else { + source_using_linegetter((void *)&cookie, get_str_line, + ":source (no file)"); + } + ga_clear(&ga); +} + /// Executes lines in `src` as Ex commands. /// /// @see do_source() @@ -3227,26 +2463,11 @@ char_u *getsourceline(int c, void *cookie, int indent, bool do_concat) ga_init(&ga, (int)sizeof(char_u), 400); ga_concat(&ga, line); - if (*p == '\\') { - ga_concat(&ga, p + 1); - } - for (;; ) { + while (sp->nextline != NULL + && concat_continued_line(&ga, 400, sp->nextline, + STRLEN(sp->nextline))) { xfree(sp->nextline); sp->nextline = get_one_sourceline(sp); - if (sp->nextline == NULL) { - break; - } - p = skipwhite(sp->nextline); - if (*p == '\\') { - // Adjust the growsize to the current length to speed up - // concatenating many lines. - if (ga.ga_len > 400) { - ga_set_growsize(&ga, (ga.ga_len > 8000) ? 8000 : ga.ga_len); - } - ga_concat(&ga, p + 1); - } else if (p[0] != '"' || p[1] != '\\' || p[2] != ' ') { - break; - } } ga_append(&ga, NUL); xfree(line); diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4078deb292..67b0c21fc5 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -15,6 +15,7 @@ #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/debugger.h" #include "nvim/diff.h" #include "nvim/digraph.h" #include "nvim/edit.h" @@ -80,14 +81,14 @@ static int quitmore = 0; static bool ex_pressedreturn = false; typedef struct ucmd { - char_u *uc_name; // The command name + char_u *uc_name; // The command name uint32_t uc_argt; // The argument type - char_u *uc_rep; // The command's replacement string + char_u *uc_rep; // The command's replacement string long uc_def; // The default value for a range/count int uc_compl; // completion type cmd_addr_T uc_addr_type; // The command's address type sctx_T uc_script_ctx; // SCTX where the command was defined - char_u *uc_compl_arg; // completion argument if any + char_u *uc_compl_arg; // completion argument if any } ucmd_T; #define UC_BUFFER 1 // -buffer: local to current buffer @@ -102,7 +103,7 @@ static garray_T ucmds = { 0, 0, sizeof(ucmd_T), 4, NULL }; // Struct for storing a line inside a while/for loop typedef struct { - char_u *line; // command line + char_u *line; // command line linenr_T lnum; // sourcing_lnum of the line } wcmd_T; @@ -114,12 +115,12 @@ typedef struct { * reads more lines that may come from the while/for loop. */ struct loop_cookie { - garray_T *lines_gap; // growarray with line info + garray_T *lines_gap; // growarray with line info int current_line; // last read line from growarray int repeating; // TRUE when looping a second time // When "repeating" is FALSE use "getline" and "cookie" to get lines - char_u *(*getline)(int, void *, int, bool); - void *cookie; + char_u *(*getline)(int, void *, int, bool); + void *cookie; }; @@ -127,14 +128,14 @@ struct loop_cookie { struct dbg_stuff { int trylevel; int force_abort; - except_T *caught_stack; - char_u *vv_exception; - char_u *vv_throwpoint; + except_T *caught_stack; + char_u *vv_exception; + char_u *vv_throwpoint; int did_emsg; int got_int; int need_rethrow; int check_cstack; - except_T *current_exception; + except_T *current_exception; }; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -309,8 +310,8 @@ int do_cmdline_cmd(const char *cmd) /// @return FAIL if cmdline could not be executed, OK otherwise int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) { - char_u *next_cmdline; // next cmd to execute - char_u *cmdline_copy = NULL; // copy of cmd line + char_u *next_cmdline; // next cmd to execute + char_u *cmdline_copy = NULL; // copy of cmd line bool used_getline = false; // used "fgetline" to obtain command static int recursive = 0; // recursive depth bool msg_didout_before_start = false; @@ -322,19 +323,19 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) }; garray_T lines_ga; // keep lines for ":while"/":for" int current_line = 0; // active line in lines_ga - char_u *fname = NULL; // function or script name + char_u *fname = NULL; // function or script name linenr_T *breakpoint = NULL; // ptr to breakpoint field in cookie - int *dbg_tick = NULL; // ptr to dbg_tick field in cookie + int *dbg_tick = NULL; // ptr to dbg_tick field in cookie struct dbg_stuff debug_saved; // saved things for debug mode int initial_trylevel; - struct msglist **saved_msg_list = NULL; - struct msglist *private_msg_list; + struct msglist **saved_msg_list = NULL; + struct msglist *private_msg_list; // "fgetline" and "cookie" passed to do_one_cmd() - char_u *(*cmd_getline)(int, void *, int, bool); - void *cmd_cookie; + char_u *(*cmd_getline)(int, void *, int, bool); + void *cmd_cookie; struct loop_cookie cmd_loop_cookie; - void *real_cookie; + void *real_cookie; int getline_is_func; static int call_depth = 0; // recursiveness @@ -964,9 +965,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, void *cookie, int flags) */ static char_u *get_loop_line(int c, void *cookie, int indent, bool do_concat) { - struct loop_cookie *cp = (struct loop_cookie *)cookie; - wcmd_T *wp; - char_u *line; + struct loop_cookie *cp = (struct loop_cookie *)cookie; + wcmd_T *wp; + char_u *line; if (cp->current_line + 1 >= cp->lines_gap->ga_len) { if (cp->repeating) { @@ -1251,16 +1252,16 @@ static char_u *skip_colon_white(const char_u *p, bool skipleadingwhite) static char_u * do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineGetter fgetline, void *cookie) { - char_u *p; + char_u *p; linenr_T lnum; long n; - char_u *errormsg = NULL; // error message - char_u *after_modifier = NULL; + char_u *errormsg = NULL; // error message + char_u *after_modifier = NULL; exarg_T ea; const int save_msg_scroll = msg_scroll; cmdmod_T save_cmdmod; const int save_reg_executing = reg_executing; - char_u *cmd; + char_u *cmd; memset(&ea, 0, sizeof(ea)); ea.line1 = 1; @@ -1456,7 +1457,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, int flags, cstack_T *cstack, LineG ++p; } p = vim_strnsave(ea.cmd, p - ea.cmd); - int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, TRUE, NULL); + int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, true, NULL); xfree(p); // If the autocommands did something and didn't cause an error, try // finding the command again. @@ -2578,7 +2579,7 @@ static char_u *find_command(exarg_T *eap, int *full) FUNC_ATTR_NONNULL_ARG(1) { int len; - char_u *p; + char_u *p; int i; /* @@ -2644,7 +2645,7 @@ static char_u *find_command(exarg_T *eap, int *full) const int c1 = eap->cmd[0]; const int c2 = len == 1 ? NUL : eap->cmd[1]; - if (command_count != (int)CMD_SIZE) { + if (command_count != CMD_SIZE) { iemsg((char *)_("E943: Command table needs to be updated, run 'make'")); getout(1); } @@ -2659,7 +2660,7 @@ static char_u *find_command(exarg_T *eap, int *full) eap->cmdidx = CMD_bang; } - for (; (int)eap->cmdidx < (int)CMD_SIZE; + for (; (int)eap->cmdidx < CMD_SIZE; eap->cmdidx = (cmdidx_T)((int)eap->cmdidx + 1)) { if (STRNCMP(cmdnames[(int)eap->cmdidx].cmd_name, (char *)eap->cmd, (size_t)len) == 0) { @@ -2701,13 +2702,13 @@ static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int * { int len = (int)(p - eap->cmd); int j, k, matchlen = 0; - ucmd_T *uc; - int found = FALSE; - int possible = FALSE; - char_u *cp, *np; // Point into typed cmd and test name - garray_T *gap; - int amb_local = FALSE; /* Found ambiguous buffer-local command, - only full match global is accepted. */ + ucmd_T *uc; + bool found = false; + bool possible = false; + char_u *cp, *np; // Point into typed cmd and test name + garray_T *gap; + bool amb_local = false; // Found ambiguous buffer-local command, + // only full match global is accepted. /* * Look for buffer-local user commands first, then global ones. @@ -2730,7 +2731,7 @@ static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int * if (gap == &ucmds) { return NULL; } - amb_local = TRUE; + amb_local = true; } if (!found || (k == len && *np == NUL)) { @@ -2739,9 +2740,9 @@ static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int * * should use instead. */ if (k == len) { - found = TRUE; + found = true; } else { - possible = TRUE; + possible = true; } if (gap == &ucmds) { @@ -2768,7 +2769,7 @@ static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int * if (full != NULL) { *full = TRUE; } - amb_local = FALSE; + amb_local = false; break; } } @@ -2799,7 +2800,7 @@ static char_u *find_ucmd(exarg_T *eap, char_u *p, int *full, expand_T *xp, int * } static struct cmdmod { - char *name; + char *name; int minlen; int has_count; // :123verbose :3tab } cmdmods[] = { @@ -2834,7 +2835,7 @@ static struct cmdmod { */ int modifier_len(char_u *cmd) { - char_u *p = cmd; + char_u *p = cmd; if (ascii_isdigit(*cmd)) { p = skipwhite(skipdigits(cmd + 1)); @@ -2863,13 +2864,13 @@ int modifier_len(char_u *cmd) int cmd_exists(const char *const name) { exarg_T ea; - char_u *p; + char_u *p; // Check command modifiers. for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) { int j; for (j = 0; name[j] != NUL; j++) { - if (name[j] != (char)cmdmods[i].name[j]) { + if (name[j] != cmdmods[i].name[j]) { break; } } @@ -2989,7 +2990,7 @@ const char * set_one_cmd_context(expand_T *xp, const char *buff) xp->xp_context = EXPAND_UNSUCCESSFUL; return NULL; } - for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < (int)CMD_SIZE; + for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < CMD_SIZE; ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1)) { if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd, len) == 0) { break; @@ -3851,9 +3852,9 @@ static linenr_T get_address(exarg_T *eap, char_u **ptr, cmd_addr_T addr_type, in int c; int i; long n; - char_u *cmd; + char_u *cmd; pos_T pos; - pos_T *fp; + pos_T *fp; linenr_T lnum; buf_T *buf; @@ -4296,7 +4297,7 @@ static void correct_range(exarg_T *eap) */ static char_u *skip_grep_pat(exarg_T *eap) { - char_u *p = eap->arg; + char_u *p = eap->arg; if (*p != NUL && (eap->cmdidx == CMD_vimgrep || eap->cmdidx == CMD_lvimgrep || eap->cmdidx == CMD_vimgrepadd @@ -4316,10 +4317,10 @@ static char_u *skip_grep_pat(exarg_T *eap) */ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep) { - char_u *new_cmdline; - char_u *program; - char_u *pos; - char_u *ptr; + char_u *new_cmdline; + char_u *program; + char_u *pos; + char_u *ptr; int len; int i; @@ -4387,9 +4388,9 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep) int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) { int has_wildcards; // need to expand wildcards - char_u *repl; + char_u *repl; size_t srclen; - char_u *p; + char_u *p; int escaped; // Skip a regexp pattern for ":vimgrep[add] pat file..." @@ -4459,7 +4460,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) && eap->cmdidx != CMD_make && eap->cmdidx != CMD_terminal && !(eap->argt & EX_NOSPC)) { - char_u *l; + char_u *l; #ifdef BACKSLASH_IN_FILENAME /* Don't escape a backslash here, because rem_backslash() doesn't * remove it later. */ @@ -4484,7 +4485,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) || eap->cmdidx == CMD_bang || eap->cmdidx == CMD_terminal) && vim_strpbrk(repl, (char_u *)"!") != NULL) { - char_u *l; + char_u *l; l = vim_strsave_escaped(repl, (char_u *)"!"); xfree(repl); @@ -4511,8 +4512,7 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp) */ if (vim_strchr(eap->arg, '$') != NULL || vim_strchr(eap->arg, '~') != NULL) { - expand_env_esc(eap->arg, NameBuff, MAXPATHL, - TRUE, TRUE, NULL); + expand_env_esc(eap->arg, NameBuff, MAXPATHL, true, true, NULL); has_wildcards = path_has_wildcard(NameBuff); p = NameBuff; } else { @@ -4610,7 +4610,7 @@ static char_u *repl_cmdline(exarg_T *eap, char_u *src, size_t srclen, char_u *re */ void separate_nextcmd(exarg_T *eap) { - char_u *p; + char_u *p; p = skip_grep_pat(eap); @@ -4727,10 +4727,10 @@ int get_bad_opt(const char_u *p, exarg_T *eap) */ static int getargopt(exarg_T *eap) { - char_u *arg = eap->arg + 2; - int *pp = NULL; + char_u *arg = eap->arg + 2; + int *pp = NULL; int bad_char_idx; - char_u *p; + char_u *p; // ":edit ++[no]bin[ary] file" if (STRNCMP(arg, "bin", 3) == 0 || STRNCMP(arg, "nobin", 5) == 0) { @@ -5144,7 +5144,7 @@ static int check_more(int message, bool forceit) */ char_u *get_command_name(expand_T *xp, int idx) { - if (idx >= (int)CMD_SIZE) { + if (idx >= CMD_SIZE) { return get_user_command_name(idx); } return cmdnames[idx].cmd_name; @@ -5154,11 +5154,11 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep, uint32_t a int flags, int compl, char_u *compl_arg, cmd_addr_T addr_type, bool force) FUNC_ATTR_NONNULL_ARG(1, 3) { - ucmd_T *cmd = NULL; + ucmd_T *cmd = NULL; int i; int cmp = 1; - char_u *rep_buf = NULL; - garray_T *gap; + char_u *rep_buf = NULL; + garray_T *gap; replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, true, CPO_TO_CPO_FLAGS); @@ -5325,7 +5325,7 @@ static void uc_list(char_u *name, size_t name_len) { int i, j; bool found = false; - ucmd_T *cmd; + ucmd_T *cmd; uint32_t a; // In cmdwin, the alternative buffer should be used. @@ -5489,7 +5489,7 @@ static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def, int int *complp, char_u **compl_arg, cmd_addr_T *addr_type_arg) FUNC_ATTR_NONNULL_ALL { - char_u *p; + char_u *p; if (len == 0) { EMSG(_("E175: No attribute specified")); @@ -5507,7 +5507,7 @@ static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def, int *argt |= EX_TRLBAR; } else { int i; - char_u *val = NULL; + char_u *val = NULL; size_t vallen = 0; size_t attrlen = len; @@ -5630,14 +5630,14 @@ static char e_complete_used_without_nargs[] = N_("E1208: -complete used without */ static void ex_command(exarg_T *eap) { - char_u *name; - char_u *end; - char_u *p; + char_u *name; + char_u *end; + char_u *p; uint32_t argt = 0; long def = -1; int flags = 0; int compl = EXPAND_NOTHING; - char_u *compl_arg = NULL; + char_u *compl_arg = NULL; cmd_addr_T addr_type_arg = ADDR_NONE; int has_attr = (eap->arg[0] == '-'); int name_len; @@ -5696,7 +5696,7 @@ void ex_comclear(exarg_T *eap) uc_clear(&curbuf->b_ucmds); } -static void free_ucmd(ucmd_T* cmd) { +static void free_ucmd(ucmd_T * cmd) { xfree(cmd->uc_name); xfree(cmd->uc_rep); xfree(cmd->uc_compl_arg); @@ -5713,9 +5713,9 @@ void uc_clear(garray_T *gap) static void ex_delcommand(exarg_T *eap) { int i = 0; - ucmd_T *cmd = NULL; + ucmd_T *cmd = NULL; int cmp = -1; - garray_T *gap; + garray_T *gap; gap = &curbuf->b_ucmds; for (;; ) { @@ -5854,7 +5854,7 @@ static size_t uc_check_code(char_u *code, size_t len, char_u *buf, ucmd_T *cmd, char_u **split_buf, size_t *split_len) { size_t result = 0; - char_u *p = code + 1; + char_u *p = code + 1; size_t l = len - 2; int quote = 0; enum { @@ -6132,18 +6132,18 @@ static size_t uc_check_code(char_u *code, size_t len, char_u *buf, ucmd_T *cmd, static void do_ucmd(exarg_T *eap) { - char_u *buf; - char_u *p; - char_u *q; + char_u *buf; + char_u *p; + char_u *q; - char_u *start; - char_u *end = NULL; - char_u *ksp; + char_u *start; + char_u *end = NULL; + char_u *ksp; size_t len, totlen; size_t split_len = 0; - char_u *split_buf = NULL; - ucmd_T *cmd; + char_u *split_buf = NULL; + ucmd_T *cmd; const sctx_T save_current_sctx = current_sctx; if (eap->cmdidx == CMD_USER) { @@ -6240,7 +6240,7 @@ static void do_ucmd(exarg_T *eap) static char_u *get_user_command_name(int idx) { - return get_user_commands(NULL, idx - (int)CMD_SIZE); + return get_user_commands(NULL, idx - CMD_SIZE); } /* * Function given to ExpandGeneric() to obtain the list of user address type names. @@ -6643,7 +6643,7 @@ static void ex_pclose(exarg_T *eap) void ex_win_close(int forceit, win_T *win, tabpage_T *tp) { int need_hide; - buf_T *buf = win->w_buffer; + buf_T *buf = win->w_buffer; // Never close the autocommand window. if (win == aucmd_win) { @@ -6682,7 +6682,7 @@ void ex_win_close(int forceit, win_T *win, tabpage_T *tp) */ static void ex_tabclose(exarg_T *eap) { - tabpage_T *tp; + tabpage_T *tp; if (cmdwin_type != 0) { cmdwin_result = K_IGNORE; @@ -6767,7 +6767,7 @@ void tabpage_close(int forceit) void tabpage_close_other(tabpage_T *tp, int forceit) { int done = 0; - win_T *wp; + win_T *wp; int h = tabline_height(); char_u prev_idx[NUMBUFLEN]; @@ -6993,11 +6993,11 @@ void alist_new(void) */ void alist_expand(int *fnum_list, int fnum_len) { - char_u **old_arg_files; + char_u **old_arg_files; int old_arg_count; - char_u **new_arg_files; + char_u **new_arg_files; int new_arg_file_count; - char_u *save_p_su = p_su; + char_u *save_p_su = p_su; int i; /* Don't use 'suffixes' here. This should work like the shell did the @@ -7159,8 +7159,8 @@ static void ex_wrongmodifier(exarg_T *eap) */ void ex_splitview(exarg_T *eap) { - win_T *old_curwin = curwin; - char_u *fname = NULL; + win_T *old_curwin = curwin; + char_u *fname = NULL; const bool use_tab = eap->cmdidx == CMD_tabedit || eap->cmdidx == CMD_tabfind || eap->cmdidx == CMD_tabnew; @@ -7192,7 +7192,7 @@ void ex_splitview(exarg_T *eap) if (win_new_tabpage(cmdmod.tab != 0 ? cmdmod.tab : eap->addr_count == 0 ? 0 : (int)eap->line2 + 1, eap->arg) != FAIL) { do_exedit(eap, old_curwin); - apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_TABNEWENTERED, NULL, NULL, false, curbuf); // set the alternate buffer for the window we came from if (curwin != old_curwin @@ -7332,8 +7332,7 @@ static void ex_tabs(exarg_T *eap) if (buf_spname(wp->w_buffer) != NULL) { STRLCPY(IObuff, buf_spname(wp->w_buffer), IOSIZE); } else { - home_replace(wp->w_buffer, wp->w_buffer->b_fname, - IObuff, IOSIZE, TRUE); + home_replace(wp->w_buffer, wp->w_buffer->b_fname, IObuff, IOSIZE, true); } msg_outtrans(IObuff); ui_flush(); // output one line at a time @@ -7364,7 +7363,7 @@ static void ex_mode(exarg_T *eap) static void ex_resize(exarg_T *eap) { int n; - win_T *wp = curwin; + win_T *wp = curwin; if (eap->addr_count > 0) { n = eap->line2; @@ -7396,7 +7395,7 @@ static void ex_resize(exarg_T *eap) */ static void ex_find(exarg_T *eap) { - char_u *fname; + char_u *fname; int count; fname = find_file_in_path(eap->arg, STRLEN(eap->arg), @@ -7579,8 +7578,8 @@ static void ex_swapname(exarg_T *eap) */ static void ex_syncbind(exarg_T *eap) { - win_T *save_curwin = curwin; - buf_T *save_curbuf = curbuf; + win_T *save_curwin = curwin; + buf_T *save_curbuf = curbuf; long topline; long y; linenr_T old_linenr = curwin->w_cursor.lnum; @@ -7696,7 +7695,7 @@ static void ex_read(exarg_T *eap) } } -static char_u *prev_dir = NULL; +static char_u *prev_dir = NULL; #if defined(EXITFREE) void free_cd_dir(void) @@ -7756,8 +7755,8 @@ void post_chdir(CdScope scope, bool trigger_dirchanged) /// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`. void ex_cd(exarg_T *eap) { - char_u *new_dir; - char_u *tofree; + char_u *new_dir; + char_u *tofree; new_dir = eap->arg; #if !defined(UNIX) @@ -7895,7 +7894,7 @@ void do_sleep(long msec) static void do_exmap(exarg_T *eap, int isabbrev) { int mode; - char_u *cmdp; + char_u *cmdp; cmdp = eap->cmd; mode = get_map_mode(&cmdp, eap->forceit || isabbrev); @@ -7936,7 +7935,7 @@ static void ex_winsize(exarg_T *eap) static void ex_wincmd(exarg_T *eap) { int xchar = NUL; - char_u *p; + char_u *p; if (*eap->arg == 'g' || *eap->arg == Ctrl_G) { // CTRL-W g and CTRL-W CTRL-G have an extra command character @@ -8190,7 +8189,7 @@ static void ex_later(exarg_T *eap) long count = 0; bool sec = false; bool file = false; - char_u *p = eap->arg; + char_u *p = eap->arg; if (*p == NUL) { count = 1; @@ -8223,9 +8222,9 @@ static void ex_later(exarg_T *eap) */ static void ex_redir(exarg_T *eap) { - char *mode; - char_u *fname; - char_u *arg = eap->arg; + char *mode; + char_u *fname; + char_u *arg = eap->arg; if (STRICMP(eap->arg, "END") == 0) { close_redir(); @@ -8416,7 +8415,7 @@ int vim_mkdir_emsg(const char *const name, const int prot) /// @return file descriptor, or NULL on failure. FILE *open_exfile(char_u *fname, int forceit, char *mode) { - FILE *fd; + FILE *fd; #ifdef UNIX // with Unix it is possible to open a directory @@ -8535,9 +8534,9 @@ static void ex_normal(exarg_T *eap) return; } save_state_T save_state; - char_u *arg = NULL; + char_u *arg = NULL; int l; - char_u *p; + char_u *p; if (ex_normal_lock > 0) { EMSG(_(e_secure)); @@ -8689,7 +8688,7 @@ void exec_normal(bool was_typed) static void ex_checkpath(exarg_T *eap) { - find_pattern_in_path(NULL, 0, 0, FALSE, FALSE, CHECK_PATH, 1L, + find_pattern_in_path(NULL, 0, 0, false, false, CHECK_PATH, 1L, eap->forceit ? ACTION_SHOW_ALL : ACTION_SHOW, (linenr_T)1, (linenr_T)MAXLNUM); } @@ -8706,9 +8705,9 @@ static void ex_psearch(exarg_T *eap) static void ex_findpat(exarg_T *eap) { - int whole = TRUE; + bool whole = true; long n; - char_u *p; + char_u *p; int action; switch (cmdnames[eap->cmdidx].cmd_name[2]) { @@ -8773,7 +8772,7 @@ static void ex_ptag(exarg_T *eap) */ static void ex_pedit(exarg_T *eap) { - win_T *curwin_save = curwin; + win_T *curwin_save = curwin; // Open the preview window or popup and make it the current window. g_do_tagpreview = p_pvh; @@ -8944,14 +8943,14 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum char_u **errormsg, int *escaped) { int i; - char_u *s; - char_u *result; - char_u *resultbuf = NULL; + char_u *s; + char_u *result; + char_u *resultbuf = NULL; size_t resultlen; - buf_T *buf; + buf_T *buf; int valid = VALID_HEAD | VALID_PATH; // Assume valid result. bool tilde_file = false; - int skip_mod = false; + bool skip_mod = false; char strbuf[30]; *errormsg = NULL; @@ -9021,7 +9020,7 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum if (escaped != NULL) { *escaped = TRUE; } - skip_mod = TRUE; + skip_mod = true; break; } s = src + 1; @@ -9201,8 +9200,8 @@ static char_u *arg_all(void) { int len; int idx; - char_u *retval = NULL; - char_u *p; + char_u *retval = NULL; + char_u *p; /* * Do this loop two times: @@ -9262,13 +9261,13 @@ static char_u *arg_all(void) */ char_u *expand_sfile(char_u *arg) { - char_u *errormsg; + char_u *errormsg; size_t len; - char_u *result; - char_u *newres; - char_u *repl; + char_u *result; + char_u *newres; + char_u *repl; size_t srclen; - char_u *p; + char_u *p; result = vim_strsave(arg); @@ -9310,7 +9309,7 @@ char_u *expand_sfile(char_u *arg) */ static void ex_shada(exarg_T *eap) { - char_u *save_shada; + char_u *save_shada; save_shada = p_shada; if (*p_shada == NUL) { @@ -9404,7 +9403,7 @@ static TriState filetype_indent = kNone; */ static void ex_filetype(exarg_T *eap) { - char_u *arg = eap->arg; + char_u *arg = eap->arg; bool plugin = false; bool indent = false; diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index 1ceccac2bb..54776c35e7 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -13,6 +13,7 @@ #include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/debugger.h" #include "nvim/ex_eval.h" #include "nvim/charset.h" #include "nvim/eval.h" diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 0f98c9cd34..b90773ce83 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -6056,7 +6056,7 @@ int get_list_range(char_u **str, int *num1, int *num2) *str = skipwhite(*str); if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range - vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0); + vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false); *str += len; *num1 = (int)num; first = true; @@ -6064,7 +6064,7 @@ int get_list_range(char_u **str, int *num1, int *num2) *str = skipwhite(*str); if (**str == ',') { // parse "to" part of range *str = skipwhite(*str + 1); - vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0); + vim_str2nr(*str, NULL, &len, 0, &num, NULL, 0, false); if (len > 0) { *num2 = (int)num; *str = skipwhite(*str + len); diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 92b48c36cb..870c6ca2b1 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -5,15 +5,13 @@ #include <assert.h> #include <errno.h> +#include <fcntl.h> +#include <inttypes.h> #include <stdbool.h> #include <string.h> -#include <inttypes.h> -#include <fcntl.h> -#include "nvim/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/ascii.h" -#include "nvim/fileio.h" #include "nvim/buffer.h" #include "nvim/buffer_updates.h" #include "nvim/change.h" @@ -25,8 +23,10 @@ #include "nvim/ex_cmds.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" +#include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/func_attr.h" +#include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/hashtab.h" #include "nvim/iconv.h" @@ -36,10 +36,13 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/garray.h" #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/os_defs.h" +#include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/quickfix.h" @@ -47,21 +50,18 @@ #include "nvim/screen.h" #include "nvim/search.h" #include "nvim/sha256.h" +#include "nvim/shada.h" #include "nvim/state.h" #include "nvim/strings.h" +#include "nvim/types.h" #include "nvim/ui.h" #include "nvim/ui_compositor.h" -#include "nvim/types.h" #include "nvim/undo.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/shada.h" -#include "nvim/os/os.h" -#include "nvim/os/os_defs.h" -#include "nvim/os/time.h" -#include "nvim/os/input.h" -#define BUFSIZE 8192 /* size of normal write buffer */ -#define SMBUFSIZE 256 /* size of emergency write buffer */ +#define BUFSIZE 8192 // size of normal write buffer +#define SMBUFSIZE 256 // size of emergency write buffer // For compatibility with libuv < 1.20.0 (tested on 1.18.0) #ifndef UV_FS_COPYFILE_FICLONE @@ -69,15 +69,15 @@ #endif #define HAS_BW_FLAGS -#define FIO_LATIN1 0x01 /* convert Latin1 */ -#define FIO_UTF8 0x02 /* convert UTF-8 */ -#define FIO_UCS2 0x04 /* convert UCS-2 */ -#define FIO_UCS4 0x08 /* convert UCS-4 */ -#define FIO_UTF16 0x10 /* convert UTF-16 */ -#define FIO_ENDIAN_L 0x80 /* little endian */ -#define FIO_NOCONVERT 0x2000 /* skip encoding conversion */ -#define FIO_UCSBOM 0x4000 /* check for BOM at start of file */ -#define FIO_ALL -1 /* allow all formats */ +#define FIO_LATIN1 0x01 // convert Latin1 +#define FIO_UTF8 0x02 // convert UTF-8 +#define FIO_UCS2 0x04 // convert UCS-2 +#define FIO_UCS4 0x08 // convert UCS-4 +#define FIO_UTF16 0x10 // convert UTF-16 +#define FIO_ENDIAN_L 0x80 // little endian +#define FIO_NOCONVERT 0x2000 // skip encoding conversion +#define FIO_UCSBOM 0x4000 // check for BOM at start of file +#define FIO_ALL -1 // allow all formats /* When converting, a read() or write() may leave some bytes to be converted * for the next call. The value is guessed... */ @@ -92,7 +92,7 @@ */ struct bw_info { int bw_fd; // file descriptor - char_u *bw_buf; // buffer with data to be written + char_u *bw_buf; // buffer with data to be written int bw_len; // length of data #ifdef HAS_BW_FLAGS int bw_flags; // FIO_ flags @@ -100,7 +100,7 @@ struct bw_info { char_u bw_rest[CONV_RESTLEN]; // not converted bytes int bw_restlen; // nr of bytes in bw_rest[] int bw_first; // first write call - char_u *bw_conv_buf; // buffer for writing converted chars + char_u *bw_conv_buf; // buffer for writing converted chars int bw_conv_buflen; // size of bw_conv_buf int bw_conv_error; // set for conversion error linenr_T bw_conv_error_lnum; // first line with error or zero @@ -114,8 +114,7 @@ struct bw_info { # include "fileio.c.generated.h" #endif -static char *e_auchangedbuf = N_( - "E812: Autocommands changed buffer or buffer name"); +static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name"); void filemess(buf_T *buf, char_u *name, char_u *s, int attr) { @@ -131,56 +130,50 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr) // For further ones overwrite the previous one, reset msg_scroll before // calling filemess(). msg_scroll_save = msg_scroll; - if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) + if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0) { msg_scroll = FALSE; - if (!msg_scroll) /* wait a bit when overwriting an error msg */ - check_for_delay(FALSE); + } + if (!msg_scroll) { // wait a bit when overwriting an error msg + check_for_delay(false); + } msg_start(); msg_scroll = msg_scroll_save; - msg_scrolled_ign = TRUE; - /* may truncate the message to avoid a hit-return prompt */ + msg_scrolled_ign = true; + // may truncate the message to avoid a hit-return prompt msg_outtrans_attr(msg_may_trunc(FALSE, IObuff), attr); msg_clr_eos(); ui_flush(); - msg_scrolled_ign = FALSE; + msg_scrolled_ign = false; } -/* - * Read lines from file "fname" into the buffer after line "from". - * - * 1. We allocate blocks with try_malloc, as big as possible. - * 2. Each block is filled with characters from the file with a single read(). - * 3. The lines are inserted in the buffer with ml_append(). - * - * (caller must check that fname != NULL, unless READ_STDIN is used) - * - * "lines_to_skip" is the number of lines that must be skipped - * "lines_to_read" is the number of lines that are appended - * When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM. - * - * flags: - * READ_NEW starting to edit a new buffer - * READ_FILTER reading filter output - * READ_STDIN read from stdin instead of a file - * READ_BUFFER read from curbuf instead of a file (converting after reading - * stdin) - * READ_DUMMY read into a dummy buffer (to check if file contents changed) - * READ_KEEP_UNDO don't clear undo info or read it from a file - * READ_FIFO read from fifo/socket instead of a file - * - * return FAIL for failure, NOTDONE for directory (failure), or OK - */ -int -readfile( - char_u *fname, - char_u *sfname, - linenr_T from, - linenr_T lines_to_skip, - linenr_T lines_to_read, - exarg_T *eap, // can be NULL! - int flags -) +/// Read lines from file "fname" into the buffer after line "from". +/// +/// 1. We allocate blocks with try_malloc, as big as possible. +/// 2. Each block is filled with characters from the file with a single read(). +/// 3. The lines are inserted in the buffer with ml_append(). +/// +/// (caller must check that fname != NULL, unless READ_STDIN is used) +/// +/// "lines_to_skip" is the number of lines that must be skipped +/// "lines_to_read" is the number of lines that are appended +/// When not recovering lines_to_skip is 0 and lines_to_read MAXLNUM. +/// +/// flags: +/// READ_NEW starting to edit a new buffer +/// READ_FILTER reading filter output +/// READ_STDIN read from stdin instead of a file +/// READ_BUFFER read from curbuf instead of a file (converting after reading +/// stdin) +/// READ_DUMMY read into a dummy buffer (to check if file contents changed) +/// READ_KEEP_UNDO don't clear undo info or read it from a file +/// READ_FIFO read from fifo/socket instead of a file +/// +/// @param eap can be NULL! +/// +/// @return FAIL for failure, NOTDONE for directory (failure), or OK +int readfile(char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip, + linenr_T lines_to_read, exarg_T *eap, int flags) { int fd = 0; int newfile = (flags & READ_NEW); @@ -191,35 +184,34 @@ readfile( int read_fifo = (flags & READ_FIFO); int set_options = newfile || read_buffer || (eap != NULL && eap->read_edit); - linenr_T read_buf_lnum = 1; /* next line to read from curbuf */ - colnr_T read_buf_col = 0; /* next char to read from this line */ + linenr_T read_buf_lnum = 1; // next line to read from curbuf + colnr_T read_buf_col = 0; // next char to read from this line char_u c; linenr_T lnum = from; - char_u *ptr = NULL; /* pointer into read buffer */ - char_u *buffer = NULL; /* read buffer */ - char_u *new_buffer = NULL; /* init to shut up gcc */ - char_u *line_start = NULL; /* init to shut up gcc */ - int wasempty; /* buffer was empty before reading */ + char_u *ptr = NULL; // pointer into read buffer + char_u *buffer = NULL; // read buffer + char_u *new_buffer = NULL; // init to shut up gcc + char_u *line_start = NULL; // init to shut up gcc + int wasempty; // buffer was empty before reading colnr_T len; long size = 0; uint8_t *p = NULL; off_T filesize = 0; - int skip_read = false; + bool skip_read = false; context_sha256_T sha_ctx; int read_undo_file = false; int split = 0; // number of split lines linenr_T linecnt; - int error = FALSE; /* errors encountered */ - int ff_error = EOL_UNKNOWN; /* file format with errors */ - long linerest = 0; /* remaining chars in line */ + bool error = false; // errors encountered + int ff_error = EOL_UNKNOWN; // file format with errors + long linerest = 0; // remaining chars in line int perm = 0; #ifdef UNIX - int swap_mode = -1; /* protection bits for swap file */ + int swap_mode = -1; // protection bits for swap file #endif int fileformat = 0; // end-of-line format bool keep_fileformat = false; FileInfo file_info; - int file_readonly; linenr_T skip_count = 0; linenr_T read_count = 0; int msg_save = msg_scroll; @@ -234,33 +226,32 @@ readfile( int bad_char_behavior = BAD_REPLACE; /* BAD_KEEP, BAD_DROP or character to * replace with */ - char_u *tmpname = NULL; /* name of 'charconvert' output file */ + char_u *tmpname = NULL; // name of 'charconvert' output file int fio_flags = 0; - char_u *fenc; // fileencoding to use + char_u *fenc; // fileencoding to use bool fenc_alloced; // fenc_next is in allocated memory - char_u *fenc_next = NULL; // next item in 'fencs' or NULL + char_u *fenc_next = NULL; // next item in 'fencs' or NULL bool advance_fenc = false; long real_size = 0; # ifdef HAVE_ICONV iconv_t iconv_fd = (iconv_t)-1; // descriptor for iconv() or -1 - int did_iconv = false; // TRUE when iconv() failed and trying + bool did_iconv = false; // true when iconv() failed and trying // 'charconvert' next # endif - int converted = FALSE; /* TRUE if conversion done */ - int notconverted = FALSE; /* TRUE if conversion wanted but it - wasn't possible */ + bool converted = false; // true if conversion done + bool notconverted = false; // true if conversion wanted but it wasn't possible char_u conv_rest[CONV_RESTLEN]; - int conv_restlen = 0; /* nr of bytes in conv_rest[] */ - buf_T *old_curbuf; - char_u *old_b_ffname; - char_u *old_b_fname; + int conv_restlen = 0; // nr of bytes in conv_rest[] + buf_T *old_curbuf; + char_u *old_b_ffname; + char_u *old_b_fname; int using_b_ffname; int using_b_fname; static char *msg_is_a_directory = N_("is a directory"); au_did_filetype = false; // reset before triggering any autocommands - curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */ + curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read /* * If there is no file name yet, use the one for the read file. @@ -273,8 +264,9 @@ readfile( && fname != NULL && vim_strchr(p_cpo, CPO_FNAMER) != NULL && !(flags & READ_DUMMY)) { - if (set_rw_fname(fname, sfname) == FAIL) + if (set_rw_fname(fname, sfname) == FAIL) { return FAIL; + } } /* Remember the initial values of curbuf, curbuf->b_ffname and @@ -315,7 +307,7 @@ readfile( pos = curbuf->b_op_start; - /* Set '[ mark to the line above where the lines go (line 1 if zero). */ + // Set '[ mark to the line above where the lines go (line 1 if zero). curbuf->b_op_start.lnum = ((from == 0) ? 1 : from); curbuf->b_op_start.col = 0; @@ -346,11 +338,11 @@ readfile( curbuf->b_op_start = pos; } - if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) - msg_scroll = FALSE; /* overwrite previous file message */ - else - msg_scroll = TRUE; /* don't overwrite previous file message */ - + if ((shortmess(SHM_OVER) || curbuf->b_help) && p_verbose == 0) { + msg_scroll = FALSE; // overwrite previous file message + } else { + msg_scroll = TRUE; // don't overwrite previous file message + } // If the name is too long we might crash further on, quit here. if (fname != NULL && *fname != NUL) { size_t namelen = STRLEN(fname); @@ -397,7 +389,7 @@ readfile( } } - /* Set default or forced 'fileformat' and 'binary'. */ + // Set default or forced 'fileformat' and 'binary'. set_file_options(set_options, eap); /* @@ -407,8 +399,9 @@ readfile( * Only set/reset b_p_ro when BF_CHECK_RO is set. */ check_readonly = (newfile && (curbuf->b_flags & BF_CHECK_RO)); - if (check_readonly && !readonlymode) + if (check_readonly && !readonlymode) { curbuf->b_p_ro = FALSE; + } if (newfile && !read_stdin && !read_buffer && !read_fifo) { // Remember time of file. @@ -442,7 +435,7 @@ readfile( } // Check readonly. - file_readonly = false; + bool file_readonly = false; if (!read_buffer && !read_stdin) { if (!newfile || readonlymode || !(perm & 0222) || !os_file_is_writable((char *)fname)) { @@ -466,7 +459,7 @@ readfile( * "nofile" or "nowrite" buffer type. */ if (!bt_dontwrite(curbuf)) { check_need_swap(newfile); - /* SwapExists autocommand may mess things up */ + // SwapExists autocommand may mess things up if (curbuf != old_curbuf || (using_b_ffname && (old_b_ffname != curbuf->b_ffname)) @@ -493,19 +486,20 @@ readfile( // remember the current fileformat save_file_ff(curbuf); - if (aborting()) /* autocmds may abort script processing */ + if (aborting()) { // autocmds may abort script processing return FAIL; - return OK; /* a new file is not an error */ + } + return OK; // a new file is not an error } else { filemess(curbuf, sfname, (char_u *)( - (fd == UV_EFBIG) ? _("[File too big]") : + (fd == UV_EFBIG) ? _("[File too big]") : # if defined(UNIX) && defined(EOVERFLOW) - // libuv only returns -errno in Unix and in Windows open() does not - // set EOVERFLOW - (fd == -EOVERFLOW) ? _("[File too big]") : + // libuv only returns -errno in Unix and in Windows open() does not + // set EOVERFLOW + (fd == -EOVERFLOW) ? _("[File too big]") : # endif - _("[Permission Denied]")), 0); - curbuf->b_p_ro = TRUE; /* must use "w!" now */ + _("[Permission Denied]")), 0); + curbuf->b_p_ro = TRUE; // must use "w!" now } return FAIL; @@ -513,10 +507,11 @@ readfile( /* * Only set the 'ro' flag for readonly files the first time they are - * loaded. Help files always get readonly mode + * loaded. Help files always get readonly mode */ - if ((check_readonly && file_readonly) || curbuf->b_help) + if ((check_readonly && file_readonly) || curbuf->b_help) { curbuf->b_p_ro = TRUE; + } if (set_options) { /* Don't change 'eol' if reading from buffer as it will already be @@ -573,12 +568,13 @@ readfile( // If "Quit" selected at ATTENTION dialog, don't load the file. if (swap_exists_action == SEA_QUIT) { - if (!read_buffer && !read_stdin) + if (!read_buffer && !read_stdin) { close(fd); + } return FAIL; } - ++no_wait_return; /* don't wait for return yet */ + ++no_wait_return; // don't wait for return yet /* * Set '[ mark to the line above where the lines go (line 1 if zero). @@ -627,10 +623,10 @@ readfile( msg_scroll = m; } - if (aborting()) { /* autocmds may abort script processing */ + if (aborting()) { // autocmds may abort script processing --no_wait_return; msg_scroll = msg_save; - curbuf->b_p_ro = TRUE; /* must use "w!" now */ + curbuf->b_p_ro = TRUE; // must use "w!" now return FAIL; } /* @@ -646,16 +642,17 @@ readfile( || (fd = os_open((char *)fname, O_RDONLY, 0)) < 0)) { --no_wait_return; msg_scroll = msg_save; - if (fd < 0) + if (fd < 0) { EMSG(_("E200: *ReadPre autocommands made the file unreadable")); - else + } else { EMSG(_("E201: *ReadPre autocommands must not change current buffer")); - curbuf->b_p_ro = TRUE; /* must use "w!" now */ + } + curbuf->b_p_ro = TRUE; // must use "w!" now return FAIL; } } - /* Autocommands may add lines to the file, need to check if it is empty */ + // Autocommands may add lines to the file, need to check if it is empty wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY); if (!recoverymode && !filtering && !(flags & READ_DUMMY)) { @@ -664,7 +661,7 @@ readfile( } } - msg_scroll = FALSE; /* overwrite the file message */ + msg_scroll = FALSE; // overwrite the file message /* * Set linecnt now, before the "retry" caused by a wrong guess for @@ -672,13 +669,15 @@ readfile( */ linecnt = curbuf->b_ml.ml_line_count; - /* "++bad=" argument. */ + // "++bad=" argument. if (eap != NULL && eap->bad_char != 0) { bad_char_behavior = eap->bad_char; - if (set_options) + if (set_options) { curbuf->b_bad_char = eap->bad_char; - } else + } + } else { curbuf->b_bad_char = 0; + } /* * Decide which 'encoding' to use or use first. @@ -715,16 +714,16 @@ readfile( * - "fileformat" check failed: try another * * Variables set for special retry actions: - * "file_rewind" Rewind the file to start reading it again. - * "advance_fenc" Advance "fenc" using "fenc_next". - * "skip_read" Re-use already read bytes (BOM detected). - * "did_iconv" iconv() conversion failed, try 'charconvert'. + * "file_rewind" Rewind the file to start reading it again. + * "advance_fenc" Advance "fenc" using "fenc_next". + * "skip_read" Re-use already read bytes (BOM detected). + * "did_iconv" iconv() conversion failed, try 'charconvert'. * "keep_fileformat" Don't reset "fileformat". * * Other status indicators: - * "tmpname" When != NULL did conversion with 'charconvert'. - * Output file has to be deleted afterwards. - * "iconv_fd" When != -1 did conversion with iconv(). + * "tmpname" When != NULL did conversion with 'charconvert'. + * Output file has to be deleted afterwards. + * "iconv_fd" When != -1 did conversion with iconv(). */ retry: @@ -759,17 +758,19 @@ retry: if (eap != NULL && eap->force_ff != 0) { fileformat = get_fileformat_force(curbuf, eap); try_unix = try_dos = try_mac = FALSE; - } else if (curbuf->b_p_bin) - fileformat = EOL_UNIX; /* binary: use Unix format */ - else if (*p_ffs == NUL) - fileformat = get_fileformat(curbuf); /* use format from buffer */ - else - fileformat = EOL_UNKNOWN; /* detect from file */ + } else if (curbuf->b_p_bin) { + fileformat = EOL_UNIX; // binary: use Unix format + } else if (*p_ffs == + NUL) { + fileformat = get_fileformat(curbuf); // use format from buffer + } else { + fileformat = EOL_UNKNOWN; // detect from file + } } # ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { - /* aborted conversion with iconv(), close the descriptor */ + // aborted conversion with iconv(), close the descriptor iconv_close(iconv_fd); iconv_fd = (iconv_t)-1; } @@ -782,17 +783,19 @@ retry: advance_fenc = false; if (eap != NULL && eap->force_enc != 0) { - /* Conversion given with "++cc=" wasn't possible, read - * without conversion. */ - notconverted = TRUE; + // Conversion given with "++cc=" wasn't possible, read + // without conversion. + notconverted = true; conv_error = 0; - if (fenc_alloced) + if (fenc_alloced) { xfree(fenc); + } fenc = (char_u *)""; fenc_alloced = false; } else { - if (fenc_alloced) + if (fenc_alloced) { xfree(fenc); + } if (fenc_next != NULL) { fenc = next_fenc(&fenc_next, &fenc_alloced); } else { @@ -813,7 +816,6 @@ retry: fio_flags = 0; converted = need_conversion(fenc); if (converted) { - /* "ucs-bom" means we need to check the first bytes of the file * for a BOM. */ if (STRCMP(fenc, ENC_UCSBOM) == 0) { @@ -834,8 +836,7 @@ retry: # ifdef HAVE_ICONV // Try using iconv() if we can't convert internally. if (fio_flags == 0 - && !did_iconv - ) { + && !did_iconv) { iconv_fd = (iconv_t)my_iconv_open((char_u *)"utf-8", fenc); } # endif @@ -861,9 +862,9 @@ retry: // Conversion failed. Try another one. advance_fenc = true; if (fd < 0) { - /* Re-opening the original file failed! */ + // Re-opening the original file failed! EMSG(_("E202: Conversion made file unreadable!")); - error = TRUE; + error = true; goto failed; } goto retry; @@ -901,8 +902,9 @@ retry: && !read_fifo && !read_stdin && !read_buffer); - if (read_undo_file) + if (read_undo_file) { sha256_start(&sha_ctx); + } } while (!error && !got_int) { @@ -936,11 +938,12 @@ retry: } } if (new_buffer == NULL) { - error = TRUE; + error = true; break; } - if (linerest) /* copy characters from the previous buffer */ + if (linerest) { // copy characters from the previous buffer memmove(new_buffer, ptr - linerest, (size_t)linerest); + } xfree(buffer); buffer = new_buffer; ptr = buffer + linerest; @@ -972,7 +975,7 @@ retry: size = size / ICONV_MULT; // worst case } # ifdef HAVE_ICONV - } + } # endif if (conv_restlen > 0) { // Insert unconverted bytes from previous line. @@ -986,9 +989,9 @@ retry: * Read bytes from curbuf. Used for converting text read * from stdin. */ - if (read_buf_lnum > from) + if (read_buf_lnum > from) { size = 0; - else { + } else { int n, ni; long tlen; @@ -1002,10 +1005,11 @@ retry: * below. */ n = (int)(size - tlen); for (ni = 0; ni < n; ++ni) { - if (p[ni] == NL) + if (p[ni] == NL) { ptr[tlen++] = NUL; - else + } else { ptr[tlen++] = p[ni]; + } } read_buf_col += n; break; @@ -1013,18 +1017,20 @@ retry: /* Append whole line and new-line. Change NL * to NUL to reverse the effect done below. */ for (ni = 0; ni < n; ++ni) { - if (p[ni] == NL) + if (p[ni] == NL) { ptr[tlen++] = NUL; - else + } else { ptr[tlen++] = p[ni]; + } } ptr[tlen++] = NL; read_buf_col = 0; if (++read_buf_lnum > from) { /* When the last line didn't have an * end-of-line don't add it now either. */ - if (!curbuf->b_p_eol) + if (!curbuf->b_p_eol) { --tlen; + } size = tlen; break; } @@ -1039,30 +1045,33 @@ retry: } if (size <= 0) { - if (size < 0) /* read error */ - error = TRUE; - else if (conv_restlen > 0) { + if (size < 0) { // read error + error = true; + } else if (conv_restlen > 0) { /* * Reached end-of-file but some trailing bytes could * not be converted. Truncated file? */ - /* When we did a conversion report an error. */ + // When we did a conversion report an error. if (fio_flags != 0 # ifdef HAVE_ICONV || iconv_fd != (iconv_t)-1 # endif ) { - if (can_retry) + if (can_retry) { goto rewind_retry; - if (conv_error == 0) + } + if (conv_error == 0) { conv_error = curbuf->b_ml.ml_line_count - linecnt + 1; + } } - /* Remember the first linenr with an illegal byte */ - else if (illegal_byte == 0) + // Remember the first linenr with an illegal byte + else if (illegal_byte == 0) { illegal_byte = curbuf->b_ml.ml_line_count - linecnt + 1; + } if (bad_char_behavior == BAD_DROP) { *(ptr - conv_restlen) = NUL; conv_restlen = 0; @@ -1093,7 +1102,7 @@ retry: } } - skip_read = FALSE; + skip_read = false; /* * At start of file: Check for BOM. @@ -1106,17 +1115,18 @@ retry: || (!curbuf->b_p_bomb && tmpname == NULL && (*fenc == 'u' || *fenc == NUL)))) { - char_u *ccname; + char_u *ccname; int blen; - /* no BOM detection in a short file or in binary mode */ - if (size < 2 || curbuf->b_p_bin) + // no BOM detection in a short file or in binary mode + if (size < 2 || curbuf->b_p_bin) { ccname = NULL; - else + } else { ccname = check_for_bom(ptr, size, &blen, - fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc)); + fio_flags == FIO_UCSBOM ? FIO_ALL : get_fio_flags(fenc)); + } if (ccname != NULL) { - /* Remove BOM from the text */ + // Remove BOM from the text filesize += blen; size -= blen; memmove(ptr, ptr + blen, (size_t)size); @@ -1131,27 +1141,29 @@ retry: // No BOM detected: retry with next encoding. advance_fenc = true; } else { - /* BOM detected: set "fenc" and jump back */ - if (fenc_alloced) + // BOM detected: set "fenc" and jump back + if (fenc_alloced) { xfree(fenc); + } fenc = ccname; fenc_alloced = false; } - /* retry reading without getting new bytes or rewinding */ - skip_read = TRUE; + // retry reading without getting new bytes or rewinding + skip_read = true; goto retry; } } - /* Include not converted bytes. */ + // Include not converted bytes. ptr -= conv_restlen; size += conv_restlen; conv_restlen = 0; /* * Break here for a read error or end-of-file. */ - if (size <= 0) + if (size <= 0) { break; + } # ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { @@ -1159,8 +1171,8 @@ retry: * Attempt conversion of the read bytes to 'encoding' using * iconv(). */ - const char *fromp; - char *top; + const char *fromp; + char *top; size_t from_size; size_t to_size; @@ -1176,16 +1188,18 @@ retry: * alternative (help files). */ while ((iconv(iconv_fd, (void *)&fromp, &from_size, - &top, &to_size) + &top, &to_size) == (size_t)-1 && ICONV_ERRNO != ICONV_EINVAL) || from_size > CONV_RESTLEN) { - if (can_retry) + if (can_retry) { goto rewind_retry; - if (conv_error == 0) + } + if (conv_error == 0) { conv_error = readfile_linenr(linecnt, - ptr, (char_u *)top); + ptr, (char_u *)top); + } - /* Deal with a bad byte and continue with the next. */ + // Deal with a bad byte and continue with the next. ++fromp; --from_size; if (bad_char_behavior == BAD_KEEP) { @@ -1204,17 +1218,17 @@ retry: conv_restlen = (int)from_size; } - /* move the linerest to before the converted characters */ + // move the linerest to before the converted characters line_start = ptr - linerest; memmove(line_start, buffer, (size_t)linerest); - size = (long)((char_u *)top - ptr); + size = ((char_u *)top - ptr); } # endif if (fio_flags != 0) { unsigned int u8c; - char_u *dest; - char_u *tail = NULL; + char_u *dest; + char_u *tail = NULL; // Convert Unicode or Latin1 to UTF-8. // Go from end to start through the buffer, because the number @@ -1225,22 +1239,25 @@ retry: if (fio_flags == FIO_LATIN1 || fio_flags == FIO_UTF8) { p = ptr + size; if (fio_flags == FIO_UTF8) { - /* Check for a trailing incomplete UTF-8 sequence */ + // Check for a trailing incomplete UTF-8 sequence tail = ptr + size - 1; - while (tail > ptr && (*tail & 0xc0) == 0x80) + while (tail > ptr && (*tail & 0xc0) == 0x80) { --tail; - if (tail + utf_byte2len(*tail) <= ptr + size) + } + if (tail + utf_byte2len(*tail) <= ptr + size) { tail = NULL; - else + } else { p = tail; + } } } else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) { - /* Check for a trailing byte */ + // Check for a trailing byte p = ptr + (size & ~1); - if (size & 1) + if (size & 1) { tail = p; + } if ((fio_flags & FIO_UTF16) && p > ptr) { - /* Check for a trailing leading word */ + // Check for a trailing leading word if (fio_flags & FIO_ENDIAN_L) { u8c = (*--p << 8); u8c += *--p; @@ -1248,16 +1265,18 @@ retry: u8c = *--p; u8c += (*--p << 8); } - if (u8c >= 0xd800 && u8c <= 0xdbff) + if (u8c >= 0xd800 && u8c <= 0xdbff) { tail = p; - else + } else { p += 2; + } } - } else { /* FIO_UCS4 */ - /* Check for trailing 1, 2 or 3 bytes */ + } else { // FIO_UCS4 + // Check for trailing 1, 2 or 3 bytes p = ptr + (size & ~3); - if (size & 3) + if (size & 3) { tail = p; + } } /* If there is a trailing incomplete sequence move it to @@ -1270,9 +1289,9 @@ retry: while (p > ptr) { - if (fio_flags & FIO_LATIN1) + if (fio_flags & FIO_LATIN1) { u8c = *--p; - else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) { + } else if (fio_flags & (FIO_UCS2 | FIO_UTF16)) { if (fio_flags & FIO_ENDIAN_L) { u8c = (*--p << 8); u8c += *--p; @@ -1285,16 +1304,20 @@ retry: int u16c; if (p == ptr) { - /* Missing leading word. */ - if (can_retry) + // Missing leading word. + if (can_retry) { goto rewind_retry; - if (conv_error == 0) + } + if (conv_error == 0) { conv_error = readfile_linenr(linecnt, - ptr, p); - if (bad_char_behavior == BAD_DROP) + ptr, p); + } + if (bad_char_behavior == BAD_DROP) { continue; - if (bad_char_behavior != BAD_KEEP) + } + if (bad_char_behavior != BAD_KEEP) { u8c = bad_char_behavior; + } } /* found second word of double-word, get the first @@ -1309,17 +1332,21 @@ retry: u8c = 0x10000 + ((u16c & 0x3ff) << 10) + (u8c & 0x3ff); - /* Check if the word is indeed a leading word. */ + // Check if the word is indeed a leading word. if (u16c < 0xd800 || u16c > 0xdbff) { - if (can_retry) + if (can_retry) { goto rewind_retry; - if (conv_error == 0) + } + if (conv_error == 0) { conv_error = readfile_linenr(linecnt, - ptr, p); - if (bad_char_behavior == BAD_DROP) + ptr, p); + } + if (bad_char_behavior == BAD_DROP) { continue; - if (bad_char_behavior != BAD_KEEP) + } + if (bad_char_behavior != BAD_KEEP) { u8c = bad_char_behavior; + } } } } else if (fio_flags & FIO_UCS4) { @@ -1328,16 +1355,16 @@ retry: u8c += (unsigned)(*--p) << 16; u8c += (unsigned)(*--p) << 8; u8c += *--p; - } else { /* big endian */ + } else { // big endian u8c = *--p; u8c += (unsigned)(*--p) << 8; u8c += (unsigned)(*--p) << 16; u8c += (unsigned)(*--p) << 24; } - } else { /* UTF-8 */ - if (*--p < 0x80) + } else { // UTF-8 + if (*--p < 0x80) { u8c = *p; - else { + } else { len = utf_head_off(ptr, p); p -= len; u8c = utf_ptr2char(p); @@ -1345,15 +1372,19 @@ retry: /* Not a valid UTF-8 character, retry with * another fenc when possible, otherwise just * report the error. */ - if (can_retry) + if (can_retry) { goto rewind_retry; - if (conv_error == 0) + } + if (conv_error == 0) { conv_error = readfile_linenr(linecnt, - ptr, p); - if (bad_char_behavior == BAD_DROP) + ptr, p); + } + if (bad_char_behavior == BAD_DROP) { continue; - if (bad_char_behavior != BAD_KEEP) + } + if (bad_char_behavior != BAD_KEEP) { u8c = bad_char_behavior; + } } } } @@ -1366,7 +1397,7 @@ retry: // move the linerest to before the converted characters line_start = dest - linerest; memmove(line_start, buffer, (size_t)linerest); - size = (long)((ptr + real_size) - dest); + size = ((ptr + real_size) - dest); ptr = dest; } else if (!curbuf->b_p_bin) { bool incomplete_tail = false; @@ -1407,31 +1438,35 @@ retry: /* Illegal byte. If we can try another encoding * do that, unless at EOF where a truncated * file is more likely than a conversion error. */ - if (can_retry && !incomplete_tail) + if (can_retry && !incomplete_tail) { break; + } # ifdef HAVE_ICONV // When we did a conversion report an error. if (iconv_fd != (iconv_t)-1 && conv_error == 0) { conv_error = readfile_linenr(linecnt, ptr, p); } # endif - /* Remember the first linenr with an illegal byte */ - if (conv_error == 0 && illegal_byte == 0) + // Remember the first linenr with an illegal byte + if (conv_error == 0 && illegal_byte == 0) { illegal_byte = readfile_linenr(linecnt, ptr, p); + } - /* Drop, keep or replace the bad byte. */ + // Drop, keep or replace the bad byte. if (bad_char_behavior == BAD_DROP) { memmove(p, p + 1, todo - 1); --p; --size; - } else if (bad_char_behavior != BAD_KEEP) + } else if (bad_char_behavior != BAD_KEEP) { *p = bad_char_behavior; - } else + } + } else { p += l - 1; + } } } if (p < ptr + size && !incomplete_tail) { - /* Detected a UTF-8 error. */ + // Detected a UTF-8 error. rewind_retry: // Retry reading with another conversion. # ifdef HAVE_ICONV @@ -1443,21 +1478,21 @@ rewind_retry: // use next item from 'fileencodings' advance_fenc = true; # ifdef HAVE_ICONV - } + } # endif file_rewind = true; goto retry; } } - /* count the number of characters (after conversion!) */ + // count the number of characters (after conversion!) filesize += size; /* * when reading the first part of a file: guess EOL type */ if (fileformat == EOL_UNKNOWN) { - /* First try finding a NL, for Dos and Unix */ + // First try finding a NL, for Dos and Unix if (try_dos || try_unix) { // Reset the carriage return counter. if (try_mac) { @@ -1467,32 +1502,36 @@ rewind_retry: for (p = ptr; p < ptr + size; ++p) { if (*p == NL) { if (!try_unix - || (try_dos && p > ptr && p[-1] == CAR)) + || (try_dos && p > ptr && p[-1] == CAR)) { fileformat = EOL_DOS; - else + } else { fileformat = EOL_UNIX; + } break; } else if (*p == CAR && try_mac) { try_mac++; } } - /* Don't give in to EOL_UNIX if EOL_MAC is more likely */ + // Don't give in to EOL_UNIX if EOL_MAC is more likely if (fileformat == EOL_UNIX && try_mac) { - /* Need to reset the counters when retrying fenc. */ + // Need to reset the counters when retrying fenc. try_mac = 1; try_unix = 1; - for (; p >= ptr && *p != CAR; p--) + for (; p >= ptr && *p != CAR; p--) { ; + } if (p >= ptr) { for (p = ptr; p < ptr + size; ++p) { - if (*p == NL) + if (*p == NL) { try_unix++; - else if (*p == CAR) + } else if (*p == CAR) { try_mac++; + } } - if (try_mac > try_unix) + if (try_mac > try_unix) { fileformat = EOL_MAC; + } } } else if (fileformat == EOL_UNKNOWN && try_mac == 1) { // Looking for CR but found no end-of-line markers at all: @@ -1501,13 +1540,15 @@ rewind_retry: } } - /* No NL found: may use Mac format */ - if (fileformat == EOL_UNKNOWN && try_mac) + // No NL found: may use Mac format + if (fileformat == EOL_UNKNOWN && try_mac) { fileformat = EOL_MAC; + } - /* Still nothing found? Use first format in 'ffs' */ - if (fileformat == EOL_UNKNOWN) + // Still nothing found? Use first format in 'ffs' + if (fileformat == EOL_UNKNOWN) { fileformat = default_fileformat(); + } // May set 'p_ff' if editing a new file. if (set_options) { @@ -1523,44 +1564,48 @@ rewind_retry: if (fileformat == EOL_MAC) { --ptr; while (++ptr, --size >= 0) { - /* catch most common case first */ - if ((c = *ptr) != NUL && c != CAR && c != NL) + // catch most common case first + if ((c = *ptr) != NUL && c != CAR && c != NL) { continue; - if (c == NUL) - *ptr = NL; /* NULs are replaced by newlines! */ - else if (c == NL) - *ptr = CAR; /* NLs are replaced by CRs! */ - else { + } + if (c == NUL) { + *ptr = NL; // NULs are replaced by newlines! + } else if (c == NL) { + *ptr = CAR; // NLs are replaced by CRs! + } else { if (skip_count == 0) { - *ptr = NUL; /* end of line */ - len = (colnr_T) (ptr - line_start + 1); + *ptr = NUL; // end of line + len = (colnr_T)(ptr - line_start + 1); if (ml_append(lnum, line_start, len, newfile) == FAIL) { - error = TRUE; + error = true; break; } - if (read_undo_file) + if (read_undo_file) { sha256_update(&sha_ctx, line_start, len); + } ++lnum; if (--read_count == 0) { - error = TRUE; /* break loop */ - line_start = ptr; /* nothing left to write */ + error = true; // break loop + line_start = ptr; // nothing left to write break; } - } else + } else { --skip_count; + } line_start = ptr + 1; } } } else { --ptr; while (++ptr, --size >= 0) { - if ((c = *ptr) != NUL && c != NL) /* catch most common case */ + if ((c = *ptr) != NUL && c != NL) { // catch most common case continue; - if (c == NUL) - *ptr = NL; /* NULs are replaced by newlines! */ - else { + } + if (c == NUL) { + *ptr = NL; // NULs are replaced by newlines! + } else { if (skip_count == 0) { - *ptr = NUL; /* end of line */ + *ptr = NUL; // end of line len = (colnr_T)(ptr - line_start + 1); if (fileformat == EOL_DOS) { if (ptr > line_start && ptr[-1] == CAR) { @@ -1577,8 +1622,9 @@ rewind_retry: && (read_buffer || vim_lseek(fd, (off_T)0L, SEEK_SET) == 0)) { fileformat = EOL_UNIX; - if (set_options) + if (set_options) { set_fileformat(EOL_UNIX, OPT_LOCAL); + } file_rewind = true; keep_fileformat = true; goto retry; @@ -1587,31 +1633,34 @@ rewind_retry: } } if (ml_append(lnum, line_start, len, newfile) == FAIL) { - error = TRUE; + error = true; break; } - if (read_undo_file) + if (read_undo_file) { sha256_update(&sha_ctx, line_start, len); + } ++lnum; if (--read_count == 0) { - error = TRUE; /* break loop */ - line_start = ptr; /* nothing left to write */ + error = true; // break loop + line_start = ptr; // nothing left to write break; } - } else + } else { --skip_count; + } line_start = ptr + 1; } } } - linerest = (long)(ptr - line_start); + linerest = (ptr - line_start); os_breakcheck(); } failed: - /* not an error, max. number of lines reached */ - if (error && read_count == 0) - error = FALSE; + // not an error, max. number of lines reached + if (error && read_count == 0) { + error = false; + } /* * If we get EOF in the middle of a line, note the fact and @@ -1625,16 +1674,18 @@ failed: && fileformat == EOL_DOS && *line_start == Ctrl_Z && ptr == line_start + 1)) { - /* remember for when writing */ - if (set_options) + // remember for when writing + if (set_options) { curbuf->b_p_eol = FALSE; + } *ptr = NUL; len = (colnr_T)(ptr - line_start + 1); - if (ml_append(lnum, line_start, len, newfile) == FAIL) - error = TRUE; - else { - if (read_undo_file) + if (ml_append(lnum, line_start, len, newfile) == FAIL) { + error = true; + } else { + if (read_undo_file) { sha256_update(&sha_ctx, line_start, len); + } read_no_eol_lnum = ++lnum; } } @@ -1646,8 +1697,9 @@ failed: // Also for ":read ++edit file". set_string_option_direct("fenc", -1, fenc, OPT_FREE | OPT_LOCAL, 0); } - if (fenc_alloced) + if (fenc_alloced) { xfree(fenc); + } # ifdef HAVE_ICONV if (iconv_fd != (iconv_t)-1) { iconv_close(iconv_fd); @@ -1679,13 +1731,13 @@ failed: os_remove((char *)tmpname); // delete converted file xfree(tmpname); } - --no_wait_return; /* may wait for return now */ + --no_wait_return; // may wait for return now /* * In recovery mode everything but autocommands is skipped. */ if (!recoverymode) { - /* need to delete the last line, which comes from the empty buffer */ + // need to delete the last line, which comes from the empty buffer if (newfile && wasempty && !(curbuf->b_ml.ml_flags & ML_EMPTY)) { ml_delete(curbuf->b_ml.ml_line_count, false); linecnt--; @@ -1695,8 +1747,9 @@ failed: curbuf->deleted_codepoints = 0; curbuf->deleted_codeunits = 0; linecnt = curbuf->b_ml.ml_line_count - linecnt; - if (filesize == 0) + if (filesize == 0) { linecnt = 0; + } if (newfile || read_buffer) { redraw_curbuf_later(NOT_VALID); /* After reading the text into the buffer the diff info needs to @@ -1705,8 +1758,9 @@ failed: /* All folds in the window are invalid now. Mark them for update * before triggering autocommands. */ foldUpdateAll(curwin); - } else if (linecnt) /* appended at least one line */ + } else if (linecnt) { // appended at least one line appended_lines_mark(from, linecnt); + } /* * If we were reading from the same terminal as where messages go, @@ -1720,12 +1774,13 @@ failed: if (got_int) { if (!(flags & READ_DUMMY)) { filemess(curbuf, sfname, (char_u *)_(e_interr), 0); - if (newfile) - curbuf->b_p_ro = TRUE; /* must use "w!" now */ + if (newfile) { + curbuf->b_p_ro = TRUE; // must use "w!" now + } } msg_scroll = msg_save; check_marks_read(); - return OK; /* an interrupt isn't really an error */ + return OK; // an interrupt isn't really an error } if (!filtering && !(flags & READ_DUMMY)) { @@ -1742,7 +1797,7 @@ failed: c = TRUE; } # ifdef OPEN_CHR_FILES - if (S_ISCHR(perm)) { /* or character special */ + if (S_ISCHR(perm)) { // or character special STRCAT(IObuff, _("[character special]")); c = TRUE; } @@ -1773,24 +1828,25 @@ failed: } if (conv_error != 0) { sprintf((char *)IObuff + STRLEN(IObuff), - _("[CONVERSION ERROR in line %" PRId64 "]"), (int64_t)conv_error); + _("[CONVERSION ERROR in line %" PRId64 "]"), (int64_t)conv_error); c = TRUE; } else if (illegal_byte > 0) { sprintf((char *)IObuff + STRLEN(IObuff), - _("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte); + _("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte); c = TRUE; - } else if (error) { + } else if (error) { STRCAT(IObuff, _("[READ ERRORS]")); c = TRUE; } - if (msg_add_fileformat(fileformat)) + if (msg_add_fileformat(fileformat)) { c = TRUE; + } msg_add_lines(c, (long)linecnt, filesize); XFREE_CLEAR(keep_msg); p = NULL; - msg_scrolled_ign = TRUE; + msg_scrolled_ign = true; if (!read_stdin && !read_buffer) { p = msg_trunc_attr(IObuff, FALSE, 0); @@ -1805,28 +1861,30 @@ failed: // - When the screen was scrolled but there is no wait-return prompt. set_keep_msg(p, 0); } - msg_scrolled_ign = FALSE; + msg_scrolled_ign = false; } - /* with errors writing the file requires ":w!" */ + // with errors writing the file requires ":w!" if (newfile && (error || conv_error != 0 || (illegal_byte > 0 && bad_char_behavior != BAD_KEEP) - )) + )) { curbuf->b_p_ro = TRUE; + } - u_clearline(); /* cannot use "U" command after adding lines */ + u_clearline(); // cannot use "U" command after adding lines /* * In Ex mode: cursor at last new line. * Otherwise: cursor at first new line. */ - if (exmode_active) + if (exmode_active) { curwin->w_cursor.lnum = from + linecnt; - else + } else { curwin->w_cursor.lnum = from + 1; + } check_cursor_lnum(); - beginline(BL_WHITE | BL_FIX); /* on first non-blank */ + beginline(BL_WHITE | BL_FIX); // on first non-blank /* * Set '[ and '] marks to the newly read lines. @@ -1835,7 +1893,6 @@ failed: curbuf->b_op_start.col = 0; curbuf->b_op_end.lnum = from + linecnt; curbuf->b_op_end.col = 0; - } msg_scroll = msg_save; @@ -1854,8 +1911,9 @@ failed: /* When reloading a buffer put the cursor at the first line that is * different. */ - if (flags & READ_KEEP_UNDO) + if (flags & READ_KEEP_UNDO) { u_find_first_changed(); + } /* * When opening a new file locate undo info and read it. @@ -1873,8 +1931,9 @@ failed: /* Save the fileformat now, otherwise the buffer will be considered * modified if the format/encoding was automatically detected. */ - if (set_options) + if (set_options) { save_file_ff(curbuf); + } /* * The output from the autocommands should not overwrite anything and @@ -1906,8 +1965,9 @@ failed: } } - if (recoverymode && error) + if (recoverymode && error) { return FAIL; + } return OK; } @@ -1930,25 +1990,24 @@ bool is_dev_fd_file(char_u *fname) #endif -/* - * From the current line count and characters read after that, estimate the - * line number where we are now. - * Used for error messages that include a line number. - */ -static linenr_T -readfile_linenr( - linenr_T linecnt, // line count before reading more bytes - char_u *p, // start of more bytes read - char_u *endp // end of more bytes read -) +/// From the current line count and characters read after that, estimate the +/// line number where we are now. +/// Used for error messages that include a line number. +/// +/// @param linecnt line count before reading more bytes +/// @param p start of more bytes read +/// @param endp end of more bytes read +static linenr_T readfile_linenr(linenr_T linecnt, char_u *p, char_u *endp) { - char_u *s; + char_u *s; linenr_T lnum; lnum = curbuf->b_ml.ml_line_count - linecnt + 1; - for (s = p; s < endp; ++s) - if (*s == '\n') + for (s = p; s < endp; ++s) { + if (*s == '\n') { ++lnum; + } + } return lnum; } @@ -1977,15 +2036,16 @@ void prep_exarg(exarg_T *eap, const buf_T *buf) */ void set_file_options(int set_options, exarg_T *eap) { - /* set default 'fileformat' */ + // set default 'fileformat' if (set_options) { - if (eap != NULL && eap->force_ff != 0) + if (eap != NULL && eap->force_ff != 0) { set_fileformat(get_fileformat_force(curbuf, eap), OPT_LOCAL); - else if (*p_ffs != NUL) + } else if (*p_ffs != NUL) { set_fileformat(default_fileformat(), OPT_LOCAL); + } } - /* set or reset 'binary' */ + // set or reset 'binary' if (eap != NULL && eap->force_bin != 0) { int oldval = curbuf->b_p_bin; @@ -2015,8 +2075,8 @@ void set_forced_fenc(exarg_T *eap) static char_u *next_fenc(char_u **pp, bool *alloced) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { - char_u *p; - char_u *r; + char_u *p; + char_u *r; *alloced = false; if (**pp == NUL) { @@ -2038,29 +2098,26 @@ static char_u *next_fenc(char_u **pp, bool *alloced) return r; } -/* - * Convert a file with the 'charconvert' expression. - * This closes the file which is to be read, converts it and opens the - * resulting file for reading. - * Returns name of the resulting converted file (the caller should delete it - * after reading it). - * Returns NULL if the conversion failed ("*fdp" is not set) . - */ -static char_u * -readfile_charconvert ( - char_u *fname, /* name of input file */ - char_u *fenc, /* converted from */ - int *fdp /* in/out: file descriptor of file */ -) +/// Convert a file with the 'charconvert' expression. +/// This closes the file which is to be read, converts it and opens the +/// resulting file for reading. +/// +/// @param fname name of input file +/// @param fenc converted from +/// @param fdp in/out: file descriptor of file +/// +/// @return name of the resulting converted file (the caller should delete it after reading it). +/// Returns NULL if the conversion failed ("*fdp" is not set) . +static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp) { - char_u *tmpname; - char_u *errmsg = NULL; + char_u *tmpname; + char_u *errmsg = NULL; tmpname = vim_tempname(); - if (tmpname == NULL) + if (tmpname == NULL) { errmsg = (char_u *)_("Can't find temp file for conversion"); - else { - close(*fdp); /* close the input file, ignore errors */ + } else { + close(*fdp); // close the input file, ignore errors *fdp = -1; if (eval_charconvert((char *)fenc, "utf-8", (char *)fname, (char *)tmpname) == FAIL) { @@ -2081,7 +2138,7 @@ readfile_charconvert ( } } - /* If the input file is closed, open it (caller should check for error). */ + // If the input file is closed, open it (caller should check for error). if (*fdp < 0) { *fdp = os_open((char *)fname, O_RDONLY, 0); } @@ -2111,45 +2168,35 @@ char *new_file_message(void) return shortmess(SHM_NEW) ? _("[New]") : _("[New File]"); } -/* - * buf_write() - write to file "fname" lines "start" through "end" - * - * We do our own buffering here because fwrite() is so slow. - * - * If "forceit" is true, we don't care for errors when attempting backups. - * In case of an error everything possible is done to restore the original - * file. But when "forceit" is TRUE, we risk losing it. - * - * When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and - * "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed. - * - * This function must NOT use NameBuff (because it's called by autowrite()). - * - * return FAIL for failure, OK otherwise - */ -int -buf_write( - buf_T *buf, - char_u *fname, - char_u *sfname, - linenr_T start, - linenr_T end, - exarg_T *eap, /* for forced 'ff' and 'fenc', can be - NULL! */ - int append, /* append to the file */ - int forceit, - int reset_changed, - int filtering -) +/// buf_write() - write to file "fname" lines "start" through "end" +/// +/// We do our own buffering here because fwrite() is so slow. +/// +/// If "forceit" is true, we don't care for errors when attempting backups. +/// In case of an error everything possible is done to restore the original +/// file. But when "forceit" is TRUE, we risk losing it. +/// +/// When "reset_changed" is TRUE and "append" == FALSE and "start" == 1 and +/// "end" == curbuf->b_ml.ml_line_count, reset curbuf->b_changed. +/// +/// This function must NOT use NameBuff (because it's called by autowrite()). +/// +/// +/// @param eap for forced 'ff' and 'fenc', can be NULL! +/// @param append append to the file +/// +/// @return FAIL for failure, OK otherwise +int buf_write(buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, + int append, int forceit, int reset_changed, int filtering) { int fd; - char_u *backup = NULL; - int backup_copy = FALSE; /* copy the original file? */ + char_u *backup = NULL; + int backup_copy = FALSE; // copy the original file? int dobackup; - char_u *ffname; - char_u *wfname = NULL; /* name of file to write to */ - char_u *s; - char_u *ptr; + char_u *ffname; + char_u *wfname = NULL; // name of file to write to + char_u *s; + char_u *ptr; char_u c; int len; linenr_T lnum; @@ -2164,9 +2211,9 @@ buf_write( char *errmsg = NULL; int errmsgarg = 0; bool errmsg_allocated = false; - char_u *buffer; + char_u *buffer; char_u smallbuf[SMBUFSIZE]; - char_u *backup_ext; + char_u *backup_ext; int bufsize; long perm; // file permissions int retval = OK; @@ -2178,21 +2225,21 @@ buf_write( int prev_got_int = got_int; int checking_conversion; bool file_readonly = false; // overwritten file is read-only - static char *err_readonly = + static char *err_readonly = "is read-only (cannot override: \"W\" in 'cpoptions')"; #if defined(UNIX) - int made_writable = FALSE; /* 'w' bit has been set */ + int made_writable = FALSE; // 'w' bit has been set #endif - /* writing everything */ + // writing everything int whole = (start == 1 && end == buf->b_ml.ml_line_count); linenr_T old_line_count = buf->b_ml.ml_line_count; int fileformat; int write_bin; - struct bw_info write_info; /* info for buf_write_bytes() */ + struct bw_info write_info; // info for buf_write_bytes() int converted = FALSE; int notconverted = FALSE; - char_u *fenc; /* effective 'fileencoding' */ - char_u *fenc_tofree = NULL; /* allocated "fenc" */ + char_u *fenc; // effective 'fileencoding' + char_u *fenc_tofree = NULL; // allocated "fenc" #ifdef HAS_BW_FLAGS int wb_flags = 0; #endif @@ -2204,8 +2251,9 @@ buf_write( context_sha256_T sha_ctx; unsigned int bkc = get_bkc_value(buf); - if (fname == NULL || *fname == NUL) /* safety check */ + if (fname == NULL || *fname == NUL) { // safety check return FAIL; + } if (buf->b_ml.ml_mfp == NULL) { /* This can happen during startup when there is a stray "w" in the * vimrc file. */ @@ -2217,16 +2265,17 @@ buf_write( * Disallow writing from .exrc and .vimrc in current directory for * security reasons. */ - if (check_secure()) + if (check_secure()) { return FAIL; + } - /* Avoid a crash for a long name. */ + // Avoid a crash for a long name. if (STRLEN(fname) >= MAXPATHL) { EMSG(_(e_longname)); return FAIL; } - /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */ + // must init bw_conv_buf and bw_iconv_fd before jumping to "fail" write_info.bw_conv_buf = NULL; write_info.bw_conv_error = FALSE; write_info.bw_conv_error_lnum = 0; @@ -2254,13 +2303,15 @@ buf_write( && !filtering && (!append || vim_strchr(p_cpo, CPO_FNAMEAPP) != NULL) && vim_strchr(p_cpo, CPO_FNAMEW) != NULL) { - if (set_rw_fname(fname, sfname) == FAIL) + if (set_rw_fname(fname, sfname) == FAIL) { return FAIL; - buf = curbuf; /* just in case autocmds made "buf" invalid */ + } + buf = curbuf; // just in case autocmds made "buf" invalid } - if (sfname == NULL) + if (sfname == NULL) { sfname = fname; + } // For Unix: Use the short file name whenever possible. // Avoids problems with networks and when directory names are changed. @@ -2271,12 +2322,13 @@ buf_write( fname = sfname; #endif - if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0) + if (buf->b_ffname != NULL && fnamecmp(ffname, buf->b_ffname) == 0) { overwriting = TRUE; - else + } else { overwriting = FALSE; + } - ++no_wait_return; /* don't wait for return yet */ + ++no_wait_return; // don't wait for return yet /* * Set '[ and '] marks to the lines to be written. @@ -2302,14 +2354,18 @@ buf_write( * Set curbuf to the buffer to be written. * Careful: The autocommands may call buf_write() recursively! */ - if (ffname == buf->b_ffname) + if (ffname == buf->b_ffname) { buf_ffname = TRUE; - if (sfname == buf->b_sfname) + } + if (sfname == buf->b_sfname) { buf_sfname = TRUE; - if (fname == buf->b_ffname) + } + if (fname == buf->b_ffname) { buf_fname_f = TRUE; - if (fname == buf->b_sfname) + } + if (fname == buf->b_sfname) { buf_fname_s = TRUE; + } // Set curwin/curbuf to buf and save a few things. aucmd_prepbuf(&aco, buf); @@ -2317,21 +2373,22 @@ buf_write( if (append) { if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD, - sfname, sfname, FALSE, curbuf, eap))) { - if (overwriting && bt_nofile(curbuf)) + sfname, sfname, FALSE, curbuf, eap))) { + if (overwriting && bt_nofile(curbuf)) { nofile_err = TRUE; - else + } else { apply_autocmds_exarg(EVENT_FILEAPPENDPRE, - sfname, sfname, FALSE, curbuf, eap); + sfname, sfname, FALSE, curbuf, eap); + } } } else if (filtering) { apply_autocmds_exarg(EVENT_FILTERWRITEPRE, - NULL, sfname, FALSE, curbuf, eap); - } else if (reset_changed && whole) { + NULL, sfname, FALSE, curbuf, eap); + } else if (reset_changed && whole) { int was_changed = curbufIsChanged(); did_cmd = apply_autocmds_exarg(EVENT_BUFWRITECMD, - sfname, sfname, FALSE, curbuf, eap); + sfname, sfname, FALSE, curbuf, eap); if (did_cmd) { if (was_changed && !curbufIsChanged()) { /* Written everything correctly and BufWriteCmd has reset @@ -2341,24 +2398,26 @@ buf_write( u_update_save_nr(curbuf); } } else { - if (overwriting && bt_nofile(curbuf)) + if (overwriting && bt_nofile(curbuf)) { nofile_err = TRUE; - else + } else { apply_autocmds_exarg(EVENT_BUFWRITEPRE, - sfname, sfname, FALSE, curbuf, eap); + sfname, sfname, FALSE, curbuf, eap); + } } } else { if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEWRITECMD, - sfname, sfname, FALSE, curbuf, eap))) { - if (overwriting && bt_nofile(curbuf)) + sfname, sfname, FALSE, curbuf, eap))) { + if (overwriting && bt_nofile(curbuf)) { nofile_err = TRUE; - else + } else { apply_autocmds_exarg(EVENT_FILEWRITEPRE, - sfname, sfname, FALSE, curbuf, eap); + sfname, sfname, FALSE, curbuf, eap); + } } } - /* restore curwin/curbuf and a few other things */ + // restore curwin/curbuf and a few other things aucmd_restbuf(&aco); // In three situations we return here and don't write the file: @@ -2370,41 +2429,45 @@ buf_write( } if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline) || did_cmd || nofile_err - || aborting() - ) { + || aborting()) { --no_wait_return; msg_scroll = msg_save; - if (nofile_err) + if (nofile_err) { EMSG(_("E676: No matching autocommands for acwrite buffer")); + } if (nofile_err - || aborting() - ) + || aborting()) { /* An aborting error, interrupt or exception in the * autocommands. */ return FAIL; + } if (did_cmd) { - if (buf == NULL) + if (buf == NULL) { /* The buffer was deleted. We assume it was written * (can't retry anyway). */ return OK; + } if (overwriting) { - /* Assume the buffer was written, update the timestamp. */ + // Assume the buffer was written, update the timestamp. ml_timestamp(buf); - if (append) + if (append) { buf->b_flags &= ~BF_NEW; - else + } else { buf->b_flags &= ~BF_WRITE_MASK; + } } if (reset_changed && buf->b_changed && !append - && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) + && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) { /* Buffer still changed, the autocommands didn't work * properly. */ return FAIL; + } return OK; } - if (!aborting()) + if (!aborting()) { EMSG(_("E203: Autocommands deleted or unloaded buffer to be written")); + } return FAIL; } @@ -2415,11 +2478,11 @@ buf_write( * changed the number of lines that are to be written (tricky!). */ if (buf->b_ml.ml_line_count != old_line_count) { - if (whole) /* write all */ + if (whole) { // write all end = buf->b_ml.ml_line_count; - else if (buf->b_ml.ml_line_count > old_line_count) /* more lines */ + } else if (buf->b_ml.ml_line_count > old_line_count) { // more lines end += buf->b_ml.ml_line_count - old_line_count; - else { /* less lines */ + } else { // less lines end -= old_line_count - buf->b_ml.ml_line_count; if (end < start) { --no_wait_return; @@ -2434,30 +2497,36 @@ buf_write( * The autocommands may have changed the name of the buffer, which may * be kept in fname, ffname and sfname. */ - if (buf_ffname) + if (buf_ffname) { ffname = buf->b_ffname; - if (buf_sfname) + } + if (buf_sfname) { sfname = buf->b_sfname; - if (buf_fname_f) + } + if (buf_fname_f) { fname = buf->b_ffname; - if (buf_fname_s) + } + if (buf_fname_s) { fname = buf->b_sfname; + } } - if (shortmess(SHM_OVER) && !exiting) - msg_scroll = FALSE; /* overwrite previous file message */ - else - msg_scroll = TRUE; /* don't overwrite previous file message */ - if (!filtering) + if (shortmess(SHM_OVER) && !exiting) { + msg_scroll = FALSE; // overwrite previous file message + } else { + msg_scroll = TRUE; // don't overwrite previous file message + } + if (!filtering) { filemess(buf, #ifndef UNIX - sfname, + sfname, #else - fname, + fname, #endif - (char_u *)"", 0); /* show that we are busy */ - msg_scroll = FALSE; /* always overwrite the file message now */ + (char_u *)"", 0); // show that we are busy + } + msg_scroll = FALSE; // always overwrite the file message now buffer = verbose_try_malloc(BUFSIZE); // can't allocate big buffer, use small one (to be able to write when out of @@ -2465,8 +2534,9 @@ buf_write( if (buffer == NULL) { buffer = smallbuf; bufsize = SMBUFSIZE; - } else + } else { bufsize = BUFSIZE; + } /* * Get information about original file (if there is one). @@ -2478,7 +2548,7 @@ buf_write( newfile = TRUE; } else { perm = file_info_old.stat.st_mode; - if (!S_ISREG(file_info_old.stat.st_mode)) { /* not a file */ + if (!S_ISREG(file_info_old.stat.st_mode)) { // not a file if (S_ISDIR(file_info_old.stat.st_mode)) { SET_ERRMSG_NUM("E502", _("is a directory")); goto fail; @@ -2540,8 +2610,9 @@ buf_write( */ if (overwriting) { retval = check_mtime(buf, &file_info_old); - if (retval == FAIL) + if (retval == FAIL) { goto fail; + } } } @@ -2549,16 +2620,18 @@ buf_write( /* * For systems that support ACL: get the ACL from the original file. */ - if (!newfile) + if (!newfile) { acl = mch_get_acl(fname); + } #endif /* * If 'backupskip' is not empty, don't make a backup for some files. */ dobackup = (p_wb || p_bk || *p_pm != NUL); - if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname)) + if (dobackup && *p_bsk != NUL && match_file_list(p_bsk, sfname, ffname)) { dobackup = FALSE; + } /* * Save the value of got_int and reset it. We don't want a previous @@ -2568,7 +2641,7 @@ buf_write( prev_got_int = got_int; got_int = FALSE; - /* Mark the buffer as 'being saved' to prevent changed buffer warnings */ + // Mark the buffer as 'being saved' to prevent changed buffer warnings buf->b_saving = true; /* @@ -2583,9 +2656,9 @@ buf_write( FileInfo file_info; const bool no_prepend_dot = false; - if ((bkc & BKC_YES) || append) { /* "yes" */ + if ((bkc & BKC_YES) || append) { // "yes" backup_copy = TRUE; - } else if ((bkc & BKC_AUTO)) { /* "auto" */ + } else if ((bkc & BKC_AUTO)) { // "auto" int i; /* @@ -2613,10 +2686,10 @@ buf_write( } } fd = os_open((char *)IObuff, - O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); - if (fd < 0) /* can't write in directory */ + O_CREAT|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); + if (fd < 0) { // can't write in directory backup_copy = TRUE; - else { + } else { # ifdef UNIX os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid); if (!os_fileinfo((char *)IObuff, &file_info) @@ -2641,14 +2714,14 @@ buf_write( # ifdef UNIX bool file_info_link_ok = os_fileinfo_link((char *)fname, &file_info); - /* Symlinks. */ + // Symlinks. if ((bkc & BKC_BREAKSYMLINK) && file_info_link_ok && !os_fileinfo_id_equal(&file_info, &file_info_old)) { backup_copy = FALSE; } - /* Hardlinks. */ + // Hardlinks. if ((bkc & BKC_BREAKHARDLINK) && os_fileinfo_hardlinks(&file_info_old) > 1 && (!file_info_link_ok @@ -2658,18 +2731,19 @@ buf_write( # endif } - /* make sure we have a valid backup extension to use */ - if (*p_bex == NUL) + // make sure we have a valid backup extension to use + if (*p_bex == NUL) { backup_ext = (char_u *)".bak"; - else + } else { backup_ext = p_bex; + } if (backup_copy) { char_u *wp; int some_error = false; - char_u *dirp; - char_u *rootname; - char_u *p; + char_u *dirp; + char_u *rootname; + char_u *p; /* * Try to make the backup in each directory in the 'bdir' option. @@ -2715,7 +2789,7 @@ buf_write( rootname = get_file_in_dir(fname, IObuff); if (rootname == NULL) { - some_error = TRUE; /* out of memory */ + some_error = TRUE; // out of memory goto nobackup; } @@ -2731,7 +2805,7 @@ buf_write( if (backup == NULL) { xfree(rootname); - some_error = TRUE; /* out of memory */ + some_error = TRUE; // out of memory goto nobackup; } @@ -2774,7 +2848,7 @@ buf_write( * Try to create the backup file */ if (backup != NULL) { - /* remove old backup, if present */ + // remove old backup, if present os_remove((char *)backup); // set file protection same as original file, but @@ -2815,8 +2889,7 @@ buf_write( nobackup: if (backup == NULL && errmsg == NULL) { - SET_ERRMSG(_( - "E509: Cannot create backup file (add ! to override)")); + SET_ERRMSG(_("E509: Cannot create backup file (add ! to override)")); } // Ignore errors when forceit is TRUE. if ((some_error || errmsg != NULL) && !forceit) { @@ -2825,9 +2898,9 @@ nobackup: } SET_ERRMSG(NULL); } else { - char_u *dirp; - char_u *p; - char_u *rootname; + char_u *dirp; + char_u *p; + char_u *rootname; /* * Make a backup by renaming the original file. @@ -2897,8 +2970,9 @@ nobackup: */ if (!p_bk && os_path_exists(backup)) { p = backup + STRLEN(backup) - 1 - STRLEN(backup_ext); - if (p < backup) /* empty file name ??? */ + if (p < backup) { // empty file name ??? p = backup; + } *p = 'z'; while (*p > 'a' && os_path_exists(backup)) { (*p)--; @@ -2951,10 +3025,12 @@ nobackup: status_redraw_all(); // redraw status lines later } - if (end > buf->b_ml.ml_line_count) + if (end > buf->b_ml.ml_line_count) { end = buf->b_ml.ml_line_count; - if (buf->b_ml.ml_flags & ML_EMPTY) + } + if (buf->b_ml.ml_flags & ML_EMPTY) { start = end + 1; + } // If the original file is being overwritten, there is a small chance that // we crash in the middle of writing. Therefore the file is preserved now. @@ -3014,7 +3090,7 @@ nobackup: // internally. write_info.bw_iconv_fd = (iconv_t)my_iconv_open(fenc, (char_u *)"utf-8"); if (write_info.bw_iconv_fd != (iconv_t)-1) { - /* We're going to use iconv(), allocate a buffer to convert in. */ + // We're going to use iconv(), allocate a buffer to convert in. write_info.bw_conv_buflen = bufsize * ICONV_MULT; write_info.bw_conv_buf = verbose_try_malloc(write_info.bw_conv_buflen); if (!write_info.bw_conv_buf) { @@ -3041,11 +3117,9 @@ nobackup: # ifdef HAVE_ICONV && write_info.bw_iconv_fd == (iconv_t)-1 # endif - && wfname == fname - ) { + && wfname == fname) { if (!forceit) { - SET_ERRMSG(_( - "E213: Cannot convert (add ! to write without conversion)")); + SET_ERRMSG(_("E213: Cannot convert (add ! to write without conversion)")); goto restore_backup; } notconverted = TRUE; @@ -3080,7 +3154,7 @@ nobackup: O_WRONLY | (append ? (forceit ? (O_APPEND | O_CREAT) : O_APPEND) - : (O_CREAT | O_TRUNC)) + : (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 @@ -3096,28 +3170,28 @@ nobackup: 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); } -#ifdef UNIX + continue; } +#ifdef UNIX + } #endif } @@ -3282,7 +3356,7 @@ restore_backup: // Stop when writing done or an error was encountered. if (!checking_conversion || end == 0) { - break; + break; } // If no error happened until now, writing should be ok, so loop to @@ -3371,17 +3445,15 @@ restore_backup: if (errmsg == NULL) { if (write_info.bw_conv_error) { if (write_info.bw_conv_error_lnum == 0) { - SET_ERRMSG(_( - "E513: write error, conversion failed " - "(make 'fenc' empty to override)")); + SET_ERRMSG(_("E513: write error, conversion failed " + "(make 'fenc' empty to override)")); } else { errmsg_allocated = true; SET_ERRMSG(xmalloc(300)); - vim_snprintf( - errmsg, 300, - _("E513: write error, conversion failed in line %" PRIdLINENR - " (make 'fenc' empty to override)"), - write_info.bw_conv_error_lnum); + vim_snprintf(errmsg, 300, + _("E513: write error, conversion failed in line %" PRIdLINENR + " (make 'fenc' empty to override)"), + write_info.bw_conv_error_lnum); } } else if (got_int) { SET_ERRMSG(_(e_interr)); @@ -3420,11 +3492,11 @@ restore_backup: goto fail; } - lnum -= start; /* compute number of written lines */ - --no_wait_return; /* may wait for return now */ + lnum -= start; // compute number of written lines + --no_wait_return; // may wait for return now #if !defined(UNIX) - fname = sfname; /* use shortname now, for the messages */ + fname = sfname; // use shortname now, for the messages #endif if (!filtering) { add_quoted_fname((char *)IObuff, IOSIZE, buf, (const char *)fname); @@ -3432,9 +3504,10 @@ restore_backup: if (write_info.bw_conv_error) { STRCAT(IObuff, _(" CONVERSION ERROR")); c = TRUE; - if (write_info.bw_conv_error_lnum != 0) + if (write_info.bw_conv_error_lnum != 0) { vim_snprintf_add((char *)IObuff, IOSIZE, _(" in line %" PRId64 ";"), - (int64_t)write_info.bw_conv_error_lnum); + (int64_t)write_info.bw_conv_error_lnum); + } } else if (notconverted) { STRCAT(IObuff, _("[NOT converted]")); c = TRUE; @@ -3453,15 +3526,17 @@ restore_backup: msg_add_eol(); c = TRUE; } - /* may add [unix/dos/mac] */ - if (msg_add_fileformat(fileformat)) + // may add [unix/dos/mac] + if (msg_add_fileformat(fileformat)) { c = TRUE; - msg_add_lines(c, (long)lnum, nchars); /* add line/char count */ + } + msg_add_lines(c, (long)lnum, nchars); // add line/char count if (!shortmess(SHM_WRITE)) { - if (append) + if (append) { STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended")); - else + } else { STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written")); + } } set_keep_msg(msg_trunc_attr(IObuff, FALSE, 0), 0); @@ -3489,10 +3564,11 @@ restore_backup: */ if (overwriting) { ml_timestamp(buf); - if (append) + if (append) { buf->b_flags &= ~BF_NEW; - else + } else { buf->b_flags &= ~BF_WRITE_MASK; + } } /* @@ -3528,11 +3604,12 @@ restore_backup: if (org == NULL || (empty_fd = os_open(org, - O_CREAT | O_EXCL | O_NOFOLLOW, - perm < 0 ? 0666 : (perm & 0777))) < 0) + O_CREAT | O_EXCL | O_NOFOLLOW, + perm < 0 ? 0666 : (perm & 0777))) < 0) { EMSG(_("E206: patchmode: can't touch empty original file")); - else + } else { close(empty_fd); + } } if (org != NULL) { os_setperm(org, os_getperm((const char *)fname) & 0777); @@ -3555,15 +3632,16 @@ restore_backup: * Finish up. We get here either after failure or success. */ fail: - --no_wait_return; /* may wait for return now */ + --no_wait_return; // may wait for return now nofail: - /* Done saving, we accept changed buffer warnings again */ + // Done saving, we accept changed buffer warnings again buf->b_saving = false; xfree(backup); - if (buffer != smallbuf) + if (buffer != smallbuf) { xfree(buffer); + } xfree(fenc_tofree); xfree(write_info.bw_conv_buf); # ifdef HAVE_ICONV @@ -3603,9 +3681,8 @@ nofail: const int attr = HL_ATTR(HLF_E); // Set highlight for error messages. MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"), attr | MSG_HIST); - MSG_PUTS_ATTR(_( - "don't quit the editor until the file is successfully written!"), - attr | MSG_HIST); + MSG_PUTS_ATTR(_("don't quit the editor until the file is successfully written!"), + attr | MSG_HIST); /* Update the timestamp to avoid an "overwrite changed file" * prompt when writing again. */ @@ -3631,7 +3708,7 @@ nofail: if (!should_abort(retval)) { aco_save_T aco; - curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */ + curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read /* * Apply POST autocommands. @@ -3639,24 +3716,26 @@ nofail: */ aucmd_prepbuf(&aco, buf); - if (append) + if (append) { apply_autocmds_exarg(EVENT_FILEAPPENDPOST, fname, fname, - FALSE, curbuf, eap); - else if (filtering) + FALSE, curbuf, eap); + } else if (filtering) { apply_autocmds_exarg(EVENT_FILTERWRITEPOST, NULL, fname, - FALSE, curbuf, eap); - else if (reset_changed && whole) + FALSE, curbuf, eap); + } else if (reset_changed && whole) { apply_autocmds_exarg(EVENT_BUFWRITEPOST, fname, fname, - FALSE, curbuf, eap); - else + FALSE, curbuf, eap); + } else { apply_autocmds_exarg(EVENT_FILEWRITEPOST, fname, fname, - FALSE, curbuf, eap); + FALSE, curbuf, eap); + } - /* restore curwin/curbuf and a few other things */ + // restore curwin/curbuf and a few other things aucmd_restbuf(&aco); - if (aborting()) /* autocmds may abort script processing */ + if (aborting()) { // autocmds may abort script processing retval = FALSE; + } } got_int |= prev_got_int; @@ -3673,16 +3752,18 @@ nofail: */ static int set_rw_fname(char_u *fname, char_u *sfname) { - buf_T *buf = curbuf; + buf_T *buf = curbuf; - /* It's like the unnamed buffer is deleted.... */ - if (curbuf->b_p_bl) - apply_autocmds(EVENT_BUFDELETE, NULL, NULL, FALSE, curbuf); - apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf); - if (aborting()) /* autocmds may abort script processing */ + // It's like the unnamed buffer is deleted.... + if (curbuf->b_p_bl) { + apply_autocmds(EVENT_BUFDELETE, NULL, NULL, false, curbuf); + } + apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, false, curbuf); + if (aborting()) { // autocmds may abort script processing return FAIL; + } if (curbuf != buf) { - /* We are in another buffer now, don't do the renaming. */ + // We are in another buffer now, don't do the renaming. EMSG(_(e_auchangedbuf)); return FAIL; } @@ -3691,14 +3772,16 @@ static int set_rw_fname(char_u *fname, char_u *sfname) curbuf->b_flags |= BF_NOTEDITED; } - /* ....and a new named one is created */ - apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, curbuf); - if (curbuf->b_p_bl) - apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, curbuf); - if (aborting()) /* autocmds may abort script processing */ + // ....and a new named one is created + apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, curbuf); + if (curbuf->b_p_bl) { + apply_autocmds(EVENT_BUFADD, NULL, NULL, false, curbuf); + } + if (aborting()) { // autocmds may abort script processing return FAIL; + } - /* Do filetype detection now if 'filetype' is empty. */ + // Do filetype detection now if 'filetype' is empty. if (*curbuf->b_p_ft == NUL) { if (au_has_group((char_u *)"filetypedetect")) { (void)do_doautocmd((char_u *)"filetypedetect BufRead", false, NULL); @@ -3717,8 +3800,8 @@ static int set_rw_fname(char_u *fname, char_u *sfname) /// @param[in] buf_len ret_buf length. /// @param[in] buf buf_T file name is coming from. /// @param[in] fname File name to write. -static void add_quoted_fname(char *const ret_buf, const size_t buf_len, - const buf_T *const buf, const char *fname) +static void add_quoted_fname(char *const ret_buf, const size_t buf_len, const buf_T *const buf, + const char *fname) FUNC_ATTR_NONNULL_ARG(1) { if (fname == NULL) { @@ -3761,25 +3844,26 @@ static bool msg_add_fileformat(int eol_type) */ void msg_add_lines(int insert_space, long lnum, off_T nchars) { - char_u *p; + char_u *p; p = IObuff + STRLEN(IObuff); - if (insert_space) + if (insert_space) { *p++ = ' '; - if (shortmess(SHM_LINES)) { - sprintf((char *)p, "%" PRId64 "L, %" PRId64 "C", - (int64_t)lnum, (int64_t)nchars); } - else { - if (lnum == 1) + if (shortmess(SHM_LINES)) { + sprintf((char *)p, "%" PRId64 "L, %" PRId64 "C", + (int64_t)lnum, (int64_t)nchars); + } else { + if (lnum == 1) { STRCPY(p, _("1 line, ")); - else + } else { sprintf((char *)p, _("%" PRId64 " lines, "), (int64_t)lnum); + } p += STRLEN(p); - if (nchars == 1) + if (nchars == 1) { STRCPY(p, _("1 character")); - else { + } else { sprintf((char *)p, _("%" PRId64 " characters"), (int64_t)nchars); } } @@ -3791,7 +3875,7 @@ void msg_add_lines(int insert_space, long lnum, off_T nchars) static void msg_add_eol(void) { STRCAT(IObuff, - shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]")); + shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]")); } /* @@ -3842,17 +3926,17 @@ static bool time_differs(long t1, long t2) FUNC_ATTR_CONST static int buf_write_bytes(struct bw_info *ip) { int wlen; - char_u *buf = ip->bw_buf; /* data to write */ - int len = ip->bw_len; /* length of data */ + char_u *buf = ip->bw_buf; // data to write + int len = ip->bw_len; // length of data #ifdef HAS_BW_FLAGS - int flags = ip->bw_flags; /* extra flags */ + int flags = ip->bw_flags; // extra flags #endif /* * Skip conversion when writing the BOM. */ if (!(flags & FIO_NOCONVERT)) { - char_u *p; + char_u *p; unsigned c; int n; @@ -3860,9 +3944,10 @@ static int buf_write_bytes(struct bw_info *ip) /* * Convert latin1 in the buffer to UTF-8 in the file. */ - p = ip->bw_conv_buf; /* translate to buffer */ - for (wlen = 0; wlen < len; ++wlen) + p = ip->bw_conv_buf; // translate to buffer + for (wlen = 0; wlen < len; ++wlen) { p += utf_char2bytes(buf[wlen], p); + } buf = ip->bw_conv_buf; len = (int)(p - ip->bw_conv_buf); } else if (flags & (FIO_UCS4 | FIO_UTF16 | FIO_UCS2 | FIO_LATIN1)) { @@ -3870,10 +3955,11 @@ static int buf_write_bytes(struct bw_info *ip) * Convert UTF-8 bytes in the buffer to UCS-2, UCS-4, UTF-16 or * Latin1 chars in the file. */ - if (flags & FIO_LATIN1) - p = buf; /* translate in-place (can only get shorter) */ - else - p = ip->bw_conv_buf; /* translate to buffer */ + if (flags & FIO_LATIN1) { + p = buf; // translate in-place (can only get shorter) + } else { + p = ip->bw_conv_buf; // translate to buffer + } for (wlen = 0; wlen < len; wlen += n) { if (wlen == 0 && ip->bw_restlen != 0) { int l; @@ -3882,30 +3968,33 @@ static int buf_write_bytes(struct bw_info *ip) * buf[] to get a full sequence. Might still be too * short! */ l = CONV_RESTLEN - ip->bw_restlen; - if (l > len) + if (l > len) { l = len; + } memmove(ip->bw_rest + ip->bw_restlen, buf, (size_t)l); n = utf_ptr2len_len(ip->bw_rest, ip->bw_restlen + l); if (n > ip->bw_restlen + len) { /* We have an incomplete byte sequence at the end to * be written. We can't convert it without the * remaining bytes. Keep them for the next call. */ - if (ip->bw_restlen + len > CONV_RESTLEN) + if (ip->bw_restlen + len > CONV_RESTLEN) { return FAIL; + } ip->bw_restlen += len; break; } - if (n > 1) + if (n > 1) { c = utf_ptr2char(ip->bw_rest); - else + } else { c = ip->bw_rest[0]; + } if (n >= ip->bw_restlen) { n -= ip->bw_restlen; ip->bw_restlen = 0; } else { ip->bw_restlen -= n; memmove(ip->bw_rest, ip->bw_rest + n, - (size_t)ip->bw_restlen); + (size_t)ip->bw_restlen); n = 0; } } else { @@ -3914,29 +4003,32 @@ static int buf_write_bytes(struct bw_info *ip) /* We have an incomplete byte sequence at the end to * be written. We can't convert it without the * remaining bytes. Keep them for the next call. */ - if (len - wlen > CONV_RESTLEN) + if (len - wlen > CONV_RESTLEN) { return FAIL; + } ip->bw_restlen = len - wlen; memmove(ip->bw_rest, buf + wlen, - (size_t)ip->bw_restlen); + (size_t)ip->bw_restlen); break; } - if (n > 1) + if (n > 1) { c = utf_ptr2char(buf + wlen); - else + } else { c = buf[wlen]; + } } if (ucs2bytes(c, &p, flags) && !ip->bw_conv_error) { ip->bw_conv_error = TRUE; ip->bw_conv_error_lnum = ip->bw_start_lnum; } - if (c == NL) + if (c == NL) { ++ip->bw_start_lnum; + } } - if (flags & FIO_LATIN1) + if (flags & FIO_LATIN1) { len = (int)(p - buf); - else { + } else { buf = ip->bw_conv_buf; len = (int)(p - ip->bw_conv_buf); } @@ -3944,12 +4036,12 @@ static int buf_write_bytes(struct bw_info *ip) # ifdef HAVE_ICONV if (ip->bw_iconv_fd != (iconv_t)-1) { - const char *from; + const char *from; size_t fromlen; - char *to; + char *to; size_t tolen; - /* Convert with iconv(). */ + // Convert with iconv(). if (ip->bw_restlen > 0) { char *fp; @@ -3972,7 +4064,7 @@ static int buf_write_bytes(struct bw_info *ip) if (ip->bw_first) { size_t save_len = tolen; - /* output the initial shift state sequence */ + // output the initial shift state sequence (void)iconv(ip->bw_iconv_fd, NULL, NULL, &to, &tolen); /* There is a bug in iconv() on Linux (which appears to be @@ -3995,9 +4087,10 @@ static int buf_write_bytes(struct bw_info *ip) return FAIL; } - /* copy remainder to ip->bw_rest[] to be used for the next call. */ - if (fromlen > 0) + // copy remainder to ip->bw_rest[] to be used for the next call. + if (fromlen > 0) { memmove(ip->bw_rest, (void *)from, fromlen); + } ip->bw_restlen = (int)fromlen; buf = ip->bw_conv_buf; @@ -4023,7 +4116,7 @@ static int buf_write_bytes(struct bw_info *ip) /// @return true for an error, false when it's OK. static bool ucs2bytes(unsigned c, char_u **pp, int flags) FUNC_ATTR_NONNULL_ALL { - char_u *p = *pp; + char_u *p = *pp; bool error = false; int cc; @@ -4069,12 +4162,13 @@ static bool ucs2bytes(unsigned c, char_u **pp, int flags) FUNC_ATTR_NONNULL_ALL *p++ = (c >> 8); *p++ = c; } - } else { /* Latin1 */ + } else { // Latin1 if (c >= 0x100) { error = true; *p++ = 0xBF; - } else + } else { *p++ = c; + } } *pp = p; @@ -4129,25 +4223,29 @@ static int get_fio_flags(const char_u *name) prop = enc_canon_props(name); if (prop & ENC_UNICODE) { if (prop & ENC_2BYTE) { - if (prop & ENC_ENDIAN_L) + if (prop & ENC_ENDIAN_L) { return FIO_UCS2 | FIO_ENDIAN_L; + } return FIO_UCS2; } if (prop & ENC_4BYTE) { - if (prop & ENC_ENDIAN_L) + if (prop & ENC_ENDIAN_L) { return FIO_UCS4 | FIO_ENDIAN_L; + } return FIO_UCS4; } if (prop & ENC_2WORD) { - if (prop & ENC_ENDIAN_L) + if (prop & ENC_ENDIAN_L) { return FIO_UTF16 | FIO_ENDIAN_L; + } return FIO_UTF16; } return FIO_UTF8; } - if (prop & ENC_LATIN1) + if (prop & ENC_LATIN1) { return FIO_LATIN1; - /* must be ENC_DBCS, requires iconv() */ + } + // must be ENC_DBCS, requires iconv() return 0; } @@ -4161,34 +4259,37 @@ static int get_fio_flags(const char_u *name) */ static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags) { - char *name = NULL; + char *name = NULL; int len = 2; if (p[0] == 0xef && p[1] == 0xbb && size >= 3 && p[2] == 0xbf && (flags == FIO_ALL || flags == FIO_UTF8 || flags == 0)) { - name = "utf-8"; /* EF BB BF */ + name = "utf-8"; // EF BB BF len = 3; } else if (p[0] == 0xff && p[1] == 0xfe) { if (size >= 4 && p[2] == 0 && p[3] == 0 && (flags == FIO_ALL || flags == (FIO_UCS4 | FIO_ENDIAN_L))) { - name = "ucs-4le"; /* FF FE 00 00 */ + name = "ucs-4le"; // FF FE 00 00 len = 4; - } else if (flags == (FIO_UCS2 | FIO_ENDIAN_L)) - name = "ucs-2le"; /* FF FE */ - else if (flags == FIO_ALL || flags == (FIO_UTF16 | FIO_ENDIAN_L)) - /* utf-16le is preferred, it also works for ucs-2le text */ - name = "utf-16le"; /* FF FE */ + } else if (flags == (FIO_UCS2 | FIO_ENDIAN_L)) { + name = "ucs-2le"; // FF FE + } else if (flags == FIO_ALL || + flags == (FIO_UTF16 | FIO_ENDIAN_L)) { + // utf-16le is preferred, it also works for ucs-2le text + name = "utf-16le"; // FF FE + } } else if (p[0] == 0xfe && p[1] == 0xff && (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16)) { - /* Default to utf-16, it works also for ucs-2 text. */ - if (flags == FIO_UCS2) - name = "ucs-2"; /* FE FF */ - else - name = "utf-16"; /* FE FF */ + // Default to utf-16, it works also for ucs-2 text. + if (flags == FIO_UCS2) { + name = "ucs-2"; // FE FF + } else { + name = "utf-16"; // FE FF + } } else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe && p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4)) { - name = "ucs-4"; /* 00 00 FE FF */ + name = "ucs-4"; // 00 00 FE FF len = 4; } @@ -4203,15 +4304,16 @@ static char_u *check_for_bom(char_u *p, long size, int *lenp, int flags) static int make_bom(char_u *buf, char_u *name) { int flags; - char_u *p; + char_u *p; flags = get_fio_flags(name); - /* Can't put a BOM in a non-Unicode file. */ - if (flags == FIO_LATIN1 || flags == 0) + // Can't put a BOM in a non-Unicode file. + if (flags == FIO_LATIN1 || flags == 0) { return 0; + } - if (flags == FIO_UTF8) { /* UTF-8 */ + if (flags == FIO_UTF8) { // UTF-8 buf[0] = 0xef; buf[1] = 0xbb; buf[2] = 0xbf; @@ -4231,7 +4333,7 @@ static int make_bom(char_u *buf, char_u *name) /// name. void shorten_buf_fname(buf_T *buf, char_u *dirname, int force) { - char_u *p; + char_u *p; if (buf->b_fname != NULL && !bt_nofile(buf) @@ -4260,7 +4362,7 @@ void shorten_fnames(int force) os_dirname(dirname, MAXPATHL); FOR_ALL_BUFFERS(buf) { - shorten_buf_fname(buf, dirname, force); + shorten_buf_fname(buf, dirname, force); // Always make the swap file name a full path, a "nofile" buffer may // also have a swap file. @@ -4533,11 +4635,11 @@ int vim_rename(const char_u *from, const char_u *to) int fd_in; int fd_out; int n; - char *errmsg = NULL; - char *buffer; + char *errmsg = NULL; + char *buffer; long perm; #ifdef HAVE_ACL - vim_acl_T acl; /* ACL from original file */ + vim_acl_T acl; // ACL from original file #endif bool use_tmp_file = false; @@ -4577,8 +4679,9 @@ int vim_rename(const char_u *from, const char_u *to) * Find a name that doesn't exist and is in the same directory. * Rename "from" to "tempname" and then rename "tempname" to "to". */ - if (STRLEN(from) >= MAXPATHL - 5) + if (STRLEN(from) >= MAXPATHL - 5) { return -1; + } STRCPY(tempname, from); for (n = 123; n < 99999; n++) { char * tail = (char *)path_tail(tempname); @@ -4613,8 +4716,9 @@ int vim_rename(const char_u *from, const char_u *to) /* * First try a normal rename, return if it works. */ - if (os_rename(from, to) == OK) + if (os_rename(from, to) == OK) { return 0; + } /* * Rename() failed, try copying the file. @@ -4632,9 +4736,9 @@ int vim_rename(const char_u *from, const char_u *to) return -1; } - /* Create the new file with same permissions as the original. */ + // Create the new file with same permissions as the original. fd_out = os_open((char *)to, - O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm); + O_CREAT|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)perm); if (fd_out < 0) { close(fd_in); #ifdef HAVE_ACL @@ -4655,16 +4759,18 @@ int vim_rename(const char_u *from, const char_u *to) return -1; } - while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0) + while ((n = read_eintr(fd_in, buffer, BUFSIZE)) > 0) { if (write_eintr(fd_out, buffer, n) != n) { errmsg = _("E208: Error writing to \"%s\""); break; } + } xfree(buffer); close(fd_in); - if (close(fd_out) < 0) + if (close(fd_out) < 0) { errmsg = _("E209: Error closing \"%s\""); + } if (n < 0) { errmsg = _("E210: Error reading \"%s\""); to = from; @@ -4686,23 +4792,23 @@ int vim_rename(const char_u *from, const char_u *to) static int already_warned = FALSE; -// Check if any not hidden buffer has been changed. -// Postpone the check if there are characters in the stuff buffer, a global -// command is being executed, a mapping is being executed or an autocommand is -// busy. -// Returns TRUE if some message was written (screen should be redrawn and -// cursor positioned). -int -check_timestamps( - int focus // called for GUI focus event -) +/// Check if any not hidden buffer has been changed. +/// Postpone the check if there are characters in the stuff buffer, a global +/// command is being executed, a mapping is being executed or an autocommand is +/// busy. +/// +/// @param focus called for GUI focus event +/// +/// @return TRUE if some message was written (screen should be redrawn and cursor positioned). +int check_timestamps(int focus) { int didit = 0; /* Don't check timestamps while system() or another low-level function may * cause us to lose and gain focus. */ - if (no_check_timestamps > 0) + if (no_check_timestamps > 0) { return FALSE; + } /* Avoid doing a check twice. The OK/Reload dialog can cause a focus * event and we would keep on checking if the file is steadily growing. @@ -4713,8 +4819,8 @@ check_timestamps( } if (!stuff_empty() || global_busy || !typebuf_typed() - || autocmd_busy || curbuf->b_ro_locked > 0 || allbuf_lock > 0 - ) { + || autocmd_busy || curbuf->b_ro_locked > 0 || + allbuf_lock > 0) { need_check_timestamps = true; // check later } else { no_wait_return++; @@ -4754,12 +4860,12 @@ check_timestamps( */ static int move_lines(buf_T *frombuf, buf_T *tobuf) { - buf_T *tbuf = curbuf; + buf_T *tbuf = curbuf; int retval = OK; linenr_T lnum; - char_u *p; + char_u *p; - /* Copy the lines in "frombuf" to "tobuf". */ + // Copy the lines in "frombuf" to "tobuf". curbuf = tobuf; for (lnum = 1; lnum <= frombuf->b_ml.ml_line_count; lnum++) { p = vim_strsave(ml_get_buf(frombuf, lnum, false)); @@ -4771,7 +4877,7 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf) xfree(p); } - /* Delete all the lines in "frombuf". */ + // Delete all the lines in "frombuf". if (retval != FAIL) { curbuf = frombuf; for (lnum = curbuf->b_ml.ml_line_count; lnum > 0; lnum--) { @@ -4799,17 +4905,17 @@ int buf_check_timestamp(buf_T *buf) FUNC_ATTR_NONNULL_ALL { int retval = 0; - char_u *path; - char *mesg = NULL; - char *mesg2 = ""; + char_u *path; + char *mesg = NULL; + char *mesg2 = ""; bool helpmesg = false; bool reload = false; bool can_reload = false; uint64_t orig_size = buf->b_orig_size; int orig_mode = buf->b_orig_mode; static bool busy = false; - char_u *s; - char *reason; + char_u *s; + char *reason; bufref_T bufref; set_bufref(&bufref, buf); @@ -4822,9 +4928,9 @@ int buf_check_timestamp(buf_T *buf) || buf->b_ml.ml_mfp == NULL || !bt_normal(buf) || buf->b_saving - || busy - ) + || busy) { return 0; + } FileInfo file_info; bool file_info_ok; @@ -4910,24 +5016,22 @@ int buf_check_timestamp(buf_T *buf) // changed. if (reason[2] == 'n') { mesg = _( - "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"); + "W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as well"); mesg2 = _("See \":help W12\" for more info."); } else if (reason[1] == 'h') { - mesg = _( - "W11: Warning: File \"%s\" has changed since editing started"); + mesg = _("W11: Warning: File \"%s\" has changed since editing started"); mesg2 = _("See \":help W11\" for more info."); } else if (*reason == 'm') { - mesg = _( - "W16: Warning: Mode of file \"%s\" has changed since editing started"); + mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started"); mesg2 = _("See \":help W16\" for more info."); - } else + } else { /* Only timestamp changed, store it to avoid a warning * in check_mtime() later. */ buf->b_mtime_read = buf->b_mtime; + } } } } - } else if ((buf->b_flags & BF_NEW) && !(buf->b_flags & BF_NEW_W) && os_path_exists(buf->b_ffname)) { retval = 1; @@ -4952,8 +5056,8 @@ int buf_check_timestamp(buf_T *buf) xstrlcat(tbuf, "\n", tbuf_len - 1); xstrlcat(tbuf, mesg2, tbuf_len - 1); } - if (do_dialog(VIM_WARNING, (char_u *) _("Warning"), (char_u *) tbuf, - (char_u *) _("&OK\n&Load File"), 1, NULL, true) == 2) { + if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), (char_u *)tbuf, + (char_u *)_("&OK\n&Load File"), 1, NULL, true) == 2) { reload = true; } } else if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) { @@ -4989,7 +5093,7 @@ int buf_check_timestamp(buf_T *buf) } if (reload) { - /* Reload the buffer. */ + // Reload the buffer. buf_reload(buf, orig_mode); if (buf->b_p_udf && buf->b_ffname != NULL) { char_u hash[UNDO_HASH_SIZE]; @@ -5020,13 +5124,13 @@ void buf_reload(buf_T *buf, int orig_mode) pos_T old_cursor; linenr_T old_topline; int old_ro = buf->b_p_ro; - buf_T *savebuf; + buf_T *savebuf; bufref_T bufref; int saved = OK; aco_save_T aco; int flags = READ_NEW; - /* set curwin/curbuf for "buf" and save some things */ + // set curwin/curbuf for "buf" and save some things aucmd_prepbuf(&aco, buf); // We only want to read the text from the file, not reset the syntax @@ -5057,7 +5161,7 @@ void buf_reload(buf_T *buf, int orig_mode) savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); set_bufref(&bufref, savebuf); if (savebuf != NULL && buf == curbuf) { - /* Open the memline. */ + // Open the memline. curbuf = savebuf; curwin->w_buffer = savebuf; saved = ml_open(curbuf); @@ -5067,7 +5171,7 @@ void buf_reload(buf_T *buf, int orig_mode) if (savebuf == NULL || saved == FAIL || buf != curbuf || move_lines(buf, savebuf) == FAIL) { EMSG2(_("E462: Could not prepare for reloading \"%s\""), - buf->b_fname); + buf->b_fname); saved = FAIL; } } @@ -5110,21 +5214,22 @@ void buf_reload(buf_T *buf, int orig_mode) wipe_buffer(savebuf, false); } - /* Invalidate diff info if necessary. */ + // Invalidate diff info if necessary. diff_invalidate(curbuf); /* Restore the topline and cursor position and check it (lines may * have been removed). */ - if (old_topline > curbuf->b_ml.ml_line_count) + if (old_topline > curbuf->b_ml.ml_line_count) { curwin->w_topline = curbuf->b_ml.ml_line_count; - else + } else { curwin->w_topline = old_topline; + } curwin->w_cursor = old_cursor; check_cursor(); update_topline(curwin); keep_filetype = false; - /* Update folds unless they are defined manually. */ + // Update folds unless they are defined manually. FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_buffer == curwin->w_buffer && !foldmethodIsManual(wp)) { @@ -5135,15 +5240,16 @@ void buf_reload(buf_T *buf, int orig_mode) /* If the mode didn't change and 'readonly' was set, keep the old * value; the user probably used the ":view" command. But don't * reset it, might have had a read error. */ - if (orig_mode == curbuf->b_orig_mode) + if (orig_mode == curbuf->b_orig_mode) { curbuf->b_p_ro |= old_ro; + } - /* Modelines must override settings done by autocommands. */ + // Modelines must override settings done by autocommands. do_modelines(0); - /* restore curwin/curbuf and a few other things */ + // restore curwin/curbuf and a few other things aucmd_restbuf(&aco); - /* Careful: autocommands may have made "buf" invalid! */ + // Careful: autocommands may have made "buf" invalid! } void buf_store_file_info(buf_T *buf, FileInfo *file_info) @@ -5160,8 +5266,9 @@ void buf_store_file_info(buf_T *buf, FileInfo *file_info) */ void write_lnum_adjust(linenr_T offset) { - if (curbuf->b_no_eol_lnum != 0) /* only if there is a missing eol */ + if (curbuf->b_no_eol_lnum != 0) { // only if there is a missing eol curbuf->b_no_eol_lnum += offset; + } } #if defined(BACKSLASH_IN_FILENAME) @@ -5169,7 +5276,7 @@ void write_lnum_adjust(linenr_T offset) /// unless when it looks like a URL. void forward_slash(char_u *fname) { - char_u *p; + char_u *p; if (path_with_url((const char *)fname)) { return; @@ -5344,18 +5451,19 @@ char_u *vim_tempname(void) /// @param allow_dirs Allow matching with dir /// /// @return true if there is a match, false otherwise -bool match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname, - char_u *sfname, char_u *tail, int allow_dirs) +bool match_file_pat(char_u *pattern, regprog_T **prog, char_u *fname, char_u *sfname, char_u *tail, + int allow_dirs) { regmatch_T regmatch; bool result = false; - regmatch.rm_ic = p_fic; /* ignore case if 'fileignorecase' is set */ + regmatch.rm_ic = p_fic; // ignore case if 'fileignorecase' is set { - if (prog != NULL) + if (prog != NULL) { regmatch.regprog = *prog; - else + } else { regmatch.regprog = vim_regcomp(pattern, RE_MAGIC); + } } /* @@ -5394,11 +5502,11 @@ bool match_file_list(char_u *list, char_u *sfname, char_u *ffname) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1, 3) { char_u buf[100]; - char_u *tail; - char_u *regpat; + char_u *tail; + char_u *regpat; char allow_dirs; bool match; - char_u *p; + char_u *p; tail = path_tail(sfname); @@ -5425,25 +5533,27 @@ bool match_file_list(char_u *list, char_u *sfname, char_u *ffname) /// allow_dirs, otherwise FALSE is put there -- webb. /// Handle backslashes before special characters, like "\*" and "\ ". /// -/// Returns NULL on failure. -char_u * file_pat_to_reg_pat( - const char_u *pat, - const char_u *pat_end, // first char after pattern or NULL - char *allow_dirs, // Result passed back out in here - int no_bslash // Don't use a backward slash as pathsep -) +/// @param pat_end first char after pattern or NULL +/// @param allow_dirs Result passed back out in here +/// @param no_bslash Don't use a backward slash as pathsep +/// +/// @return NULL on failure. +char_u * file_pat_to_reg_pat(const char_u *pat, const char_u *pat_end, char *allow_dirs, + int no_bslash) FUNC_ATTR_NONNULL_ARG(1) { const char_u *endp; - char_u *reg_pat; + char_u *reg_pat; const char_u *p; int nested = 0; int add_dollar = TRUE; - if (allow_dirs != NULL) + if (allow_dirs != NULL) { *allow_dirs = FALSE; - if (pat_end == NULL) + } + if (pat_end == NULL) { pat_end = pat + STRLEN(pat); + } if (pat_end == pat) { return (char_u *)xstrdup("^$"); @@ -5459,12 +5569,12 @@ char_u * file_pat_to_reg_pat( case '{': case '}': case '~': - size += 2; /* extra backslash */ + size += 2; // extra backslash break; #ifdef BACKSLASH_IN_FILENAME case '\\': case '/': - size += 4; /* could become "[\/]" */ + size += 4; // could become "[\/]" break; #endif default: @@ -5476,11 +5586,13 @@ char_u * file_pat_to_reg_pat( size_t i = 0; - if (pat[0] == '*') - while (pat[0] == '*' && pat < pat_end - 1) + if (pat[0] == '*') { + while (pat[0] == '*' && pat < pat_end - 1) { pat++; - else + } + } else { reg_pat[i++] = '^'; + } endp = pat_end - 1; if (endp >= pat && *endp == '*') { while (endp - pat > 0 && *endp == '*') { @@ -5493,8 +5605,9 @@ char_u * file_pat_to_reg_pat( case '*': reg_pat[i++] = '.'; reg_pat[i++] = '*'; - while (p[1] == '*') /* "**" matches like "*" */ + while (p[1] == '*') { // "**" matches like "*" ++p; + } break; case '.': case '~': @@ -5505,8 +5618,9 @@ char_u * file_pat_to_reg_pat( reg_pat[i++] = '.'; break; case '\\': - if (p[1] == NUL) + if (p[1] == NUL) { break; + } #ifdef BACKSLASH_IN_FILENAME if (!no_bslash) { /* translate: @@ -5521,8 +5635,9 @@ char_u * file_pat_to_reg_pat( reg_pat[i++] = '\\'; reg_pat[i++] = '/'; reg_pat[i++] = ']'; - if (allow_dirs != NULL) + if (allow_dirs != NULL) { *allow_dirs = TRUE; + } break; } } @@ -5555,8 +5670,9 @@ char_u * file_pat_to_reg_pat( #ifdef BACKSLASH_IN_FILENAME && (!no_bslash || *p != '\\') #endif - ) + ) { *allow_dirs = TRUE; + } reg_pat[i++] = '\\'; reg_pat[i++] = *p; } @@ -5567,8 +5683,9 @@ char_u * file_pat_to_reg_pat( reg_pat[i++] = '\\'; reg_pat[i++] = '/'; reg_pat[i++] = ']'; - if (allow_dirs != NULL) + if (allow_dirs != NULL) { *allow_dirs = TRUE; + } break; #endif case '{': @@ -5585,8 +5702,9 @@ char_u * file_pat_to_reg_pat( if (nested) { reg_pat[i++] = '\\'; reg_pat[i++] = '|'; - } else + } else { reg_pat[i++] = ','; + } break; default: if (allow_dirs != NULL && vim_ispathsep(*p)) { @@ -5596,8 +5714,9 @@ char_u * file_pat_to_reg_pat( break; } } - if (add_dollar) + if (add_dollar) { reg_pat[i++] = '$'; + } reg_pat[i] = NUL; if (nested != 0) { if (nested < 0) { @@ -5621,8 +5740,9 @@ long read_eintr(int fd, void *buf, size_t bufsize) for (;; ) { ret = read(fd, buf, bufsize); - if (ret >= 0 || errno != EINTR) + if (ret >= 0 || errno != EINTR) { break; + } } return ret; } @@ -5641,10 +5761,12 @@ long write_eintr(int fd, void *buf, size_t bufsize) while (ret < (long)bufsize) { wlen = write(fd, (char *)buf + ret, bufsize - ret); if (wlen < 0) { - if (errno != EINTR) + if (errno != EINTR) { break; - } else + } + } else { ret += wlen; + } } return ret; } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index 51a8a85aa0..bfc72e6af8 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -7,12 +7,11 @@ * fold.c: code for folding */ -#include <string.h> #include <inttypes.h> +#include <string.h> -#include "nvim/vim.h" #include "nvim/ascii.h" -#include "nvim/fold.h" +#include "nvim/buffer_updates.h" #include "nvim/change.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -20,27 +19,28 @@ #include "nvim/eval.h" #include "nvim/ex_docmd.h" #include "nvim/ex_session.h" +#include "nvim/extmark.h" +#include "nvim/fold.h" #include "nvim/func_attr.h" +#include "nvim/garray.h" #include "nvim/indent.h" -#include "nvim/buffer_updates.h" -#include "nvim/extmark.h" #include "nvim/mark.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/plines.h" -#include "nvim/garray.h" #include "nvim/move.h" +#include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/plines.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/syntax.h" #include "nvim/undo.h" -#include "nvim/ops.h" +#include "nvim/vim.h" -/* local declarations. {{{1 */ -/* typedef fold_T {{{2 */ +// local declarations. {{{1 +// typedef fold_T {{{2 /* * The toplevel folds for each window are stored in the w_folds growarray. * Each toplevel fold can contain an array of second level folds in the @@ -58,20 +58,20 @@ typedef struct { // folds too } fold_T; -#define FD_OPEN 0 /* fold is open (nested ones can be closed) */ -#define FD_CLOSED 1 /* fold is closed */ -#define FD_LEVEL 2 /* depends on 'foldlevel' (nested folds too) */ +#define FD_OPEN 0 // fold is open (nested ones can be closed) +#define FD_CLOSED 1 // fold is closed +#define FD_LEVEL 2 // depends on 'foldlevel' (nested folds too) -#define MAX_LEVEL 20 /* maximum fold depth */ +#define MAX_LEVEL 20 // maximum fold depth -/* Define "fline_T", passed to get fold level for a line. {{{2 */ +// Define "fline_T", passed to get fold level for a line. {{{2 typedef struct { - win_T *wp; /* window */ - linenr_T lnum; /* current line number */ - linenr_T off; /* offset between lnum and real line number */ - linenr_T lnum_save; /* line nr used by foldUpdateIEMSRecurse() */ - int lvl; /* current level (-1 for undefined) */ - int lvl_next; /* level used for next line */ + win_T *wp; // window + linenr_T lnum; // current line number + linenr_T off; // offset between lnum and real line number + linenr_T lnum_save; // line nr used by foldUpdateIEMSRecurse() + int lvl; // current level (-1 for undefined) + int lvl_next; // level used for next line int start; /* number of folds that are forced to start at this line. */ int end; /* level of fold that is forced to end below @@ -83,10 +83,10 @@ typedef struct { // Flag is set when redrawing is needed. static bool fold_changed; -/* Function used by foldUpdateIEMSRecurse */ +// Function used by foldUpdateIEMSRecurse typedef void (*LevelGetter)(fline_T *); -/* static functions {{{2 */ +// static functions {{{2 #ifdef INCLUDE_GENERATED_DECLARATIONS # include "fold.c.generated.h" @@ -110,17 +110,17 @@ static linenr_T invalid_bot = (linenr_T)0; static linenr_T prev_lnum = 0; static int prev_lnum_lvl = -1; -/* Flags used for "done" argument of setManualFold. */ +// Flags used for "done" argument of setManualFold. #define DONE_NOTHING 0 -#define DONE_ACTION 1 /* did close or open a fold */ -#define DONE_FOLD 2 /* did find a fold */ +#define DONE_ACTION 1 // did close or open a fold +#define DONE_FOLD 2 // did find a fold static size_t foldstartmarkerlen; static char_u *foldendmarker; static size_t foldendmarkerlen; -/* Exported folding functions. {{{1 */ -/* copyFoldingState() {{{2 */ +// Exported folding functions. {{{1 +// copyFoldingState() {{{2 /* * Copy that folding state from window "wp_from" to window "wp_to". */ @@ -131,18 +131,18 @@ void copyFoldingState(win_T *wp_from, win_T *wp_to) cloneFoldGrowArray(&wp_from->w_folds, &wp_to->w_folds); } -/* hasAnyFolding() {{{2 */ +// hasAnyFolding() {{{2 /* * Return TRUE if there may be folded lines in the current window. */ int hasAnyFolding(win_T *win) { - /* very simple now, but can become more complex later */ + // very simple now, but can become more complex later return !win->w_buffer->terminal && win->w_p_fen && (!foldmethodIsManual(win) || !GA_EMPTY(&win->w_folds)); } -/* hasFolding() {{{2 */ +// hasFolding() {{{2 /* * Return TRUE if line "lnum" in the current window is part of a closed * fold. @@ -163,20 +163,14 @@ bool hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp) /// @param[out] infop where to store fold info /// /// @return true if range contains folds -bool hasFoldingWin( - win_T *const win, - const linenr_T lnum, - linenr_T *const firstp, - linenr_T *const lastp, - const bool cache, - foldinfo_T *const infop -) +bool hasFoldingWin(win_T *const win, const linenr_T lnum, linenr_T *const firstp, + linenr_T *const lastp, const bool cache, foldinfo_T *const infop) { bool had_folded = false; linenr_T first = 0; linenr_T last = 0; linenr_T lnum_rel = lnum; - fold_T *fp; + fold_T *fp; int level = 0; bool use_level = false; bool maybe_small = false; @@ -186,8 +180,9 @@ bool hasFoldingWin( // Return quickly when there is no folding at all in this window. if (!hasAnyFolding(win)) { - if (infop != NULL) + if (infop != NULL) { infop->fi_level = 0; + } return false; } @@ -210,21 +205,23 @@ bool hasFoldingWin( */ garray_T *gap = &win->w_folds; for (;; ) { - if (!foldFind(gap, lnum_rel, &fp)) + if (!foldFind(gap, lnum_rel, &fp)) { break; + } - /* Remember lowest level of fold that starts in "lnum". */ - if (lnum_rel == fp->fd_top && low_level == 0) + // Remember lowest level of fold that starts in "lnum". + if (lnum_rel == fp->fd_top && low_level == 0) { low_level = level + 1; + } first += fp->fd_top; last += fp->fd_top; - /* is this fold closed? */ + // is this fold closed? had_folded = check_closed(win, fp, &use_level, level, - &maybe_small, lnum - lnum_rel); + &maybe_small, lnum - lnum_rel); if (had_folded) { - /* Fold closed: Set last and quit loop. */ + // Fold closed: Set last and quit loop. last += fp->fd_len - 1; break; } @@ -249,10 +246,12 @@ bool hasFoldingWin( if (last > win->w_buffer->b_ml.ml_line_count) { last = win->w_buffer->b_ml.ml_line_count; } - if (lastp != NULL) + if (lastp != NULL) { *lastp = last; - if (firstp != NULL) + } + if (firstp != NULL) { *firstp = first; + } if (infop != NULL) { infop->fi_level = level + 1; infop->fi_lnum = first; @@ -261,7 +260,7 @@ bool hasFoldingWin( return true; } -/* foldLevel() {{{2 */ +// foldLevel() {{{2 /* * Return fold level at line number "lnum" in the current window. */ @@ -269,16 +268,18 @@ int foldLevel(linenr_T lnum) { /* While updating the folds lines between invalid_top and invalid_bot have * an undefined fold level. Otherwise update the folds first. */ - if (invalid_top == (linenr_T)0) + if (invalid_top == (linenr_T)0) { checkupdate(curwin); - else if (lnum == prev_lnum && prev_lnum_lvl >= 0) + } else if (lnum == prev_lnum && prev_lnum_lvl >= 0) { return prev_lnum_lvl; - else if (lnum >= invalid_top && lnum <= invalid_bot) + } else if (lnum >= invalid_top && lnum <= invalid_bot) { return -1; + } - /* Return quickly when there is no folding at all in this window. */ - if (!hasAnyFolding(curwin)) + // Return quickly when there is no folding at all in this window. + if (!hasAnyFolding(curwin)) { return 0; + } return foldLevelWin(curwin, lnum); } @@ -308,7 +309,7 @@ foldinfo_T fold_info(win_T *win, linenr_T lnum) linenr_T last; if (hasFoldingWin(win, lnum, NULL, &last, false, &info)) { - info.fi_lines = (long)(last - lnum + 1); + info.fi_lines = (last - lnum + 1); } else { info.fi_lines = 0; } @@ -316,7 +317,7 @@ foldinfo_T fold_info(win_T *win, linenr_T lnum) return info; } -/* foldmethodIsManual() {{{2 */ +// foldmethodIsManual() {{{2 /* * Return TRUE if 'foldmethod' is "manual" */ @@ -325,7 +326,7 @@ int foldmethodIsManual(win_T *wp) return wp->w_p_fdm[3] == 'u'; } -/* foldmethodIsIndent() {{{2 */ +// foldmethodIsIndent() {{{2 /* * Return TRUE if 'foldmethod' is "indent" */ @@ -334,7 +335,7 @@ int foldmethodIsIndent(win_T *wp) return wp->w_p_fdm[0] == 'i'; } -/* foldmethodIsExpr() {{{2 */ +// foldmethodIsExpr() {{{2 /* * Return TRUE if 'foldmethod' is "expr" */ @@ -343,7 +344,7 @@ int foldmethodIsExpr(win_T *wp) return wp->w_p_fdm[1] == 'x'; } -/* foldmethodIsMarker() {{{2 */ +// foldmethodIsMarker() {{{2 /* * Return TRUE if 'foldmethod' is "marker" */ @@ -352,7 +353,7 @@ int foldmethodIsMarker(win_T *wp) return wp->w_p_fdm[2] == 'r'; } -/* foldmethodIsSyntax() {{{2 */ +// foldmethodIsSyntax() {{{2 /* * Return TRUE if 'foldmethod' is "syntax" */ @@ -361,7 +362,7 @@ int foldmethodIsSyntax(win_T *wp) return wp->w_p_fdm[0] == 's'; } -/* foldmethodIsDiff() {{{2 */ +// foldmethodIsDiff() {{{2 /* * Return TRUE if 'foldmethod' is "diff" */ @@ -378,7 +379,7 @@ void closeFold(pos_T pos, long count) setFoldRepeat(pos, count, false); } -/* closeFoldRecurse() {{{2 */ +// closeFoldRecurse() {{{2 /* * Close fold for current window at line "lnum" recursively. */ @@ -387,19 +388,15 @@ void closeFoldRecurse(pos_T pos) (void)setManualFold(pos, false, true, NULL); } -/* opFoldRange() {{{2 */ -/* - * Open or Close folds for current window in lines "first" to "last". - * Used for "zo", "zO", "zc" and "zC" in Visual mode. - */ -void -opFoldRange( - pos_T firstpos, - pos_T lastpos, - int opening, // TRUE to open, FALSE to close - int recurse, // TRUE to do it recursively - int had_visual // TRUE when Visual selection used -) +// opFoldRange() {{{2 +/// +/// Open or Close folds for current window in lines "first" to "last". +/// Used for "zo", "zO", "zc" and "zC" in Visual mode. +/// +/// @param opening TRUE to open, FALSE to close +/// @param recurse TRUE to do it recursively +/// @param had_visual TRUE when Visual selection used +void opFoldRange(pos_T firstpos, pos_T lastpos, int opening, int recurse, int had_visual) { int done = DONE_NOTHING; // avoid error messages linenr_T first = firstpos.lnum; @@ -412,8 +409,9 @@ opFoldRange( lnum_next = lnum; /* Opening one level only: next fold to open is after the one going to * be opened. */ - if (opening && !recurse) + if (opening && !recurse) { (void)hasFolding(lnum, NULL, &lnum_next); + } (void)setManualFold(temp, opening, recurse, &done); // Closing one level only: next line to close a fold is after just // closed fold. @@ -421,14 +419,16 @@ opFoldRange( (void)hasFolding(lnum, NULL, &lnum_next); } } - if (done == DONE_NOTHING) + if (done == DONE_NOTHING) { EMSG(_(e_nofold)); - /* Force a redraw to remove the Visual highlighting. */ - if (had_visual) + } + // Force a redraw to remove the Visual highlighting. + if (had_visual) { redraw_curbuf_later(INVERTED); + } } -/* openFold() {{{2 */ +// openFold() {{{2 /* * Open fold for current window at line "lnum". * Repeat "count" times. @@ -438,7 +438,7 @@ void openFold(pos_T pos, long count) setFoldRepeat(pos, count, true); } -/* openFoldRecurse() {{{2 */ +// openFoldRecurse() {{{2 /* * Open fold for current window at line "lnum" recursively. */ @@ -447,7 +447,7 @@ void openFoldRecurse(pos_T pos) (void)setManualFold(pos, true, true, NULL); } -/* foldOpenCursor() {{{2 */ +// foldOpenCursor() {{{2 /* * Open folds until the cursor line is not in a closed fold. */ @@ -456,7 +456,7 @@ void foldOpenCursor(void) int done; checkupdate(curwin); - if (hasAnyFolding(curwin)) + if (hasAnyFolding(curwin)) { for (;; ) { done = DONE_NOTHING; (void)setManualFold(curwin->w_cursor, true, false, &done); @@ -464,9 +464,10 @@ void foldOpenCursor(void) break; } } + } } -/* newFoldLevel() {{{2 */ +// newFoldLevel() {{{2 /* * Set new foldlevel for current window. */ @@ -489,7 +490,7 @@ void newFoldLevel(void) static void newFoldLevelWin(win_T *wp) { - fold_T *fp; + fold_T *fp; checkupdate(wp); if (wp->w_fold_manual) { @@ -497,62 +498,67 @@ static void newFoldLevelWin(win_T *wp) * manual open/close will then change the flags to FD_OPEN or * FD_CLOSED for those folds that don't use 'foldlevel'. */ fp = (fold_T *)wp->w_folds.ga_data; - for (int i = 0; i < wp->w_folds.ga_len; ++i) + for (int i = 0; i < wp->w_folds.ga_len; ++i) { fp[i].fd_flags = FD_LEVEL; + } wp->w_fold_manual = false; } changed_window_setting_win(wp); } -/* foldCheckClose() {{{2 */ +// foldCheckClose() {{{2 /* * Apply 'foldlevel' to all folds that don't contain the cursor. */ void foldCheckClose(void) { - if (*p_fcl != NUL) { /* can only be "all" right now */ + if (*p_fcl != NUL) { // can only be "all" right now checkupdate(curwin); if (checkCloseRec(&curwin->w_folds, curwin->w_cursor.lnum, - (int)curwin->w_p_fdl)) + (int)curwin->w_p_fdl)) { changed_window_setting(); + } } } -/* checkCloseRec() {{{2 */ +// checkCloseRec() {{{2 static int checkCloseRec(garray_T *gap, linenr_T lnum, int level) { - fold_T *fp; + fold_T *fp; int retval = FALSE; fp = (fold_T *)gap->ga_data; for (int i = 0; i < gap->ga_len; ++i) { - /* Only manually opened folds may need to be closed. */ + // Only manually opened folds may need to be closed. if (fp[i].fd_flags == FD_OPEN) { if (level <= 0 && (lnum < fp[i].fd_top || lnum >= fp[i].fd_top + fp[i].fd_len)) { fp[i].fd_flags = FD_LEVEL; retval = TRUE; - } else + } else { retval |= checkCloseRec(&fp[i].fd_nested, lnum - fp[i].fd_top, - level - 1); + level - 1); + } } } return retval; } -/* foldCreateAllowed() {{{2 */ +// foldCreateAllowed() {{{2 /* * Return TRUE if it's allowed to manually create or delete a fold. * Give an error message and return FALSE if not. */ int foldManualAllowed(int create) { - if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin)) + if (foldmethodIsManual(curwin) || foldmethodIsMarker(curwin)) { return TRUE; - if (create) + } + if (create) { EMSG(_("E350: Cannot create fold with current 'foldmethod'")); - else + } else { EMSG(_("E351: Cannot delete fold with current 'foldmethod'")); + } return FALSE; } @@ -561,8 +567,8 @@ int foldManualAllowed(int create) /// window. void foldCreate(win_T *wp, pos_T start, pos_T end) { - fold_T *fp; - garray_T *gap; + fold_T *fp; + garray_T *gap; garray_T fold_ga; int i; int cont; @@ -659,13 +665,14 @@ void foldCreate(win_T *wp, pos_T start, pos_T end) ((fold_T *)fold_ga.ga_data)[j].fd_top -= start_rel.lnum; } } - /* Move remaining entries to after the new fold. */ - if (i < gap->ga_len) + // Move remaining entries to after the new fold. + if (i < gap->ga_len) { memmove(fp + 1, (fold_T *)gap->ga_data + i, sizeof(fold_T) * (size_t)(gap->ga_len - i)); + } gap->ga_len = gap->ga_len + 1 - cont; - /* insert new fold */ + // insert new fold fp->fd_nested = fold_ga; fp->fd_top = start_rel.lnum; fp->fd_len = end_rel.lnum - start_rel.lnum + 1; @@ -693,16 +700,11 @@ void foldCreate(win_T *wp, pos_T start, pos_T end) /// @param end delete all folds from start to end when not 0 /// @param recursive delete recursively if true /// @param had_visual true when Visual selection used -void deleteFold( - win_T *const wp, - const linenr_T start, - const linenr_T end, - const int recursive, - const bool had_visual // true when Visual selection used -) -{ - fold_T *fp; - fold_T *found_fp = NULL; +void deleteFold(win_T *const wp, const linenr_T start, const linenr_T end, const int recursive, + const bool had_visual) +{ + fold_T *fp; + fold_T *found_fp = NULL; linenr_T found_off = 0; bool maybe_small = false; int level = 0; @@ -720,9 +722,10 @@ void deleteFold( linenr_T lnum_off = 0; bool use_level = false; for (;; ) { - if (!foldFind(gap, lnum - lnum_off, &fp)) + if (!foldFind(gap, lnum - lnum_off, &fp)) { break; - /* lnum is inside this fold, remember info */ + } + // lnum is inside this fold, remember info found_ga = gap; found_fp = fp; found_off = lnum_off; @@ -733,7 +736,7 @@ void deleteFold( break; } - /* check nested folds */ + // check nested folds gap = &fp->fd_nested; lnum_off += fp->fd_top; ++level; @@ -791,7 +794,7 @@ void deleteFold( } } -/* clearFolding() {{{2 */ +// clearFolding() {{{2 /* * Remove all folding for window "win". */ @@ -801,7 +804,7 @@ void clearFolding(win_T *win) win->w_foldinvalid = false; } -/* foldUpdate() {{{2 */ +// foldUpdate() {{{2 /* * Update folds for changes in the buffer of a window. * Note that inserted/deleted lines must have already been taken care of by @@ -837,7 +840,7 @@ void foldUpdate(win_T *wp, linenr_T top, linenr_T bot) || foldmethodIsSyntax(wp)) { int save_got_int = got_int; - /* reset got_int here, otherwise it won't work */ + // reset got_int here, otherwise it won't work got_int = FALSE; foldUpdateIEMS(wp, top, bot); got_int |= save_got_int; @@ -857,7 +860,7 @@ void foldUpdateAfterInsert(void) foldOpenCursor(); } -/* foldUpdateAll() {{{2 */ +// foldUpdateAll() {{{2 /* * Update all lines in a window for folding. * Used when a fold setting changes or after reloading the buffer. @@ -871,19 +874,17 @@ void foldUpdateAll(win_T *win) } // 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 -) +/// +/// If "updown" is false: Move to the start or end of the fold. +/// If "updown" is true: move to fold at the same level. +/// @return FAIL if not moved. +/// +/// @param dir FORWARD or BACKWARD +int foldMoveTo(const bool updown, const int dir, const long count) { int retval = FAIL; linenr_T lnum; - fold_T *fp; + fold_T *fp; checkupdate(curwin); @@ -910,12 +911,14 @@ int foldMoveTo( /* When moving up, consider a fold above the cursor; when * moving down consider a fold below the cursor. */ if (dir == FORWARD) { - if (fp - (fold_T *)gap->ga_data >= gap->ga_len) + if (fp - (fold_T *)gap->ga_data >= gap->ga_len) { break; + } --fp; } else { - if (fp == (fold_T *)gap->ga_data) + if (fp == (fold_T *)gap->ga_data) { break; + } } /* don't look for contained folds, they will always move * the cursor too far. */ @@ -923,31 +926,34 @@ int foldMoveTo( } if (!last) { - /* Check if this fold is closed. */ + // Check if this fold is closed. if (check_closed(curwin, fp, &use_level, level, &maybe_small, lnum_off)) { last = true; } - /* "[z" and "]z" stop at closed fold */ - if (last && !updown) + // "[z" and "]z" stop at closed fold + if (last && !updown) { break; + } } if (updown) { if (dir == FORWARD) { - /* to start of next fold if there is one */ + // to start of next fold if there is one if (fp + 1 - (fold_T *)gap->ga_data < gap->ga_len) { lnum = fp[1].fd_top + lnum_off; - if (lnum > curwin->w_cursor.lnum) + if (lnum > curwin->w_cursor.lnum) { lnum_found = lnum; + } } } else { - /* to end of previous fold if there is one */ + // to end of previous fold if there is one if (fp > (fold_T *)gap->ga_data) { lnum = fp[-1].fd_top + lnum_off + fp[-1].fd_len - 1; - if (lnum < curwin->w_cursor.lnum) + if (lnum < curwin->w_cursor.lnum) { lnum_found = lnum; + } } } } else { @@ -955,37 +961,42 @@ int foldMoveTo( * nested folds. */ if (dir == FORWARD) { lnum = fp->fd_top + lnum_off + fp->fd_len - 1; - if (lnum > curwin->w_cursor.lnum) + if (lnum > curwin->w_cursor.lnum) { lnum_found = lnum; + } } else { lnum = fp->fd_top + lnum_off; - if (lnum < curwin->w_cursor.lnum) + if (lnum < curwin->w_cursor.lnum) { lnum_found = lnum; + } } } - if (last) + if (last) { break; + } - /* Check nested folds (if any). */ + // Check nested folds (if any). gap = &fp->fd_nested; lnum_off += fp->fd_top; ++level; } if (lnum_found != curwin->w_cursor.lnum) { - if (retval == FAIL) + if (retval == FAIL) { setpcmark(); + } curwin->w_cursor.lnum = lnum_found; curwin->w_cursor.col = 0; retval = OK; - } else + } else { break; + } } return retval; } -/* foldInitWin() {{{2 */ +// foldInitWin() {{{2 /* * Init the fold info in a new window. */ @@ -994,7 +1005,7 @@ void foldInitWin(win_T *new_win) ga_init(&new_win->w_folds, (int)sizeof(fold_T), 10); } -/* find_wl_entry() {{{2 */ +// find_wl_entry() {{{2 /* * Find an entry in the win->w_lines[] array for buffer line "lnum". * Only valid entries are considered (for entries where wl_valid is FALSE the @@ -1005,27 +1016,31 @@ int find_wl_entry(win_T *win, linenr_T lnum) { int i; - for (i = 0; i < win->w_lines_valid; ++i) + for (i = 0; i < win->w_lines_valid; ++i) { if (win->w_lines[i].wl_valid) { - if (lnum < win->w_lines[i].wl_lnum) + if (lnum < win->w_lines[i].wl_lnum) { return -1; - if (lnum <= win->w_lines[i].wl_lastlnum) + } + if (lnum <= win->w_lines[i].wl_lastlnum) { return i; + } } + } return -1; } -/* foldAdjustVisual() {{{2 */ +// foldAdjustVisual() {{{2 /* * Adjust the Visual area to include any fold at the start or end completely. */ void foldAdjustVisual(void) { - pos_T *start, *end; - char_u *ptr; + pos_T *start, *end; + char_u *ptr; - if (!VIsual_active || !hasAnyFolding(curwin)) + if (!VIsual_active || !hasAnyFolding(curwin)) { return; + } if (ltoreq(VIsual, curwin->w_cursor)) { start = &VIsual; @@ -1034,8 +1049,9 @@ void foldAdjustVisual(void) start = &curwin->w_cursor; end = &VIsual; } - if (hasFolding(start->lnum, &start->lnum, NULL)) + if (hasFolding(start->lnum, &start->lnum, NULL)) { start->col = 0; + } if (hasFolding(end->lnum, NULL, &end->lnum)) { ptr = ml_get(end->lnum); end->col = (colnr_T)STRLEN(ptr); @@ -1047,7 +1063,7 @@ void foldAdjustVisual(void) } } -/* cursor_foldstart() {{{2 */ +// cursor_foldstart() {{{2 /* * Move the cursor to the first line of a closed fold. */ @@ -1056,20 +1072,21 @@ void foldAdjustCursor(void) (void)hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL); } -/* Internal functions for "fold_T" {{{1 */ -/* cloneFoldGrowArray() {{{2 */ +// Internal functions for "fold_T" {{{1 +// cloneFoldGrowArray() {{{2 /* * Will "clone" (i.e deep copy) a garray_T of folds. */ void cloneFoldGrowArray(garray_T *from, garray_T *to) { - fold_T *from_p; - fold_T *to_p; + fold_T *from_p; + fold_T *to_p; ga_init(to, from->ga_itemsize, from->ga_growsize); - if (GA_EMPTY(from)) + if (GA_EMPTY(from)) { return; + } ga_grow(to, from->ga_len); @@ -1088,7 +1105,7 @@ void cloneFoldGrowArray(garray_T *from, garray_T *to) } } -/* foldFind() {{{2 */ +// foldFind() {{{2 /* * Search for line "lnum" in folds of growarray "gap". * Set *fpp to the fold struct for the fold that contains "lnum" or @@ -1098,7 +1115,7 @@ void cloneFoldGrowArray(garray_T *from, garray_T *to) static bool foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp) { linenr_T low, high; - fold_T *fp; + fold_T *fp; if (gap->ga_len == 0) { *fpp = NULL; @@ -1115,14 +1132,14 @@ static bool foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp) high = gap->ga_len - 1; while (low <= high) { linenr_T i = (low + high) / 2; - if (fp[i].fd_top > lnum) - /* fold below lnum, adjust high */ + if (fp[i].fd_top > lnum) { + // fold below lnum, adjust high high = i - 1; - else if (fp[i].fd_top + fp[i].fd_len <= lnum) - /* fold above lnum, adjust low */ + } else if (fp[i].fd_top + fp[i].fd_len <= lnum) { + // fold above lnum, adjust low low = i + 1; - else { - /* lnum is inside this fold */ + } else { + // lnum is inside this fold *fpp = fp + i; return TRUE; } @@ -1131,23 +1148,24 @@ static bool foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp) return false; } -/* foldLevelWin() {{{2 */ +// foldLevelWin() {{{2 /* * Return fold level at line number "lnum" in window "wp". */ static int foldLevelWin(win_T *wp, linenr_T lnum) { - fold_T *fp; + fold_T *fp; linenr_T lnum_rel = lnum; int level = 0; - garray_T *gap; + garray_T *gap; - /* Recursively search for a fold that contains "lnum". */ + // Recursively search for a fold that contains "lnum". gap = &wp->w_folds; for (;; ) { - if (!foldFind(gap, lnum_rel, &fp)) + if (!foldFind(gap, lnum_rel, &fp)) { break; - /* Check nested folds. Line number is relative to containing fold. */ + } + // Check nested folds. Line number is relative to containing fold. gap = &fp->fd_nested; lnum_rel -= fp->fd_top; ++level; @@ -1156,19 +1174,19 @@ static int foldLevelWin(win_T *wp, linenr_T lnum) return level; } -/* checkupdate() {{{2 */ +// checkupdate() {{{2 /* * Check if the folds in window "wp" are invalid and update them if needed. */ static void checkupdate(win_T *wp) { if (wp->w_foldinvalid) { - foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); /* will update all */ + foldUpdate(wp, (linenr_T)1, (linenr_T)MAXLNUM); // will update all wp->w_foldinvalid = false; } } -/* setFoldRepeat() {{{2 */ +// setFoldRepeat() {{{2 /* * Open or close fold for current window at line "lnum". * Repeat "count" times. @@ -1182,26 +1200,23 @@ static void setFoldRepeat(pos_T pos, long count, int do_open) done = DONE_NOTHING; (void)setManualFold(pos, do_open, false, &done); if (!(done & DONE_ACTION)) { - /* Only give an error message when no fold could be opened. */ - if (n == 0 && !(done & DONE_FOLD)) + // Only give an error message when no fold could be opened. + if (n == 0 && !(done & DONE_FOLD)) { EMSG(_(e_nofold)); + } break; } } } -/* setManualFold() {{{2 */ -/* - * Open or close the fold in the current window which contains "lnum". - * Also does this for other windows in diff mode when needed. - */ -static linenr_T -setManualFold( - pos_T pos, - int opening, // TRUE when opening, FALSE when closing - int recurse, // TRUE when closing/opening recursive - int *donep -) +// setManualFold() {{{2 +/// +/// Open or close the fold in the current window which contains "lnum". +/// Also does this for other windows in diff mode when needed. +/// +/// @param opening TRUE when opening, FALSE when closing +/// @param recurse TRUE when closing/opening recursive +static linenr_T setManualFold(pos_T pos, int opening, int recurse, int *donep) { linenr_T lnum = pos.lnum; if (foldmethodIsDiff(curwin) && curwin->w_p_scb) { @@ -1224,33 +1239,28 @@ setManualFold( return setManualFoldWin(curwin, lnum, opening, recurse, donep); } -/* setManualFoldWin() {{{2 */ -/* - * Open or close the fold in window "wp" which contains "lnum". - * "donep", when not NULL, points to flag that is set to DONE_FOLD when some - * fold was found and to DONE_ACTION when some fold was opened or closed. - * When "donep" is NULL give an error message when no fold was found for - * "lnum", but only if "wp" is "curwin". - * Return the line number of the next line that could be closed. - * It's only valid when "opening" is TRUE! - */ -static linenr_T -setManualFoldWin( - win_T *wp, - linenr_T lnum, - int opening, // TRUE when opening, FALSE when closing - int recurse, // TRUE when closing/opening recursive - int *donep -) -{ - fold_T *fp; - fold_T *fp2; - fold_T *found = NULL; +// setManualFoldWin() {{{2 +/// Open or close the fold in window "wp" which contains "lnum". +/// "donep", when not NULL, points to flag that is set to DONE_FOLD when some +/// fold was found and to DONE_ACTION when some fold was opened or closed. +/// When "donep" is NULL give an error message when no fold was found for +/// "lnum", but only if "wp" is "curwin". +/// +/// @param opening TRUE when opening, FALSE when closing +/// @param recurse TRUE when closing/opening recursive +/// +/// @return the line number of the next line that could be closed. +/// It's only valid when "opening" is TRUE! +static linenr_T setManualFoldWin(win_T *wp, linenr_T lnum, int opening, int recurse, int *donep) +{ + fold_T *fp; + fold_T *fp2; + fold_T *found = NULL; int j; int level = 0; int use_level = FALSE; int found_fold = FALSE; - garray_T *gap; + garray_T *gap; linenr_T next = MAXLNUM; linenr_T off = 0; int done = 0; @@ -1270,43 +1280,47 @@ setManualFoldWin( break; } - /* lnum is inside this fold */ + // lnum is inside this fold found_fold = TRUE; - /* If there is a following fold, continue there next time. */ - if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len) + // If there is a following fold, continue there next time. + if (fp + 1 < (fold_T *)gap->ga_data + gap->ga_len) { next = fp[1].fd_top + off; + } - /* Change from level-dependent folding to manual. */ + // Change from level-dependent folding to manual. if (use_level || fp->fd_flags == FD_LEVEL) { use_level = TRUE; - if (level >= wp->w_p_fdl) + if (level >= wp->w_p_fdl) { fp->fd_flags = FD_CLOSED; - else + } else { fp->fd_flags = FD_OPEN; + } fp2 = (fold_T *)fp->fd_nested.ga_data; - for (j = 0; j < fp->fd_nested.ga_len; ++j) + for (j = 0; j < fp->fd_nested.ga_len; ++j) { fp2[j].fd_flags = FD_LEVEL; + } } - /* Simple case: Close recursively means closing the fold. */ + // Simple case: Close recursively means closing the fold. if (!opening && recurse) { if (fp->fd_flags != FD_CLOSED) { done |= DONE_ACTION; fp->fd_flags = FD_CLOSED; } } else if (fp->fd_flags == FD_CLOSED) { - /* When opening, open topmost closed fold. */ + // When opening, open topmost closed fold. if (opening) { fp->fd_flags = FD_OPEN; done |= DONE_ACTION; - if (recurse) + if (recurse) { foldOpenNested(fp); + } } break; } - /* fold is open, check nested folds */ + // fold is open, check nested folds found = fp; gap = &fp->fd_nested; lnum -= fp->fd_top; @@ -1314,31 +1328,34 @@ setManualFoldWin( ++level; } if (found_fold) { - /* When closing and not recurse, close deepest open fold. */ + // When closing and not recurse, close deepest open fold. if (!opening && found != NULL) { found->fd_flags = FD_CLOSED; done |= DONE_ACTION; } wp->w_fold_manual = true; - if (done & DONE_ACTION) + if (done & DONE_ACTION) { changed_window_setting_win(wp); + } done |= DONE_FOLD; - } else if (donep == NULL && wp == curwin) + } else if (donep == NULL && wp == curwin) { EMSG(_(e_nofold)); + } - if (donep != NULL) + if (donep != NULL) { *donep |= done; + } return next; } -/* foldOpenNested() {{{2 */ +// foldOpenNested() {{{2 /* * Open all nested folds in fold "fpr" recursively. */ static void foldOpenNested(fold_T *fpr) { - fold_T *fp; + fold_T *fp; fp = (fold_T *)fpr->fd_nested.ga_data; for (int i = 0; i < fpr->fd_nested.ga_len; ++i) { @@ -1368,15 +1385,16 @@ static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx, int moved = fp->fd_nested.ga_len; ga_grow(gap, moved - 1); { - /* Get "fp" again, the array may have been reallocated. */ + // 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 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) + if (fp->fd_flags == FD_LEVEL) { nfp[i].fd_flags = FD_LEVEL; + } if (fp->fd_small == kNone) { nfp[i].fd_small = kNone; } @@ -1395,7 +1413,7 @@ static void deleteFoldEntry(win_T *const wp, garray_T *const gap, const int idx, } } -/* deleteFoldRecurse() {{{2 */ +// deleteFoldRecurse() {{{2 /* * Delete nested folds in a fold. */ @@ -1405,7 +1423,7 @@ void deleteFoldRecurse(buf_T *bp, garray_T *gap) GA_DEEP_CLEAR(gap, fold_T, DELETE_FOLD_NESTED); } -/* foldMarkAdjust() {{{2 */ +// foldMarkAdjust() {{{2 /* * Update line numbers of folds for inserted/deleted lines. */ @@ -1413,8 +1431,9 @@ void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long { /* If deleting marks from line1 to line2, but not deleting all those * lines, set line2 so that only deleted lines have their folds removed. */ - if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) + if (amount == MAXLNUM && line2 >= line1 && line2 - line1 >= -amount_after) { line2 = line1 - amount_after - 1; + } /* If appending a line in Insert mode, it should be included in the fold * just above the line. */ if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) { @@ -1424,12 +1443,10 @@ void foldMarkAdjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long } // foldMarkAdjustRecurse() {{{2 -static void foldMarkAdjustRecurse( - win_T *wp, garray_T *gap, - linenr_T line1, linenr_T line2, long amount, long amount_after -) +static void foldMarkAdjustRecurse(win_T *wp, garray_T *gap, linenr_T line1, linenr_T line2, + long amount, long amount_after) { - fold_T *fp; + fold_T *fp; linenr_T last; linenr_T top; @@ -1439,12 +1456,13 @@ static void foldMarkAdjustRecurse( /* In Insert mode an inserted line at the top of a fold is considered part * of the fold, otherwise it isn't. */ - if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) + if ((State & INSERT) && amount == (linenr_T)1 && line2 == MAXLNUM) { top = line1 + 1; - else + } else { top = line1; + } - /* Find the fold containing or just below "line1". */ + // Find the fold containing or just below "line1". (void)foldFind(gap, line1, &fp); /* @@ -1453,26 +1471,28 @@ static void foldMarkAdjustRecurse( for (int i = (int)(fp - (fold_T *)gap->ga_data); i < gap->ga_len; ++i, ++fp) { /* * Check for these situations: - * 1 2 3 - * 1 2 3 - * line1 2 3 4 5 - * 2 3 4 5 - * 2 3 4 5 - * line2 2 3 4 5 - * 3 5 6 - * 3 5 6 + * 1 2 3 + * 1 2 3 + * line1 2 3 4 5 + * 2 3 4 5 + * 2 3 4 5 + * line2 2 3 4 5 + * 3 5 6 + * 3 5 6 */ - last = fp->fd_top + fp->fd_len - 1; /* last line of fold */ + last = fp->fd_top + fp->fd_len - 1; // last line of fold - /* 1. fold completely above line1: nothing to do */ - if (last < line1) + // 1. fold completely above line1: nothing to do + if (last < line1) { continue; + } - /* 6. fold below line2: only adjust for amount_after */ + // 6. fold below line2: only adjust for amount_after if (fp->fd_top > line2) { - if (amount_after == 0) + if (amount_after == 0) { break; + } fp->fd_top += amount_after; } else { if (fp->fd_top >= top && last <= line2) { @@ -1491,13 +1511,14 @@ static void foldMarkAdjustRecurse( foldMarkAdjustRecurse(wp, &fp->fd_nested, line1 - fp->fd_top, line2 - fp->fd_top, amount, amount_after); if (last <= line2) { - /* 2. fold contains line1, line2 is below fold */ - if (amount == MAXLNUM) + // 2. fold contains line1, line2 is below fold + if (amount == MAXLNUM) { fp->fd_len = line1 - fp->fd_top; - else + } else { fp->fd_len += amount; + } } else { - /* 3. fold contains line1 and line2 */ + // 3. fold contains line1 and line2 fp->fd_len += amount_after; } } else { @@ -1522,7 +1543,7 @@ static void foldMarkAdjustRecurse( } } -/* getDeepestNesting() {{{2 */ +// getDeepestNesting() {{{2 /* * Get the lowest 'foldlevel' value that makes the deepest nested fold in the * current window open. @@ -1537,13 +1558,14 @@ static int getDeepestNestingRecurse(garray_T *gap) { int level; int maxlevel = 0; - fold_T *fp; + fold_T *fp; fp = (fold_T *)gap->ga_data; for (int i = 0; i < gap->ga_len; ++i) { level = getDeepestNestingRecurse(&fp[i].fd_nested) + 1; - if (level > maxlevel) + if (level > maxlevel) { maxlevel = level; + } } return maxlevel; @@ -1558,14 +1580,8 @@ static int getDeepestNestingRecurse(garray_T *gap) /// @param[out] maybe_smallp true: outer this had fd_small == kNone /// @param lnum_off line number offset for fp->fd_top /// @return true if fold is closed -static bool check_closed( - win_T *const wp, - fold_T *const fp, - bool *const use_levelp, - const int level, - bool *const maybe_smallp, - const linenr_T lnum_off -) +static bool check_closed(win_T *const wp, fold_T *const fp, bool *const use_levelp, const int level, + bool *const maybe_smallp, const linenr_T lnum_off) { bool closed = false; @@ -1598,13 +1614,9 @@ static bool check_closed( // checkSmall() {{{2 /// Update fd_small field of fold "fp". -/// @param lnum_off offset for fp->fd_top -static void -checkSmall( - win_T *const wp, - fold_T *const fp, - const linenr_T lnum_off // offset for fp->fd_top -) +/// +/// @param lnum_off offset for fp->fd_top +static void checkSmall(win_T *const wp, fold_T *const fp, const linenr_T lnum_off) { if (fp->fd_small == kNone) { // Mark any nested folds to maybe-small @@ -1636,7 +1648,7 @@ static void setSmallMaybe(garray_T *gap) } } -/* foldCreateMarkers() {{{2 */ +// foldCreateMarkers() {{{2 /* * Create a fold from line "start" to line "end" (inclusive) in the current * window by adding markers. @@ -1665,17 +1677,16 @@ static void foldCreateMarkers(win_T *wp, pos_T start, pos_T end) buf_updates_send_changes(buf, start.lnum, num_changed, num_changed, true); } -/* foldAddMarker() {{{2 */ +// foldAddMarker() {{{2 /* * Add "marker[markerlen]" in 'commentstring' to line "lnum". */ -static void foldAddMarker( - buf_T *buf, pos_T pos, const char_u *marker, size_t markerlen) +static void foldAddMarker(buf_T *buf, pos_T pos, const char_u *marker, size_t markerlen) { - char_u *cms = buf->b_p_cms; - char_u *line; - char_u *newline; - char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s"); + char_u *cms = buf->b_p_cms; + char_u *line; + char_u *newline; + char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s"); bool line_is_comment = false; linenr_T lnum = pos.lnum; @@ -1707,17 +1718,11 @@ static void foldAddMarker( } } -/* deleteFoldMarkers() {{{2 */ -/* - * Delete the markers for a fold, causing it to be deleted. - */ -static void -deleteFoldMarkers( - win_T *wp, - fold_T *fp, - int recursive, - linenr_T lnum_off // offset for fp->fd_top -) +// deleteFoldMarkers() {{{2 +/// Delete the markers for a fold, causing it to be deleted. +/// +/// @param lnum_off offset for fp->fd_top +static void deleteFoldMarkers(win_T *wp, fold_T *fp, int recursive, linenr_T lnum_off) { if (recursive) { for (int i = 0; i < fp->fd_nested.ga_len; i++) { @@ -1737,13 +1742,11 @@ deleteFoldMarkers( // Delete 'commentstring' if it matches. // If the marker is not found, there is no error message. Could be a missing // close-marker. -static void foldDelMarker( - buf_T *buf, linenr_T lnum, char_u *marker, size_t markerlen -) +static void foldDelMarker(buf_T *buf, linenr_T lnum, char_u *marker, size_t markerlen) { - char_u *newline; - char_u *cms = buf->b_p_cms; - char_u *cms2; + char_u *newline; + char_u *cms = buf->b_p_cms; + char_u *cms2; // end marker may be missing and fold extends below the last line if (lnum > buf->b_ml.ml_line_count) { @@ -1754,12 +1757,13 @@ static void foldDelMarker( if (STRNCMP(p, marker, markerlen) != 0) { continue; } - /* Found the marker, include a digit if it's there. */ + // Found the marker, include a digit if it's there. size_t len = markerlen; - if (ascii_isdigit(p[len])) + if (ascii_isdigit(p[len])) { ++len; + } if (*cms != NUL) { - /* Also delete 'commentstring' if it matches. */ + // Also delete 'commentstring' if it matches. cms2 = (char_u *)strstr((char *)cms, "%s"); if (p - line >= cms2 - cms && STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0 @@ -1769,7 +1773,7 @@ static void foldDelMarker( } } if (u_save(lnum - 1, lnum + 1) == OK) { - /* Make new line: text-before-marker + text-after-marker */ + // Make new line: text-before-marker + text-after-marker newline = xmalloc(STRLEN(line) - len + 1); assert(p >= line); memcpy(newline, line, (size_t)(p - line)); @@ -1791,34 +1795,35 @@ static void foldDelMarker( /// @return the text for a closed fold /// /// Otherwise the result is in allocated memory. -char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, - foldinfo_T foldinfo, char_u *buf) +char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo, char_u *buf) FUNC_ATTR_NONNULL_ARG(1) { - char_u *text = NULL; - /* an error occurred when evaluating 'fdt' setting */ + char_u *text = NULL; + // an error occurred when evaluating 'fdt' setting static int got_fdt_error = FALSE; int save_did_emsg = did_emsg; - static win_T *last_wp = NULL; + static win_T *last_wp = NULL; static linenr_T last_lnum = 0; - if (last_wp == NULL || last_wp != wp || last_lnum > lnum || last_lnum == 0) - /* window changed, try evaluating foldtext setting once again */ + if (last_wp == NULL || last_wp != wp || last_lnum > lnum || last_lnum == 0) { + // window changed, try evaluating foldtext setting once again got_fdt_error = FALSE; + } - if (!got_fdt_error) - /* a previous error should not abort evaluating 'foldexpr' */ + if (!got_fdt_error) { + // a previous error should not abort evaluating 'foldexpr' did_emsg = FALSE; + } if (*wp->w_p_fdt != NUL) { char dashes[MAX_LEVEL + 2]; - win_T *save_curwin; + win_T *save_curwin; int level; - char_u *p; + char_u *p; // Set "v:foldstart" and "v:foldend". - set_vim_var_nr(VV_FOLDSTART, (varnumber_T) lnum); - set_vim_var_nr(VV_FOLDEND, (varnumber_T) lnume); + set_vim_var_nr(VV_FOLDSTART, (varnumber_T)lnum); + set_vim_var_nr(VV_FOLDEND, (varnumber_T)lnume); // Set "v:folddashes" to a string of "level" dashes. // Set "v:foldlevel" to "level". @@ -1829,22 +1834,22 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, memset(dashes, '-', (size_t)level); dashes[level] = NUL; set_vim_var_string(VV_FOLDDASHES, dashes, -1); - set_vim_var_nr(VV_FOLDLEVEL, (varnumber_T) level); + set_vim_var_nr(VV_FOLDLEVEL, (varnumber_T)level); - /* skip evaluating foldtext on errors */ + // skip evaluating foldtext on errors if (!got_fdt_error) { save_curwin = curwin; curwin = wp; curbuf = wp->w_buffer; emsg_silent++; // handle exceptions, but don't display errors - text = eval_to_string_safe( - wp->w_p_fdt, NULL, - was_set_insecurely(wp, (char_u *)"foldtext", OPT_LOCAL)); + text = eval_to_string_safe(wp->w_p_fdt, NULL, + was_set_insecurely(wp, (char_u *)"foldtext", OPT_LOCAL)); emsg_silent--; - if (text == NULL || did_emsg) + if (text == NULL || did_emsg) { got_fdt_error = TRUE; + } curwin = save_curwin; curbuf = curwin->w_buffer; @@ -1853,8 +1858,9 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, last_wp = wp; set_vim_var_string(VV_FOLDDASHES, NULL, -1); - if (!did_emsg && save_did_emsg) + if (!did_emsg && save_did_emsg) { did_emsg = save_did_emsg; + } if (text != NULL) { /* Replace unprintable characters, if there are any. But @@ -1867,10 +1873,11 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, break; } p += len - 1; - } else if (*p == TAB) + } else if (*p == TAB) { *p = ' '; - else if (ptr2cells(p) > 1) + } else if (ptr2cells(p) > 1) { break; + } } if (*p != NUL) { p = (char_u *)transstr((const char *)text); @@ -1891,35 +1898,37 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, return text; } -/* foldtext_cleanup() {{{2 */ +// foldtext_cleanup() {{{2 /* * Remove 'foldmarker' and 'commentstring' from "str" (in-place). */ void foldtext_cleanup(char_u *str) { - char_u *s; - char_u *p; + char_u *s; + char_u *p; int did1 = FALSE; int did2 = FALSE; - /* Ignore leading and trailing white space in 'commentstring'. */ + // Ignore leading and trailing white space in 'commentstring'. char_u *cms_start = skipwhite(curbuf->b_p_cms); size_t cms_slen = STRLEN(cms_start); - while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1])) + while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1])) { --cms_slen; + } - /* locate "%s" in 'commentstring', use the part before and after it. */ + // locate "%s" in 'commentstring', use the part before and after it. char_u *cms_end = (char_u *)strstr((char *)cms_start, "%s"); size_t cms_elen = 0; if (cms_end != NULL) { cms_elen = cms_slen - (size_t)(cms_end - cms_start); cms_slen = (size_t)(cms_end - cms_start); - /* exclude white space before "%s" */ - while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1])) + // exclude white space before "%s" + while (cms_slen > 0 && ascii_iswhite(cms_start[cms_slen - 1])) { --cms_slen; + } - /* skip "%s" and white space after it */ + // skip "%s" and white space after it s = skipwhite(cms_end + 2); cms_elen -= (size_t)(s - cms_end); cms_end = s; @@ -1928,18 +1937,21 @@ void foldtext_cleanup(char_u *str) for (s = str; *s != NUL; ) { size_t len = 0; - if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) + if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0) { len = foldstartmarkerlen; - else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) + } else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0) { len = foldendmarkerlen; + } if (len > 0) { - if (ascii_isdigit(s[len])) + if (ascii_isdigit(s[len])) { ++len; + } /* May remove 'commentstring' start. Useful when it's a double * quote and we already removed a double quote. */ - for (p = s; p > str && ascii_iswhite(p[-1]); --p) + for (p = s; p > str && ascii_iswhite(p[-1]); --p) { ; + } if (p >= str + cms_slen && STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) { len += (size_t)(s - p) + cms_slen; @@ -1956,8 +1968,9 @@ void foldtext_cleanup(char_u *str) } } if (len != 0) { - while (ascii_iswhite(s[len])) + while (ascii_iswhite(s[len])) { ++len; + } STRMOVE(s, s + len); } else { MB_PTR_ADV(s); @@ -1965,10 +1978,10 @@ void foldtext_cleanup(char_u *str) } } -/* Folding by indent, expr, marker and syntax. {{{1 */ -/* Function declarations. {{{2 */ +// Folding by indent, expr, marker and syntax. {{{1 +// Function declarations. {{{2 -/* foldUpdateIEMS() {{{2 */ +// foldUpdateIEMS() {{{2 /* * Update the folding for window "wp", at least from lines "top" to "bot". * IEMS = "Indent Expr Marker Syntax" @@ -1977,28 +1990,30 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) { fline_T fline; LevelGetter getlevel = NULL; - fold_T *fp; + fold_T *fp; - /* Avoid problems when being called recursively. */ - if (invalid_top != (linenr_T)0) + // Avoid problems when being called recursively. + if (invalid_top != (linenr_T)0) { return; + } if (wp->w_foldinvalid) { - /* Need to update all folds. */ + // Need to update all folds. top = 1; bot = wp->w_buffer->b_ml.ml_line_count; wp->w_foldinvalid = false; - /* Mark all folds a maybe-small. */ + // Mark all folds a maybe-small. setSmallMaybe(&wp->w_folds); } - /* add the context for "diff" folding */ + // add the context for "diff" folding if (foldmethodIsDiff(wp)) { - if (top > diff_context) + if (top > diff_context) { top -= diff_context; - else + } else { top = 1; + } bot += diff_context; } @@ -2023,7 +2038,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) if (foldmethodIsMarker(wp)) { getlevel = foldlevelMarker; - /* Init marker variables to speed up foldlevelMarker(). */ + // Init marker variables to speed up foldlevelMarker(). parseMarker(wp); /* Need to get the level of the line above top, it is used if there is @@ -2032,7 +2047,7 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) // 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. */ + // The fold may end just above the top, check for that. fline.lnum = top - 1; fline.lvl = level; getlevel(&fline); @@ -2040,10 +2055,11 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) /* If a fold started here, we already had the level, if it stops * here, we need to use lvl_next. Could also start and end a fold * in the same line. */ - if (fline.lvl > level) + if (fline.lvl > level) { fline.lvl = level - (fline.lvl - fline.lvl_next); - else + } else { fline.lvl = fline.lvl_next; + } } fline.lnum = top; getlevel(&fline); @@ -2053,14 +2069,16 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) getlevel = foldlevelExpr; /* start one line back, because a "<1" may indicate the end of a * fold in the topline */ - if (top > 1) + if (top > 1) { --fline.lnum; - } else if (foldmethodIsSyntax(wp)) + } + } else if (foldmethodIsSyntax(wp)) { getlevel = foldlevelSyntax; - else if (foldmethodIsDiff(wp)) + } else if (foldmethodIsDiff(wp)) { getlevel = foldlevelDiff; - else + } else { getlevel = foldlevelIndent; + } /* Backup to a line for which the fold level is defined. Since it's * always defined for line one, we will stop there. */ @@ -2070,8 +2088,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) * the next line, but we search backwards here. */ fline.lvl_next = -1; getlevel(&fline); - if (fline.lvl >= 0) + if (fline.lvl >= 0) { break; + } } } @@ -2084,14 +2103,15 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) */ if (foldlevelSyntax == getlevel) { garray_T *gap = &wp->w_folds; - fold_T *fpn = NULL; + fold_T *fpn = NULL; int current_fdl = 0; linenr_T fold_start_lnum = 0; linenr_T lnum_rel = fline.lnum; while (current_fdl < fline.lvl) { - if (!foldFind(gap, lnum_rel, &fpn)) + if (!foldFind(gap, lnum_rel, &fpn)) { break; + } ++current_fdl; fold_start_lnum += fpn->fd_top; @@ -2101,8 +2121,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) if (fpn != NULL && current_fdl == fline.lvl) { linenr_T fold_end_lnum = fold_start_lnum + fpn->fd_len; - if (fold_end_lnum > bot) + if (fold_end_lnum > bot) { bot = fold_end_lnum; + } } } @@ -2115,34 +2136,37 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) while (!got_int) { /* Always stop at the end of the file ("end" can be past the end of * the file). */ - if (fline.lnum > wp->w_buffer->b_ml.ml_line_count) + if (fline.lnum > wp->w_buffer->b_ml.ml_line_count) { break; + } if (fline.lnum > end) { /* For "marker", "expr" and "syntax" methods: If a change caused * a fold to be removed, we need to continue at least until where * it ended. */ if (getlevel != foldlevelMarker && getlevel != foldlevelSyntax - && getlevel != foldlevelExpr) + && getlevel != foldlevelExpr) { break; + } if ((start <= end && foldFind(&wp->w_folds, end, &fp) && fp->fd_top + fp->fd_len - 1 > end) || (fline.lvl == 0 && foldFind(&wp->w_folds, fline.lnum, &fp) - && fp->fd_top < fline.lnum)) + && fp->fd_top < fline.lnum)) { end = fp->fd_top + fp->fd_len - 1; - else if (getlevel == foldlevelSyntax - && foldLevelWin(wp, fline.lnum) != fline.lvl) + } else if (getlevel == foldlevelSyntax + && foldLevelWin(wp, fline.lnum) != fline.lvl) { /* For "syntax" method: Compare the foldlevel that the syntax * tells us to the foldlevel from the existing folds. If they * don't match continue updating folds. */ end = fline.lnum; - else + } else { break; + } } - /* A level 1 fold starts at a line with foldlevel > 0. */ + // A level 1 fold starts at a line with foldlevel > 0. if (fline.lvl > 0) { invalid_top = fline.lnum; invalid_bot = end; @@ -2150,8 +2174,9 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) FD_LEVEL); start = fline.lnum; } else { - if (fline.lnum == wp->w_buffer->b_ml.ml_line_count) + if (fline.lnum == wp->w_buffer->b_ml.ml_line_count) { break; + } ++fline.lnum; fline.lvl = fline.lvl_next; getlevel(&fline); @@ -2161,56 +2186,58 @@ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) // There can't be any folds from start until end now. foldRemove(wp, &wp->w_folds, start, end); - /* If some fold changed, need to redraw and position cursor. */ - if (fold_changed && wp->w_p_fen) + // If some fold changed, need to redraw and position cursor. + if (fold_changed && wp->w_p_fen) { changed_window_setting_win(wp); + } /* If we updated folds past "bot", need to redraw more lines. Don't do * this in other situations, the changed lines will be redrawn anyway and * this method can cause the whole window to be updated. */ if (end != bot) { - if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) + if (wp->w_redraw_top == 0 || wp->w_redraw_top > top) { wp->w_redraw_top = top; - if (wp->w_redraw_bot < end) + } + if (wp->w_redraw_bot < end) { wp->w_redraw_bot = end; + } } invalid_top = (linenr_T)0; } -/* foldUpdateIEMSRecurse() {{{2 */ -/* - * Update a fold that starts at "flp->lnum". At this line there is always a - * valid foldlevel, and its level >= "level". - * "flp" is valid for "flp->lnum" when called and it's valid when returning. - * "flp->lnum" is set to the lnum just below the fold, if it ends before - * "bot", it's "bot" plus one if the fold continues and it's bigger when using - * the marker method and a text change made following folds to change. - * When returning, "flp->lnum_save" is the line number that was used to get - * the level when the level at "flp->lnum" is invalid. - * Remove any folds from "startlnum" up to here at this level. - * Recursively update nested folds. - * Below line "bot" there are no changes in the text. - * "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the - * outer fold. - * "flp->off" is the offset to the real line number in the buffer. - * - * All this would be a lot simpler if all folds in the range would be deleted - * and then created again. But we would lose all information about the - * folds, even when making changes that don't affect the folding (e.g. "vj~"). - * - * 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 *const gap, const int level, const linenr_T startlnum, - fline_T *const flp, LevelGetter getlevel, linenr_T bot, - const char topflags // containing fold flags -) +// foldUpdateIEMSRecurse() {{{2 +/// Update a fold that starts at "flp->lnum". At this line there is always a +/// valid foldlevel, and its level >= "level". +/// +/// "flp" is valid for "flp->lnum" when called and it's valid when returning. +/// "flp->lnum" is set to the lnum just below the fold, if it ends before +/// "bot", it's "bot" plus one if the fold continues and it's bigger when using +/// the marker method and a text change made following folds to change. +/// When returning, "flp->lnum_save" is the line number that was used to get +/// the level when the level at "flp->lnum" is invalid. +/// Remove any folds from "startlnum" up to here at this level. +/// Recursively update nested folds. +/// Below line "bot" there are no changes in the text. +/// "flp->lnum", "flp->lnum_save" and "bot" are relative to the start of the +/// outer fold. +/// "flp->off" is the offset to the real line number in the buffer. +/// +/// All this would be a lot simpler if all folds in the range would be deleted +/// and then created again. But we would lose all information about the +/// folds, even when making changes that don't affect the folding (e.g. "vj~"). +/// +/// @param topflags containing fold flags +/// +/// @return 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 *const gap, const int level, + const linenr_T startlnum, fline_T *const flp, + LevelGetter getlevel, linenr_T bot, const char topflags) { linenr_T ll; - fold_T *fp = NULL; - fold_T *fp2; + fold_T *fp = NULL; + fold_T *fp2; int lvl = level; linenr_T startlnum2 = startlnum; const linenr_T firstlnum = flp->lnum; // first lnum we got @@ -2248,7 +2275,7 @@ static linenr_T foldUpdateIEMSRecurse( */ flp->lnum_save = flp->lnum; while (!got_int) { - /* Updating folds can be slow, check for CTRL-C. */ + // Updating folds can be slow, check for CTRL-C. line_breakcheck(); /* Set "lvl" to the level of line "flp->lnum". When flp->start is set @@ -2256,11 +2283,13 @@ static linenr_T foldUpdateIEMSRecurse( * force the fold to end. Do the same when had_end is set: Previous * line was marked as end of a fold. */ lvl = flp->lvl; - if (lvl > MAX_LEVEL) + if (lvl > MAX_LEVEL) { lvl = MAX_LEVEL; + } if (flp->lnum > firstlnum - && (level > lvl - flp->start || level >= flp->had_end)) + && (level > lvl - flp->start || level >= flp->had_end)) { lvl = 0; + } if (flp->lnum > bot && !finish && fp != NULL) { /* For "marker" and "syntax" methods: @@ -2271,8 +2300,9 @@ static linenr_T foldUpdateIEMSRecurse( */ if (getlevel != foldlevelMarker && getlevel != foldlevelExpr - && getlevel != foldlevelSyntax) + && getlevel != foldlevelSyntax) { break; + } i = 0; fp2 = fp; if (lvl >= level) { @@ -2313,10 +2343,11 @@ static linenr_T foldUpdateIEMSRecurse( while (!got_int) { /* set concat to 1 if it's allowed to concatenated this fold * with a previous one that touches it. */ - if (flp->start != 0 || flp->had_end <= MAX_LEVEL) + if (flp->start != 0 || flp->had_end <= MAX_LEVEL) { concat = 0; - else + } else { concat = 1; + } /* Find an existing fold to re-use. Preferably one that * includes startlnum, otherwise one that ends just before @@ -2343,14 +2374,14 @@ static linenr_T foldUpdateIEMSRecurse( // nested folds (with relative line numbers) down. foldMarkAdjustRecurse(flp->wp, &fp->fd_nested, (linenr_T)0, (linenr_T)MAXLNUM, - (long)(fp->fd_top - firstlnum), 0L); + (fp->fd_top - firstlnum), 0L); } else { // Will move fold down, move nested folds relatively up. foldMarkAdjustRecurse(flp->wp, &fp->fd_nested, (linenr_T)0, - (long)(firstlnum - fp->fd_top - 1), + (firstlnum - fp->fd_top - 1), (linenr_T)MAXLNUM, - (long)(fp->fd_top - firstlnum)); + (fp->fd_top - firstlnum)); } fp->fd_len += fp->fd_top - firstlnum; fp->fd_top = firstlnum; @@ -2413,7 +2444,7 @@ static linenr_T foldUpdateIEMSRecurse( * to stop just above startlnum. */ fp->fd_len = startlnum - fp->fd_top; foldMarkAdjustRecurse(flp->wp, &fp->fd_nested, - (linenr_T)fp->fd_len, (linenr_T)MAXLNUM, + fp->fd_len, (linenr_T)MAXLNUM, (linenr_T)MAXLNUM, 0L); fold_changed = true; } @@ -2439,10 +2470,12 @@ static linenr_T foldUpdateIEMSRecurse( fp->fd_flags = FD_OPEN; } else if (i <= 0) { fp->fd_flags = topflags; - if (topflags != FD_LEVEL) + if (topflags != FD_LEVEL) { flp->wp->w_fold_manual = true; - } else + } + } else { fp->fd_flags = (fp - 1)->fd_flags; + } fp->fd_small = kNone; // If using the "marker", "expr" or "syntax" method, we // need to continue until the end of the fold is found. @@ -2491,7 +2524,7 @@ static linenr_T foldUpdateIEMSRecurse( bot += fp->fd_top; startlnum2 = flp->lnum; - /* This fold may end at the same line, don't incr. flp->lnum. */ + // This fold may end at the same line, don't incr. flp->lnum. } else { /* * Get the level of the next line, then continue the loop to check @@ -2502,20 +2535,23 @@ static linenr_T foldUpdateIEMSRecurse( flp->lnum = flp->lnum_save; ll = flp->lnum + 1; while (!got_int) { - /* Make the previous level available to foldlevel(). */ + // Make the previous level available to foldlevel(). prev_lnum = flp->lnum; prev_lnum_lvl = flp->lvl; - if (++flp->lnum > linecount) + if (++flp->lnum > linecount) { break; + } flp->lvl = flp->lvl_next; getlevel(flp); - if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL) + if (flp->lvl >= 0 || flp->had_end <= MAX_LEVEL) { break; + } } prev_lnum = 0; - if (flp->lnum > linecount) + if (flp->lnum > linecount) { break; + } /* leave flp->lnum_save to lnum of the line that was used to get * the level, flp->lnum to the lnum of the next line. */ @@ -2524,8 +2560,9 @@ static linenr_T foldUpdateIEMSRecurse( } } - if (fp == NULL) /* only happens when got_int is set */ + if (fp == NULL) { // only happens when got_int is set return bot; + } /* * Get here when: @@ -2574,18 +2611,19 @@ static linenr_T foldUpdateIEMSRecurse( } } - /* delete following folds that end before the current line */ + // delete following folds that end before the current line for (;; ) { fp2 = fp + 1; if (fp2 >= (fold_T *)gap->ga_data + gap->ga_len - || fp2->fd_top > flp->lnum) + || fp2->fd_top > flp->lnum) { break; + } if (fp2->fd_top + fp2->fd_len > flp->lnum) { if (fp2->fd_top < flp->lnum) { // Make fold that includes lnum start at lnum. foldMarkAdjustRecurse(flp->wp, &fp2->fd_nested, - (linenr_T)0, (long)(flp->lnum - fp2->fd_top - 1), - (linenr_T)MAXLNUM, (long)(fp2->fd_top-flp->lnum)); + (linenr_T)0, (flp->lnum - fp2->fd_top - 1), + (linenr_T)MAXLNUM, (fp2->fd_top-flp->lnum)); fp2->fd_len -= flp->lnum - fp2->fd_top; fp2->fd_top = flp->lnum; fold_changed = true; @@ -2603,19 +2641,20 @@ static linenr_T foldUpdateIEMSRecurse( /* Need to redraw the lines we inspected, which might be further down than * was asked for. */ - if (bot < flp->lnum - 1) + if (bot < flp->lnum - 1) { bot = flp->lnum - 1; + } return bot; } -/* foldInsert() {{{2 */ +// foldInsert() {{{2 /* * Insert a new fold in "gap" at position "i". */ static void foldInsert(garray_T *gap, int i) { - fold_T *fp; + fold_T *fp; ga_grow(gap, 1); @@ -2627,7 +2666,7 @@ static void foldInsert(garray_T *gap, int i) ga_init(&fp->fd_nested, (int)sizeof(fold_T), 10); } -/* foldSplit() {{{2 */ +// foldSplit() {{{2 /* * Split the "i"th fold in "gap", which starts before "top" and ends below * "bot" in two pieces, one ending above "top" and the other starting below @@ -2635,14 +2674,12 @@ 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(buf_T *buf, garray_T *const gap, - const int i, const linenr_T top, - const linenr_T bot - ) +static void foldSplit(buf_T *buf, garray_T *const gap, const int i, const linenr_T top, + const linenr_T bot) { - fold_T *fp2; + fold_T *fp2; - /* The fold continues below bot, need to split it. */ + // The fold continues below bot, need to split it. foldInsert(gap, i + 1); fold_T *const fp = (fold_T *)gap->ga_data + i; @@ -2675,7 +2712,7 @@ static void foldSplit(buf_T *buf, garray_T *const gap, fold_changed = true; } -/* foldRemove() {{{2 */ +// foldRemove() {{{2 /* * Remove folds within the range "top" to and including "bot". * Check for these situations: @@ -2694,11 +2731,9 @@ static void foldSplit(buf_T *buf, garray_T *const gap, * 5: made to start below "bot". * 6: not changed */ -static void foldRemove( - win_T *const wp, garray_T *gap, linenr_T top, linenr_T bot -) +static void foldRemove(win_T *const wp, garray_T *gap, linenr_T top, linenr_T bot) { - fold_T *fp = NULL; + fold_T *fp = NULL; if (bot < top) { return; // nothing to do @@ -2731,10 +2766,9 @@ static void foldRemove( fold_changed = true; if (fp->fd_top + fp->fd_len - 1 > bot) { // 5: Make fold that includes bot start below bot. - foldMarkAdjustRecurse( - wp, &fp->fd_nested, - (linenr_T)0, (long)(bot - fp->fd_top), - (linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1)); + foldMarkAdjustRecurse(wp, &fp->fd_nested, + (linenr_T)0, (bot - fp->fd_top), + (linenr_T)MAXLNUM, (fp->fd_top - bot - 1)); fp->fd_len -= bot - fp->fd_top + 1; fp->fd_top = bot + 1; break; @@ -2747,10 +2781,7 @@ static void foldRemove( } // foldReverseOrder() {{{2 -static void foldReverseOrder( - garray_T *gap, - const linenr_T start_arg, - const linenr_T end_arg) +static void foldReverseOrder(garray_T *gap, const linenr_T start_arg, const linenr_T end_arg) { linenr_T start = start_arg; linenr_T end = end_arg; @@ -2805,11 +2836,8 @@ static void truncate_fold(win_T *const wp, fold_T *fp, linenr_T end) #define VALID_FOLD(fp, gap) \ ((gap)->ga_len > 0 && (fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len)) #define FOLD_INDEX(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data))) -void foldMoveRange( - win_T *const wp, garray_T *gap, - const linenr_T line1, const linenr_T line2, - const linenr_T dest -) +void foldMoveRange(win_T *const wp, garray_T *gap, const linenr_T line1, const linenr_T line2, + const linenr_T dest) { fold_T *fp; const linenr_T range_len = line2 - line1 + 1; @@ -2909,7 +2937,7 @@ void foldMoveRange( #undef VALID_FOLD #undef FOLD_INDEX -/* foldMerge() {{{2 */ +// foldMerge() {{{2 /* * Merge two adjacent folds (and the nested ones in them). * This only works correctly when the folds are really adjacent! Thus "fp1" @@ -2919,11 +2947,11 @@ void foldMoveRange( */ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2) { - fold_T *fp3; - fold_T *fp4; + fold_T *fp3; + fold_T *fp4; int idx; - garray_T *gap1 = &fp1->fd_nested; - garray_T *gap2 = &fp2->fd_nested; + garray_T *gap1 = &fp1->fd_nested; + garray_T *gap2 = &fp2->fd_nested; /* If the last nested fold in fp1 touches the first nested fold in fp2, * merge them recursively. */ @@ -2931,7 +2959,7 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2) foldMerge(wp, fp3, gap2, fp4); } - /* Move nested folds in fp2 to the end of fp1. */ + // Move nested folds in fp2 to the end of fp1. if (!GA_EMPTY(gap2)) { ga_grow(gap1, gap2->ga_len); for (idx = 0; idx < gap2->ga_len; ++idx) { @@ -2948,7 +2976,7 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2) fold_changed = true; } -/* foldlevelIndent() {{{2 */ +// foldlevelIndent() {{{2 /* * Low level function to get the foldlevel for the "indent" method. * Doesn't use any caching. @@ -2956,8 +2984,8 @@ static void foldMerge(win_T *const wp, fold_T *fp1, garray_T *gap, fold_T *fp2) */ static void foldlevelIndent(fline_T *flp) { - char_u *s; - buf_T *buf; + char_u *s; + buf_T *buf; linenr_T lnum = flp->lnum + flp->off; buf = flp->wp->w_buffer; @@ -2966,33 +2994,35 @@ static void foldlevelIndent(fline_T *flp) /* empty line or lines starting with a character in 'foldignore': level * depends on surrounding lines */ if (*s == NUL || vim_strchr(flp->wp->w_p_fdi, *s) != NULL) { - /* first and last line can't be undefined, use level 0 */ - if (lnum == 1 || lnum == buf->b_ml.ml_line_count) + // first and last line can't be undefined, use level 0 + if (lnum == 1 || lnum == buf->b_ml.ml_line_count) { flp->lvl = 0; - else + } else { flp->lvl = -1; + } } 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); + flp->lvl = (int)MAX(0, flp->wp->w_p_fdn); } } -/* foldlevelDiff() {{{2 */ +// foldlevelDiff() {{{2 /* * Low level function to get the foldlevel for the "diff" method. * Doesn't use any caching. */ static void foldlevelDiff(fline_T *flp) { - if (diff_infold(flp->wp, flp->lnum + flp->off)) + if (diff_infold(flp->wp, flp->lnum + flp->off)) { flp->lvl = 1; - else + } else { flp->lvl = 0; + } } -/* foldlevelExpr() {{{2 */ +// foldlevelExpr() {{{2 /* * Low level function to get the foldlevel for the "expr" method. * Doesn't use any caching. @@ -3000,20 +3030,21 @@ static void foldlevelDiff(fline_T *flp) */ static void foldlevelExpr(fline_T *flp) { - win_T *win; + win_T *win; int c; linenr_T lnum = flp->lnum + flp->off; win = curwin; curwin = flp->wp; curbuf = flp->wp->w_buffer; - set_vim_var_nr(VV_LNUM, (varnumber_T) lnum); + set_vim_var_nr(VV_LNUM, (varnumber_T)lnum); flp->start = 0; flp->had_end = flp->end; flp->end = MAX_LEVEL + 1; - if (lnum <= 1) + if (lnum <= 1) { flp->lvl = 0; + } /* KeyTyped may be reset to 0 when calling a function which invokes * do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */ @@ -3022,46 +3053,54 @@ static void foldlevelExpr(fline_T *flp) KeyTyped = save_keytyped; switch (c) { - /* "a1", "a2", .. : add to the fold level */ - case 'a': if (flp->lvl >= 0) { + // "a1", "a2", .. : add to the fold level + case 'a': + if (flp->lvl >= 0) { flp->lvl += n; flp->lvl_next = flp->lvl; - } + } flp->start = n; break; - /* "s1", "s2", .. : subtract from the fold level */ - case 's': if (flp->lvl >= 0) { - if (n > flp->lvl) + // "s1", "s2", .. : subtract from the fold level + case 's': + if (flp->lvl >= 0) { + if (n > flp->lvl) { flp->lvl_next = 0; - else + } else { flp->lvl_next = flp->lvl - n; + } flp->end = flp->lvl_next + 1; - } + } break; - /* ">1", ">2", .. : start a fold with a certain level */ - case '>': flp->lvl = n; + // ">1", ">2", .. : start a fold with a certain level + case '>': + flp->lvl = n; flp->lvl_next = n; flp->start = 1; break; - /* "<1", "<2", .. : end a fold with a certain level */ - case '<': flp->lvl_next = n - 1; + // "<1", "<2", .. : end a fold with a certain level + case '<': + flp->lvl_next = n - 1; flp->end = n; break; - /* "=": No change in level */ - case '=': flp->lvl_next = flp->lvl; + // "=": No change in level + case '=': + flp->lvl_next = flp->lvl; break; - /* "-1", "0", "1", ..: set fold level */ - default: if (n < 0) + // "-1", "0", "1", ..: set fold level + default: + if (n < 0) { /* Use the current level for the next line, so that "a1" * will work there. */ flp->lvl_next = flp->lvl; - else + } else { flp->lvl_next = n; + } flp->lvl = n; break; } @@ -3073,15 +3112,16 @@ static void foldlevelExpr(fline_T *flp) flp->lvl = 0; flp->lvl_next = 0; } - if (lnum == curbuf->b_ml.ml_line_count) + if (lnum == curbuf->b_ml.ml_line_count) { flp->lvl_next = 0; + } } curwin = win; curbuf = curwin->w_buffer; } -/* parseMarker() {{{2 */ +// parseMarker() {{{2 /* * Parse 'foldmarker' and set "foldendmarker", "foldstartmarkerlen" and * "foldendmarkerlen". @@ -3094,7 +3134,7 @@ static void parseMarker(win_T *wp) foldendmarkerlen = STRLEN(foldendmarker); } -/* foldlevelMarker() {{{2 */ +// foldlevelMarker() {{{2 /* * Low level function to get the foldlevel for the "marker" method. * "foldendmarker", "foldstartmarkerlen" and "foldendmarkerlen" must have been @@ -3106,20 +3146,20 @@ static void parseMarker(win_T *wp) */ static void foldlevelMarker(fline_T *flp) { - char_u *startmarker; + char_u *startmarker; int cstart; int cend; int start_lvl = flp->lvl; - char_u *s; + char_u *s; int n; - /* cache a few values for speed */ + // cache a few values for speed startmarker = flp->wp->w_p_fmr; cstart = *startmarker; ++startmarker; cend = *foldendmarker; - /* Default: no start found, next level is same as current level */ + // Default: no start found, next level is same as current level flp->start = 0; flp->lvl_next = flp->lvl; @@ -3127,17 +3167,18 @@ static void foldlevelMarker(fline_T *flp) while (*s) { if (*s == cstart && STRNCMP(s + 1, startmarker, foldstartmarkerlen - 1) == 0) { - /* found startmarker: set flp->lvl */ + // found startmarker: set flp->lvl s += foldstartmarkerlen; if (ascii_isdigit(*s)) { n = atoi((char *)s); if (n > 0) { flp->lvl = n; flp->lvl_next = n; - if (n <= start_lvl) + if (n <= start_lvl) { flp->start = 1; - else + } else { flp->start = n - start_lvl; + } } } else { ++flp->lvl; @@ -3146,16 +3187,17 @@ static void foldlevelMarker(fline_T *flp) } } else if (*s == cend && STRNCMP(s + 1, foldendmarker + 1, foldendmarkerlen - 1) == 0) { - /* found endmarker: set flp->lvl_next */ + // found endmarker: set flp->lvl_next s += foldendmarkerlen; if (ascii_isdigit(*s)) { n = atoi((char *)s); if (n > 0) { flp->lvl = n; flp->lvl_next = n - 1; - /* never start a fold with an end marker */ - if (flp->lvl_next > start_lvl) + // never start a fold with an end marker + if (flp->lvl_next > start_lvl) { flp->lvl_next = start_lvl; + } } } else { flp->lvl_next--; @@ -3165,12 +3207,13 @@ static void foldlevelMarker(fline_T *flp) } } - /* The level can't go negative, must be missing a start marker. */ - if (flp->lvl_next < 0) + // The level can't go negative, must be missing a start marker. + if (flp->lvl_next < 0) { flp->lvl_next = 0; + } } -/* foldlevelSyntax() {{{2 */ +// foldlevelSyntax() {{{2 /* * Low level function to get the foldlevel for the "syntax" method. * Doesn't use any caching. @@ -3180,20 +3223,20 @@ static void foldlevelSyntax(fline_T *flp) linenr_T lnum = flp->lnum + flp->off; int n; - /* Use the maximum fold level at the start of this line and the next. */ + // Use the maximum fold level at the start of this line and the next. flp->lvl = syn_get_foldlevel(flp->wp, lnum); flp->start = 0; if (lnum < flp->wp->w_buffer->b_ml.ml_line_count) { n = syn_get_foldlevel(flp->wp, lnum + 1); if (n > flp->lvl) { - flp->start = n - flp->lvl; /* fold(s) start here */ + flp->start = n - flp->lvl; // fold(s) start here flp->lvl = n; } } } -/* functions for storing the fold state in a View {{{1 */ -/* put_folds() {{{2 */ +// functions for storing the fold state in a View {{{1 +// put_folds() {{{2 /* * Write commands to "fd" to restore the manual folds in window "wp". @@ -3209,14 +3252,15 @@ int put_folds(FILE *fd, win_T *wp) } } - /* If some folds are manually opened/closed, need to restore that. */ - if (wp->w_fold_manual) + // If some folds are manually opened/closed, need to restore that. + if (wp->w_fold_manual) { return put_foldopen_recurse(fd, wp, &wp->w_folds, (linenr_T)0); + } return OK; } -/* put_folds_recurse() {{{2 */ +// put_folds_recurse() {{{2 /* * Write commands to "fd" to recreate manually created folds. * Returns FAIL when writing failed. @@ -3225,20 +3269,22 @@ static int put_folds_recurse(FILE *fd, garray_T *gap, linenr_T off) { fold_T *fp = (fold_T *)gap->ga_data; for (int i = 0; i < gap->ga_len; i++) { - /* Do nested folds first, they will be created closed. */ - if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL) + // Do nested folds first, they will be created closed. + if (put_folds_recurse(fd, &fp->fd_nested, off + fp->fd_top) == FAIL) { return FAIL; + } if (fprintf(fd, "%" PRId64 ",%" PRId64 "fold", (int64_t)(fp->fd_top + off), (int64_t)(fp->fd_top + off + fp->fd_len - 1)) < 0 - || put_eol(fd) == FAIL) + || put_eol(fd) == FAIL) { return FAIL; + } ++fp; } return OK; } -/* put_foldopen_recurse() {{{2 */ +// put_foldopen_recurse() {{{2 /* * Write commands to "fd" to open and close manually opened/closed folds. * Returns FAIL when writing failed. @@ -3251,19 +3297,22 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off for (int i = 0; i < gap->ga_len; i++) { if (fp->fd_flags != FD_LEVEL) { if (!GA_EMPTY(&fp->fd_nested)) { - /* open nested folds while this fold is open */ + // open nested folds while this fold is open if (fprintf(fd, "%" PRId64, (int64_t)(fp->fd_top + off)) < 0 || put_eol(fd) == FAIL - || put_line(fd, "normal! zo") == FAIL) + || put_line(fd, "normal! zo") == FAIL) { return FAIL; + } if (put_foldopen_recurse(fd, wp, &fp->fd_nested, - off + fp->fd_top) - == FAIL) + off + fp->fd_top) + == FAIL) { return FAIL; - /* close the parent when needed */ + } + // close the parent when needed if (fp->fd_flags == FD_CLOSED) { - if (put_fold_open_close(fd, fp, off) == FAIL) + if (put_fold_open_close(fd, fp, off) == FAIL) { return FAIL; + } } } else { /* Open or close the leaf according to the window foldlevel. @@ -3271,9 +3320,11 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off * the parent. */ level = foldLevelWin(wp, off + fp->fd_top); if ((fp->fd_flags == FD_CLOSED && wp->w_p_fdl >= level) - || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level)) - if (put_fold_open_close(fd, fp, off) == FAIL) + || (fp->fd_flags != FD_CLOSED && wp->w_p_fdl < level)) { + if (put_fold_open_close(fd, fp, off) == FAIL) { return FAIL; + } + } } } ++fp; @@ -3282,7 +3333,7 @@ static int put_foldopen_recurse(FILE *fd, win_T *wp, garray_T *gap, linenr_T off return OK; } -/* put_fold_open_close() {{{2 */ +// put_fold_open_close() {{{2 /* * Write the open or close command to "fd". * Returns FAIL when writing failed. @@ -3292,11 +3343,12 @@ static int put_fold_open_close(FILE *fd, fold_T *fp, linenr_T off) if (fprintf(fd, "%" PRId64, (int64_t)(fp->fd_top + off)) < 0 || put_eol(fd) == FAIL || fprintf(fd, "normal! z%c", - fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0 - || put_eol(fd) == FAIL) + fp->fd_flags == FD_CLOSED ? 'c' : 'o') < 0 + || put_eol(fd) == FAIL) { return FAIL; + } return OK; } -/* }}}1 */ +// }}}1 diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 2a72dbcd09..4d54907a75 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -939,13 +939,18 @@ EXTERN char_u e_readonlyvar[] INIT(= N_( "E46: Cannot change read-only variable \"%.*s\"")); EXTERN char_u e_stringreq[] INIT(= N_("E928: String required")); EXTERN char_u e_dictreq[] INIT(= N_("E715: Dictionary required")); +EXTERN char_u e_blobidx[] INIT(= N_("E979: Blob index out of range: %" PRId64)); +EXTERN char_u e_invalblob[] INIT(= N_("E978: Invalid operation for Blob")); EXTERN char_u e_toomanyarg[] INIT(= N_( "E118: Too many arguments for function: %s")); EXTERN char_u e_dictkey[] INIT(= N_( "E716: Key not present in Dictionary: \"%s\"")); EXTERN char_u e_listreq[] INIT(= N_("E714: List required")); +EXTERN char_u e_listblobreq[] INIT(= N_("E897: List or Blob required")); EXTERN char_u e_listdictarg[] INIT(= N_( "E712: Argument of %s must be a List or Dictionary")); +EXTERN char_u e_listdictblobarg[] INIT(= N_( + "E896: Argument of %s must be a List, Dictionary or Blob")); EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here")); diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 277b9ade89..c6966ff9fa 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -628,7 +628,11 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, if (end - bp > 3 && bp[0] == 't' && bp[1] == '_') { bp += 3; // skip t_xx, xx may be '-' or '>' } else if (end - bp > 4 && STRNICMP(bp, "char-", 5) == 0) { - vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0); + vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0, true); + if (l == 0) { + EMSG(_(e_invarg)); + return 0; + } bp += l + 5; break; } @@ -654,7 +658,11 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp, if (STRNICMP(last_dash + 1, "char-", 5) == 0 && ascii_isdigit(last_dash[6])) { // <Char-123> or <Char-033> or <Char-0x33> - vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0); + vim_str2nr(last_dash + 6, NULL, &l, STR2NR_ALL, NULL, &n, 0, true); + if (l == 0) { + EMSG(_(e_invarg)); + return 0; + } key = (int)n; } else { int off = 1; diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 1a59cd94ae..0adbbdb953 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -481,6 +481,14 @@ static bool typval_conv_special = false; #define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \ TYPVAL_ENCODE_CONV_NIL(tv) +#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \ + do { \ + const blob_T *const blob_ = (blob); \ + lua_pushlstring(lstate, \ + blob_ != NULL ? (const char *)blob_->bv_ga.ga_data : "", \ + (size_t)(len)); \ + } while (0) + #define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \ do { \ TYPVAL_ENCODE_CONV_NIL(tv); \ @@ -579,6 +587,7 @@ static bool typval_conv_special = false; #undef TYPVAL_ENCODE_CONV_STRING #undef TYPVAL_ENCODE_CONV_STR_STRING #undef TYPVAL_ENCODE_CONV_EXT_STRING +#undef TYPVAL_ENCODE_CONV_BLOB #undef TYPVAL_ENCODE_CONV_NUMBER #undef TYPVAL_ENCODE_CONV_FLOAT #undef TYPVAL_ENCODE_CONV_FUNC_START diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index d071203db1..ce5bfabd9f 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -90,7 +90,7 @@ static void nlua_error(lua_State *const lstate, const char *const msg) lua_pop(lstate, 1); } -/// Return version of current neovim build +/// Gets the version of the current Nvim build. /// /// @param lstate Lua interpreter state. static int nlua_nvim_version(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua index c6bbdee7ad..ba124c41ad 100644 --- a/src/nvim/lua/vim.lua +++ b/src/nvim/lua/vim.lua @@ -105,6 +105,9 @@ setmetatable(vim, { elseif key == 'highlight' then t.highlight = require('vim.highlight') return t.highlight + elseif key == 'diagnostic' then + t.diagnostic = require('vim.diagnostic') + return t.diagnostic end end }) diff --git a/src/nvim/main.c b/src/nvim/main.c index 716434f32e..1fc140e525 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -459,7 +459,7 @@ int main(int argc, char **argv) curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; } - apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf); TIME_MSG("BufEnter autocommands"); setpcmark(); diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c index cba372b9d3..fea1ab77a2 100644 --- a/src/nvim/mbyte.c +++ b/src/nvim/mbyte.c @@ -31,30 +31,30 @@ #include <wchar.h> #include <wctype.h> -#include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/vim.h" #ifdef HAVE_LOCALE_H # include <locale.h> #endif -#include "nvim/eval.h" -#include "nvim/path.h" -#include "nvim/iconv.h" -#include "nvim/mbyte.h" +#include "nvim/arabic.h" #include "nvim/charset.h" #include "nvim/cursor.h" +#include "nvim/eval.h" #include "nvim/fileio.h" #include "nvim/func_attr.h" +#include "nvim/iconv.h" +#include "nvim/mark.h" +#include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/memory.h" #include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/path.h" #include "nvim/screen.h" #include "nvim/spell.h" #include "nvim/strings.h" -#include "nvim/os/os.h" -#include "nvim/arabic.h" -#include "nvim/mark.h" typedef struct { int rangeStart; @@ -70,6 +70,7 @@ struct interval { #ifdef INCLUDE_GENERATED_DECLARATIONS # include "mbyte.c.generated.h" + # include "unicode_tables.generated.h" #endif @@ -127,131 +128,131 @@ static struct enc_canon_table[] = { #define IDX_LATIN_1 0 - {"latin1", ENC_8BIT + ENC_LATIN1, 1252}, + { "latin1", ENC_8BIT + ENC_LATIN1, 1252 }, #define IDX_ISO_2 1 - {"iso-8859-2", ENC_8BIT, 0}, + { "iso-8859-2", ENC_8BIT, 0 }, #define IDX_ISO_3 2 - {"iso-8859-3", ENC_8BIT, 0}, + { "iso-8859-3", ENC_8BIT, 0 }, #define IDX_ISO_4 3 - {"iso-8859-4", ENC_8BIT, 0}, + { "iso-8859-4", ENC_8BIT, 0 }, #define IDX_ISO_5 4 - {"iso-8859-5", ENC_8BIT, 0}, + { "iso-8859-5", ENC_8BIT, 0 }, #define IDX_ISO_6 5 - {"iso-8859-6", ENC_8BIT, 0}, + { "iso-8859-6", ENC_8BIT, 0 }, #define IDX_ISO_7 6 - {"iso-8859-7", ENC_8BIT, 0}, + { "iso-8859-7", ENC_8BIT, 0 }, #define IDX_ISO_8 7 - {"iso-8859-8", ENC_8BIT, 0}, + { "iso-8859-8", ENC_8BIT, 0 }, #define IDX_ISO_9 8 - {"iso-8859-9", ENC_8BIT, 0}, + { "iso-8859-9", ENC_8BIT, 0 }, #define IDX_ISO_10 9 - {"iso-8859-10", ENC_8BIT, 0}, + { "iso-8859-10", ENC_8BIT, 0 }, #define IDX_ISO_11 10 - {"iso-8859-11", ENC_8BIT, 0}, + { "iso-8859-11", ENC_8BIT, 0 }, #define IDX_ISO_13 11 - {"iso-8859-13", ENC_8BIT, 0}, + { "iso-8859-13", ENC_8BIT, 0 }, #define IDX_ISO_14 12 - {"iso-8859-14", ENC_8BIT, 0}, + { "iso-8859-14", ENC_8BIT, 0 }, #define IDX_ISO_15 13 - {"iso-8859-15", ENC_8BIT + ENC_LATIN9, 0}, + { "iso-8859-15", ENC_8BIT + ENC_LATIN9, 0 }, #define IDX_KOI8_R 14 - {"koi8-r", ENC_8BIT, 0}, + { "koi8-r", ENC_8BIT, 0 }, #define IDX_KOI8_U 15 - {"koi8-u", ENC_8BIT, 0}, + { "koi8-u", ENC_8BIT, 0 }, #define IDX_UTF8 16 - {"utf-8", ENC_UNICODE, 0}, + { "utf-8", ENC_UNICODE, 0 }, #define IDX_UCS2 17 - {"ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0}, + { "ucs-2", ENC_UNICODE + ENC_ENDIAN_B + ENC_2BYTE, 0 }, #define IDX_UCS2LE 18 - {"ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0}, + { "ucs-2le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2BYTE, 0 }, #define IDX_UTF16 19 - {"utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0}, + { "utf-16", ENC_UNICODE + ENC_ENDIAN_B + ENC_2WORD, 0 }, #define IDX_UTF16LE 20 - {"utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0}, + { "utf-16le", ENC_UNICODE + ENC_ENDIAN_L + ENC_2WORD, 0 }, #define IDX_UCS4 21 - {"ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0}, + { "ucs-4", ENC_UNICODE + ENC_ENDIAN_B + ENC_4BYTE, 0 }, #define IDX_UCS4LE 22 - {"ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0}, + { "ucs-4le", ENC_UNICODE + ENC_ENDIAN_L + ENC_4BYTE, 0 }, - /* For debugging DBCS encoding on Unix. */ + // For debugging DBCS encoding on Unix. #define IDX_DEBUG 23 - {"debug", ENC_DBCS, DBCS_DEBUG}, + { "debug", ENC_DBCS, DBCS_DEBUG }, #define IDX_EUC_JP 24 - {"euc-jp", ENC_DBCS, DBCS_JPNU}, + { "euc-jp", ENC_DBCS, DBCS_JPNU }, #define IDX_SJIS 25 - {"sjis", ENC_DBCS, DBCS_JPN}, + { "sjis", ENC_DBCS, DBCS_JPN }, #define IDX_EUC_KR 26 - {"euc-kr", ENC_DBCS, DBCS_KORU}, + { "euc-kr", ENC_DBCS, DBCS_KORU }, #define IDX_EUC_CN 27 - {"euc-cn", ENC_DBCS, DBCS_CHSU}, + { "euc-cn", ENC_DBCS, DBCS_CHSU }, #define IDX_EUC_TW 28 - {"euc-tw", ENC_DBCS, DBCS_CHTU}, + { "euc-tw", ENC_DBCS, DBCS_CHTU }, #define IDX_BIG5 29 - {"big5", ENC_DBCS, DBCS_CHT}, + { "big5", ENC_DBCS, DBCS_CHT }, /* MS-DOS and MS-Windows codepages are included here, so that they can be * used on Unix too. Most of them are similar to ISO-8859 encodings, but * not exactly the same. */ #define IDX_CP437 30 - {"cp437", ENC_8BIT, 437}, /* like iso-8859-1 */ + { "cp437", ENC_8BIT, 437 }, // like iso-8859-1 #define IDX_CP737 31 - {"cp737", ENC_8BIT, 737}, /* like iso-8859-7 */ + { "cp737", ENC_8BIT, 737 }, // like iso-8859-7 #define IDX_CP775 32 - {"cp775", ENC_8BIT, 775}, /* Baltic */ + { "cp775", ENC_8BIT, 775 }, // Baltic #define IDX_CP850 33 - {"cp850", ENC_8BIT, 850}, /* like iso-8859-4 */ + { "cp850", ENC_8BIT, 850 }, // like iso-8859-4 #define IDX_CP852 34 - {"cp852", ENC_8BIT, 852}, /* like iso-8859-1 */ + { "cp852", ENC_8BIT, 852 }, // like iso-8859-1 #define IDX_CP855 35 - {"cp855", ENC_8BIT, 855}, /* like iso-8859-2 */ + { "cp855", ENC_8BIT, 855 }, // like iso-8859-2 #define IDX_CP857 36 - {"cp857", ENC_8BIT, 857}, /* like iso-8859-5 */ + { "cp857", ENC_8BIT, 857 }, // like iso-8859-5 #define IDX_CP860 37 - {"cp860", ENC_8BIT, 860}, /* like iso-8859-9 */ + { "cp860", ENC_8BIT, 860 }, // like iso-8859-9 #define IDX_CP861 38 - {"cp861", ENC_8BIT, 861}, /* like iso-8859-1 */ + { "cp861", ENC_8BIT, 861 }, // like iso-8859-1 #define IDX_CP862 39 - {"cp862", ENC_8BIT, 862}, /* like iso-8859-1 */ + { "cp862", ENC_8BIT, 862 }, // like iso-8859-1 #define IDX_CP863 40 - {"cp863", ENC_8BIT, 863}, /* like iso-8859-8 */ + { "cp863", ENC_8BIT, 863 }, // like iso-8859-8 #define IDX_CP865 41 - {"cp865", ENC_8BIT, 865}, /* like iso-8859-1 */ + { "cp865", ENC_8BIT, 865 }, // like iso-8859-1 #define IDX_CP866 42 - {"cp866", ENC_8BIT, 866}, /* like iso-8859-5 */ + { "cp866", ENC_8BIT, 866 }, // like iso-8859-5 #define IDX_CP869 43 - {"cp869", ENC_8BIT, 869}, /* like iso-8859-7 */ + { "cp869", ENC_8BIT, 869 }, // like iso-8859-7 #define IDX_CP874 44 - {"cp874", ENC_8BIT, 874}, /* Thai */ + { "cp874", ENC_8BIT, 874 }, // Thai #define IDX_CP932 45 - {"cp932", ENC_DBCS, DBCS_JPN}, + { "cp932", ENC_DBCS, DBCS_JPN }, #define IDX_CP936 46 - {"cp936", ENC_DBCS, DBCS_CHS}, + { "cp936", ENC_DBCS, DBCS_CHS }, #define IDX_CP949 47 - {"cp949", ENC_DBCS, DBCS_KOR}, + { "cp949", ENC_DBCS, DBCS_KOR }, #define IDX_CP950 48 - {"cp950", ENC_DBCS, DBCS_CHT}, + { "cp950", ENC_DBCS, DBCS_CHT }, #define IDX_CP1250 49 - {"cp1250", ENC_8BIT, 1250}, /* Czech, Polish, etc. */ + { "cp1250", ENC_8BIT, 1250 }, // Czech, Polish, etc. #define IDX_CP1251 50 - {"cp1251", ENC_8BIT, 1251}, /* Cyrillic */ - /* cp1252 is considered to be equal to latin1 */ + { "cp1251", ENC_8BIT, 1251 }, // Cyrillic + // cp1252 is considered to be equal to latin1 #define IDX_CP1253 51 - {"cp1253", ENC_8BIT, 1253}, /* Greek */ + { "cp1253", ENC_8BIT, 1253 }, // Greek #define IDX_CP1254 52 - {"cp1254", ENC_8BIT, 1254}, /* Turkish */ + { "cp1254", ENC_8BIT, 1254 }, // Turkish #define IDX_CP1255 53 - {"cp1255", ENC_8BIT, 1255}, /* Hebrew */ + { "cp1255", ENC_8BIT, 1255 }, // Hebrew #define IDX_CP1256 54 - {"cp1256", ENC_8BIT, 1256}, /* Arabic */ + { "cp1256", ENC_8BIT, 1256 }, // Arabic #define IDX_CP1257 55 - {"cp1257", ENC_8BIT, 1257}, /* Baltic */ + { "cp1257", ENC_8BIT, 1257 }, // Baltic #define IDX_CP1258 56 - {"cp1258", ENC_8BIT, 1258}, /* Vietnamese */ + { "cp1258", ENC_8BIT, 1258 }, // Vietnamese #define IDX_MACROMAN 57 - {"macroman", ENC_8BIT + ENC_MACROMAN, 0}, /* Mac OS */ + { "macroman", ENC_8BIT + ENC_MACROMAN, 0 }, // Mac OS #define IDX_HPROMAN8 58 - {"hp-roman8", ENC_8BIT, 0}, /* HP Roman8 */ + { "hp-roman8", ENC_8BIT, 0 }, // HP Roman8 #define IDX_COUNT 59 }; @@ -336,9 +337,11 @@ static int enc_canon_search(const char_u *name) { int i; - for (i = 0; i < IDX_COUNT; ++i) - if (STRCMP(name, enc_canon_table[i].name) == 0) + for (i = 0; i < IDX_COUNT; ++i) { + if (STRCMP(name, enc_canon_table[i].name) == 0) { return i; + } + } return -1; } @@ -353,12 +356,13 @@ int enc_canon_props(const char_u *name) int i; i = enc_canon_search(name); - if (i >= 0) + if (i >= 0) { return enc_canon_table[i].prop; - if (STRNCMP(name, "2byte-", 6) == 0) + } else if (STRNCMP(name, "2byte-", 6) == 0) { return ENC_DBCS; - if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0) + } else if (STRNCMP(name, "8bit-", 5) == 0 || STRNCMP(name, "iso-8859-", 9) == 0) { return ENC_8BIT; + } return 0; } @@ -436,21 +440,23 @@ static bool intable(const struct interval *table, size_t n_items, int c) { int mid, bot, top; - /* first quick check for Latin1 etc. characters */ - if (c < table[0].first) + // first quick check for Latin1 etc. characters + if (c < table[0].first) { return false; + } - /* binary search in table */ + // binary search in table bot = 0; top = (int)(n_items - 1); while (top >= bot) { mid = (bot + top) / 2; - if (table[mid].last < c) + if (table[mid].last < c) { bot = mid + 1; - else if (table[mid].first > c) + } else if (table[mid].first > c) { top = mid - 1; - else + } else { return true; + } } return false; } @@ -512,12 +518,14 @@ int utf_ptr2cells(const char_u *p) // Need to convert to a character number. if (*p >= 0x80) { c = utf_ptr2char(p); - /* An illegal byte is displayed as <xx>. */ - if (utf_ptr2len(p) == 1 || c == NUL) + // An illegal byte is displayed as <xx>. + if (utf_ptr2len(p) == 1 || c == NUL) { return 4; - /* If the char is ASCII it must be an overlong sequence. */ - if (c < 0x80) + } + // If the char is ASCII it must be an overlong sequence. + if (c < 0x80) { return char2cells(c); + } return utf_char2cells(c); } return 1; @@ -529,17 +537,20 @@ int utf_ptr2cells_len(const char_u *p, int size) { int c; - /* Need to convert to a wide character. */ + // Need to convert to a wide character. if (size > 0 && *p >= 0x80) { - if (utf_ptr2len_len(p, size) < utf8len_tab[*p]) - return 1; /* truncated */ + if (utf_ptr2len_len(p, size) < utf8len_tab[*p]) { + return 1; // truncated + } c = utf_ptr2char(p); - /* An illegal byte is displayed as <xx>. */ - if (utf_ptr2len(p) == 1 || c == NUL) + // An illegal byte is displayed as <xx>. + if (utf_ptr2len(p) == 1 || c == NUL) { return 4; - /* If the char is ASCII it must be an overlong sequence. */ - if (c < 0x80) + } + // If the char is ASCII it must be an overlong sequence. + if (c < 0x80) { return char2cells(c); + } return utf_char2cells(c); } return 1; @@ -651,13 +662,14 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n) { int c; - if (*n == 0) /* end of buffer */ + if (*n == 0) { // end of buffer return 0; + } uint8_t k = utf8len_tab_zero[**s]; if (k == 1) { - /* ASCII character or NUL */ + // ASCII character or NUL (*n)--; return *(*s)++; } @@ -674,14 +686,14 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n) * U+00C3 (UTF-8: 0xC3 0x83), so need to check that special case too. * It's safe even if n=1, else we would have k=2 > n. */ if (c != (int)(**s) || (c == 0xC3 && (*s)[1] == 0x83)) { - /* byte sequence was successfully decoded */ + // byte sequence was successfully decoded *s += k; *n -= k; return c; } } - /* byte sequence is incomplete or illegal */ + // byte sequence is incomplete or illegal return -1; } @@ -721,10 +733,12 @@ bool utf_composinglike(const char_u *p1, const char_u *p2) int c2; c2 = utf_ptr2char(p2); - if (utf_iscomposing(c2)) + if (utf_iscomposing(c2)) { return true; - if (!arabic_maycombine(c2)) + } + if (!arabic_maycombine(c2)) { return false; + } return arabic_combine(utf_ptr2char(p1), c2); } @@ -746,23 +760,26 @@ int utfc_ptr2char(const char_u *p, int *pcc) c = utf_ptr2char(p); len = utf_ptr2len(p); - /* Only accept a composing char when the first char isn't illegal. */ + // Only accept a composing char when the first char isn't illegal. if ((len > 1 || *p < 0x80) && p[len] >= 0x80 && UTF_COMPOSINGLIKE(p, p + len)) { cc = utf_ptr2char(p + len); for (;; ) { pcc[i++] = cc; - if (i == MAX_MCO) + if (i == MAX_MCO) { break; + } len += utf_ptr2len(p + len); - if (p[len] < 0x80 || !utf_iscomposing(cc = utf_ptr2char(p + len))) + if (p[len] < 0x80 || !utf_iscomposing(cc = utf_ptr2char(p + len))) { break; + } } } - if (i < MAX_MCO) /* last composing char must be 0 */ + if (i < MAX_MCO) { // last composing char must be 0 pcc[i] = 0; + } return c; } @@ -855,15 +872,19 @@ int utf_ptr2len_len(const char_u *p, int size) int m; len = utf8len_tab[*p]; - if (len == 1) - return 1; /* NUL, ascii or illegal lead byte */ - if (len > size) - m = size; /* incomplete byte sequence. */ - else + if (len == 1) { + return 1; // NUL, ascii or illegal lead byte + } + if (len > size) { + m = size; // incomplete byte sequence. + } else { m = len; - for (i = 1; i < m; ++i) - if ((p[i] & 0xc0) != 0x80) + } + for (i = 1; i < m; ++i) { + if ((p[i] & 0xc0) != 0x80) { return 1; + } + } return len; } @@ -915,17 +936,20 @@ int utfc_ptr2len_len(const char_u *p, int size) int len; int prevlen; - if (size < 1 || *p == NUL) + if (size < 1 || *p == NUL) { return 0; - if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) /* be quick for ASCII */ + } + if (p[0] < 0x80 && (size == 1 || p[1] < 0x80)) { // be quick for ASCII return 1; + } - /* Skip over first UTF-8 char, stopping at a NUL byte. */ + // Skip over first UTF-8 char, stopping at a NUL byte. len = utf_ptr2len_len(p, size); - /* Check for illegal byte and incomplete byte sequence. */ - if ((len == 1 && p[0] >= 0x80) || len > size) + // Check for illegal byte and incomplete byte sequence. + if ((len == 1 && p[0] >= 0x80) || len > size) { return 1; + } /* * Check for composing characters. We can handle only the first six, but @@ -935,21 +959,24 @@ int utfc_ptr2len_len(const char_u *p, int size) while (len < size) { int len_next_char; - if (p[len] < 0x80) + if (p[len] < 0x80) { break; + } /* * Next character length should not go beyond size to ensure that * UTF_COMPOSINGLIKE(...) does not read beyond size. */ len_next_char = utf_ptr2len_len(p + len, size - len); - if (len_next_char > size - len) + if (len_next_char > size - len) { break; + } - if (!UTF_COMPOSINGLIKE(p + prevlen, p + len)) + if (!UTF_COMPOSINGLIKE(p + prevlen, p + len)) { break; + } - /* Skip over composing char */ + // Skip over composing char prevlen = len; len += len_next_char; } @@ -1043,9 +1070,9 @@ bool utf_printable(int c) * 0xd800-0xdfff is reserved for UTF-16, actually illegal. */ static struct interval nonprint[] = { - {0x070f, 0x070f}, {0x180b, 0x180e}, {0x200b, 0x200f}, {0x202a, 0x202e}, - {0x206a, 0x206f}, {0xd800, 0xdfff}, {0xfeff, 0xfeff}, {0xfff9, 0xfffb}, - {0xfffe, 0xffff} + { 0x070f, 0x070f }, { 0x180b, 0x180e }, { 0x200b, 0x200f }, { 0x202a, 0x202e }, + { 0x206a, 0x206f }, { 0xd800, 0xdfff }, { 0xfeff, 0xfeff }, { 0xfff9, 0xfffb }, + { 0xfffe, 0xffff } }; return !intable(nonprint, ARRAY_SIZE(nonprint), c); @@ -1065,7 +1092,7 @@ int utf_class(const int c) int utf_class_tab(const int c, const uint64_t *const chartab) { - /* sorted list of non-overlapping intervals */ + // sorted list of non-overlapping intervals static struct clinterval { unsigned int first; unsigned int last; @@ -1147,7 +1174,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab) int top = ARRAY_SIZE(classes) - 1; int mid; - /* First quick check for Latin1 characters, use 'iskeyword'. */ + // First quick check for Latin1 characters, use 'iskeyword'. if (c < 0x100) { if (c == ' ' || c == '\t' || c == NUL || c == 0xa0) { return 0; // blank @@ -1158,15 +1185,16 @@ int utf_class_tab(const int c, const uint64_t *const chartab) return 1; // punctuation } - /* binary search in table */ + // binary search in table while (top >= bot) { mid = (bot + top) / 2; - if (classes[mid].last < (unsigned int)c) + if (classes[mid].last < (unsigned int)c) { bot = mid + 1; - else if (classes[mid].first > (unsigned int)c) + } else if (classes[mid].first > (unsigned int)c) { top = mid - 1; - else + } else { return (int)classes[mid].class; + } } // emoji @@ -1174,7 +1202,7 @@ int utf_class_tab(const int c, const uint64_t *const chartab) return 3; } - /* most other characters are "word" characters */ + // most other characters are "word" characters return 2; } @@ -1191,25 +1219,27 @@ bool utf_ambiguous_width(int c) */ static int utf_convert(int a, const convertStruct *const table, size_t n_items) { - size_t start, mid, end; /* indices into table */ + size_t start, mid, end; // indices into table start = 0; end = n_items; while (start < end) { - /* need to search further */ + // need to search further mid = (end + start) / 2; - if (table[mid].rangeEnd < a) + if (table[mid].rangeEnd < a) { start = mid + 1; - else + } else { end = mid; + } } if (start < n_items && table[start].rangeStart <= a && a <= table[start].rangeEnd - && (a - table[start].rangeStart) % table[start].step == 0) + && (a - table[start].rangeStart) % table[start].step == 0) { return a + table[start].offset; - else + } else { return a; + } } /* @@ -1234,21 +1264,24 @@ int utf_fold(int a) /// simple case folding. int mb_toupper(int a) { - /* If 'casemap' contains "keepascii" use ASCII style toupper(). */ - if (a < 128 && (cmp_flags & CMP_KEEPASCII)) + // If 'casemap' contains "keepascii" use ASCII style toupper(). + if (a < 128 && (cmp_flags & CMP_KEEPASCII)) { return TOUPPER_ASC(a); + } #if defined(__STDC_ISO_10646__) - /* If towupper() is available and handles Unicode, use it. */ - if (!(cmp_flags & CMP_INTERNAL)) + // If towupper() is available and handles Unicode, use it. + if (!(cmp_flags & CMP_INTERNAL)) { return towupper(a); + } #endif - /* For characters below 128 use locale sensitive toupper(). */ - if (a < 128) + // For characters below 128 use locale sensitive toupper(). + if (a < 128) { return TOUPPER_LOC(a); + } - /* For any other characters use the above mapping table. */ + // For any other characters use the above mapping table. return utf_convert(a, toUpper, ARRAY_SIZE(toUpper)); } @@ -1262,21 +1295,24 @@ bool mb_islower(int a) /// simple case folding. int mb_tolower(int a) { - /* If 'casemap' contains "keepascii" use ASCII style tolower(). */ - if (a < 128 && (cmp_flags & CMP_KEEPASCII)) + // If 'casemap' contains "keepascii" use ASCII style tolower(). + if (a < 128 && (cmp_flags & CMP_KEEPASCII)) { return TOLOWER_ASC(a); + } #if defined(__STDC_ISO_10646__) - /* If towlower() is available and handles Unicode, use it. */ - if (!(cmp_flags & CMP_INTERNAL)) + // If towlower() is available and handles Unicode, use it. + if (!(cmp_flags & CMP_INTERNAL)) { return towlower(a); + } #endif - /* For characters below 128 use locale sensitive tolower(). */ - if (a < 128) + // For characters below 128 use locale sensitive tolower(). + if (a < 128) { return TOLOWER_LOC(a); + } - /* For any other characters use the above mapping table. */ + // For any other characters use the above mapping table. return utf_convert(a, toLower, ARRAY_SIZE(toLower)); } @@ -1285,8 +1321,7 @@ bool mb_isupper(int a) return mb_tolower(a) != a; } -static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, - size_t n2) +static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, size_t n2) { int c1, c2, cdiff; char_u buffer[6]; @@ -1295,23 +1330,27 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, c1 = utf_safe_read_char_adv(&s1, &n1); c2 = utf_safe_read_char_adv(&s2, &n2); - if (c1 <= 0 || c2 <= 0) + if (c1 <= 0 || c2 <= 0) { break; + } - if (c1 == c2) + if (c1 == c2) { continue; + } cdiff = utf_fold(c1) - utf_fold(c2); - if (cdiff != 0) + if (cdiff != 0) { return cdiff; + } } - /* some string ended or has an incomplete/illegal character sequence */ + // some string ended or has an incomplete/illegal character sequence if (c1 == 0 || c2 == 0) { - /* some string ended. shorter string is smaller */ - if (c1 == 0 && c2 == 0) + // some string ended. shorter string is smaller + if (c1 == 0 && c2 == 0) { return 0; + } return c1 == 0 ? -1 : 1; } @@ -1332,8 +1371,9 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, while (n1 > 0 && n2 > 0 && *s1 != NUL && *s2 != NUL) { cdiff = (int)(*s1) - (int)(*s2); - if (cdiff != 0) + if (cdiff != 0) { return cdiff; + } s1++; s2++; @@ -1341,19 +1381,22 @@ static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1, n2--; } - if (n1 > 0 && *s1 == NUL) + if (n1 > 0 && *s1 == NUL) { n1 = 0; - if (n2 > 0 && *s2 == NUL) + } + if (n2 > 0 && *s2 == NUL) { n2 = 0; + } - if (n1 == 0 && n2 == 0) + if (n1 == 0 && n2 == 0) { return 0; + } return n1 == 0 ? -1 : 1; } #ifdef WIN32 #ifndef CP_UTF8 -# define CP_UTF8 65001 /* magic number from winnls.h */ +# define CP_UTF8 65001 // magic number from winnls.h #endif /// Converts string from UTF-8 to UTF-16. @@ -1453,8 +1496,7 @@ int utf16_to_utf8(const wchar_t *utf16, int utf16len, char **utf8) /// @param len maximum length (an earlier NUL terminates) /// @param[out] codepoints incremented with UTF-32 code point size /// @param[out] codeunits incremented with UTF-16 code unit size -void mb_utflen(const char_u *s, size_t len, size_t *codepoints, - size_t *codeunits) +void mb_utflen(const char_u *s, size_t len, size_t *codepoints, size_t *codeunits) FUNC_ATTR_NONNULL_ALL { size_t count = 0, extra = 0; @@ -1473,8 +1515,7 @@ void mb_utflen(const char_u *s, size_t len, size_t *codepoints, *codeunits += count + extra; } -ssize_t mb_utf_index_to_bytes(const char_u *s, size_t len, - size_t index, bool use_utf16_units) +ssize_t mb_utf_index_to_bytes(const char_u *s, size_t len, size_t index, bool use_utf16_units) FUNC_ATTR_NONNULL_ALL { size_t count = 0; @@ -1537,7 +1578,7 @@ void show_utf8(void) { int len; int rlen = 0; - char_u *line; + char_u *line; int clen; int i; @@ -1553,7 +1594,7 @@ void show_utf8(void) clen = 0; for (i = 0; i < len; ++i) { if (clen == 0) { - /* start of (composing) character, get its length */ + // start of (composing) character, get its length if (i > 0) { STRCPY(IObuff + rlen, "+ "); rlen += 2; @@ -1561,11 +1602,12 @@ void show_utf8(void) clen = utf_ptr2len(line + i); } sprintf((char *)IObuff + rlen, "%02x ", - (line[i] == NL) ? NUL : line[i]); /* NUL is stored as NL */ + (line[i] == NL) ? NUL : line[i]); // NUL is stored as NL --clen; rlen += (int)STRLEN(IObuff + rlen); - if (rlen > IOSIZE - 20) + if (rlen > IOSIZE - 20) { break; + } } msg(IObuff); @@ -1579,42 +1621,49 @@ int utf_head_off(const char_u *base, const char_u *p) int c; int len; - if (*p < 0x80) /* be quick for ASCII */ + if (*p < 0x80) { // be quick for ASCII return 0; + } /* Skip backwards over trailing bytes: 10xx.xxxx * Skip backwards again if on a composing char. */ const char_u *q; for (q = p;; --q) { - /* Move s to the last byte of this char. */ + // Move s to the last byte of this char. const char_u *s; for (s = q; (s[1] & 0xc0) == 0x80; ++s) {} - /* Move q to the first byte of this char. */ - while (q > base && (*q & 0xc0) == 0x80) + // Move q to the first byte of this char. + while (q > base && (*q & 0xc0) == 0x80) { --q; + } /* Check for illegal sequence. Do allow an illegal byte after where we * started. */ len = utf8len_tab[*q]; - if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) + if (len != (int)(s - q + 1) && len != (int)(p - q + 1)) { return 0; + } - if (q <= base) + if (q <= base) { break; + } c = utf_ptr2char(q); - if (utf_iscomposing(c)) + if (utf_iscomposing(c)) { continue; + } if (arabic_maycombine(c)) { - /* Advance to get a sneak-peak at the next char */ + // Advance to get a sneak-peak at the next char const char_u *j = q; --j; - /* Move j to the first byte of this char. */ - while (j > base && (*j & 0xc0) == 0x80) + // Move j to the first byte of this char. + while (j > base && (*j & 0xc0) == 0x80) { --j; - if (arabic_combine(utf_ptr2char(j), c)) + } + if (arabic_combine(utf_ptr2char(j), c)) { continue; + } } break; } @@ -1627,12 +1676,12 @@ bool utf_eat_space(int cc) FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT { return (cc >= 0x2000 && cc <= 0x206F) // General punctuations - || (cc >= 0x2e00 && cc <= 0x2e7f) // Supplemental punctuations - || (cc >= 0x3000 && cc <= 0x303f) // CJK symbols and punctuations - || (cc >= 0xff01 && cc <= 0xff0f) // Full width ASCII punctuations - || (cc >= 0xff1a && cc <= 0xff20) // .. - || (cc >= 0xff3b && cc <= 0xff40) // .. - || (cc >= 0xff5b && cc <= 0xff65); // .. + || (cc >= 0x2e00 && cc <= 0x2e7f) // Supplemental punctuations + || (cc >= 0x3000 && cc <= 0x303f) // CJK symbols and punctuations + || (cc >= 0xff01 && cc <= 0xff0f) // Full width ASCII punctuations + || (cc >= 0xff1a && cc <= 0xff20) // .. + || (cc >= 0xff3b && cc <= 0xff40) // .. + || (cc >= 0xff5b && cc <= 0xff65); // .. } // Whether line break is allowed before "cc". @@ -1814,8 +1863,9 @@ int mb_tail_off(char_u *base, char_u *p) int i; int j; - if (*p == NUL) + if (*p == NUL) { return 0; + } // Find the last character that is 10xx.xxxx for (i = 0; (p[i + 1] & 0xc0) == 0x80; i++) {} @@ -1839,10 +1889,10 @@ int mb_tail_off(char_u *base, char_u *p) void utf_find_illegal(void) { pos_T pos = curwin->w_cursor; - char_u *p; + char_u *p; int len; vimconv_T vimconv; - char_u *tofree = NULL; + char_u *tofree = NULL; vimconv.vc_type = CONV_NONE; if (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT) { @@ -1858,8 +1908,9 @@ void utf_find_illegal(void) if (vimconv.vc_type != CONV_NONE) { xfree(tofree); tofree = string_convert(&vimconv, p, NULL); - if (tofree == NULL) + if (tofree == NULL) { break; + } p = tofree; } @@ -1868,10 +1919,10 @@ void utf_find_illegal(void) * utf_ptr2len()) or too many of them (overlong sequence). */ len = utf_ptr2len(p); if (*p >= 0x80 && (len == 1 - || utf_char2len(utf_ptr2char(p)) != len)) { - if (vimconv.vc_type == CONV_NONE) + || utf_char2len(utf_ptr2char(p)) != len)) { + if (vimconv.vc_type == CONV_NONE) { curwin->w_cursor.col += (colnr_T)(p - get_cursor_pos_ptr()); - else { + } else { int l; len = (int)(p - tofree); @@ -1884,13 +1935,14 @@ void utf_find_illegal(void) } p += len; } - if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) + if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) { break; + } ++curwin->w_cursor.lnum; curwin->w_cursor.col = 0; } - /* didn't find it: don't move and beep */ + // didn't find it: don't move and beep curwin->w_cursor = pos; beep_flush(); @@ -1944,13 +1996,10 @@ void mb_check_adjust_col(void *win_) } } -/* - * Return a pointer to the character before "*p", if there is one. - */ -char_u * mb_prevptr( - char_u *line, /* start of the string */ - char_u *p - ) +/// @param line start of the string +/// +/// @return a pointer to the character before "*p", if there is one. +char_u * mb_prevptr(char_u *line, char_u *p) { if (p > line) { MB_PTR_BACK(line, p); @@ -1964,14 +2013,16 @@ char_u * mb_prevptr( */ int mb_charlen(char_u *str) { - char_u *p = str; + char_u *p = str; int count; - if (p == NULL) + if (p == NULL) { return 0; + } - for (count = 0; *p != NUL; count++) + for (count = 0; *p != NUL; count++) { p += (*mb_ptr2len)(p); + } return count; } @@ -1981,11 +2032,12 @@ int mb_charlen(char_u *str) */ int mb_charlen_len(char_u *str, int len) { - char_u *p = str; + char_u *p = str; int count; - for (count = 0; *p != NUL && p < str + len; count++) + for (count = 0; *p != NUL && p < str + len; count++) { p += (*mb_ptr2len)(p); + } return count; } @@ -2049,10 +2101,12 @@ const char *mb_unescape(const char **const pp) */ char_u * enc_skip(char_u *p) { - if (STRNCMP(p, "2byte-", 6) == 0) + if (STRNCMP(p, "2byte-", 6) == 0) { return p + 6; - if (STRNCMP(p, "8bit-", 5) == 0) + } + if (STRNCMP(p, "8bit-", 5) == 0) { return p + 5; + } return p; } @@ -2064,7 +2118,7 @@ char_u * enc_skip(char_u *p) */ char_u *enc_canonize(char_u *enc) FUNC_ATTR_NONNULL_RET { - char_u *p, *s; + char_u *p, *s; int i; if (STRCMP(enc, "default") == 0) { @@ -2072,47 +2126,51 @@ char_u *enc_canonize(char_u *enc) FUNC_ATTR_NONNULL_RET return vim_strsave(fenc_default); } - /* copy "enc" to allocated memory, with room for two '-' */ + // copy "enc" to allocated memory, with room for two '-' char_u *r = xmalloc(STRLEN(enc) + 3); - /* Make it all lower case and replace '_' with '-'. */ + // Make it all lower case and replace '_' with '-'. p = r; for (s = enc; *s != NUL; ++s) { - if (*s == '_') + if (*s == '_') { *p++ = '-'; - else + } else { *p++ = TOLOWER_ASC(*s); + } } *p = NUL; - /* Skip "2byte-" and "8bit-". */ + // Skip "2byte-" and "8bit-". p = enc_skip(r); - /* Change "microsoft-cp" to "cp". Used in some spell files. */ - if (STRNCMP(p, "microsoft-cp", 12) == 0) + // Change "microsoft-cp" to "cp". Used in some spell files. + if (STRNCMP(p, "microsoft-cp", 12) == 0) { STRMOVE(p, p + 10); + } - /* "iso8859" -> "iso-8859" */ + // "iso8859" -> "iso-8859" if (STRNCMP(p, "iso8859", 7) == 0) { STRMOVE(p + 4, p + 3); p[3] = '-'; } - /* "iso-8859n" -> "iso-8859-n" */ + // "iso-8859n" -> "iso-8859-n" if (STRNCMP(p, "iso-8859", 8) == 0 && p[8] != '-') { STRMOVE(p + 9, p + 8); p[8] = '-'; } - /* "latin-N" -> "latinN" */ - if (STRNCMP(p, "latin-", 6) == 0) + // "latin-N" -> "latinN" + if (STRNCMP(p, "latin-", 6) == 0) { STRMOVE(p + 5, p + 6); + } if (enc_canon_search(p) >= 0) { - /* canonical name can be used unmodified */ - if (p != r) + // canonical name can be used unmodified + if (p != r) { STRMOVE(r, p); + } } else if ((i = enc_alias_search(p)) >= 0) { - /* alias recognized, get canonical name */ + // alias recognized, get canonical name xfree(r); r = vim_strsave((char_u *)enc_canon_table[i].name); } @@ -2127,9 +2185,11 @@ static int enc_alias_search(char_u *name) { int i; - for (i = 0; enc_alias_table[i].name != NULL; ++i) - if (STRCMP(name, enc_alias_table[i].name) == 0) + for (i = 0; enc_alias_table[i].name != NULL; ++i) { + if (STRCMP(name, enc_alias_table[i].name) == 0) { return enc_alias_table[i].canon; + } + } return -1; } @@ -2219,13 +2279,13 @@ void * my_iconv_open(char_u *to, char_u *from) iconv_t fd; #define ICONV_TESTLEN 400 char_u tobuf[ICONV_TESTLEN]; - char *p; + char *p; size_t tolen; static WorkingStatus iconv_working = kUnknown; - if (iconv_working == kBroken) - return (void *)-1; /* detected a broken iconv() previously */ - + if (iconv_working == kBroken) { + return (void *)-1; // detected a broken iconv() previously + } fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from)); if (fd != (iconv_t)-1 && iconv_working == kUnknown) { @@ -2243,8 +2303,9 @@ void * my_iconv_open(char_u *to, char_u *from) iconv_working = kBroken; iconv_close(fd); fd = (iconv_t)-1; - } else + } else { iconv_working = kWorking; + } } return (void *)fd; @@ -2257,17 +2318,17 @@ void * my_iconv_open(char_u *to, char_u *from) * Returns the converted string in allocated memory. NULL for an error. * If resultlenp is not NULL, sets it to the result length in bytes. */ -static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, - size_t slen, size_t *unconvlenp, size_t *resultlenp) +static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, size_t slen, + size_t *unconvlenp, size_t *resultlenp) { - const char *from; + const char *from; size_t fromlen; - char *to; + char *to; size_t tolen; size_t len = 0; size_t done = 0; - char_u *result = NULL; - char_u *p; + char_u *result = NULL; + char_u *p; int l; from = (char *)str; @@ -2278,8 +2339,9 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, * increase the buffer size. */ len = len + fromlen * 2 + 40; p = xmalloc(len); - if (done > 0) + if (done > 0) { memmove(p, result, done); + } xfree(result); result = p; } @@ -2327,8 +2389,9 @@ static char_u *iconv_string(const vimconv_T *const vcp, char_u *str, done = to - (char *)result; } - if (resultlenp != NULL && result != NULL) + if (resultlenp != NULL && result != NULL) { *resultlenp = (size_t)(to - (char *)result); + } return result; } @@ -2353,8 +2416,8 @@ int convert_setup(vimconv_T *vcp, char_u *from, char_u *to) /// As convert_setup(), but only when from_unicode_is_utf8 is true will all /// "from" unicode charsets be considered utf-8. Same for "to". -int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, - char_u *to, bool to_unicode_is_utf8) +int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, char_u *to, + bool to_unicode_is_utf8) { int from_prop; int to_prop; @@ -2369,51 +2432,54 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8, # endif *vcp = (vimconv_T)MBYTE_NONE_CONV; - /* No conversion when one of the names is empty or they are equal. */ + // No conversion when one of the names is empty or they are equal. if (from == NULL || *from == NUL || to == NULL || *to == NUL - || STRCMP(from, to) == 0) + || STRCMP(from, to) == 0) { return OK; + } from_prop = enc_canon_props(from); to_prop = enc_canon_props(to); - if (from_unicode_is_utf8) + if (from_unicode_is_utf8) { from_is_utf8 = from_prop & ENC_UNICODE; - else + } else { from_is_utf8 = from_prop == ENC_UNICODE; - if (to_unicode_is_utf8) + } + if (to_unicode_is_utf8) { to_is_utf8 = to_prop & ENC_UNICODE; - else + } else { to_is_utf8 = to_prop == ENC_UNICODE; + } if ((from_prop & ENC_LATIN1) && to_is_utf8) { - /* Internal latin1 -> utf-8 conversion. */ + // Internal latin1 -> utf-8 conversion. vcp->vc_type = CONV_TO_UTF8; - vcp->vc_factor = 2; /* up to twice as long */ + vcp->vc_factor = 2; // up to twice as long } else if ((from_prop & ENC_LATIN9) && to_is_utf8) { - /* Internal latin9 -> utf-8 conversion. */ + // Internal latin9 -> utf-8 conversion. vcp->vc_type = CONV_9_TO_UTF8; - vcp->vc_factor = 3; /* up to three as long (euro sign) */ + vcp->vc_factor = 3; // up to three as long (euro sign) } else if (from_is_utf8 && (to_prop & ENC_LATIN1)) { - /* Internal utf-8 -> latin1 conversion. */ + // Internal utf-8 -> latin1 conversion. vcp->vc_type = CONV_TO_LATIN1; } else if (from_is_utf8 && (to_prop & ENC_LATIN9)) { - /* Internal utf-8 -> latin9 conversion. */ + // Internal utf-8 -> latin9 conversion. vcp->vc_type = CONV_TO_LATIN9; } # ifdef HAVE_ICONV else { // NOLINT(readability/braces) // Use iconv() for conversion. - vcp->vc_fd = (iconv_t)my_iconv_open( - to_is_utf8 ? (char_u *)"utf-8" : to, - from_is_utf8 ? (char_u *)"utf-8" : from); + vcp->vc_fd = (iconv_t)my_iconv_open(to_is_utf8 ? (char_u *)"utf-8" : to, + from_is_utf8 ? (char_u *)"utf-8" : from); if (vcp->vc_fd != (iconv_t)-1) { vcp->vc_type = CONV_ICONV; - vcp->vc_factor = 4; /* could be longer too... */ + vcp->vc_factor = 4; // could be longer too... } } # endif - if (vcp->vc_type == CONV_NONE) + if (vcp->vc_type == CONV_NONE) { return FAIL; + } return OK; } @@ -2435,129 +2501,153 @@ char_u *string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp) * an incomplete sequence at the end it is not converted and "*unconvlenp" is * set to the number of remaining bytes. */ -char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, - size_t *lenp, size_t *unconvlenp) +char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr, size_t *lenp, + size_t *unconvlenp) { - char_u *retval = NULL; - char_u *d; + char_u *retval = NULL; + char_u *d; int l; int c; size_t len; - if (lenp == NULL) + if (lenp == NULL) { len = STRLEN(ptr); - else + } else { len = *lenp; - if (len == 0) + } + if (len == 0) { return vim_strsave((char_u *)""); + } switch (vcp->vc_type) { - case CONV_TO_UTF8: /* latin1 to utf-8 conversion */ - retval = xmalloc(len * 2 + 1); - d = retval; - for (size_t i = 0; i < len; ++i) { - c = ptr[i]; - if (c < 0x80) - *d++ = c; - else { - *d++ = 0xc0 + ((unsigned)c >> 6); - *d++ = 0x80 + (c & 0x3f); - } + case CONV_TO_UTF8: // latin1 to utf-8 conversion + retval = xmalloc(len * 2 + 1); + d = retval; + for (size_t i = 0; i < len; ++i) { + c = ptr[i]; + if (c < 0x80) { + *d++ = c; + } else { + *d++ = 0xc0 + ((unsigned)c >> 6); + *d++ = 0x80 + (c & 0x3f); } - *d = NUL; - if (lenp != NULL) - *lenp = (size_t)(d - retval); - break; + } + *d = NUL; + if (lenp != NULL) { + *lenp = (size_t)(d - retval); + } + break; - case CONV_9_TO_UTF8: /* latin9 to utf-8 conversion */ - retval = xmalloc(len * 3 + 1); - d = retval; - for (size_t i = 0; i < len; ++i) { - c = ptr[i]; - switch (c) { - case 0xa4: c = 0x20ac; break; /* euro */ - case 0xa6: c = 0x0160; break; /* S hat */ - case 0xa8: c = 0x0161; break; /* S -hat */ - case 0xb4: c = 0x017d; break; /* Z hat */ - case 0xb8: c = 0x017e; break; /* Z -hat */ - case 0xbc: c = 0x0152; break; /* OE */ - case 0xbd: c = 0x0153; break; /* oe */ - case 0xbe: c = 0x0178; break; /* Y */ - } - d += utf_char2bytes(c, d); + case CONV_9_TO_UTF8: // latin9 to utf-8 conversion + retval = xmalloc(len * 3 + 1); + d = retval; + for (size_t i = 0; i < len; ++i) { + c = ptr[i]; + switch (c) { + case 0xa4: + c = 0x20ac; break; // euro + case 0xa6: + c = 0x0160; break; // S hat + case 0xa8: + c = 0x0161; break; // S -hat + case 0xb4: + c = 0x017d; break; // Z hat + case 0xb8: + c = 0x017e; break; // Z -hat + case 0xbc: + c = 0x0152; break; // OE + case 0xbd: + c = 0x0153; break; // oe + case 0xbe: + c = 0x0178; break; // Y } - *d = NUL; - if (lenp != NULL) - *lenp = (size_t)(d - retval); - break; + d += utf_char2bytes(c, d); + } + *d = NUL; + if (lenp != NULL) { + *lenp = (size_t)(d - retval); + } + break; - case CONV_TO_LATIN1: /* utf-8 to latin1 conversion */ - case CONV_TO_LATIN9: /* utf-8 to latin9 conversion */ - retval = xmalloc(len + 1); - d = retval; - for (size_t i = 0; i < len; ++i) { - l = utf_ptr2len_len(ptr + i, len - i); - if (l == 0) - *d++ = NUL; - else if (l == 1) { - uint8_t l_w = utf8len_tab_zero[ptr[i]]; - - if (l_w == 0) { - /* Illegal utf-8 byte cannot be converted */ + case CONV_TO_LATIN1: // utf-8 to latin1 conversion + case CONV_TO_LATIN9: // utf-8 to latin9 conversion + retval = xmalloc(len + 1); + d = retval; + for (size_t i = 0; i < len; ++i) { + l = utf_ptr2len_len(ptr + i, len - i); + if (l == 0) { + *d++ = NUL; + } else if (l == 1) { + uint8_t l_w = utf8len_tab_zero[ptr[i]]; + + if (l_w == 0) { + // Illegal utf-8 byte cannot be converted + xfree(retval); + return NULL; + } + if (unconvlenp != NULL && l_w > len - i) { + // Incomplete sequence at the end. + *unconvlenp = len - i; + break; + } + *d++ = ptr[i]; + } else { + c = utf_ptr2char(ptr + i); + if (vcp->vc_type == CONV_TO_LATIN9) { + switch (c) { + case 0x20ac: + c = 0xa4; break; // euro + case 0x0160: + c = 0xa6; break; // S hat + case 0x0161: + c = 0xa8; break; // S -hat + case 0x017d: + c = 0xb4; break; // Z hat + case 0x017e: + c = 0xb8; break; // Z -hat + case 0x0152: + c = 0xbc; break; // OE + case 0x0153: + c = 0xbd; break; // oe + case 0x0178: + c = 0xbe; break; // Y + case 0xa4: + case 0xa6: + case 0xa8: + case 0xb4: + case 0xb8: + case 0xbc: + case 0xbd: + case 0xbe: + c = 0x100; break; // not in latin9 + } + } + if (!utf_iscomposing(c)) { // skip composing chars + if (c < 0x100) { + *d++ = c; + } else if (vcp->vc_fail) { xfree(retval); return NULL; - } - if (unconvlenp != NULL && l_w > len - i) { - /* Incomplete sequence at the end. */ - *unconvlenp = len - i; - break; - } - *d++ = ptr[i]; - } else { - c = utf_ptr2char(ptr + i); - if (vcp->vc_type == CONV_TO_LATIN9) - switch (c) { - case 0x20ac: c = 0xa4; break; /* euro */ - case 0x0160: c = 0xa6; break; /* S hat */ - case 0x0161: c = 0xa8; break; /* S -hat */ - case 0x017d: c = 0xb4; break; /* Z hat */ - case 0x017e: c = 0xb8; break; /* Z -hat */ - case 0x0152: c = 0xbc; break; /* OE */ - case 0x0153: c = 0xbd; break; /* oe */ - case 0x0178: c = 0xbe; break; /* Y */ - case 0xa4: - case 0xa6: - case 0xa8: - case 0xb4: - case 0xb8: - case 0xbc: - case 0xbd: - case 0xbe: c = 0x100; break; /* not in latin9 */ - } - if (!utf_iscomposing(c)) { /* skip composing chars */ - if (c < 0x100) - *d++ = c; - else if (vcp->vc_fail) { - xfree(retval); - return NULL; - } else { - *d++ = 0xbf; - if (utf_char2cells(c) > 1) - *d++ = '?'; + } else { + *d++ = 0xbf; + if (utf_char2cells(c) > 1) { + *d++ = '?'; } } - i += l - 1; } + i += l - 1; } - *d = NUL; - if (lenp != NULL) - *lenp = (size_t)(d - retval); - break; + } + *d = NUL; + if (lenp != NULL) { + *lenp = (size_t)(d - retval); + } + break; # ifdef HAVE_ICONV - case CONV_ICONV: // conversion with vcp->vc_fd - retval = iconv_string(vcp, ptr, len, unconvlenp, lenp); - break; + case CONV_ICONV: // conversion with vcp->vc_fd + retval = iconv_string(vcp, ptr, len, unconvlenp, lenp); + break; # endif } diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 230361b997..f1774a20cf 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -3341,11 +3341,11 @@ static int do_swapexists(buf_T *buf, char_u *fname) set_vim_var_string(VV_SWAPNAME, (char *) fname, -1); set_vim_var_string(VV_SWAPCHOICE, NULL, -1); - /* Trigger SwapExists autocommands with <afile> set to the file being - * edited. Disallow changing directory here. */ - ++allbuf_lock; - apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL); - --allbuf_lock; + // Trigger SwapExists autocommands with <afile> set to the file being + // edited. Disallow changing directory here. + allbuf_lock++; + apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, false, NULL); + allbuf_lock--; set_vim_var_string(VV_SWAPNAME, NULL, -1); diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index c599f4ea97..c4fa269851 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -228,10 +228,6 @@ retnomove: redraw_curbuf_later(INVERTED); // delete the inversion } - - row -= curwin->w_winrow; - col -= curwin->w_wincol; - // When clicking beyond the end of the window, scroll the screen. // Scroll by however many rows outside the window we are. if (row < 0) { diff --git a/src/nvim/move.c b/src/nvim/move.c index 09815d1e6a..21cbac4d79 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -788,11 +788,12 @@ void curs_columns( wp->w_wcol -= n * width; wp->w_wrow += n; - /* When cursor wraps to first char of next line in Insert - * mode, the 'showbreak' string isn't shown, backup to first - * column */ - if (*p_sbr && *get_cursor_pos_ptr() == NUL - && wp->w_wcol == (int)vim_strsize(p_sbr)) { + // When cursor wraps to first char of next line in Insert + // mode, the 'showbreak' string isn't shown, backup to first + // column + char_u *const sbr = get_showbreak_value(wp); + if (*sbr && *get_cursor_pos_ptr() == NUL + && wp->w_wcol == (int)vim_strsize(sbr)) { wp->w_wcol = 0; } } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 85897bac12..51e6827636 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -618,7 +618,7 @@ static void normal_redraw_mode_message(NormalState *s) // If need to redraw, and there is a "keep_msg", redraw before the // delay if (must_redraw && keep_msg != NULL && !emsg_on_display) { - char_u *kmsg; + char_u *kmsg; kmsg = keep_msg; keep_msg = NULL; @@ -1456,7 +1456,7 @@ static void set_vcount_ca(cmdarg_T *cap, bool *set_prevcount) // "gui_yank" is true when yanking text for the clipboard. void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) { - oparg_T *oap = cap->oap; + oparg_T *oap = cap->oap; pos_T old_cursor; bool empty_region_error; int restart_edit_save; @@ -2267,7 +2267,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) bool in_sep_line; // mouse in vertical separator line int c1, c2; pos_T save_cursor; - win_T *old_curwin = curwin; + win_T *old_curwin = curwin; static pos_T orig_cursor; colnr_T leftcol, rightcol; pos_T end_visual; @@ -2886,7 +2886,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) * A double click selects a word or a block. */ if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) { - pos_T *pos = NULL; + pos_T *pos = NULL; int gc; if (is_click) { @@ -2961,7 +2961,7 @@ bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent) */ static void find_start_of_word(pos_T *pos) { - char_u *line; + char_u *line; int cclass; int col; @@ -2984,7 +2984,7 @@ static void find_start_of_word(pos_T *pos) */ static void find_end_of_word(pos_T *pos) { - char_u *line; + char_u *line; int cclass; int col; @@ -3407,18 +3407,21 @@ void clear_showcmd(void) lines = bot - top + 1; if (VIsual_mode == Ctrl_V) { - char_u *saved_sbr = p_sbr; + char_u *const saved_sbr = p_sbr; + char_u *const saved_w_sbr = curwin->w_p_sbr; // Make 'sbr' empty for a moment to get the correct size. p_sbr = empty_option; + curwin->w_p_sbr = empty_option; getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol); p_sbr = saved_sbr; + curwin->w_p_sbr = saved_w_sbr; snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64 "x%" PRId64, (int64_t)lines, (int64_t)rightcol - leftcol + 1); } else if (VIsual_mode == 'V' || VIsual.lnum != curwin->w_cursor.lnum) { snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64, (int64_t)lines); } else { - char_u *s, *e; + char_u *s, *e; int l; int bytes = 0; int chars = 0; @@ -3469,7 +3472,7 @@ void clear_showcmd(void) */ bool add_to_showcmd(int c) { - char_u *p; + char_u *p; int i; static int ignore[] = { @@ -3615,10 +3618,10 @@ static void display_showcmd(void) */ void do_check_scrollbind(bool check) { - static win_T *old_curwin = NULL; + static win_T *old_curwin = NULL; static linenr_T old_topline = 0; static int old_topfill = 0; - static buf_T *old_buf = NULL; + static buf_T *old_buf = NULL; static colnr_T old_leftcol = 0; if (check && curwin->w_p_scb) { @@ -3673,8 +3676,8 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff) { bool want_ver; bool want_hor; - win_T *old_curwin = curwin; - buf_T *old_curbuf = curbuf; + win_T *old_curwin = curwin; + buf_T *old_curbuf = curbuf; int old_VIsual_select = VIsual_select; int old_VIsual_active = VIsual_active; colnr_T tgt_leftcol = curwin->w_leftcol; @@ -3878,7 +3881,7 @@ static bool is_ident(char_u *line, int offset) /// @return fail when not found. bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_arg) { - char_u *pat; + char_u *pat; pos_T old_pos; pos_T par_pos; pos_T found_pos; @@ -4141,8 +4144,8 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist) */ validate_virtcol(); colnr_T virtcol = curwin->w_virtcol; - if (virtcol > (colnr_T)width1 && *p_sbr != NUL) { - virtcol -= vim_strsize(p_sbr); + if (virtcol > (colnr_T)width1 && *get_showbreak_value(curwin) != NUL) { + virtcol -= vim_strsize(get_showbreak_value(curwin)); } if (virtcol > curwin->w_curswant @@ -4699,7 +4702,7 @@ dozet: case 'G': // "zG": add good word to temp word list case 'W': // "zW": add wrong word to temp word list { - char_u *ptr = NULL; + char_u *ptr = NULL; size_t len; if (checkclearop(cap->oap)) { @@ -4958,13 +4961,13 @@ void do_nv_ident(int c1, int c2) */ static void nv_ident(cmdarg_T *cap) { - char_u *ptr = NULL; - char_u *p; + char_u *ptr = NULL; + char_u *p; size_t n = 0; // init for GCC int cmdchar; bool g_cmd; // "g" command bool tag_cmd = false; - char_u *aux_ptr; + char_u *aux_ptr; if (cap->cmdchar == 'g') { // "g*", "g#", "g]" and "gCTRL-]" cmdchar = cap->nchar; @@ -5513,7 +5516,7 @@ static void nv_down(cmdarg_T *cap) */ static void nv_gotofile(cmdarg_T *cap) { - char_u *ptr; + char_u *ptr; linenr_T lnum = -1; if (text_locked()) { @@ -5588,7 +5591,7 @@ static void nv_dollar(cmdarg_T *cap) */ static void nv_search(cmdarg_T *cap) { - oparg_T *oap = cap->oap; + oparg_T *oap = cap->oap; pos_T save_cursor = curwin->w_cursor; if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13) { @@ -5719,7 +5722,7 @@ static void nv_brackets(cmdarg_T *cap) { pos_T new_pos = { 0, 0, 0 }; pos_T prev_pos; - pos_T *pos = NULL; // init for GCC + pos_T *pos = NULL; // init for GCC pos_T old_pos; // cursor position before command int flag; long n; @@ -5749,7 +5752,7 @@ static void nv_brackets(cmdarg_T *cap) if (vim_strchr((char_u *) "iI\011dD\004", cap->nchar) != NULL) { - char_u *ptr; + char_u *ptr; size_t len; if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0) { @@ -5993,7 +5996,7 @@ static void nv_brackets(cmdarg_T *cap) */ static void nv_percent(cmdarg_T *cap) { - pos_T *pos; + pos_T *pos; linenr_T lnum = curwin->w_cursor.lnum; cap->oap->inclusive = true; @@ -6135,7 +6138,7 @@ static void nv_kundo(cmdarg_T *cap) */ static void nv_replace(cmdarg_T *cap) { - char_u *ptr; + char_u *ptr; int had_ctrl_v; if (checkclearop(cap->oap)) { @@ -6554,7 +6557,7 @@ static void nv_optrans(cmdarg_T *cap) */ static void nv_gomark(cmdarg_T *cap) { - pos_T *pos; + pos_T *pos; int c; pos_T old_cursor = curwin->w_cursor; const bool old_KeyTyped = KeyTyped; // getting file may reset it @@ -6593,7 +6596,7 @@ static void nv_gomark(cmdarg_T *cap) // Handle CTRL-O, CTRL-I, "g;", "g,", and "CTRL-Tab" commands. static void nv_pcmark(cmdarg_T *cap) { - pos_T *pos; + pos_T *pos; linenr_T lnum = curwin->w_cursor.lnum; const bool old_KeyTyped = KeyTyped; // getting file may reset it @@ -6841,7 +6844,7 @@ static void nv_suspend(cmdarg_T *cap) */ static void nv_g_cmd(cmdarg_T *cap) { - oparg_T *oap = cap->oap; + oparg_T *oap = cap->oap; pos_T tpos; int i; bool flag = false; @@ -7076,7 +7079,7 @@ static void nv_g_cmd(cmdarg_T *cap) cap->oap->op_type == OP_NOP) == false) { clearopbeep(cap->oap); } else { - char_u *ptr = get_cursor_line_ptr(); + char_u *ptr = get_cursor_line_ptr(); // In Visual mode we may end up after the line. if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL) { @@ -7734,7 +7737,7 @@ static void adjust_for_sel(cmdarg_T *cap) */ static bool unadjust_for_sel(void) { - pos_T *pp; + pos_T *pp; if (*p_sel == 'e' && !equalpos(VIsual, curwin->w_cursor)) { if (lt(VIsual, curwin->w_cursor)) { @@ -8002,7 +8005,7 @@ static void nv_object(cmdarg_T *cap) { bool flag; bool include; - char_u *mps_save; + char_u *mps_save; if (cap->cmdchar == 'i') { include = false; // "ix" = inner object: exclude white space @@ -8401,13 +8404,13 @@ static void nv_event(cmdarg_T *cap) // not safe to perform garbage collection because there could be unreferenced // lists or dicts being used. may_garbage_collect = false; - bool may_restart = (restart_edit != 0); + bool may_restart = (restart_edit != 0 || restart_VIsual_select != 0); state_handle_k_event(); finish_op = false; if (may_restart) { // Tricky: if restart_edit was set before the handler we are in ctrl-o mode, // but if not, the event should be allowed to trigger :startinsert. - cap->retval |= CA_COMMAND_BUSY; // don't call edit() now + cap->retval |= CA_COMMAND_BUSY; // don't call edit() or restart Select now } } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index b493200005..a0dee7ace8 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -73,7 +73,7 @@ struct block_def { int startspaces; // 'extra' cols before first char int endspaces; // 'extra' cols after last char int textlen; // chars in block - char_u *textstart; // pointer to 1st char (partially) in block + char_u *textstart; // pointer to 1st char (partially) in block colnr_T textcol; // index of chars (partially) in block colnr_T start_vcol; // start col of 1st char wholly inside block colnr_T end_vcol; // start col of 1st char wholly after block @@ -210,7 +210,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) { long i; int first_char; - char_u *s; + char_u *s; int block_col = 0; if (u_save((linenr_T)(oap->start.lnum - 1), @@ -387,7 +387,7 @@ static void shift_block(oparg_T *oap, int amount) } for (; ascii_iswhite(*bd.textstart); ) { // TODO: is passing bd.textstart for start of the line OK? - incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (colnr_T)(bd.start_vcol)); + incr = lbr_chartabsize_adv(bd.textstart, &bd.textstart, (bd.start_vcol)); total += incr; bd.start_vcol += incr; } @@ -425,7 +425,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 - char_u *non_white = bd.textstart; + char_u *non_white = bd.textstart; /* * Firstly, let's find the first non-whitespace character that is @@ -506,7 +506,7 @@ static void shift_block(oparg_T *oap, int amount) } // replace the line ml_replace(curwin->w_cursor.lnum, newp, false); - changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol); + changed_bytes(curwin->w_cursor.lnum, bd.textcol); extmark_splice_cols(curbuf, (int)curwin->w_cursor.lnum-1, startcol, oldlen, newlen, kExtmarkUndo); @@ -526,7 +526,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def int spaces = 0; // non-zero if cutting a TAB colnr_T offset; // pointer along new line size_t s_len = STRLEN(s); - char_u *newp, *oldp; // new, old lines + char_u *newp, *oldp; // new, old lines linenr_T lnum; // loop var int oldstate = State; State = INSERT; // don't want REPLACE for State @@ -632,7 +632,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def void op_reindent(oparg_T *oap, Indenter how) { long i; - char_u *l; + char_u *l; int amount; linenr_T first_changed = 0; linenr_T last_changed = 0; @@ -709,7 +709,7 @@ void op_reindent(oparg_T *oap, Indenter how) /* * Keep the last expression line here, for repeating. */ -static char_u *expr_line = NULL; +static char_u *expr_line = NULL; /* * Get an expression for the "\"=expr1" or "CTRL-R =expr1" @@ -717,7 +717,7 @@ static char_u *expr_line = NULL; */ int get_expr_register(void) { - char_u *new_line; + char_u *new_line; new_line = getcmdline('=', 0L, 0, true); if (new_line == NULL) { @@ -747,8 +747,8 @@ void set_expr_line(char_u *new_line) */ char_u *get_expr_line(void) { - char_u *expr_copy; - char_u *rv; + char_u *expr_copy; + char_u *rv; static int nested = 0; if (expr_line == NULL) { @@ -910,9 +910,9 @@ bool yank_register_mline(int regname) */ int do_record(int c) { - char_u *p; + char_u *p; static int regname; - yankreg_T *old_y_previous; + yankreg_T *old_y_previous; int retval; if (reg_recording == 0) { @@ -1152,7 +1152,7 @@ static int put_in_typebuf(char_u *s, bool esc, bool colon, int silent) retval = ins_typebuf((char_u *)"\n", REMAP_NONE, 0, true, silent); } if (retval == OK) { - char_u *p; + char_u *p; if (esc) { p = vim_strsave_escape_csi(s); @@ -1253,7 +1253,7 @@ static void stuffescaped(const char *arg, int literally) arg++; } if (arg > start) { - stuffReadbuffLen(start, (long)(arg - start)); + stuffReadbuffLen(start, (arg - start)); } // stuff a single special character @@ -1417,8 +1417,8 @@ int op_delete(oparg_T *oap) { int n; linenr_T lnum; - char_u *ptr; - char_u *newp, *oldp; + char_u *ptr; + char_u *newp, *oldp; struct block_def bd = { 0 }; linenr_T old_lcount = curbuf->b_ml.ml_line_count; @@ -1670,7 +1670,7 @@ int op_delete(oparg_T *oap) /* fix up things for virtualedit-delete: * break the tabs which are going to get in our way */ - char_u *curline = get_cursor_line_ptr(); + char_u *curline = get_cursor_line_ptr(); int len = (int)STRLEN(curline); if (oap->end.coladd != 0 @@ -1748,7 +1748,7 @@ setmarks: */ static void mb_adjust_opend(oparg_T *oap) { - char_u *p; + char_u *p; if (oap->inclusive) { p = ml_get(oap->end.lnum); @@ -1788,10 +1788,10 @@ int op_replace(oparg_T *oap, int c) { int n, numc; int num_chars; - char_u *newp, *oldp; + char_u *newp, *oldp; colnr_T oldlen; struct block_def bd; - char_u *after_p = NULL; + char_u *after_p = NULL; int had_ctrl_v_cr = false; if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty) { @@ -2180,7 +2180,7 @@ bool swapchar(int op_type, pos_T *pos) void op_insert(oparg_T *oap, long count1) { long ins_len, pre_textlen = 0; - char_u *firstline, *ins_text; + char_u *firstline, *ins_text; colnr_T ind_pre = 0; struct block_def bd; int i; @@ -2881,7 +2881,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) int delcount; int incr = 0; struct block_def bd; - char_u **y_array = NULL; + char_u **y_array = NULL; long nr_lines = 0; pos_T new_cursor; int indent; @@ -2890,7 +2890,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) int first_indent = TRUE; int lendiff = 0; pos_T old_pos; - char_u *insert_string = NULL; + char_u *insert_string = NULL; bool allocated = false; long cnt; @@ -3227,7 +3227,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags) oldlen = STRLEN(oldp); for (ptr = oldp; vcol < col && *ptr; ) { // Count a tab for what it's worth (if list mode not on) - incr = lbr_chartabsize_adv(oldp, &ptr, (colnr_T)vcol); + incr = lbr_chartabsize_adv(oldp, &ptr, vcol); vcol += incr; } bd.textcol = (colnr_T)(ptr - oldp); @@ -3762,7 +3762,7 @@ void ex_display(exarg_T *eap) * display alternate file name */ if ((arg == NULL || vim_strchr(arg, '%') != NULL) && !got_int) { - char_u *fname; + char_u *fname; linenr_T dummy; if (buflist_name_nr(0, &fname, &dummy) != FAIL) { @@ -3892,11 +3892,11 @@ char_u *skip_comment(char_u *line, bool process, bool include_space, bool *is_co // return FAIL for failure, OK otherwise int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions, bool setmark) { - char_u *curr = NULL; - char_u *curr_start = NULL; - char_u *cend; - char_u *newp; - char_u *spaces; // number of spaces inserted before a line + char_u *curr = NULL; + char_u *curr_start = NULL; + char_u *cend; + char_u *newp; + char_u *spaces; // number of spaces inserted before a line int endcurr1 = NUL; int endcurr2 = NUL; int currsize = 0; // size of the current line @@ -3904,7 +3904,7 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions linenr_T t; colnr_T col = 0; int ret = OK; - int *comments = NULL; + int *comments = NULL; int remove_comments = (use_formatoptions == TRUE) && has_format_option(FO_REMOVE_COMS); bool prev_was_comment = false; @@ -4026,8 +4026,8 @@ int do_join(size_t count, int insert_space, int save_undo, int use_formatoptions const int spaces_removed = (int)((curr - curr_start) - spaces[t]); linenr_T lnum = curwin->w_cursor.lnum + t; colnr_T mincol = (colnr_T)0; - long lnum_amount = (linenr_T)-t; - long col_amount = (long)(cend - newp - spaces_removed); + long lnum_amount = -t; + long col_amount = (cend - newp - spaces_removed); mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed); @@ -4099,9 +4099,9 @@ static int same_leader(linenr_T lnum, int leader1_len, char_u *leader1_flags, in char_u *leader2_flags) { int idx1 = 0, idx2 = 0; - char_u *p; - char_u *line1; - char_u *line2; + char_u *p; + char_u *line1; + char_u *line2; if (leader1_len == 0) { return leader2_len == 0; @@ -4507,7 +4507,7 @@ void format_lines(linenr_T line_count, int avoid_fex) */ static int ends_in_white(linenr_T lnum) { - char_u *s = ml_get(lnum); + char_u *s = ml_get(lnum); size_t l; if (*s == NUL) { @@ -4527,12 +4527,12 @@ static int ends_in_white(linenr_T lnum) */ static int fmt_check_par(linenr_T lnum, int *leader_len, char_u **leader_flags, int do_comments) { - char_u *flags = NULL; // init for GCC - char_u *ptr; + char_u *flags = NULL; // init for GCC + char_u *ptr; ptr = ml_get(lnum); if (do_comments) { - *leader_len = get_leader_len(ptr, leader_flags, FALSE, TRUE); + *leader_len = get_leader_len(ptr, leader_flags, false, true); } else { *leader_len = 0; } @@ -4609,11 +4609,11 @@ int paragraph_start(linenr_T lnum) static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del) { int incr = 0; - char_u *pend; - char_u *pstart; - char_u *line; - char_u *prev_pstart; - char_u *prev_pend; + char_u *pend; + char_u *pstart; + char_u *line; + char_u *prev_pstart; + char_u *prev_pend; const int lbr_saved = curwin->w_p_lbr; // Avoid a problem with unwanted linebreaks in block mode. @@ -4635,7 +4635,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool prev_pstart = line; while (bdp->start_vcol < oap->start_vcol && *pstart) { // Count a tab for what it's worth (if list mode not on) - incr = lbr_chartabsize(line, pstart, (colnr_T)bdp->start_vcol); + incr = lbr_chartabsize(line, pstart, bdp->start_vcol); bdp->start_vcol += incr; if (ascii_iswhite(*pstart)) { bdp->pre_whitesp += incr; @@ -4686,7 +4686,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool while (bdp->end_vcol <= oap->end_vcol && *pend != NUL) { // Count a tab for what it's worth (if list mode not on) prev_pend = pend; - incr = lbr_chartabsize_adv(line, &pend, (colnr_T)bdp->end_vcol); + incr = lbr_chartabsize_adv(line, &pend, bdp->end_vcol); bdp->end_vcol += incr; } if (bdp->end_vcol <= oap->end_vcol @@ -4833,13 +4833,13 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd) int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) { int col; - char_u *buf1 = NULL; + char_u *buf1 = NULL; char_u buf2[NUMBUFLEN]; int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin static bool hexupper = false; // 0xABC uvarnumber_T n; uvarnumber_T oldn; - char_u *ptr; + char_u *ptr; int c; int todel; int firstdigit; @@ -5017,7 +5017,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1) 0 + (do_bin ? STR2NR_BIN : 0) + (do_oct ? STR2NR_OCT : 0) + (do_hex ? STR2NR_HEX : 0), - NULL, &n, maxlen); + NULL, &n, maxlen, false); // ignore leading '-' for hex, octal and bin numbers if (pre && negative) { @@ -5400,7 +5400,7 @@ void write_reg_contents_lst(int name, char_u **strings, bool must_append, Motion colnr_T block_len) { if (name == '/' || name == '=') { - char_u *s = strings[0]; + char_u *s = strings[0]; if (strings[0] == NULL) { s = (char_u *)""; } else if (strings[1] != NULL) { @@ -5417,7 +5417,7 @@ void write_reg_contents_lst(int name, char_u **strings, bool must_append, Motion return; } - yankreg_T *old_y_previous, *reg; + yankreg_T *old_y_previous, *reg; if (!(reg = init_write_reg(name, &old_y_previous, must_append))) { return; } @@ -5506,7 +5506,7 @@ void write_reg_contents_ex(int name, const char_u *str, ssize_t len, bool must_a return; } - yankreg_T *old_y_previous, *reg; + yankreg_T *old_y_previous, *reg; if (!(reg = init_write_reg(name, &old_y_previous, must_append))) { return; } @@ -5680,7 +5680,7 @@ static varnumber_T line_count_info(char_u *line, varnumber_T *wc, varnumber_T *c /// When "dict" is not NULL store the info there instead of showing it. void cursor_pos_info(dict_T *dict) { - char_u *p; + char_u *p; char_u buf1[50]; char_u buf2[40]; linenr_T lnum; @@ -5726,16 +5726,19 @@ void cursor_pos_info(dict_T *dict) } if (l_VIsual_mode == Ctrl_V) { - char_u * saved_sbr = p_sbr; + char_u *const saved_sbr = p_sbr; + char_u *const saved_w_sbr = curwin->w_p_sbr; // Make 'sbr' empty for a moment to get the correct size. p_sbr = empty_option; + curwin->w_p_sbr = empty_option; oparg.is_VIsual = true; oparg.motion_type = kMTBlockWise; oparg.op_type = OP_NOP; getvcols(curwin, &min_pos, &max_pos, &oparg.start_vcol, &oparg.end_vcol); p_sbr = saved_sbr; + curwin->w_p_sbr = saved_w_sbr; if (curwin->w_curswant == MAXCOL) { oparg.end_vcol = MAXCOL; } @@ -5762,7 +5765,7 @@ void cursor_pos_info(dict_T *dict) // Do extra processing for VIsual mode. if (l_VIsual_active && lnum >= min_pos.lnum && lnum <= max_pos.lnum) { - char_u *s = NULL; + char_u *s = NULL; long len = 0L; switch (l_VIsual_mode) { @@ -5905,18 +5908,18 @@ void cursor_pos_info(dict_T *dict) if (dict != NULL) { // Don't shorten this message, the user asked for it. - tv_dict_add_nr(dict, S_LEN("words"), (varnumber_T)word_count); - tv_dict_add_nr(dict, S_LEN("chars"), (varnumber_T)char_count); + tv_dict_add_nr(dict, S_LEN("words"), word_count); + tv_dict_add_nr(dict, S_LEN("chars"), char_count); tv_dict_add_nr(dict, S_LEN("bytes"), (varnumber_T)(byte_count + bom_count)); STATIC_ASSERT(sizeof("visual") == sizeof("cursor"), "key_len argument in tv_dict_add_nr is wrong"); tv_dict_add_nr(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes", - sizeof("visual_bytes") - 1, (varnumber_T)byte_count_cursor); + sizeof("visual_bytes") - 1, byte_count_cursor); tv_dict_add_nr(dict, l_VIsual_active ? "visual_chars" : "cursor_chars", - sizeof("visual_chars") - 1, (varnumber_T)char_count_cursor); + sizeof("visual_chars") - 1, char_count_cursor); tv_dict_add_nr(dict, l_VIsual_active ? "visual_words" : "cursor_words", - sizeof("visual_words") - 1, (varnumber_T)word_count_cursor); + sizeof("visual_words") - 1, word_count_cursor); } } @@ -6155,7 +6158,7 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet) reg->y_array[tv_idx++] = (char_u *)xstrdupnul((const char *)TV_LIST_ITEM_TV(li)->vval.v_string); }); - if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) { + if (reg->y_size > 0 && strlen((char *)reg->y_array[reg->y_size-1]) == 0) { // a known-to-be charwise yank might have a final linebreak // but otherwise there is no line after the final newline if (reg->y_type != kMTCharWise) { diff --git a/src/nvim/option.c b/src/nvim/option.c index d11bbc8ecc..fb7a0446b6 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -1276,9 +1276,9 @@ int do_set( } } else if (*arg == '-' || ascii_isdigit(*arg)) { // Allow negative, octal and hex numbers. - vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0); - if (arg[i] != NUL && !ascii_iswhite(arg[i])) { - errmsg = e_invarg; + vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0, true); + if (i == 0 || (arg[i] != NUL && !ascii_iswhite(arg[i]))) { + errmsg = (char_u *)N_("E521: Number required after ="); goto skip; } } else { @@ -2740,10 +2740,11 @@ ambw_end: if (*p_shada && errmsg == NULL && get_shada_parameter('\'') < 0) { errmsg = (char_u *)N_("E528: Must specify a ' value"); } - } else if (varp == &p_sbr) { // 'showbreak' - for (s = p_sbr; *s; ) { + } else if (gvarp == &p_sbr) { // 'showbreak' + for (s = *varp; *s; ) { if (ptr2cells(s) != 1) { - errmsg = (char_u *)N_("E595: contains unprintable or wide character"); + errmsg = (char_u *)N_( + "E595: 'showbreak' contains unprintable or wide character"); } MB_PTR_ADV(s); } @@ -5523,6 +5524,9 @@ void unset_global_local_option(char *name, void *from) case PV_MP: clear_string_option(&buf->b_p_mp); break; + case PV_SBR: + clear_string_option(&((win_T *)from)->w_p_sbr); + break; case PV_STL: clear_string_option(&((win_T *)from)->w_p_stl); break; @@ -5576,6 +5580,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags) case PV_DICT: return (char_u *)&(curbuf->b_p_dict); case PV_TSR: return (char_u *)&(curbuf->b_p_tsr); case PV_TFU: return (char_u *)&(curbuf->b_p_tfu); + case PV_SBR: return (char_u *)&(curwin->w_p_sbr); case PV_STL: return (char_u *)&(curwin->w_p_stl); case PV_UL: return (char_u *)&(curbuf->b_p_ul); case PV_LW: return (char_u *)&(curbuf->b_p_lw); @@ -5635,6 +5640,8 @@ static char_u *get_varp(vimoption_T *p) ? (char_u *)&(curbuf->b_p_gp) : p->var; case PV_MP: return *curbuf->b_p_mp != NUL ? (char_u *)&(curbuf->b_p_mp) : p->var; + case PV_SBR: return *curwin->w_p_sbr != NUL + ? (char_u *)&(curwin->w_p_sbr) : p->var; case PV_STL: return *curwin->w_p_stl != NUL ? (char_u *)&(curwin->w_p_stl) : p->var; case PV_UL: return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL @@ -5788,6 +5795,7 @@ void copy_winopt(winopt_T *from, winopt_T *to) to->wo_nuw = from->wo_nuw; to->wo_rl = from->wo_rl; to->wo_rlc = vim_strsave(from->wo_rlc); + to->wo_sbr = vim_strsave(from->wo_sbr); to->wo_stl = vim_strsave(from->wo_stl); to->wo_wrap = from->wo_wrap; to->wo_wrap_save = from->wo_wrap_save; @@ -5851,6 +5859,7 @@ static void check_winopt(winopt_T *wop) check_string_option(&wop->wo_fmr); check_string_option(&wop->wo_scl); check_string_option(&wop->wo_rlc); + check_string_option(&wop->wo_sbr); check_string_option(&wop->wo_stl); check_string_option(&wop->wo_culopt); check_string_option(&wop->wo_cc); @@ -5874,6 +5883,7 @@ void clear_winopt(winopt_T *wop) clear_string_option(&wop->wo_fmr); clear_string_option(&wop->wo_scl); clear_string_option(&wop->wo_rlc); + clear_string_option(&wop->wo_sbr); clear_string_option(&wop->wo_stl); clear_string_option(&wop->wo_culopt); clear_string_option(&wop->wo_cc); @@ -7472,6 +7482,22 @@ unsigned int get_bkc_value(buf_T *buf) return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags; } +/// Get the local or global value of 'showbreak'. +/// +/// @param win If not NULL, the window to get the local option from; global +/// otherwise. +char_u *get_showbreak_value(win_T *const win) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (win->w_p_sbr == NULL || *win->w_p_sbr == NUL) { + return p_sbr; + } + if (STRCMP(win->w_p_sbr, "NONE") == 0) { + return empty_option; + } + return win->w_p_sbr; +} + /// Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC. int get_fileformat(const buf_T *buf) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL @@ -7618,6 +7644,12 @@ int csh_like_shell(void) return strstr((char *)path_tail(p_sh), "csh") != NULL; } +/// Return true when 'shell' has "fish" in the tail. +bool fish_like_shell(void) +{ + return strstr((char *)path_tail(p_sh), "fish") != NULL; +} + /// Return the number of requested sign columns, based on current /// buffer signs and on user configuration. int win_signcol_count(win_T *wp) @@ -7672,12 +7704,6 @@ int win_signcol_configured(win_T *wp, int *is_fixed) return ret; } -// Get the local or global value of 'showbreak'. -char_u *get_showbreak_value(win_T *win FUNC_ATTR_UNUSED) -{ - return p_sbr; -} - /// Get window or buffer local options dict_T *get_winbuf_options(const int bufopt) FUNC_ATTR_WARN_UNUSED_RESULT diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 97ada9eb25..e588d3f373 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -877,6 +877,7 @@ enum { , WV_CUL , WV_CULOPT , WV_CC + , WV_SBR , WV_STL , WV_WFH , WV_WFW diff --git a/src/nvim/options.lua b/src/nvim/options.lua index df2a8edc04..8b9cdefd57 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -2175,7 +2175,7 @@ return { { full_name='showbreak', abbreviation='sbr', short_desc=N_("string to use at the start of wrapped lines"), - type='string', scope={'global'}, + type='string', scope={'global', 'window'}, redraw={'all_windows'}, varname='p_sbr', defaults={if_true=""} diff --git a/src/nvim/os/dl.c b/src/nvim/os/dl.c index 8483d316f3..b2e3994d10 100644 --- a/src/nvim/os/dl.c +++ b/src/nvim/os/dl.c @@ -7,10 +7,10 @@ #include <stdint.h> #include <uv.h> -#include "nvim/os/dl.h" -#include "nvim/os/os.h" #include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/dl.h" +#include "nvim/os/os.h" /// possible function prototypes that can be called by os_libcall() /// int -> int @@ -38,12 +38,8 @@ typedef int (*int_int_fn)(int i); /// not NULL. NULL when using `int_out`. /// @param[out] int_out the output integer param /// @return true on success, false on failure -bool os_libcall(const char *libname, - const char *funcname, - const char *argv, - int argi, - char **str_out, - int *int_out) +bool os_libcall(const char *libname, const char *funcname, const char *argv, int argi, + char **str_out, int *int_out) { if (!libname || !funcname) { return false; @@ -53,17 +49,17 @@ bool os_libcall(const char *libname, // open the dynamic loadable library if (uv_dlopen(libname, &lib)) { - EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); - uv_dlclose(&lib); - return false; + EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); + uv_dlclose(&lib); + return false; } // find and load the requested function in the library gen_fn fn; - if (uv_dlsym(&lib, funcname, (void **) &fn)) { - EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); - uv_dlclose(&lib); - return false; + if (uv_dlsym(&lib, funcname, (void **)&fn)) { + EMSG2(_("dlerror = \"%s\""), uv_dlerror(&lib)); + uv_dlclose(&lib); + return false; } // call the library and save the result @@ -71,17 +67,17 @@ bool os_libcall(const char *libname, // exceptions. jmp's on Unix seem to interact trickily with signals as // well. So for now we only support those libraries that are well-behaved. if (str_out) { - str_str_fn sfn = (str_str_fn) fn; - int_str_fn ifn = (int_str_fn) fn; + str_str_fn sfn = (str_str_fn)fn; + int_str_fn ifn = (int_str_fn)fn; const char *res = argv ? sfn(argv) : ifn(argi); // assume that ptr values of NULL, 1 or -1 are illegal - *str_out = (res && (intptr_t) res != 1 && (intptr_t) res != -1) + *str_out = (res && (intptr_t)res != 1 && (intptr_t)res != -1) ? xstrdup(res) : NULL; } else { - str_int_fn sfn = (str_int_fn) fn; - int_int_fn ifn = (int_int_fn) fn; + str_int_fn sfn = (str_int_fn)fn; + int_int_fn ifn = (int_int_fn)fn; *int_out = argv ? sfn(argv) : ifn(argi); } diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c index 92b5e14824..0fc3f35ffc 100644 --- a/src/nvim/os/env.c +++ b/src/nvim/os/env.c @@ -6,20 +6,20 @@ #include <assert.h> #include <uv.h> -#include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/charset.h" +#include "nvim/eval.h" +#include "nvim/ex_getln.h" #include "nvim/fileio.h" -#include "nvim/os/os.h" +#include "nvim/macros.h" +#include "nvim/map.h" #include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/os.h" #include "nvim/path.h" -#include "nvim/macros.h" #include "nvim/strings.h" -#include "nvim/eval.h" -#include "nvim/ex_getln.h" #include "nvim/version.h" -#include "nvim/map.h" +#include "nvim/vim.h" #ifdef WIN32 #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 @@ -206,7 +206,7 @@ size_t os_get_fullenv_size(void) # if defined(HAVE__NSGETENVIRON) char **environ = *_NSGetEnviron(); # else - extern char **environ; + extern char **environ; # endif while (environ[len] != NULL) { @@ -219,7 +219,9 @@ size_t os_get_fullenv_size(void) void os_free_fullenv(char **env) { - if (!env) { return; } + if (!env) { + return; + } for (char **it = env; *it; it++) { XFREE_CLEAR(*it); } @@ -262,7 +264,7 @@ void os_copy_fullenv(char **env, size_t env_size) # if defined(HAVE__NSGETENVIRON) char **environ = *_NSGetEnviron(); # else - extern char **environ; + extern char **environ; # endif for (size_t i = 0; i < env_size && environ[i] != NULL; i++) { @@ -322,7 +324,7 @@ char *os_getenvname_at_index(size_t index) # if defined(HAVE__NSGETENVIRON) char **environ = *_NSGetEnviron(); # else - extern char **environ; + extern char **environ; # endif // check if index is inside the environ array @@ -566,16 +568,12 @@ void expand_env(char_u *src, char_u *dst, int dstlen) /// @param esc Escape spaces in expanded variables /// @param one `srcp` is a single filename /// @param prefix Start again after this (can be NULL) -void expand_env_esc(char_u *restrict srcp, - char_u *restrict dst, - int dstlen, - bool esc, - bool one, +void expand_env_esc(char_u *restrict srcp, char_u *restrict dst, int dstlen, bool esc, bool one, char_u *prefix) FUNC_ATTR_NONNULL_ARG(1, 2) { - char_u *tail; - char_u *var; + char_u *tail; + char_u *var; bool copy_char; bool mustfree; // var was allocated, need to free it later bool at_start = true; // at start of a name @@ -621,7 +619,7 @@ void expand_env_esc(char_u *restrict srcp, while (c-- > 0 && *tail != NUL && *tail != '}') { *var++ = *tail++; } - } else // NOLINT + } else // NOLINT #endif { while (c-- > 0 && *tail != NUL && vim_isIDc(*tail)) { @@ -642,7 +640,7 @@ void expand_env_esc(char_u *restrict srcp, var = (char_u *)vim_getenv((char *)dst); mustfree = true; #if defined(UNIX) - } + } #endif } else if (src[1] == NUL // home directory || vim_ispathsep(src[1]) @@ -673,7 +671,7 @@ void expand_env_esc(char_u *restrict srcp, ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; var = ExpandOne(&xpc, dst, NULL, - WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE); + WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE); mustfree = true; } #else @@ -687,7 +685,7 @@ void expand_env_esc(char_u *restrict srcp, // If 'shellslash' is set change backslashes to forward slashes. // Can't use slash_adjust(), p_ssl may be set temporarily. if (p_ssl && var != NULL && vim_strchr(var, '\\') != NULL) { - char_u *p = vim_strsave(var); + char_u *p = vim_strsave(var); if (mustfree) { xfree(var); @@ -701,7 +699,7 @@ void expand_env_esc(char_u *restrict srcp, // If "var" contains white space, escape it with a backslash. // Required for ":e ~/tt" when $HOME includes a space. if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL) { - char_u *p = vim_strsave_escaped(var, (char_u *)" \t"); + char_u *p = vim_strsave_escaped(var, (char_u *)" \t"); if (mustfree) { xfree(var); @@ -721,8 +719,9 @@ void expand_env_esc(char_u *restrict srcp, #if defined(BACKSLASH_IN_FILENAME) && dst[-1] != ':' #endif - && vim_ispathsep(*tail)) + && vim_ispathsep(*tail)) { ++tail; + } dst += c; src = tail; copy_char = false; @@ -826,14 +825,11 @@ static char *remove_tail(char *path, char *pend, char *dirname) /// @param[out] len Location where current directory length should be saved. /// /// @return Next iter argument value or NULL when iteration should stop. -const void *vim_env_iter(const char delim, - const char *const val, - const void *const iter, - const char **const dir, - size_t *const len) +const void *vim_env_iter(const char delim, const char *const val, const void *const iter, + const char **const dir, size_t *const len) FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { - const char *varval = (const char *) iter; + const char *varval = (const char *)iter; if (varval == NULL) { varval = val; } @@ -843,7 +839,7 @@ const void *vim_env_iter(const char delim, *len = strlen(varval); return NULL; } else { - *len = (size_t) (dirend - varval); + *len = (size_t)(dirend - varval); return dirend + 1; } } @@ -861,14 +857,11 @@ const void *vim_env_iter(const char delim, /// @param[out] len Location where current directory length should be saved. /// /// @return Next iter argument value or NULL when iteration should stop. -const void *vim_env_iter_rev(const char delim, - const char *const val, - const void *const iter, - const char **const dir, - size_t *const len) +const void *vim_env_iter_rev(const char delim, const char *const val, const void *const iter, + const char **const dir, size_t *const len) FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT { - const char *varend = (const char *) iter; + const char *varend = (const char *)iter; if (varend == NULL) { varend = val + strlen(val) - 1; } @@ -880,7 +873,7 @@ const void *vim_env_iter_rev(const char delim, return NULL; } else { *dir = colon + 1; - *len = (size_t) (varend - colon); + *len = (size_t)(varend - colon); return colon - 1; } } @@ -955,10 +948,9 @@ char *vim_getenv(const char *name) // Find runtime path relative to the nvim binary: ../share/nvim/runtime if (vim_path == NULL) { vim_get_prefix_from_exepath(exe_name); - if (append_path( - exe_name, - "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR, - MAXPATHL) == OK) { + if (append_path(exe_name, + "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR, + MAXPATHL) == OK) { vim_path = exe_name; // -V507 } } @@ -1043,8 +1035,8 @@ char *vim_getenv(const char *name) /// a list of them. /// /// @return length of the string put into dst, does not include NUL byte. -size_t home_replace(const buf_T *const buf, const char_u *src, - char_u *const dst, size_t dstlen, const bool one) +size_t home_replace(const buf_T *const buf, const char_u *src, char_u *const dst, size_t dstlen, + const bool one) FUNC_ATTR_NONNULL_ARG(3) { size_t dirlen = 0; diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index fa359fa32e..1ae6ca4244 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -8,9 +8,9 @@ /// replacement. #include <assert.h> -#include <stddef.h> -#include <stdbool.h> #include <fcntl.h> +#include <stdbool.h> +#include <stddef.h> #include "auto/config.h" @@ -20,13 +20,13 @@ #include <uv.h> -#include "nvim/os/fileio.h" -#include "nvim/memory.h" -#include "nvim/os/os.h" #include "nvim/globals.h" -#include "nvim/rbuffer.h" #include "nvim/macros.h" +#include "nvim/memory.h" #include "nvim/message.h" +#include "nvim/os/fileio.h" +#include "nvim/os/os.h" +#include "nvim/rbuffer.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/fileio.c.generated.h" @@ -44,8 +44,8 @@ /// does not have kFileCreate\*). /// /// @return Error code, or 0 on success. @see os_strerror() -int file_open(FileDescriptor *const ret_fp, const char *const fname, - const int flags, const int mode) +int file_open(FileDescriptor *const ret_fp, const char *const fname, const int flags, + const int mode) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { int os_open_flags = 0; @@ -99,8 +99,7 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname, /// FILE_WRITE_ONLY or FILE_READ_ONLY is required. /// /// @return Error code (@see os_strerror()) or 0. Currently always returns 0. -int file_open_fd(FileDescriptor *const ret_fp, const int fd, - const int flags) +int file_open_fd(FileDescriptor *const ret_fp, const int fd, const int flags) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { ret_fp->wr = !!(flags & (kFileCreate @@ -131,8 +130,8 @@ int file_open_fd(FileDescriptor *const ret_fp, const int fd, /// does not have kFileCreate\*). /// /// @return [allocated] Opened file or NULL in case of error. -FileDescriptor *file_open_new(int *const error, const char *const fname, - const int flags, const int mode) +FileDescriptor *file_open_new(int *const error, const char *const fname, const int flags, + const int mode) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { FileDescriptor *const fp = xmalloc(sizeof(*fp)); @@ -152,8 +151,7 @@ FileDescriptor *file_open_new(int *const error, const char *const fname, /// does not have FILE_CREATE\*). /// /// @return [allocated] Opened file or NULL in case of error. -FileDescriptor *file_open_fd_new(int *const error, const int fd, - const int flags) +FileDescriptor *file_open_fd_new(int *const error, const int fd, const int flags) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { FileDescriptor *const fp = xmalloc(sizeof(*fp)); @@ -277,8 +275,7 @@ static void file_rb_write_full_cb(RBuffer *const rv, FileDescriptor *const fp) /// bytes. /// /// @return error_code (< 0) or number of bytes read. -ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, - const size_t size) +ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, const size_t size) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { assert(!fp->wr); @@ -362,8 +359,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf, /// @param[in] size Amount of bytes to write. /// /// @return Number of bytes written or libuv error code (< 0). -ptrdiff_t file_write(FileDescriptor *const fp, const char *const buf, - const size_t size) +ptrdiff_t file_write(FileDescriptor *const fp, const char *const buf, const size_t size) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1) { assert(fp->wr); @@ -392,8 +388,8 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size) assert(!fp->wr); size_t read_bytes = 0; do { - const ptrdiff_t new_read_bytes = file_read( - fp, skipbuf, MIN(size - read_bytes, sizeof(skipbuf))); + const ptrdiff_t new_read_bytes = + file_read(fp, skipbuf, MIN(size - read_bytes, sizeof(skipbuf))); if (new_read_bytes < 0) { return new_read_bytes; } else if (new_read_bytes == 0) { diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index b8ba2487f3..d50d68c99e 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -2,12 +2,12 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com // fs.c -- filesystem access -#include <stdbool.h> -#include <stddef.h> #include <assert.h> -#include <limits.h> -#include <fcntl.h> #include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdbool.h> +#include <stddef.h> #include "auto/config.h" @@ -17,14 +17,14 @@ #include <uv.h> -#include "nvim/os/os.h" -#include "nvim/os/os_defs.h" #include "nvim/ascii.h" +#include "nvim/assert.h" #include "nvim/memory.h" #include "nvim/message.h" -#include "nvim/assert.h" #include "nvim/misc1.h" #include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/os/os_defs.h" #include "nvim/path.h" #include "nvim/strings.h" @@ -37,18 +37,18 @@ #endif #define RUN_UV_FS_FUNC(ret, func, ...) \ - do { \ - bool did_try_to_free = false; \ + do { \ + bool did_try_to_free = false; \ uv_call_start: {} \ - uv_fs_t req; \ - ret = func(&fs_loop, &req, __VA_ARGS__); \ - uv_fs_req_cleanup(&req); \ - if (ret == UV_ENOMEM && !did_try_to_free) { \ - try_to_free_memory(); \ - did_try_to_free = true; \ - goto uv_call_start; \ - } \ - } while (0) + uv_fs_t req; \ + ret = func(&fs_loop, &req, __VA_ARGS__); \ + uv_fs_req_cleanup(&req); \ + if (ret == UV_ENOMEM && !did_try_to_free) { \ + try_to_free_memory(); \ + did_try_to_free = true; \ + goto uv_call_start; \ + } \ + } while (0) // Many fs functions from libuv return that value on success. static const int kLibuvSuccess = 0; @@ -199,16 +199,16 @@ int os_nodetype(const char *name) } switch (guess) { - case UV_TTY: // FILE_TYPE_CHAR - return NODE_WRITABLE; - case UV_FILE: // FILE_TYPE_DISK - return NODE_NORMAL; - case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c - case UV_UDP: // unix only - case UV_TCP: // unix only - case UV_UNKNOWN_HANDLE: - default: - return NODE_OTHER; // Vim os_win32.c default + case UV_TTY: // FILE_TYPE_CHAR + return NODE_WRITABLE; + case UV_FILE: // FILE_TYPE_DISK + return NODE_NORMAL; + case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c + case UV_UDP: // unix only + case UV_TCP: // unix only + case UV_UNKNOWN_HANDLE: + default: + return NODE_OTHER; // Vim os_win32.c default } #endif } @@ -326,7 +326,7 @@ static bool is_executable_ext(const char *name, char **abspath) sizeof(os_buf) - (size_t)(buf_end - os_buf), ENV_SEPSTR); if (ext_len != 0) { bool in_pathext = nameext_len == ext_len - && 0 == mb_strnicmp((char_u *)nameext, (char_u *)ext, ext_len); + && 0 == mb_strnicmp((char_u *)nameext, (char_u *)ext, ext_len); if (((in_pathext || is_unix_shell) && is_executable(name, abspath)) || is_executable(os_buf, abspath)) { @@ -436,17 +436,17 @@ FILE *os_fopen(const char *path, const char *flags) // Per table in fopen(3) manpage. if (flags[1] == '\0' || flags[1] == 'b') { switch (flags[0]) { - case 'r': - iflags = O_RDONLY; - break; - case 'w': - iflags = O_WRONLY | O_CREAT | O_TRUNC; - break; - case 'a': - iflags = O_WRONLY | O_CREAT | O_APPEND; - break; - default: - abort(); + case 'r': + iflags = O_RDONLY; + break; + case 'w': + iflags = O_WRONLY | O_CREAT | O_TRUNC; + break; + case 'a': + iflags = O_WRONLY | O_CREAT | O_APPEND; + break; + default: + abort(); } #ifdef WIN32 if (flags[1] == 'b') { @@ -458,17 +458,17 @@ FILE *os_fopen(const char *path, const char *flags) // char 1 is always '+' ('b' is handled above). assert(flags[1] == '+'); switch (flags[0]) { - case 'r': - iflags = O_RDWR; - break; - case 'w': - iflags = O_RDWR | O_CREAT | O_TRUNC; - break; - case 'a': - iflags = O_RDWR | O_CREAT | O_APPEND; - break; - default: - abort(); + case 'r': + iflags = O_RDWR; + break; + case 'w': + iflags = O_RDWR | O_CREAT | O_TRUNC; + break; + case 'a': + iflags = O_RDWR | O_CREAT | O_APPEND; + break; + default: + abort(); } } // Per fopen(3) manpage: default to 0666, it will be umask-adjusted. @@ -553,8 +553,8 @@ os_dup_dup: /// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes read or libuv error code (< 0). -ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, - const size_t size, const bool non_blocking) +ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, const size_t size, + const bool non_blocking) FUNC_ATTR_WARN_UNUSED_RESULT { *ret_eof = false; @@ -609,8 +609,8 @@ ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf, /// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes read or libuv error code (< 0). -ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, - size_t iov_size, const bool non_blocking) +ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, size_t iov_size, + const bool non_blocking) FUNC_ATTR_NONNULL_ALL { *ret_eof = false; @@ -668,8 +668,7 @@ ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov, /// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered. /// /// @return Number of bytes written or libuv error code (< 0). -ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, - const bool non_blocking) +ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, const bool non_blocking) FUNC_ATTR_WARN_UNUSED_RESULT { if (buf == NULL) { @@ -884,8 +883,7 @@ int os_mkdir(const char *path, int32_t mode) /// of the higher level directories. /// /// @return `0` for success, libuv error code for failure. -int os_mkdir_recurse(const char *const dir, int32_t mode, - char **const failed_dir) +int os_mkdir_recurse(const char *const dir, int32_t mode, char **const failed_dir) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { // Get end of directory name in "dir". @@ -1058,8 +1056,7 @@ bool os_fileinfo_fd(int file_descriptor, FileInfo *file_info) /// Compare the inodes of two FileInfos /// /// @return `true` if the two FileInfos represent the same file. -bool os_fileinfo_id_equal(const FileInfo *file_info_1, - const FileInfo *file_info_2) +bool os_fileinfo_id_equal(const FileInfo *file_info_1, const FileInfo *file_info_2) FUNC_ATTR_NONNULL_ALL { return file_info_1->stat.st_ino == file_info_2->stat.st_ino @@ -1149,8 +1146,7 @@ bool os_fileid_equal(const FileID *file_id_1, const FileID *file_id_2) /// @param file_id Pointer to a `FileID` /// @param file_info Pointer to a `FileInfo` /// @return `true` if the `FileID` and the `FileInfo` represent te same file. -bool os_fileid_equal_fileinfo(const FileID *file_id, - const FileInfo *file_info) +bool os_fileid_equal_fileinfo(const FileID *file_id, const FileInfo *file_info) FUNC_ATTR_NONNULL_ALL { return file_id->inode == file_info->stat.st_ino @@ -1219,8 +1215,7 @@ char *os_resolve_shortcut(const char *fname) EMSG2("utf8_to_utf16 failed: %d", r); } else if (p != NULL) { // Get a pointer to the IPersistFile interface. - hr = pslw->lpVtbl->QueryInterface( - pslw, &IID_IPersistFile, (void **)&ppf); + hr = pslw->lpVtbl->QueryInterface(pslw, &IID_IPersistFile, (void **)&ppf); if (hr != S_OK) { goto shortcut_errorw; } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index eca245650a..4c6e9ee4d3 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -2,28 +2,27 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <string.h> #include <stdbool.h> - +#include <string.h> #include <uv.h> #include "nvim/api/private/defs.h" -#include "nvim/os/input.h" +#include "nvim/ascii.h" #include "nvim/event/loop.h" #include "nvim/event/rstream.h" -#include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/ui.h" -#include "nvim/memory.h" -#include "nvim/keymap.h" -#include "nvim/mbyte.h" -#include "nvim/fileio.h" #include "nvim/ex_cmds2.h" +#include "nvim/fileio.h" #include "nvim/getchar.h" +#include "nvim/keymap.h" #include "nvim/main.h" +#include "nvim/mbyte.h" +#include "nvim/memory.h" #include "nvim/misc1.h" -#include "nvim/state.h" #include "nvim/msgpack_rpc/channel.h" +#include "nvim/os/input.h" +#include "nvim/state.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #define READ_BUFFER_SIZE 0xfff #define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4) @@ -102,8 +101,7 @@ static void create_cursorhold_event(bool events_enabled) /// /// wait until either the input buffer is non-empty or , if `events` is not NULL /// until `events` is non-empty. -int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, - MultiQueue *events) +int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, MultiQueue *events) { if (maxlen && rbuffer_size(input_buffer)) { return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); @@ -192,7 +190,7 @@ void os_breakcheck(void) /// @return `true` if file descriptor refers to a terminal. bool os_isatty(int fd) { - return uv_guess_handle(fd) == UV_TTY; + return uv_guess_handle(fd) == UV_TTY; } size_t input_enqueue(String keys) @@ -208,8 +206,8 @@ size_t input_enqueue(String keys) // K_SPECIAL(0x80) or CSI(0x9B). uint8_t buf[19] = { 0 }; unsigned int new_size - = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true, - false); + = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true, + false); if (new_size) { new_size = handle_mouse_event(&ptr, buf, new_size); @@ -234,13 +232,13 @@ size_t input_enqueue(String keys) // copy the character, escaping CSI and K_SPECIAL if ((uint8_t)*ptr == CSI) { - rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KS_EXTRA}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KE_CSI}, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ K_SPECIAL }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KS_EXTRA }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KE_CSI }, 1); } else if ((uint8_t)*ptr == K_SPECIAL) { - rbuffer_write(input_buffer, (char *)&(uint8_t){K_SPECIAL}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KS_SPECIAL}, 1); - rbuffer_write(input_buffer, (char *)&(uint8_t){KE_FILLER}, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ K_SPECIAL }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KS_SPECIAL }, 1); + rbuffer_write(input_buffer, (char *)&(uint8_t){ KE_FILLER }, 1); } else { rbuffer_write(input_buffer, ptr, 1); } @@ -301,8 +299,7 @@ static uint8_t check_multiclick(int code, int grid, int row, int col) // Mouse event handling code(Extract row/col if available and detect multiple // clicks) -static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, - unsigned int bufsize) +static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, unsigned int bufsize) { int mouse_code = 0; int type = 0; @@ -318,7 +315,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, if (type != KS_EXTRA || !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE) - || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { + || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { return bufsize; } @@ -364,8 +361,7 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, return bufsize; } -size_t input_enqueue_mouse(int code, uint8_t modifier, - int grid, int row, int col) +size_t input_enqueue_mouse(int code, uint8_t modifier, int grid, int row, int col) { modifier |= check_multiclick(code, grid, row, col); uint8_t buf[7], *p = buf; @@ -437,8 +433,7 @@ bool input_available(void) return rbuffer_size(input_buffer) != 0; } -static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data, - bool at_eof) +static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data, bool at_eof) { if (at_eof) { input_done(); diff --git a/src/nvim/os/os_win_console.c b/src/nvim/os/os_win_console.c index 18dcfeafa0..2c9cb699fc 100644 --- a/src/nvim/os/os_win_console.c +++ b/src/nvim/os/os_win_console.c @@ -1,9 +1,9 @@ // 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 -#include "nvim/vim.h" #include "nvim/os/input.h" #include "nvim/os/os_win_console.h" +#include "nvim/vim.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/os_win_console.c.generated.h" diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c index c7b473a012..e70bc71961 100644 --- a/src/nvim/os/process.c +++ b/src/nvim/os/process.c @@ -23,16 +23,16 @@ #endif #if defined(__APPLE__) || defined(BSD) -# include <sys/sysctl.h> # include <pwd.h> +# include <sys/sysctl.h> #endif +#include "nvim/api/private/helpers.h" #include "nvim/globals.h" #include "nvim/log.h" -#include "nvim/os/process.h" #include "nvim/os/os.h" #include "nvim/os/os_defs.h" -#include "nvim/api/private/helpers.h" +#include "nvim/os/process.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/process.c.generated.h" diff --git a/src/nvim/os/pty_conpty_win.c b/src/nvim/os/pty_conpty_win.c index 775e303f84..0625d6994e 100644 --- a/src/nvim/os/pty_conpty_win.c +++ b/src/nvim/os/pty_conpty_win.c @@ -3,9 +3,9 @@ #include <uv.h> -#include "nvim/vim.h" #include "nvim/os/os.h" #include "nvim/os/pty_conpty_win.h" +#include "nvim/vim.h" #ifndef EXTENDED_STARTUPINFO_PRESENT # define EXTENDED_STARTUPINFO_PRESENT 0x00080000 @@ -54,8 +54,7 @@ TriState os_dyn_conpty_init(void) return kTrue; } -conpty_t *os_conpty_init(char **in_name, char **out_name, - uint16_t width, uint16_t height) +conpty_t *os_conpty_init(char **in_name, char **out_name, uint16_t width, uint16_t height) { static int count = 0; conpty_t *conpty_object = xcalloc(1, sizeof(*conpty_object)); @@ -65,36 +64,34 @@ conpty_t *os_conpty_init(char **in_name, char **out_name, char buf[MAXPATHL]; SECURITY_ATTRIBUTES sa = { 0 }; const DWORD mode = PIPE_ACCESS_INBOUND - | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; + | PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE; sa.nLength = sizeof(sa); snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-in-%d-%d", os_get_pid(), count); *in_name = xstrdup(buf); - if ((in_read = CreateNamedPipeA( - *in_name, - mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 1, - 0, - 0, - 30000, - &sa)) == INVALID_HANDLE_VALUE) { + if ((in_read = CreateNamedPipeA(*in_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { emsg = "create input pipe failed"; goto failed; } snprintf(buf, sizeof(buf), "\\\\.\\pipe\\nvim-term-out-%d-%d", os_get_pid(), count); *out_name = xstrdup(buf); - if ((out_write = CreateNamedPipeA( - *out_name, - mode, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - 1, - 0, - 0, - 30000, - &sa)) == INVALID_HANDLE_VALUE) { + if ((out_write = CreateNamedPipeA(*out_name, + mode, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 1, + 0, + 0, + 30000, + &sa)) == INVALID_HANDLE_VALUE) { emsg = "create output pipe failed"; goto failed; } @@ -113,22 +110,20 @@ conpty_t *os_conpty_init(char **in_name, char **out_name, InitializeProcThreadAttributeList(NULL, 1, 0, & bytes_required); conpty_object->si_ex.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)xmalloc(bytes_required); - if (!InitializeProcThreadAttributeList( - conpty_object->si_ex.lpAttributeList, - 1, - 0, - &bytes_required)) { + if (!InitializeProcThreadAttributeList(conpty_object->si_ex.lpAttributeList, + 1, + 0, + &bytes_required)) { emsg = "InitializeProcThreadAttributeList failed"; goto failed; } - if (!UpdateProcThreadAttribute( - conpty_object->si_ex.lpAttributeList, - 0, - PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, - conpty_object->pty, - sizeof(conpty_object->pty), - NULL, - NULL)) { + if (!UpdateProcThreadAttribute(conpty_object->si_ex.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, + conpty_object->pty, + sizeof(conpty_object->pty), + NULL, + NULL)) { emsg = "UpdateProcThreadAttribute failed"; goto failed; } @@ -150,38 +145,35 @@ finished: return conpty_object; } -bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, - wchar_t *name, wchar_t *cmd_line, wchar_t *cwd, - wchar_t *env) +bool os_conpty_spawn(conpty_t *conpty_object, HANDLE *process_handle, wchar_t *name, + wchar_t *cmd_line, wchar_t *cwd, wchar_t *env) { PROCESS_INFORMATION pi = { 0 }; - if (!CreateProcessW( - name, - cmd_line, - NULL, - NULL, - false, - EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, - env, - cwd, - &conpty_object->si_ex.StartupInfo, - &pi)) { + if (!CreateProcessW(name, + cmd_line, + NULL, + NULL, + false, + EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, + env, + cwd, + &conpty_object->si_ex.StartupInfo, + &pi)) { return false; } *process_handle = pi.hProcess; return true; } -void os_conpty_set_size(conpty_t *conpty_object, - uint16_t width, uint16_t height) +void os_conpty_set_size(conpty_t *conpty_object, uint16_t width, uint16_t height) { - assert(width <= SHRT_MAX); - assert(height <= SHRT_MAX); - COORD size = { (int16_t)width, (int16_t)height }; - if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { - ELOG("ResizePseudoConsoel failed: error code: %d", - os_translate_sys_error((int)GetLastError())); - } + assert(width <= SHRT_MAX); + assert(height <= SHRT_MAX); + COORD size = { (int16_t)width, (int16_t)height }; + if (pResizePseudoConsole(conpty_object->pty, size) != S_OK) { + ELOG("ResizePseudoConsoel failed: error code: %d", + os_translate_sys_error((int)GetLastError())); + } } void os_conpty_free(conpty_t *conpty_object) diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c index 36d6dbe2db..d94de2e397 100644 --- a/src/nvim/os/pty_process_unix.c +++ b/src/nvim/os/pty_process_unix.c @@ -5,11 +5,10 @@ #include <stdbool.h> #include <stdlib.h> #include <string.h> - -#include <termios.h> +#include <sys/ioctl.h> #include <sys/types.h> #include <sys/wait.h> -#include <sys/ioctl.h> +#include <termios.h> // forkpty is not in POSIX, so headers are platform-specific #if defined(__FreeBSD__) || defined(__DragonFly__) @@ -26,15 +25,14 @@ #include <uv.h> -#include "nvim/lib/klist.h" - #include "nvim/event/loop.h" +#include "nvim/event/process.h" #include "nvim/event/rstream.h" #include "nvim/event/wstream.h" -#include "nvim/event/process.h" -#include "nvim/os/pty_process_unix.h" +#include "nvim/lib/klist.h" #include "nvim/log.h" #include "nvim/os/os.h" +#include "nvim/os/pty_process_unix.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_unix.c.generated.h" diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 2bf73d08e6..f78f3e66f5 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,15 +4,14 @@ #include <assert.h> #include <stdbool.h> #include <stdlib.h> - #include <winpty_constants.h> -#include "nvim/os/os.h" #include "nvim/ascii.h" -#include "nvim/memory.h" #include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8 -#include "nvim/os/pty_process_win.h" +#include "nvim/memory.h" +#include "nvim/os/os.h" #include "nvim/os/pty_conpty_win.h" +#include "nvim/os/pty_process_win.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/pty_process_win.c.generated.h" @@ -59,8 +58,8 @@ int pty_process_spawn(PtyProcess *ptyproc) if (os_has_conpty_working()) { if ((conpty_object = - os_conpty_init(&in_name, &out_name, - ptyproc->width, ptyproc->height)) != NULL) { + os_conpty_init(&in_name, &out_name, + ptyproc->width, ptyproc->height)) != NULL) { ptyproc->type = kConpty; } } @@ -94,20 +93,18 @@ int pty_process_spawn(PtyProcess *ptyproc) if (!proc->in.closed) { in_req = xmalloc(sizeof(uv_connect_t)); - uv_pipe_connect( - in_req, - &proc->in.uv.pipe, - in_name, - pty_process_connect_cb); + uv_pipe_connect(in_req, + &proc->in.uv.pipe, + in_name, + pty_process_connect_cb); } if (!proc->out.closed) { out_req = xmalloc(sizeof(uv_connect_t)); - uv_pipe_connect( - out_req, - &proc->out.uv.pipe, - out_name, - pty_process_connect_cb); + uv_pipe_connect(out_req, + &proc->out.uv.pipe, + out_name, + pty_process_connect_cb); } if (proc->cwd != NULL) { @@ -146,13 +143,12 @@ int pty_process_spawn(PtyProcess *ptyproc) goto cleanup; } } else { - spawncfg = winpty_spawn_config_new( - WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, - NULL, // Optional application name - cmd_line, - cwd, - env, - &err); + spawncfg = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, + NULL, // Optional application name + cmd_line, + cwd, + env, + &err); if (spawncfg == NULL) { emsg = "winpty_spawn_config_new failed"; goto cleanup; @@ -176,13 +172,12 @@ int pty_process_spawn(PtyProcess *ptyproc) } proc->pid = (int)GetProcessId(process_handle); - if (!RegisterWaitForSingleObject( - &ptyproc->finish_wait, - process_handle, - pty_process_finish1, - ptyproc, - INFINITE, - WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) { + if (!RegisterWaitForSingleObject(&ptyproc->finish_wait, + process_handle, + pty_process_finish1, + ptyproc, + INFINITE, + WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) { abort(); } @@ -193,8 +188,8 @@ int pty_process_spawn(PtyProcess *ptyproc) } (ptyproc->type == kConpty) ? - (void *)(ptyproc->object.conpty = conpty_object) : - (void *)(ptyproc->object.winpty = winpty_object); + (void *)(ptyproc->object.conpty = conpty_object) : + (void *)(ptyproc->object.winpty = winpty_object); ptyproc->process_handle = process_handle; winpty_object = NULL; conpty_object = NULL; @@ -235,8 +230,7 @@ const char *pty_process_tty_name(PtyProcess *ptyproc) return "?"; } -void pty_process_resize(PtyProcess *ptyproc, uint16_t width, - uint16_t height) +void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) FUNC_ATTR_NONNULL_ALL { if (ptyproc->type == kConpty @@ -454,15 +448,24 @@ int translate_winpty_error(int winpty_errno) } switch (winpty_errno) { - case WINPTY_ERROR_OUT_OF_MEMORY: return UV_ENOMEM; - case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: return UV_EAI_FAIL; - case WINPTY_ERROR_LOST_CONNECTION: return UV_ENOTCONN; - case WINPTY_ERROR_AGENT_EXE_MISSING: return UV_ENOENT; - case WINPTY_ERROR_UNSPECIFIED: return UV_UNKNOWN; - case WINPTY_ERROR_AGENT_DIED: return UV_ESRCH; - case WINPTY_ERROR_AGENT_TIMEOUT: return UV_ETIMEDOUT; - case WINPTY_ERROR_AGENT_CREATION_FAILED: return UV_EAI_FAIL; - default: return UV_UNKNOWN; + case WINPTY_ERROR_OUT_OF_MEMORY: + return UV_ENOMEM; + case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: + return UV_EAI_FAIL; + case WINPTY_ERROR_LOST_CONNECTION: + return UV_ENOTCONN; + case WINPTY_ERROR_AGENT_EXE_MISSING: + return UV_ENOENT; + case WINPTY_ERROR_UNSPECIFIED: + return UV_UNKNOWN; + case WINPTY_ERROR_AGENT_DIED: + return UV_ESRCH; + case WINPTY_ERROR_AGENT_TIMEOUT: + return UV_ETIMEDOUT; + case WINPTY_ERROR_AGENT_CREATION_FAILED: + return UV_EAI_FAIL; + default: + return UV_UNKNOWN; } } diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 2974245857..f0d446b4c5 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -1,36 +1,35 @@ // 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 -#include <string.h> #include <assert.h> #include <stdbool.h> #include <stdlib.h> - +#include <string.h> #include <uv.h> #include "nvim/ascii.h" -#include "nvim/fileio.h" -#include "nvim/lib/kvec.h" -#include "nvim/log.h" -#include "nvim/event/loop.h" +#include "nvim/charset.h" #include "nvim/event/libuv_process.h" +#include "nvim/event/loop.h" #include "nvim/event/rstream.h" #include "nvim/ex_cmds.h" +#include "nvim/fileio.h" +#include "nvim/lib/kvec.h" +#include "nvim/log.h" +#include "nvim/main.h" +#include "nvim/memline.h" +#include "nvim/memory.h" +#include "nvim/message.h" #include "nvim/misc1.h" +#include "nvim/option_defs.h" #include "nvim/os/shell.h" #include "nvim/os/signal.h" #include "nvim/path.h" -#include "nvim/types.h" -#include "nvim/main.h" -#include "nvim/vim.h" -#include "nvim/message.h" -#include "nvim/memory.h" -#include "nvim/ui.h" #include "nvim/screen.h" -#include "nvim/memline.h" -#include "nvim/option_defs.h" -#include "nvim/charset.h" #include "nvim/strings.h" +#include "nvim/types.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #define DYNAMIC_BUFFER_INIT { NULL, 0, 0 } #define NS_1_SECOND 1000000000U // 1 second, in nanoseconds @@ -47,8 +46,7 @@ typedef struct { # include "os/shell.c.generated.h" #endif -static void save_patterns(int num_pat, char_u **pat, int *num_file, - char_u ***file) +static void save_patterns(int num_pat, char_u **pat, int *num_file, char_u ***file) { *file = xmalloc((size_t)num_pat * sizeof(char_u *)); for (int i = 0; i < num_pat; i++) { @@ -99,22 +97,21 @@ static bool have_dollars(int num, char_u **file) /// copied into *file. /// /// @returns OK for success or FAIL for error. -int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, - char_u ***file, int flags) +int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags) FUNC_ATTR_NONNULL_ARG(3) FUNC_ATTR_NONNULL_ARG(4) { int i; size_t len; - char_u *p; + char_u *p; bool dir; char_u *extra_shell_arg = NULL; ShellOpts shellopts = kShellOptExpand | kShellOptSilent; int j; - char_u *tempname; - char_u *command; - FILE *fd; - char_u *buffer; + char_u *tempname; + char_u *command; + FILE *fd; + char_u *buffer; #define STYLE_ECHO 0 // use "echo", the default #define STYLE_GLOB 1 // use "glob", for csh #define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh @@ -215,7 +212,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, } if (is_fish_shell) { - len += sizeof("egin;"" end") - 1; + len += sizeof("egin;" " end") - 1; } command = xmalloc(len); @@ -319,9 +316,9 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, if (shell_style == STYLE_PRINT) { extra_shell_arg = (char_u *)"-G"; // Use zsh NULL_GLOB option - // If we use -f then shell variables set in .cshrc won't get expanded. - // vi can do it, so we will too, but it is only necessary if there is a "$" - // in one of the patterns, otherwise we can still use the fast option. + // If we use -f then shell variables set in .cshrc won't get expanded. + // vi can do it, so we will too, but it is only necessary if there is a "$" + // in one of the patterns, otherwise we can still use the fast option. } else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat)) { extra_shell_arg = (char_u *)"-f"; // Use csh fast option } @@ -409,7 +406,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, } p = skipwhite(p); // skip to next entry } - // file names are separated with NL + // file names are separated with NL } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) { buffer[len] = NUL; // make sure the buffer ends in NUL p = buffer; @@ -422,7 +419,7 @@ int os_expand_wildcards(int num_pat, char_u **pat, int *num_file, } p = skipwhite(p); // skip leading white space } - // file names are separated with NUL + // file names are separated with NUL } else { // Some versions of zsh use spaces instead of NULs to separate // results. Only do this when there is no NUL before the end of the @@ -705,22 +702,14 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args) /// returned buffer is not NULL) /// @return the return code of the process, -1 if the process couldn't be /// started properly -int os_system(char **argv, - const char *input, - size_t len, - char **output, +int os_system(char **argv, const char *input, size_t len, char **output, size_t *nread) FUNC_ATTR_NONNULL_ARG(1) { return do_os_system(argv, input, len, output, nread, true, false); } -static int do_os_system(char **argv, - const char *input, - size_t len, - char **output, - size_t *nread, - bool silent, - bool forward_output) +static int do_os_system(char **argv, const char *input, size_t len, char **output, size_t *nread, + bool silent, bool forward_output) { out_data_decide_throttle(0); // Initialize throttle decider. out_data_ring(NULL, 0); // Initialize output ring-buffer. @@ -851,8 +840,7 @@ static void dynamic_buffer_ensure(DynamicBuffer *buf, size_t desired) buf->data = xrealloc(buf->data, buf->cap); } -static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, - void *data, bool eof) +static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof) { DynamicBuffer *dbuf = data; @@ -1015,8 +1003,7 @@ end: ui_flush(); } -static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, - bool eof) +static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data, bool eof) { size_t cnt; char *ptr = rbuffer_read_ptr(buf, &cnt); @@ -1049,10 +1036,10 @@ static size_t tokenize(const char_u *const str, char **const argv) FUNC_ATTR_NONNULL_ARG(1) { size_t argc = 0; - const char *p = (const char *) str; + const char *p = (const char *)str; while (*p != NUL) { - const size_t len = word_length((const char_u *) p); + const size_t len = word_length((const char_u *)p); if (argv != NULL) { // Fill the slot @@ -1060,7 +1047,7 @@ static size_t tokenize(const char_u *const str, char **const argv) } argc++; - p = (const char *) skipwhite((char_u *) (p + len)); + p = (const char *)skipwhite((char_u *)(p + len)); } return argc; @@ -1115,7 +1102,7 @@ static void read_input(DynamicBuffer *buf) dynamic_buffer_ensure(buf, buf->len + len); buf->data[buf->len++] = NUL; } else { - char_u *s = vim_strchr(lp + written, NL); + char_u *s = vim_strchr(lp + written, NL); len = s == NULL ? l : (size_t)(s - (lp + written)); dynamic_buffer_ensure(buf, buf->len + len); memcpy(buf->data + buf->len, lp + written, len); diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c index bc774b8ebc..65b1845d01 100644 --- a/src/nvim/os/signal.c +++ b/src/nvim/os/signal.c @@ -3,25 +3,24 @@ #include <assert.h> #include <stdbool.h> - #include <uv.h> #ifndef WIN32 # include <signal.h> // for sigset_t #endif #include "nvim/ascii.h" -#include "nvim/log.h" -#include "nvim/vim.h" -#include "nvim/globals.h" -#include "nvim/memline.h" #include "nvim/eval.h" +#include "nvim/event/loop.h" +#include "nvim/event/signal.h" #include "nvim/fileio.h" +#include "nvim/globals.h" +#include "nvim/log.h" #include "nvim/main.h" +#include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/misc1.h" -#include "nvim/event/signal.h" #include "nvim/os/signal.h" -#include "nvim/event/loop.h" +#include "nvim/vim.h" static SignalWatcher spipe, shup, squit, sterm, susr1; #ifdef SIGPWR @@ -124,27 +123,27 @@ static char * signal_name(int signum) { switch (signum) { #ifdef SIGPWR - case SIGPWR: - return "SIGPWR"; + case SIGPWR: + return "SIGPWR"; #endif #ifdef SIGPIPE - case SIGPIPE: - return "SIGPIPE"; + case SIGPIPE: + return "SIGPIPE"; #endif - case SIGTERM: - return "SIGTERM"; + case SIGTERM: + return "SIGTERM"; #ifdef SIGQUIT - case SIGQUIT: - return "SIGQUIT"; + case SIGQUIT: + return "SIGQUIT"; #endif - case SIGHUP: - return "SIGHUP"; + case SIGHUP: + return "SIGHUP"; #ifdef SIGUSR1 - case SIGUSR1: - return "SIGUSR1"; + case SIGUSR1: + return "SIGUSR1"; #endif - default: - return "Unknown"; + default: + return "Unknown"; } } @@ -173,34 +172,34 @@ static void on_signal(SignalWatcher *handle, int signum, void *data) assert(signum >= 0); switch (signum) { #ifdef SIGPWR - case SIGPWR: - // Signal of a power failure(eg batteries low), flush the swap files to - // be safe - ml_sync_all(false, false, true); - break; + case SIGPWR: + // Signal of a power failure(eg batteries low), flush the swap files to + // be safe + ml_sync_all(false, false, true); + break; #endif #ifdef SIGPIPE - case SIGPIPE: - // Ignore - break; + case SIGPIPE: + // Ignore + break; #endif - case SIGTERM: + case SIGTERM: #ifdef SIGQUIT - case SIGQUIT: + case SIGQUIT: #endif - case SIGHUP: - if (!rejecting_deadly) { - deadly_signal(signum); - } - break; + case SIGHUP: + if (!rejecting_deadly) { + deadly_signal(signum); + } + break; #ifdef SIGUSR1 - case SIGUSR1: - apply_autocmds(EVENT_SIGNAL, (char_u *)"SIGUSR1", curbuf->b_fname, true, - curbuf); - break; -#endif - default: - ELOG("invalid signal: %d", signum); - break; + case SIGUSR1: + apply_autocmds(EVENT_SIGNAL, (char_u *)"SIGUSR1", curbuf->b_fname, true, + curbuf); + break; +#endif + default: + ELOG("invalid signal: %d", signum); + break; } } diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c index 93b8d5ca12..10b0d391bf 100644 --- a/src/nvim/os/stdpaths.c +++ b/src/nvim/os/stdpaths.c @@ -3,11 +3,11 @@ #include <stdbool.h> -#include "nvim/os/stdpaths_defs.h" +#include "nvim/ascii.h" +#include "nvim/memory.h" #include "nvim/os/os.h" +#include "nvim/os/stdpaths_defs.h" #include "nvim/path.h" -#include "nvim/memory.h" -#include "nvim/ascii.h" /// Names of the environment variables, mapped to XDGVarType values static const char *xdg_env_vars[] = { @@ -137,8 +137,7 @@ char *stdpaths_user_conf_subpath(const char *fname) /// @param[in] escape_commas If true, all commas will be escaped. /// /// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`. -char *stdpaths_user_data_subpath(const char *fname, - const size_t trailing_pathseps, +char *stdpaths_user_data_subpath(const char *fname, const size_t trailing_pathseps, const bool escape_commas) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 9ea74716aa..d9f4fe9e37 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -3,15 +3,14 @@ #include <assert.h> #include <limits.h> - #include <uv.h> #include "nvim/assert.h" -#include "nvim/os/time.h" -#include "nvim/os/input.h" #include "nvim/event/loop.h" -#include "nvim/os/os.h" #include "nvim/main.h" +#include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" static uv_mutex_t delay_mutex; static uv_cond_t delay_cond; @@ -169,8 +168,7 @@ struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL /// @param result[out] Pointer to a 'char' where the result should be placed /// @param result_len length of result buffer /// @return human-readable string of current local time -char *os_ctime_r(const time_t *restrict clock, char *restrict result, - size_t result_len) +char *os_ctime_r(const time_t *restrict clock, char *restrict result, size_t result_len) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET { struct tm clock_local; @@ -219,5 +217,5 @@ char *os_strptime(const char *str, const char *format, struct tm *tm) Timestamp os_time(void) FUNC_ATTR_WARN_UNUSED_RESULT { - return (Timestamp) time(NULL); + return (Timestamp)time(NULL); } diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c index 16e17a9c60..2687c66f24 100644 --- a/src/nvim/os/users.c +++ b/src/nvim/os/users.c @@ -6,11 +6,10 @@ #include <uv.h> #include "auto/config.h" - #include "nvim/ascii.h" -#include "nvim/os/os.h" #include "nvim/garray.h" #include "nvim/memory.h" +#include "nvim/os/os.h" #include "nvim/strings.h" #ifdef HAVE_PWD_H # include <pwd.h> diff --git a/src/nvim/plines.c b/src/nvim/plines.c index 6718b7f7a4..a656686a95 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -263,7 +263,8 @@ unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len) /// @return The number of characters taken up on the screen. int lbr_chartabsize(char_u *line, unsigned char *s, colnr_T col) { - if (!curwin->w_p_lbr && (*p_sbr == NUL) && !curwin->w_p_bri) { + if (!curwin->w_p_lbr && *get_showbreak_value(curwin) == NUL + && !curwin->w_p_bri) { if (curwin->w_p_wrap) { return win_nolbr_chartabsize(curwin, s, col, NULL); } @@ -314,7 +315,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, int n; // No 'linebreak', 'showbreak' and 'breakindent': return quickly. - if (!wp->w_p_lbr && !wp->w_p_bri && (*p_sbr == NUL)) { + if (!wp->w_p_lbr && !wp->w_p_bri && *get_showbreak_value(wp) == NUL) { if (wp->w_p_wrap) { return win_nolbr_chartabsize(wp, s, col, headp); } @@ -381,7 +382,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, // Set *headp to the size of what we add. added = 0; - if ((*p_sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && (col != 0)) { + char_u *const sbr = get_showbreak_value(wp); + if ((*sbr != NUL || wp->w_p_bri) && wp->w_p_wrap && col != 0) { colnr_T sbrlen = 0; int numberwidth = win_col_off(wp); @@ -394,8 +396,8 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, if (col >= numberextra && numberextra > 0) { col %= numberextra; } - if (*p_sbr != NUL) { - sbrlen = (colnr_T)MB_CHARLEN(p_sbr); + if (*sbr != NUL) { + sbrlen = (colnr_T)MB_CHARLEN(sbr); if (col >= sbrlen) { col -= sbrlen; } @@ -410,7 +412,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, } if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width_inner)) { - if (*p_sbr != NUL) { + if (*sbr != NUL) { if (size + sbrlen + numberwidth > (colnr_T)wp->w_width_inner) { // Calculate effective window width. int width = (colnr_T)wp->w_width_inner - sbrlen - numberwidth; @@ -420,13 +422,13 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, if (width <= 0) { width = 1; } - added += ((size - prev_width) / width) * vim_strsize(p_sbr); + added += ((size - prev_width) / width) * vim_strsize(sbr); if ((size - prev_width) % width) { // Wrapped, add another length of 'sbr'. - added += vim_strsize(p_sbr); + added += vim_strsize(sbr); } } else { - added += vim_strsize(p_sbr); + added += vim_strsize(sbr); } } diff --git a/src/nvim/po/tr.po b/src/nvim/po/tr.po index 3db3cbfef0..e1fef00863 100644 --- a/src/nvim/po/tr.po +++ b/src/nvim/po/tr.po @@ -1,16 +1,16 @@ # Turkish translations for Vim # Vim Türkçe çevirileri -# Copyright (C) 2020 Emir SARI <bitigchi@me.com> +# Copyright (C) 2021 Emir SARI <emir_sari@msn.com> # This file is distributed under the same license as the Vim package. -# Emir SARI <bitigchi@me.com>, 2019-2020 +# Emir SARI <emir_sari@msn.com>, 2019-2021 # msgid "" msgstr "" "Project-Id-Version: Vim Turkish Localization Project\n" -"Report-Msgid-Bugs-To: Emir SARI <bitigchi@me.com>\n" -"POT-Creation-Date: 2020-11-29 00:20+0300\n" -"PO-Revision-Date: 2020-11-29 20:00+0300\n" -"Last-Translator: Emir SARI <bitigchi@me.com>\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-07-16 17:56+0300\n" +"PO-Revision-Date: 2021-07-16 20:00+0300\n" +"Last-Translator: Emir SARI <emir_sari@msn.com>\n" "Language-Team: Turkish <https://github.com/bitigchi/vim>\n" "Language: tr\n" "MIME-Version: 1.0\n" @@ -28,7 +28,7 @@ msgid "E165: Cannot go beyond last file" msgstr "E165: Son dosyadan öteye gidilemez" msgid "E610: No argument to delete" -msgstr "E610: Silinecek bir değişken yok" +msgstr "E610: Silinecek bir argüman yok" msgid "E249: window layout changed unexpectedly" msgstr "E249: Pencere yerleşimi beklenmedik bir biçimde değişti" @@ -94,6 +94,9 @@ msgstr "%s çalıştırılıyor" msgid "autocommand %s" msgstr "%s otokomutu" +msgid "E972: Blob value does not have the right number of bytes" +msgstr "E972: İkili geniş nesne değeri doğru bayt sayısına sahip değil" + msgid "E831: bf_key_init() called with empty password" msgstr "E831: bf_key_init() boş bir şifre ile çağrıldı" @@ -131,6 +134,27 @@ msgstr "E931: Arabellek kaydedilemedi" msgid "E937: Attempt to delete a buffer that is in use: %s" msgstr "E937: Kullanımda olan bir arabellek silinmeye çalışılıyor: %s" +msgid "E90: Cannot unload last buffer" +msgstr "E90: Son arabellek bellekten kaldırılamıyor" + +msgid "E84: No modified buffer found" +msgstr "E84: Değiştirilmiş bir arabellek bulunamadı" + +msgid "E85: There is no listed buffer" +msgstr "E85: Listelenmiş bir arabellek yok" + +msgid "E87: Cannot go beyond last buffer" +msgstr "E87: Son arabellekten öteye gidilemez" + +msgid "E88: Cannot go before first buffer" +msgstr "E88: İlk arabellekten öncesine gidilemez" + +#, c-format +msgid "E89: No write since last change for buffer %d (add ! to override)" +msgstr "" +"E89: %d numaralı arabellek son değişiklikten sonra yazılmadı (geçersiz " +"kılmak için ! ekleyin)" + msgid "E515: No buffers were unloaded" msgstr "E515: Hiçbir arabellek bellekten kaldırılmadı" @@ -158,27 +182,6 @@ msgid_plural "%d buffers wiped out" msgstr[0] "%d arabellek yok edildi" msgstr[1] "%d arabellek yok edildi" -msgid "E90: Cannot unload last buffer" -msgstr "E90: Son arabellek bellekten kaldırılamıyor" - -msgid "E84: No modified buffer found" -msgstr "E84: Değiştirilmiş bir arabellek bulunamadı" - -msgid "E85: There is no listed buffer" -msgstr "E85: Listelenmiş bir arabellek yok" - -msgid "E87: Cannot go beyond last buffer" -msgstr "E87: Son arabellekten öteye gidilemez" - -msgid "E88: Cannot go before first buffer" -msgstr "E88: İlk arabellekten öncesine gidilemez" - -#, c-format -msgid "E89: No write since last change for buffer %d (add ! to override)" -msgstr "" -"E89: %d numaralı arabellek son değişiklikten sonra yazılmadı (geçersiz " -"kılmak için ! ekleyin)" - msgid "E948: Job still running (add ! to end the job)" msgstr "E948: İş hâlâ sürüyor (bitirmek için ! ekleyin)" @@ -424,13 +427,13 @@ msgid "E901: gethostbyname() in channel_open()" msgstr "E901: channel_open() içinde gethostbyname()" msgid "E903: received command with non-string argument" -msgstr "E903: Dizi olmayan değişken içeren komut alındı" +msgstr "E903: Dizi olmayan argüman içeren komut alındı" msgid "E904: last argument for expr/call must be a number" -msgstr "E904: İfadenin/çağrının son değişkeni bir sayı olmalıdır" +msgstr "E904: İfadenin/çağrının son argüman bir sayı olmalıdır" msgid "E904: third argument for call must be a list" -msgstr "E904: Çağrının üçüncü değişkeni bir liste olmalıdır" +msgstr "E904: Çağrının üçüncü argümanı bir liste olmalıdır" #, c-format msgid "E905: received unknown command: %s" @@ -449,7 +452,7 @@ msgstr "E631: %s(): Yazma başarısız" #, c-format msgid "E917: Cannot use a callback with %s()" -msgstr "E917: %s() ile geri çağırma kullanılamaz" +msgstr "E917: %s() ile geri çağırma kullanılamıyor" msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel" msgstr "E912: ch_evalexpr()/ch_sendexpr() raw/nl kanalları ile kullanılamaz" @@ -511,6 +514,11 @@ msgid "Warning: Using a weak encryption method; see :help 'cm'" msgstr "" "Uyarı: Zayıf bir şifreleme yöntemi kullanılıyor; bilgi için: :help 'cm'" +msgid "" +"Note: Encryption of swapfile not supported, disabling swap- and undofile" +msgstr "Takas dosyası şifrelemesi desteklenmiyor, takas ve geri al dosyası " +"devre dışı bırakılıyor" + msgid "Enter encryption key: " msgstr "Şifreleme anahtarı girin: " @@ -570,7 +578,7 @@ msgid "%3d expr %s" msgstr "%3d ifade %s" msgid "extend() argument" -msgstr "extend() değişkeni" +msgstr "extend() argümanı" #, c-format msgid "E737: Key already exists: %s" @@ -728,9 +736,6 @@ msgstr "E708: [:] en son gelmelidir" msgid "E709: [:] requires a List or Blob value" msgstr "E709: [:] bir liste veya ikili geniş nesne değeri gerektirir" -msgid "E972: Blob value does not have the right number of bytes" -msgstr "E972: İkili geniş nesne değeri doğru bayt sayısına sahip değil" - msgid "E996: Cannot lock a range" msgstr "E996: Erim kilitlenemiyor" @@ -741,7 +746,7 @@ msgid "E260: Missing name after ->" msgstr "E260: -> sonrası ad eksik" msgid "E695: Cannot index a Funcref" -msgstr "E695: Bir Funcref dizinlenemez" +msgstr "E695: Bir Funcref dizinlenemiyor" msgid "Not enough memory to set references, garbage collection aborted!" msgstr "Referansları ayarlamak için yetersiz bellek, atık toplama durduruldu" @@ -759,9 +764,6 @@ msgstr "" "\n" "\tEn son şuradan ayarlandı: " -msgid "E808: Number or Float required" -msgstr "E808: Sayı veya kayan noktalı değer gerekiyor" - #, c-format msgid "E158: Invalid buffer name: %s" msgstr "E158: Geçersiz arabellek adı: %s" @@ -780,7 +782,7 @@ msgid "E922: expected a dict" msgstr "E922: Bir sözlük bekleniyordu" msgid "E923: Second argument of function() must be a list or a dict" -msgstr "E923: function() ikinci değişkeni bir liste veya sözlük olmalıdır" +msgstr "E923: function() ikinci argümanı bir liste veya sözlük olmalıdır" msgid "" "&OK\n" @@ -882,7 +884,7 @@ msgid "E742: Cannot change value of %s" msgstr "E742: %s değeri değiştirilemiyor" msgid "E921: Invalid callback argument" -msgstr "E921: Geçersiz geri çağırma değişkeni" +msgstr "E921: Geçersiz geri çağırma argümanı" #, c-format msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s" @@ -927,6 +929,10 @@ msgstr "E135: *Süzgeç* otokomutları şu anki arabelleği değiştirmemelidir" msgid "[No write since last change]\n" msgstr "[Son değişiklikten sonra yazılmadı]\n" +#, c-format +msgid "E503: \"%s\" is not a file or writable device" +msgstr "E503: \"%s\", bir dosya veya yazılabilir aygıt değil" + msgid "Save As" msgstr "Farklı Kaydet" @@ -985,7 +991,7 @@ msgid "E143: Autocommands unexpectedly deleted new buffer %s" msgstr "E143: yeni %s arabelleğini otokomutlar beklenmedik bir biçimde sildi" msgid "E144: non-numeric argument to :z" -msgstr "E144: :z için sayısal olmayan değişken" +msgstr "E144: :z için sayısal olmayan argüman" msgid "E145: Shell commands and some functionality not allowed in rvim" msgstr "E145: rvim içinde kabuk komutları ve bazı işlevselliğe izin verilmez" @@ -1091,9 +1097,6 @@ msgstr "Kaynak alınan dosyanın sonu" msgid "End of function" msgstr "İşlevin sonu" -msgid "E464: Ambiguous use of user-defined command" -msgstr "E464: Kullanıcı tanımlı komutun belirsiz kullanımı" - msgid "E492: Not an editor command" msgstr "E492: Bir düzenleyici komutu değil" @@ -1178,7 +1181,7 @@ msgid "E187: Unknown" msgstr "E187: Bilinmeyen" msgid "E465: :winsize requires two number arguments" -msgstr "E465: :winsize iki adet sayı değişken gerektirir" +msgstr "E465: :winsize iki adet sayı argüman gerektirir" #, c-format msgid "Window position: X %d, Y %d" @@ -1188,7 +1191,7 @@ msgid "E188: Obtaining window position not implemented for this platform" msgstr "E188: Pencere konumunu alma özelliği bu platformda mevcut değil" msgid "E466: :winpos requires two number arguments" -msgstr "E466: :winpos iki adet sayı değişken gerektirir" +msgstr "E466: :winpos iki adet sayı argüman gerektirir" msgid "E930: Cannot use :redir inside execute()" msgstr "E930: :redir, execute() içinde kullanılamaz" @@ -1340,6 +1343,9 @@ msgstr "E788: Şu anda başka bir arabellek düzenlenemez" msgid "E811: Not allowed to change buffer information now" msgstr "E811: Şu anda arabellek bilgisi değiştirilemez" +msgid "[Command Line]" +msgstr "[Komut Satırı]" + msgid "E199: Active window or buffer deleted" msgstr "E199: Etkin pencere veya arabellek silinmiş" @@ -1530,7 +1536,7 @@ msgid "E655: Too many symbolic links (cycle?)" msgstr "E655: Çok fazla sembolik bağlantı (çevrim?)" msgid "writefile() first argument must be a List or a Blob" -msgstr "writefile() ilk değişkeni bir liste veya ikili geniş nesne olmalıdır" +msgstr "writefile() ilk argümanı bir liste veya ikili geniş nesne olmalıdır" msgid "Select Directory dialog" msgstr "Dizin Seç iletişim kutusu" @@ -1581,6 +1587,9 @@ msgstr "E446: İmleç altında bir dosya adı yok" msgid "E447: Can't find file \"%s\" in path" msgstr "E447: \"%s\" dosyası yol içinde bulunamadı" +msgid "E808: Number or Float required" +msgstr "E808: Sayı veya kayan noktalı değer gerekiyor" + msgid "E490: No fold found" msgstr "E490: Kıvırma bulunamadı" @@ -1805,7 +1814,7 @@ msgstr "E671: Pencere başlığı \"%s\" bulunamıyor" #, c-format msgid "E243: Argument not supported: \"-%s\"; Use the OLE version." -msgstr "E243: \"-%s\" değişkeni desteklenmiyor; OLE sürümünü kullanın." +msgstr "E243: \"-%s\" argümanı desteklenmiyor; OLE sürümünü kullanın." msgid "E988: GUI cannot be used. Cannot execute gvim.exe." msgstr "E988: Grafik arabirim kullanılamaz. gvim.exe çalıştırılamadı." @@ -2042,11 +2051,11 @@ msgstr "E411: Vurgulama grubu bulunamadı: %s" #, c-format msgid "E412: Not enough arguments: \":highlight link %s\"" -msgstr "E412: Yetersiz sayıda değişken: \":highlight link %s\"" +msgstr "E412: Yetersiz sayıda argüman: \":highlight link %s\"" #, c-format msgid "E413: Too many arguments: \":highlight link %s\"" -msgstr "E413: Çok fazla değişken: \":highlight link %s\"" +msgstr "E413: Çok fazla argüman: \":highlight link %s\"" msgid "E414: group has settings, highlight link ignored" msgstr "E414: Grup ayarları mevcut, vurgulama bağlantısı yok sayıldı" @@ -2061,7 +2070,7 @@ msgstr "E416: Eksik eşittir imi: %s" #, c-format msgid "E417: missing argument: %s" -msgstr "E417: Eksik değişkenler: %s" +msgstr "E417: Argüman eksik: %s" #, c-format msgid "E418: Illegal value: %s" @@ -2086,7 +2095,7 @@ msgstr "E422: Uçbirim kodu çok uzun: %s" #, c-format msgid "E423: Illegal argument: %s" -msgstr "E423: İzin verilmeyen değişken: %s" +msgstr "E423: İzin verilmeyen argüman: %s" msgid "E424: Too many different highlighting attributes in use" msgstr "E424: Çok fazla değişik vurgulama kuralları kullanılıyor" @@ -2295,7 +2304,7 @@ msgid "unknown option" msgstr "bilinmeyen seçenek" msgid "window index is out of range" -msgstr "pencere dizini erimin dışında" +msgstr "pencere sırası erimin dışında" msgid "couldn't open buffer" msgstr "arabellek açılamadı" @@ -2513,9 +2522,6 @@ msgstr " Dahili anahtar sözcük tamamlaması (^N^P)" msgid "Hit end of paragraph" msgstr "Paragrafın sonuna varıldı" -msgid "E839: Completion function changed window" -msgstr "E839: Tamamlama işlevi pencereyi değiştirdi" - msgid "E840: Completion function deleted text" msgstr "E840: Tamamlama işlevi metni sildi" @@ -2594,23 +2600,23 @@ msgstr "E938: JSON'da yinelenmiş anahtar: \"%s\"" #, c-format msgid "E899: Argument of %s must be a List or Blob" -msgstr "E899: %s değişkeni bir liste veya ikili geniş nesne olmalıdır" +msgstr "E899: %s argümanı bir liste veya ikili geniş nesne olmalıdır" msgid "E900: maxdepth must be non-negative number" msgstr "E900: maxdepth negatif olmayan bir sayı olmalı" msgid "flatten() argument" -msgstr "flatten() değişkeni" +msgstr "flatten() argümanı" #, c-format msgid "E696: Missing comma in List: %s" msgstr "E696: Listede virgül eksik: %s" msgid "sort() argument" -msgstr "sort() değişkeni" +msgstr "sort() argümanı" msgid "uniq() argument" -msgstr "uniq() değişkeni" +msgstr "uniq() argümanı" msgid "E702: Sort compare function failed" msgstr "E702: Sıralayıp karşılaştırma işlevi başarısız oldu" @@ -2619,25 +2625,28 @@ msgid "E882: Uniq compare function failed" msgstr "E882: Benzersizlik karşılaştırma işlevi başarısız oldu" msgid "map() argument" -msgstr "map() değişkeni" +msgstr "map() argümanı" msgid "mapnew() argument" -msgstr "mapnew() değişkeni" +msgstr "mapnew() argümanı" msgid "filter() argument" -msgstr "filter() değişkeni" +msgstr "filter() argümanı" msgid "add() argument" -msgstr "add() değişkeni" +msgstr "add() argümanı" + +msgid "extendnew() argument" +msgstr "extendnew() argümanı" msgid "insert() argument" -msgstr "insert() değişkeni" +msgstr "insert() argümanı" msgid "remove() argument" -msgstr "remove() değişkeni" +msgstr "remove() argümanı" msgid "reverse() argument" -msgstr "reverse() değişkeni" +msgstr "reverse() argümanı" #, c-format msgid "Current %slanguage: \"%s\"" @@ -2648,22 +2657,22 @@ msgid "E197: Cannot set language to \"%s\"" msgstr "E197: \"%s\" diline ayarlanamıyor" msgid "Unknown option argument" -msgstr "Bilinmeyen seçenek değişkeni" +msgstr "Bilinmeyen seçenek argümanı" msgid "Too many edit arguments" -msgstr "Çok fazla düzenleme değişkeni" +msgstr "Çok fazla düzenleme argümanı" msgid "Argument missing after" -msgstr "Şundan sonra değişken eksik:" +msgstr "Şundan sonra argüman eksik:" msgid "Garbage after option argument" -msgstr "Seçenek değişkeninden sonra anlamsız veri" +msgstr "Seçenek argümanından sonra anlamsız veri" msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments" -msgstr "Çok fazla \"+komut\", \"-c komut\" veya \"--cmd komut\" değişkeni" +msgstr "Çok fazla \"+komut\", \"-c komut\" veya \"--cmd komut\" argümanı" msgid "Invalid argument for" -msgstr "Şunun için geçersiz değişken:" +msgstr "Şunun için geçersiz argüman:" #, c-format msgid "%d files to edit\n" @@ -2735,7 +2744,7 @@ msgstr "" "Kullanım:" msgid " vim [arguments] " -msgstr " vim [değişkenler] " +msgstr " vim [argümanlar] " msgid "" "\n" @@ -2967,21 +2976,21 @@ msgid "" "Arguments recognised by gvim (Motif version):\n" msgstr "" "\n" -"gvim tarafından tanınan değişkenler (Motif sürümü):\n" +"gvim tarafından tanınan argümanlar (Motif sürümü):\n" msgid "" "\n" "Arguments recognised by gvim (neXtaw version):\n" msgstr "" "\n" -"gvim tarafından tanınan değişkenler (neXtaw sürümü):\n" +"gvim tarafından tanınan argümanlar (neXtaw sürümü):\n" msgid "" "\n" "Arguments recognised by gvim (Athena version):\n" msgstr "" "\n" -"gvim tarafından tanınan değişkenler (Athena sürümü):\n" +"gvim tarafından tanınan argümanlar (Athena sürümü):\n" msgid "-display <display>\tRun Vim on <display>" msgstr "-display <ekran>\tVim'i <ekran>'da çalıştır" @@ -3032,7 +3041,7 @@ msgid "" "Arguments recognised by gvim (GTK+ version):\n" msgstr "" "\n" -"gvim tarafından tanınan değişkenler (GTK+ sürümü):\n" +"gvim tarafından tanınan argümanlar (GTK+ sürümü):\n" msgid "-display <display>\tRun Vim on <display> (also: --display)" msgstr "-display <ekran>\tVim'i <ekran>'da çalıştır (veya: --display)" @@ -3078,7 +3087,7 @@ msgid "E228: makemap: Illegal mode" msgstr "E228: makemap: İzin verilmeyen kip" msgid "E460: entries missing in mapset() dict argument" -msgstr "E460: mapset() sözlük değişkeninde eksik girdiler" +msgstr "E460: mapset() sözlük argümanında eksik girdiler" #, c-format msgid "E357: 'langmap': Matching character missing for %s" @@ -3716,13 +3725,13 @@ msgstr "" "İ&ptal" msgid "E766: Insufficient arguments for printf()" -msgstr "E766: printf() için yetersiz değişkenler" +msgstr "E766: printf() için yetersiz argüman" msgid "E807: Expected Float argument for printf()" -msgstr "E807: printf() için kayan noktalı değer türünde değişken bekleniyordu" +msgstr "E807: printf() için kayan noktalı değer türünde argüman bekleniyordu" msgid "E767: Too many arguments to printf()" -msgstr "E767: printf() için çok fazla değişken" +msgstr "E767: printf() için çok fazla argüman" msgid "Type number and <Enter> or click with the mouse (q or empty cancels): " msgstr "" @@ -4014,12 +4023,12 @@ msgstr "E531: Grafik arabirimi başlatmak için \":gui\" yazın" msgid "E589: 'backupext' and 'patchmode' are equal" msgstr "E589: 'backupext' ve 'patchmode' birbirine eşit" -msgid "E834: Conflicts with value of 'listchars'" -msgstr "E834: 'listchars' değeriyle çakışmalar var" - msgid "E835: Conflicts with value of 'fillchars'" msgstr "E835: 'fillchars' değeriyle çakışmalar var" +msgid "E834: Conflicts with value of 'listchars'" +msgstr "E834: 'listchars' değeriyle çakışmalar var" + msgid "E617: Cannot be changed in the GTK+ 2 GUI" msgstr "E617: GTK+ 2 grafik arabiriminde değiştirilemez" @@ -4392,7 +4401,7 @@ msgid "Cannot open file \"%s\"" msgstr "\"%s\" dosyası açılamıyor" msgid "cannot have both a list and a \"what\" argument" -msgstr "ya birinci ya da son değişken belirtilmelidir" +msgstr "ya birinci ya da son argüman belirtilmelidir" msgid "E681: Buffer is not loaded" msgstr "E681: Arabellek yüklenemedi" @@ -4725,10 +4734,10 @@ msgid "modeline" msgstr "kip satırı" msgid "--cmd argument" -msgstr "--cmd değişkeni" +msgstr "--cmd argümanı" msgid "-c argument" -msgstr "-c değişkeni" +msgstr "-c argümanı" msgid "environment variable" msgstr "ortam değişkeni" @@ -4736,6 +4745,9 @@ msgstr "ortam değişkeni" msgid "error handler" msgstr "hata işleyicisi" +msgid "changed window size" +msgstr "değiştirilen pencere boyutu" + msgid "W15: Warning: Wrong line separator, ^M may be missing" msgstr "W15: Uyarı: Yanlış satır ayırıcısı, ^M eksik olabilir" @@ -5215,6 +5227,9 @@ msgstr "E765: 'spellfile' içinde %d adet girdi yok" msgid "Word '%.*s' removed from %s" msgstr "'%.*s' sözcüğü %s içinden çıkartıldı" +msgid "Seek error in spellfile" +msgstr "Yazım dosyasında arama hatası" + #, c-format msgid "Word '%.*s' added to %s" msgstr "'%.*s' sözcüğü %s dosyasına eklendi" @@ -5242,7 +5257,7 @@ msgstr " < \"%.*s\"" #, c-format msgid "E390: Illegal argument: %s" -msgstr "E390: İzin verilmeyen değişken: %s" +msgstr "E390: İzin verilmeyen argüman: %s" msgid "No Syntax items defined for this buffer" msgstr "Bu arabellek için sözdizim ögeleri tanımlanmamış" @@ -5343,7 +5358,7 @@ msgid " line breaks" msgstr " satır sonu" msgid "E395: contains argument not accepted here" -msgstr "E395: Burada kabul edilmeyen bir değişken içeriyor" +msgstr "E395: Burada kabul edilmeyen bir argüman içeriyor" msgid "E844: invalid cchar value" msgstr "E844: Geçersiz cchar değeri" @@ -5375,7 +5390,7 @@ msgstr "E398: '=' eksik: %s" #, c-format msgid "E399: Not enough arguments: syntax region %s" -msgstr "E399: Yetersiz değişken: %s sözdizim bölgesi" +msgstr "E399: Yetersiz sayıda argüman: %s sözdizim bölgesi" msgid "E848: Too many syntax clusters" msgstr "E848: Çok fazla sözdizim kümesi" @@ -5396,7 +5411,7 @@ msgstr "E403: Sözdizim eşitlemesi: Satır devamları dizgisi iki kez tanımlan #, c-format msgid "E404: Illegal arguments: %s" -msgstr "E404: İzin verilmeyen değişkenler: %s" +msgstr "E404: İzin verilmeyen argümanlar: %s" #, c-format msgid "E405: Missing equal sign: %s" @@ -5404,7 +5419,7 @@ msgstr "E405: Eşittir imi eksik: %s" #, c-format msgid "E406: Empty argument: %s" -msgstr "E406: Boş değişken: %s" +msgstr "E406: Boş argüman: %s" #, c-format msgid "E407: %s not allowed here" @@ -5539,7 +5554,7 @@ msgid "E436: No \"%s\" entry in termcap" msgstr "E436: termcap içinde \"%s\" girdisi yok" msgid "E437: terminal capability \"cm\" required" -msgstr "E437: \"cm\" uçbirim kabiliyeti gerekiyor" +msgstr "E437: \"cm\" uçbirim yeteneği gerekiyor" msgid "" "\n" @@ -5688,16 +5703,16 @@ msgstr "E914: Bir Kanal, Kayan Noktalı Değer yerine kullanılıyor" msgid "E975: Using a Blob as a Float" msgstr "E975: Bir İkili Geniş Nesne, Kayan Noktalı Değer yerine kullanılıyor" -msgid "E729: using Funcref as a String" +msgid "E729: Using a Funcref as a String" msgstr "E729: Funcref bir Dizi yerine kullanılıyor" -msgid "E730: using List as a String" +msgid "E730: Using a List as a String" msgstr "E730: Liste bir Dizi yerine kullanılıyor" -msgid "E731: using Dictionary as a String" +msgid "E731: Using a Dictionary as a String" msgstr "E731: Sözlük bir Dizi yerine kullanılıyor" -msgid "E976: using Blob as a String" +msgid "E976: Using a Blob as a String" msgstr "E976: İkili Geniş Nesne bir Dizi yerine kullanılıyor" msgid "E977: Can only compare Blob with Blob" @@ -5892,16 +5907,16 @@ msgid "E180: Invalid complete value: %s" msgstr "E180: Geçersiz tam değer: %s" msgid "E468: Completion argument only allowed for custom completion" -msgstr "E468: Tamamlama değişkenine yalnızca özel tamamlamalarda izin verilir" +msgstr "E468: Tamamlama argümanına yalnızca özel tamamlamalarda izin verilir" msgid "E467: Custom completion requires a function argument" -msgstr "E467: Özel tamamlama bir işlev değişkeni gerektirir" +msgstr "E467: Özel tamamlama bir işlev argümanı gerektirir" msgid "E175: No attribute specified" msgstr "E175: Bir öznitelik belirtilmemiş" msgid "E176: Invalid number of arguments" -msgstr "E176: Geçersiz değişken sayısı" +msgstr "E176: Geçersiz argüman sayısı" msgid "E177: Count cannot be specified twice" msgstr "E177: Sayım iki defa belirtilemez" @@ -5910,10 +5925,10 @@ msgid "E178: Invalid default value for count" msgstr "E178: Sayım için geçersiz öntanımlı değer" msgid "E179: argument required for -complete" -msgstr "E179: -complete için değişken gerekiyor" +msgstr "E179: -complete için argüman gerekiyor" msgid "E179: argument required for -addr" -msgstr "E179: -addr için değişken gerekiyor" +msgstr "E179: -addr için argüman gerekiyor" #, c-format msgid "E174: Command already exists: add ! to replace it: %s" @@ -5948,14 +5963,21 @@ msgstr "E130: Bilinmeyen işlev: %s" #, c-format msgid "E125: Illegal argument: %s" -msgstr "E125: İzin verilmeyen değişken: %s" +msgstr "E125: İzin verilmeyen argüman: %s" #, c-format msgid "E853: Duplicate argument name: %s" -msgstr "E853: Yinelenen değişken adı: %s" +msgstr "E853: Yinelenen argüman adı: %s" msgid "E989: Non-default argument follows default argument" -msgstr "E989: Öntanımlı olmayan değişken öntanımlı değişkenden sonra" +msgstr "E989: Öntanımlı olmayan argüman öntanımlı argümandan sonra" + +msgid "E126: Missing :endfunction" +msgstr "E126: :endfunction eksik" + +#, c-format +msgid "W22: Text found after :endfunction: %s" +msgstr "W22: :endfunction sonrası metin bulundu: %s" #, c-format msgid "E451: Expected }: %s" @@ -5963,11 +5985,11 @@ msgstr "E451: } bekleniyordu: %s" #, c-format msgid "E740: Too many arguments for function %s" -msgstr "E740: %s işlevi için çok fazla değişken" +msgstr "E740: %s işlevi için çok fazla argüman" #, c-format msgid "E116: Invalid arguments for function %s" -msgstr "E116: %s işlevi için geçersiz değişkenler" +msgstr "E116: %s işlevi için geçersiz argümanlar" msgid "E132: Function call depth is higher than 'maxfuncdepth'" msgstr "E132: İşlevin çağırdığı derinlik 'maxfuncdepth'ten daha yüksek" @@ -5989,7 +6011,7 @@ msgid "%s returning %s" msgstr "%s, %s döndürüyor" msgid "E699: Too many arguments" -msgstr "E699: Çok fazla değişken" +msgstr "E699: Çok fazla argüman" #, c-format msgid "E276: Cannot use function as a method: %s" @@ -6032,17 +6054,6 @@ msgstr "E862: g: burada kullanılamaz" msgid "E932: Closure function should not be at top level: %s" msgstr "E932: Kapatma işlevi en üst düzeyde olmamalıdır: %s" -msgid "E126: Missing :endfunction" -msgstr "E126: :endfunction eksik" - -#, c-format -msgid "W1001: Text found after :enddef: %s" -msgstr "W1001: :enddef sonrası metin bulundu: %s" - -#, c-format -msgid "W22: Text found after :endfunction: %s" -msgstr "W22: :endfunction sonrası metin bulundu: %s" - #, c-format msgid "E707: Function name conflicts with variable: %s" msgstr "E707: İşlev adı şu değişken ile çakışıyor: %s" @@ -6605,6 +6616,55 @@ msgstr "gvimext.dll hatası" msgid "Path length too long!" msgstr "Yol çok uzun!" +msgid "E10: \\ should be followed by /, ? or &" +msgstr "E10: \\ sonrasında /, ? veya & gelmeli" + +msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits" +msgstr "E11: Komut satırı penceresinde geçersiz; <CR> çalıştırır, CTRL-C çıkar" + +msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" +msgstr "" +"E12: Geçerli dizin veya etiket aramasında exrc veya vimrc'den komutlara izin " +"verilmiyor" + +msgid "E13: File exists (add ! to override)" +msgstr "E13: Dosya mevcut (geçersiz kılmak için ! ekleyin)" + +#, c-format +msgid "E15: Invalid expression: \"%s\"" +msgstr "E15: Geçersiz ifade: \"%s\"" + +msgid "E16: Invalid range" +msgstr "E16: Geçersiz erim" + +#, c-format +msgid "E17: \"%s\" is a directory" +msgstr "E17: \"%s\" bir dizin" + +msgid "E18: Unexpected characters in :let" +msgstr "E18: :let içinde beklenmeyen karakter" + +msgid "E18: Unexpected characters in assignment" +msgstr "E18: Atama içerisinde beklenmedik karakterler" + +msgid "E19: Mark has invalid line number" +msgstr "E19: İm satır numarası geçersiz" + +msgid "E20: Mark not set" +msgstr "E20: İm ayarlanmamış" + +msgid "E21: Cannot make changes, 'modifiable' is off" +msgstr "E21: Değişiklik yapılamıyor, 'modifiable' kapalı" + +msgid "E22: Scripts nested too deep" +msgstr "E22: Betikler çok iç içe geçmiş" + +msgid "E23: No alternate file" +msgstr "E23: Başka bir dosya yok" + +msgid "E24: No such abbreviation" +msgstr "E24: Böyle bir kısaltma yok" + #, c-format msgid "E121: Undefined variable: %s" msgstr "E121: Tanımlanmamış değişken: %s" @@ -6613,6 +6673,9 @@ msgstr "E121: Tanımlanmamış değişken: %s" msgid "E121: Undefined variable: %c:%s" msgstr "E121: Tanımlanmamış değişken: %c:%s" +msgid "E464: Ambiguous use of user-defined command" +msgstr "E464: Kullanıcı tanımlı komutun belirsiz kullanımı" + msgid "E476: Invalid command" msgstr "E476: Geçersiz komut" @@ -6633,15 +6696,19 @@ msgid "" "E856: \"assert_fails()\" second argument must be a string or a list with one " "or two strings" msgstr "" -"E856: \"assert_fails()\" ikinci değişkeni bir dizi veya bir veya iki dizili " +"E856: \"assert_fails()\" ikinci argüman bir dizi veya bir veya iki dizili " "bir liste olmalıdır" +#, c-format +msgid "E908: using an invalid value as a String: %s" +msgstr "E908: Geçersiz bir değer bir Dizi yerine kullanılıyor: %s" + msgid "E909: Cannot index a special variable" msgstr "E909: Özel bir değişken dizinlenemiyor" #, c-format -msgid "E1100: Missing :var: %s" -msgstr "E1100: :var eksik: %s" +msgid "E1100: Command not supported in Vim9 script (missing :var?): %s" +msgstr "E1100: Komut Vim9 betiğinde desteklenmiyor (:var? eksik): %s" #, c-format msgid "E1001: Variable not found: %s" @@ -6655,18 +6722,18 @@ msgid "E1003: Missing return value" msgstr "E1003: Dönüş değeri eksik" #, c-format -msgid "E1004: White space required before and after '%s'" -msgstr "E1004: '%s' öncesinde ve sonrasında boşluk gerekiyor" +msgid "E1004: White space required before and after '%s' at \"%s\"" +msgstr "E1004: Şu konumda '%s' öncesinde ve sonrasında boşluk gerekiyor: \"%s\"" msgid "E1005: Too many argument types" -msgstr "E1005: Çok fazla değişken türü" +msgstr "E1005: Çok fazla argüman türü" #, c-format msgid "E1006: %s is used as an argument" -msgstr "E1006: %s bir değişken olarak kullanılıyor" +msgstr "E1006: %s bir argüman olarak kullanılıyor" msgid "E1007: Mandatory argument after optional argument" -msgstr "E1007: İsteğe bağlı değişken sonrasında zorunlu değişken" +msgstr "E1007: İsteğe bağlı argüman sonrasında zorunlu argüman" msgid "E1008: Missing <type>" msgstr "E1008: <tür> eksik" @@ -6688,7 +6755,7 @@ msgstr "E1012: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı" #, c-format msgid "E1013: Argument %d: type mismatch, expected %s but got %s" -msgstr "E1013: %d değişkeni: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı" +msgstr "E1013: %d argümanı: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı" #, c-format msgid "E1014: Invalid key: %s" @@ -6728,8 +6795,8 @@ msgid "E1022: Type or initialization required" msgstr "E1022: Tür veya ilklendirme gerekiyor" #, c-format -msgid "E1023: Using a Number as a Bool: %d" -msgstr "E1023: Bir Sayı, bir Bool yerine kullanılıyor: %d" +msgid "E1023: Using a Number as a Bool: %lld" +msgstr "E1023: Bir Sayı, bir Boole yerine kullanılıyor: %lld" msgid "E1024: Using a Number as a String" msgstr "E1024: Bir Sayı, bir Dizi yerine kullanılıyor" @@ -6768,11 +6835,11 @@ msgid "E1034: Cannot use reserved name %s" msgstr "E1034: Ayrılmış ad %s kullanılamaz" msgid "E1035: % requires number arguments" -msgstr "E1035: %, sayı değişkenler gerektirir" +msgstr "E1035: %, sayı argümanları gerektirir" #, c-format msgid "E1036: %c requires number or float arguments" -msgstr "E1036: %c, sayı veya kayan noktalı değer değişkenler gerektirir" +msgstr "E1036: %c, sayı veya kayan noktalı değer argümanları gerektirir" #, c-format msgid "E1037: Cannot use \"%s\" with %s" @@ -6798,7 +6865,7 @@ msgid "E1043: Invalid command after :export" msgstr "E1043: :export sonrası geçersiz komut" msgid "E1044: Export with invalid argument" -msgstr "E1044: Geçersiz değişkenle dışa aktarım" +msgstr "E1044: Geçersiz argümanla dışa aktarım" msgid "E1045: Missing \"as\" after *" msgstr "E1045: * sonrası \"as\" eksik" @@ -6817,11 +6884,12 @@ msgstr "E1048: Betikte öge bulunamadı: %s" msgid "E1049: Item not exported in script: %s" msgstr "E1049: Betikte öge dışa aktarılmadı: %s" -msgid "E1050: Colon required before a range" -msgstr "E1050: Bir erim öncesi iki nokta gerekiyor" +#, c-format +msgid "E1050: Colon required before a range: %s" +msgstr "E1050: Bir erim öncesi iki nokta gerekiyor: %s" msgid "E1051: Wrong argument type for +" -msgstr "E1051: + için hatalı değişken türü" +msgstr "E1051: + için hatalı argüman türü" #, c-format msgid "E1052: Cannot declare an option: %s" @@ -6875,12 +6943,12 @@ msgid "E1067: Separator mismatch: %s" msgstr "E1067: Ayırıcı uyumsuzluğu: %s" #, c-format -msgid "E1068: No white space allowed before '%s'" -msgstr "E1068: '%s' önce boşluğa izin verilmiyor" +msgid "E1068: No white space allowed before '%s': %s" +msgstr "E1068: '%s' önce boşluğa izin verilmiyor: %s" #, c-format -msgid "E1069: White space required after '%s'" -msgstr "E1069: '%s' sonrası boşluk gerekiyor" +msgid "E1069: White space required after '%s': %s" +msgstr "E1069: '%s' sonrası boşluk gerekiyor: %s" msgid "E1070: Missing \"from\"" msgstr "E1070: \"from\" eksik" @@ -6908,7 +6976,7 @@ msgstr "E1076: Bu Vim kayan noktalı değer desteği ile derlenmemiş" #, c-format msgid "E1077: Missing argument type for %s" -msgstr "E1077: %s için değişken türü eksik" +msgstr "E1077: %s için argüman türü eksik" #, c-format msgid "E1081: Cannot unlet %s" @@ -6933,7 +7001,7 @@ msgid "E1086: Cannot use :function inside :def" msgstr "E1086: :def içinde :function kullanılamaz" msgid "E1087: Cannot use an index when declaring a variable" -msgstr "E1087: Bir değişken tanımlarken indeks kullanılamaz" +msgstr "E1087: Bir değişken tanımlarken dizinleme kullanılamaz" #, c-format msgid "E1089: Unknown variable: %s" @@ -6941,7 +7009,7 @@ msgstr "E1089: Bilinmeyen değişken: %s" #, c-format msgid "E1090: Cannot assign to argument %s" -msgstr "E1090: %s değişkenine atanamıyor" +msgstr "E1090: %s argümanına atanamıyor" #, c-format msgid "E1091: Function is not compiled: %s" @@ -6989,11 +7057,11 @@ msgid "E1105: Cannot convert %s to string" msgstr "E1105: %s bir diziye dönüştürülemiyor" msgid "E1106: One argument too many" -msgstr "E1106: Bir değişken fazladan" +msgstr "E1106: Bir argüman fazladan" #, c-format msgid "E1106: %d arguments too many" -msgstr "E1106: %d değişken fazladan" +msgstr "E1106: %d argüman fazladan" msgid "E1107: String, List, Dict or Blob required" msgstr "E1107: Dizi, Liste, Sözlük veya İkili Nesne gerekiyor" @@ -7026,10 +7094,10 @@ msgid "E1114: Only values of 0x100 and higher supported" msgstr "E1114: Yalnızca 0x100 ve daha yüksek değerler destekleniyor" msgid "E1115: \"assert_fails()\" fourth argument must be a number" -msgstr "E1115: \"assert_fails()\" dördüncü değişkeni bir sayı olmalıdır" +msgstr "E1115: \"assert_fails()\" dördüncü argüman bir sayı olmalıdır" msgid "E1116: \"assert_fails()\" fifth argument must be a string" -msgstr "E1116: \"assert_fails()\" beşinci değişkeni bir dizi olmalıdır" +msgstr "E1116: \"assert_fails()\" beşinci argüman bir dizi olmalıdır" msgid "E1117: Cannot use ! with nested :def" msgstr "E1117: !, iç içe geçmiş :def ile kullanılamaz" @@ -7080,7 +7148,7 @@ msgid "E1131: Cannot add to null blob" msgstr "E1131: Null ikili geniş nesnesine ekleme yapılamaz" msgid "E1132: Missing function argument" -msgstr "E1132: İşlev değişkeni eksik" +msgstr "E1132: İşlev argümanı eksik" msgid "E1133: Cannot extend a null dict" msgstr "E1133: Bir null sözlük genişletilemez" @@ -7108,12 +7176,259 @@ msgstr "E1138: Bir Boole, Sayı yerine kullanılıyor" msgid "E1139: Missing matching bracket after dict key" msgstr "E1139: Sözlük anahtarı sonrası eşleşen ayraç eksik" -msgid "E1140: For argument must be a sequence of lists" -msgstr "E1140: For değişkeni listelerin bir sıralaması olmalıdır" +msgid "E1140: :for argument must be a sequence of lists" +msgstr "E1140: :for argümanı listelerin bir sıralaması olmalıdır" msgid "E1141: Indexable type required" msgstr "E1141: İndekslenebilir tür gerekiyor" +msgid "E1142: Non-empty string required" +msgstr "E1142: Boş olmayan dizi gerekiyor" + +#, c-format +msgid "E1143: Empty expression: \"%s\"" +msgstr "E1143: Boş ifade: \"%s\"" + +#, c-format +msgid "E1144: Command \"%s\" is not followed by white space: %s" +msgstr "E1144: \"%s\" komutu sonrasında boşluk gelmiyor: %s" + +#, c-format +msgid "E1145: Missing heredoc end marker: %s" +msgstr "E1145: Son imleyicisi eksik: %s" + +#, c-format +msgid "E1146: Command not recognized: %s" +msgstr "E1146: Komut tanınamadı: %s" + +msgid "E1147: List not set" +msgstr "E1147: Liste ayarlanmamış" + +#, c-format +msgid "E1148: Cannot index a %s" +msgstr "E1148: Bir %s dizinlenemiyor" + +#, c-format +msgid "E1149: Script variable is invalid after reload in function %s" +msgstr "E1149: %s işlevindeki yeniden yüklemeden sonra betik değişkeni geçersiz" + +msgid "E1150: Script variable type changed" +msgstr "E1150: Betik değişkeni türü değiştirildi" + +msgid "E1151: Mismatched endfunction" +msgstr "E1151: Eşleşmeyen endfunction" + +msgid "E1152: Mismatched enddef" +msgstr "E1152: Eşleşmeyen enddef" + +msgid "E1153: Invalid operation for bool" +msgstr "E1153: Boole için geçersiz işlem" + +msgid "E1154: Divide by zero" +msgstr "E1154: Sıfır ile bölüm" + +msgid "E1155: Cannot define autocommands for ALL events" +msgstr "E1155: Otokomutlar TÜM olaylar için tanımlanamıyor" + +msgid "E1156: Cannot change the argument list recursively" +msgstr "E1156: Değişken listesi özyineli olarak değiştirilemiyor" + +msgid "E1157: Missing return type" +msgstr "E1157: Dönüş türü eksik" + +msgid "E1158: Cannot use flatten() in Vim9 script" +msgstr "E1158: flatten(), Vim9 betiğinde kullanılamaz" + +msgid "E1159: Cannot split a window when closing the buffer" +msgstr "E1159: Arabellek kapatılırken bir pencere bölünemez" + +msgid "E1160: Cannot use a default for variable arguments" +msgstr "E1160: Değişken argümanları için bir öntanımlı kullanılamaz" + +#, c-format +msgid "E1161: Cannot json encode a %s" +msgstr "E1161: Bir %s JSON olarak kodlanamıyor" + +#, c-format +msgid "E1162: Register name must be one character: %s" +msgstr "E1162: Yazmaç adı tek bir karakter olmalıdır: %s" + +#, c-format +msgid "E1163: Variable %d: type mismatch, expected %s but got %s" +msgstr "E1163: %d değişkeni: Tür uyumsuzluğu, %s bekleniyordu, ancak %s alındı" + +msgid "E1164: vim9cmd must be followed by a command" +msgstr "E1164: vim9cmd sonrasında bir komut gelmelidir" + +#, c-format +msgid "E1165: Cannot use a range with an assignment: %s" +msgstr "E1165: Bir atama ile bir erim kullanılamıyor: %s" + +msgid "E1166: Cannot use a range with a dictionary" +msgstr "E1166: Bir sözlük ile bir erim kullanılamıyor" + +#, c-format +msgid "E1167: Argument name shadows existing variable: %s" +msgstr "E1167: Argüman adı var olan değişkeni gölgeliyor: %s" + +#, c-format +msgid "E1168: Argument already declared in the script: %s" +msgstr "E1168: Betikte argüman halihazırda tanımlanmış: %s" + +msgid "E1169: 'import * as {name}' not supported here" +msgstr "E1169: 'import * as {name} burada desteklenmiyor" + +msgid "E1170: Cannot use #{ to start a comment" +msgstr "E1170: Bir yorum başlatmak için #{ kullanılamaz" + +msgid "E1171: Missing } after inline function" +msgstr "E1171: Satıriçi işlevden sonra } eksik" + +msgid "E1172: Cannot use default values in a lambda" +msgstr "E1172: Bir lambda içerisinde öntanımlı değerler kullanılamıyor" + +#, c-format +msgid "E1173: Text found after enddef: %s" +msgstr "E1173: :enddef sonrası metin bulundu: %s" + +#, c-format +msgid "E1174: String required for argument %d" +msgstr "E1174: %d argümanı için dizi gerekiyor" + +#, c-format +msgid "E1175: Non-empty string required for argument %d" +msgstr "E1175: %d argümanı için boş olmayan dizi gerekiyor" + +msgid "E1176: Misplaced command modifier" +msgstr "E1176: Yanlış yere konulmuş komut değiştiricisi" + +#, c-format +msgid "E1177: For loop on %s not supported" +msgstr "E1177: %s üzerinde for döngüsü desteklenmiyor" + +msgid "E1178: Cannot lock or unlock a local variable" +msgstr "E1178: Bir yerel değişken kilitlenemiyor/kilidi açılamıyor" + +#, c-format +msgid "" +"E1179: Failed to extract PWD from %s, check your shell's config related to " +"OSC 7" +msgstr "" +"E1179: %s içinden PWD çıkarılamadı, kabuğunuzun OSC 7 ile ilgili " +"yapılandırmasını denetleyin" + +#, c-format +msgid "E1180: Variable arguments type must be a list: %s" +msgstr "E1180: Değişken argümanları türü bir liste olmalıdır: %s" + +msgid "E1181: Cannot use an underscore here" +msgstr "E1181: Alt çizgi burada kullanılamaz" + +msgid "E1182: Blob required" +msgstr "E1182: İkili geniş nesne gerekiyor" + +#, c-format +msgid "E1183: Cannot use a range with an assignment operator: %s" +msgstr "E1183: Bir atama işleci ile bir erim kullanılamıyor: %s" + +msgid "E1184: Blob not set" +msgstr "E1184: İkili geniş nesne ayarlanmamış" + +msgid "E1185: Cannot nest :redir" +msgstr "E1185: :redir içe geçirilemiyor" + +msgid "E1185: Missing :redir END" +msgstr "E1185: :redir END eksik" + +#, c-format +msgid "E1186: Expression does not result in a value: %s" +msgstr "E1186: İfade bir değer sonucu vermiyor: %s" + +msgid "E1187: Failed to source defaults.vim" +msgstr "E1187: defaults.vim kaynaklanamadı" + +msgid "E1188: Cannot open a terminal from the command line window" +msgstr "E1188: Komut satırı penceresinden bir uçbirim açılamıyor" + +#, c-format +msgid "E1189: Cannot use :legacy with this command: %s" +msgstr "E1189: :legacy, bu komut ile kullanılamıyor: %s" + +msgid "E1190: One argument too few" +msgstr "E1190: Bir argüman daha gerekiyor" + +#, c-format +msgid "E1190: %d arguments too few" +msgstr "E1190: %d argüman daha gerekiyor" + +#, c-format +msgid "E1191: Call to function that failed to compile: %s" +msgstr "E1191: Derlenemeyen işlev çağrısı: %s" + +msgid "E1192: Empty function name" +msgstr "E1192: Boş işlev adı" + +msgid "E1193: cryptmethod xchacha20 not built into this Vim" +msgstr "E1193: cryptmethod xchacha20 bu Vim ile kullanılamıyor" + +msgid "E1194: Cannot encrypt header, not enough space" +msgstr "E1194: Üstbilgi şifrelenemiyor, yetersiz alan" + +msgid "E1195: Cannot encrypt buffer, not enough space" +msgstr "E1195: Arabellek şifrelenemiyor, yetersiz alan" + +msgid "E1196: Cannot decrypt header, not enough space" +msgstr "E1196: Üstbilgi şifresi çözülemiyor, yetersiz alan" + +msgid "E1197: Cannot allocate_buffer for encryption" +msgstr "E1197: Şifreleme için allocate_buffer yapılamıyor" + +msgid "E1198: Decryption failed: Header incomplete!" +msgstr "E1198: Şifre çözümü başarısız: Üstbilgi tam değil!" + +msgid "E1199: Cannot decrypt buffer, not enough space" +msgstr "E1199: Arabellek şifresi çözülemiyor, yetersiz alan" + +msgid "E1200: Decryption failed!" +msgstr "E1200: Şifre çözümü başarısız!" + +msgid "E1201: Decryption failed: pre-mature end of file!" +msgstr "E1201: Şifre çözümü başarısız: Beklenmedik dosya sonu!" + +#, c-format +msgid "E1202: No white space allowed after '%s': %s" +msgstr "E1202: '%s' sonrası boşluğa izin verilmiyor: %s" + +#, c-format +msgid "E1203: Dot can only be used on a dictionary: %s" +msgstr "E1203: Nokta yalnızca bir sözlükte kullanılabilir: %s" + +#, c-format +msgid "E1204: No Number allowed after .: '\\%%%c'" +msgstr "E1204: . sonrası Sayıya izin verilmiyor: '\\%%%c'" + +msgid "E1205: No white space allowed between option and" +msgstr "E1205: and seçeneği arasında boşluğa izin verilmiyor" + +#, c-format +msgid "E1206: Dictionary required for argument %d" +msgstr "E1206: %d argümanı için sözlük gerekiyor" + +#, c-format +msgid "E1207: Expression without an effect: %s" +msgstr "E1207: Bir efekt olmadan ifade: %s" + +msgid "E1208: -complete used without -nargs" +msgstr "E1208: -complete, -nargs olmadan kullanıldı" + +#, c-format +msgid "E1209: Invalid value for a line number: \"%s\"" +msgstr "E1209: Satır numarası için geçersiz değer: \"%s\"" + +#, c-format +msgid "E1210: Number required for argument %d" +msgstr "E1210: %d argümanı için sayı gerekiyor" + msgid "--No lines in buffer--" msgstr "--Arabellek içinde satır yok--" @@ -7123,17 +7438,6 @@ msgstr "E470: Komut durduruldu" msgid "E471: Argument required" msgstr "E471: Değişken gerekiyor" -msgid "E10: \\ should be followed by /, ? or &" -msgstr "E10: \\ sonrasında /, ? veya & gelmeli" - -msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits" -msgstr "E11: Komut satırı penceresinde geçersiz; <CR> çalıştırır, CTRL-C çıkar" - -msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search" -msgstr "" -"E12: Geçerli dizin veya etiket aramasında exrc veya vimrc'den komutlara izin " -"verilmiyor" - msgid "E171: Missing :endif" msgstr "E171: :endif eksik" @@ -7164,9 +7468,6 @@ msgstr "E588: :while olmadan :endwhile" msgid "E588: :endfor without :for" msgstr "E588: :for olmadan :endfor" -msgid "E13: File exists (add ! to override)" -msgstr "E13: Dosya mevcut (geçersiz kılmak için ! ekleyin)" - msgid "E472: Command failed" msgstr "E472: Komut başarısız oldu" @@ -7193,34 +7494,23 @@ msgid "Interrupted" msgstr "Yarıda kesildi" msgid "E474: Invalid argument" -msgstr "E474: Geçersiz değişken" +msgstr "E474: Geçersiz argüman" #, c-format msgid "E475: Invalid argument: %s" -msgstr "E475: Geçersiz değişken: %s" +msgstr "E475: Geçersiz argüman: %s" #, c-format msgid "E983: Duplicate argument: %s" -msgstr "E983: Yinelenen değişken: %s" +msgstr "E983: Yinelenen argüman: %s" #, c-format msgid "E475: Invalid value for argument %s" -msgstr "E475: %s değişkeni için geçersiz değer" +msgstr "E475: %s argümanı için geçersiz değer" #, c-format msgid "E475: Invalid value for argument %s: %s" -msgstr "E475: %s değişkeni için geçersiz değer: %s" - -#, c-format -msgid "E15: Invalid expression: %s" -msgstr "E15: Geçersiz ifade: %s" - -msgid "E16: Invalid range" -msgstr "E16: Geçersiz erim" - -#, c-format -msgid "E17: \"%s\" is a directory" -msgstr "E17: \"%s\" bir dizin" +msgstr "E475: %s argümanı için geçersiz değer: %s" msgid "E756: Spell checking is not possible" msgstr "E756: Yazım denetimi olanaklı değil" @@ -7236,24 +7526,6 @@ msgstr "E667: Fsync başarısız oldu" msgid "E448: Could not load library function %s" msgstr "E448: %s kitaplık işlevi yüklenemedi" -msgid "E19: Mark has invalid line number" -msgstr "E19: İm satır numarası geçersiz" - -msgid "E20: Mark not set" -msgstr "E20: İm ayarlanmamış" - -msgid "E21: Cannot make changes, 'modifiable' is off" -msgstr "E21: Değişiklik yapılamıyor, 'modifiable' kapalı" - -msgid "E22: Scripts nested too deep" -msgstr "E22: Betikler çok iç içe geçmiş" - -msgid "E23: No alternate file" -msgstr "E23: Başka bir dosya yok" - -msgid "E24: No such abbreviation" -msgstr "E24: Böyle bir kısaltma yok" - msgid "E477: No ! allowed" msgstr "E477: ! imine izin verilmiyor" @@ -7327,7 +7599,7 @@ msgid "E485: Can't read file %s" msgstr "E485: %s dosyası okunamıyor" msgid "E38: Null argument" -msgstr "E38: Anlamsız değişken" +msgstr "E38: Anlamsız argüman" msgid "E39: Number expected" msgstr "E39: Sayı bekleniyordu" @@ -7392,6 +7664,9 @@ msgstr "E794: Değişken kum havuzunda ayarlanamıyor: \"%s\"" msgid "E928: String required" msgstr "E928: Dizi gerekiyor" +msgid "E889: Number required" +msgstr "E889: Sayı gerekiyor" + msgid "E713: Cannot use empty key for Dictionary" msgstr "E713: Sözlük için boş anahtar kullanılamaz" @@ -7411,11 +7686,11 @@ msgstr "E978: İkili geniş nesne için geçersiz işlem" #, c-format msgid "E118: Too many arguments for function: %s" -msgstr "E118: İşlev için çok fazla değişken: %s" +msgstr "E118: İşlev için çok fazla argüman: %s" #, c-format msgid "E119: Not enough arguments for function: %s" -msgstr "E119: Şu işlev için yetersiz sayıda değişken: %s" +msgstr "E119: Şu işlev için yetersiz sayıda argüman: %s" #, c-format msgid "E933: Function was deleted: %s" @@ -7437,18 +7712,15 @@ msgstr "E697: Liste sonunda ']' eksik: %s" #, c-format msgid "E712: Argument of %s must be a List or Dictionary" -msgstr "E712: %s ögesinin değişkeni bir liste veya sözlük olmalıdır" +msgstr "E712: %s ögesinin argümanı bir liste veya sözlük olmalıdır" #, c-format msgid "E896: Argument of %s must be a List, Dictionary or Blob" -msgstr "E896: %s değişkeni bir liste, sözlük veya ikili geniş nesne olmalıdır" +msgstr "E896: %s argümanı bir liste, sözlük veya ikili geniş nesne olmalıdır" msgid "E804: Cannot use '%' with Float" msgstr "E804: Bir kayan noktalı değer ile '%' kullanılamaz" -msgid "E908: using an invalid value as a String" -msgstr "E908: Geçersiz bir değer bir Dizi yerine kullanılıyor" - msgid "E996: Cannot lock an option" msgstr "E996: Seçenek kilitlenemiyor" @@ -7456,9 +7728,6 @@ msgstr "E996: Seçenek kilitlenemiyor" msgid "E113: Unknown option: %s" msgstr "E113: Bilinmeyen seçenek: %s" -msgid "E18: Unexpected characters in :let" -msgstr "E18: :let içinde beklenmeyen karakter" - #, c-format msgid "E998: Reduce of an empty %s with no initial value" msgstr "E998: Başlangıç değeri olmayan boş bir %s için reduce() yapılamıyor" @@ -7616,7 +7885,7 @@ msgstr "E957: Geçersiz pencere numarası" #, c-format msgid "E686: Argument of %s must be a List" -msgstr "E686: %s değişkeni bir liste olmalı" +msgstr "E686: %s argümanı bir liste olmalı" msgid "E109: Missing ':' after '?'" msgstr "E109: '?' sonrası ':' eksik" @@ -7685,7 +7954,7 @@ msgstr "'%s' anahtarı sözlüğe eklenemedi" #, c-format msgid "index must be int or slice, not %s" -msgstr "dizin bir tamsayı veya dilim olmalıdır, %s olamaz" +msgstr "sıra bir tamsayı veya dilim olmalıdır, %s olamaz" #, c-format msgid "expected str() or unicode() instance, but got %s" @@ -7762,10 +8031,10 @@ msgid "expected sequence element of size 2, but got sequence of size %d" msgstr "2 boyut bir sıralama bekleniyordu, ancak %d boyut bir sıralama geldi" msgid "list constructor does not accept keyword arguments" -msgstr "liste yapıcısı anahtar sözcük değişkenleri kabul etmez" +msgstr "liste yapıcısı anahtar sözcük argümanları kabul etmez" msgid "list index out of range" -msgstr "liste dizini erimin dışında" +msgstr "liste sırası erimin dışında" #, c-format msgid "internal error: failed to get Vim list item %d" @@ -8013,8 +8282,7 @@ msgstr "" "düzenleyebilirsiniz." msgid "\" Hit <Enter> on a help line to open a help window on this option." -msgstr "" -"\" Yardım penceresini açmak için seçenek adı üzerinde <Enter>'a basın." +msgstr "\" Yardım penceresini açmak için seçenek adı üzerinde <Enter>'a basın." msgid "\" Hit <Enter> on an index line to jump there." msgstr "" @@ -8056,7 +8324,8 @@ msgid "moving around, searching and patterns" msgstr "dolaşma, arama ve dizgeler" msgid "list of flags specifying which commands wrap to another line" -msgstr "hangi komutların diğer satıra kaydırıldığını belirleyen bayraklar\n" +msgstr "" +"hangi komutların diğer satıra kaydırıldığını belirleyen bayraklar\n" "listesi" msgid "" @@ -8081,6 +8350,9 @@ msgstr ":cd için kullanılan dizin adları listesi" msgid "change to directory of file in buffer" msgstr "arabellekteki dosyanın olduğu dizine değiştir" +msgid "change to pwd of shell in terminal buffer" +msgstr "uçbirim arabelleğindeki kabuğun pwd'sine geç" + msgid "search commands wrap around the end of the buffer" msgstr "arama komutları, arabelleğin sonunda kaydırılır" @@ -8320,7 +8592,8 @@ msgid "multiple windows" msgstr "çoklu pencereler" msgid "0, 1 or 2; when to use a status line for the last window" -msgstr "0, 1 veya 2; son pencere için ne zaman bir durum satırı\n" +msgstr "" +"0, 1 veya 2; son pencere için ne zaman bir durum satırı\n" "kullanılacağı" msgid "alternate format to be used for a status line" @@ -8382,7 +8655,8 @@ msgid "this window scrolls together with other bound windows" msgstr "bu pencere, bağlı diğer pencerelerle birlikte kayar" msgid "\"ver\", \"hor\" and/or \"jump\"; list of options for 'scrollbind'" -msgstr "\"ver\", \"hor\" ve/veya \"jump\"; 'scrollbind' için seçenekler listesi" +msgstr "" +"\"ver\", \"hor\" ve/veya \"jump\"; 'scrollbind' için seçenekler listesi" msgid "this window's cursor moves together with other bound windows" msgstr "bu pencerenin imleci bağlı diğer pencerelerle birlikte kayar" @@ -8394,7 +8668,8 @@ msgid "key that precedes Vim commands in a terminal window" msgstr "bir uçbirim penceresinde Vim komutlarından önce gelen düğme" msgid "max number of lines to keep for scrollback in a terminal window" -msgstr "bir uçbirim penceresinde geri kaydırma için kullanılacak\n" +msgstr "" +"bir uçbirim penceresinde geri kaydırma için kullanılacak\n" "en çok satır sayısı" msgid "type of pty to use for a terminal window" @@ -8522,8 +8797,7 @@ msgid "list of flags that specify how the GUI works" msgstr "grafik arabirimin nice çalıştığını belirleyen bayraklar listesi" msgid "\"icons\", \"text\" and/or \"tooltips\"; how to show the toolbar" -msgstr "" -"\"icons\", \"text\" ve/veya \"tooltips\"; araç çubuğu kipleri " +msgstr "\"icons\", \"text\" ve/veya \"tooltips\"; araç çubuğu kipleri " msgid "size of toolbar icons" msgstr "araç çubuğu simgelerinin boyutu" @@ -8679,7 +8953,8 @@ msgid "list of directories for undo files" msgstr "geri al dosyaları için dizinler listesi" msgid "maximum number lines to save for undo on a buffer reload" -msgstr "arabellek yeniden yüklemesinde geri al için kaydedilecek\n" +msgstr "" +"arabellek yeniden yüklemesinde geri al için kaydedilecek\n" "en çok satır sayısı" msgid "changes have been made and not written to a file" @@ -8704,7 +8979,8 @@ msgid "definition of what comment lines look like" msgstr "yorum satırlarının nice görüneceğinin tanımı" msgid "list of flags that tell how automatic formatting works" -msgstr "kendiliğinden biçimlendirmenin nice çalıştığını anlatan\n" +msgstr "" +"kendiliğinden biçimlendirmenin nice çalıştığını anlatan\n" "bayraklar listesi" msgid "pattern to recognize a numbered list" @@ -8714,7 +8990,8 @@ msgid "expression used for \"gq\" to format lines" msgstr "satırları biçimlendirmek için \"gq\" için kullanılan ifade" msgid "specifies how Insert mode completion works for CTRL-N and CTRL-P" -msgstr "Ekleme kipi tamamlamasının CTRL-N ve CTRL-P için nice çalıştığını\n" +msgstr "" +"Ekleme kipi tamamlamasının CTRL-N ve CTRL-P için nice çalıştığını\n" "belirler" msgid "whether to use a popup menu for Insert mode completion" @@ -8739,7 +9016,8 @@ msgid "list of dictionary files for keyword completion" msgstr "anahtar sözcük tamamlaması için sözlük dosyaları listesi" msgid "list of thesaurus files for keyword completion" -msgstr "anahtar sözcük tamamlaması için eşanlamlılar sözlüğü dosyaları\n" +msgstr "" +"anahtar sözcük tamamlaması için eşanlamlılar sözlüğü dosyaları\n" "listesi" msgid "adjust case of a keyword completion match" @@ -8883,7 +9161,8 @@ msgid "markers used when 'foldmethod' is \"marker\"" msgstr "'foldmethod' \"marker\" olduğunda kullanılan imleyiciler" msgid "maximum fold depth for when 'foldmethod' is \"indent\" or \"syntax\"" -msgstr "'foldmethod' \"indent\" veya \"syntax\" olduğunda kullanılan en çok\n" +msgstr "" +"'foldmethod' \"indent\" veya \"syntax\" olduğunda kullanılan en çok\n" "kıvırma derinliği" msgid "diff mode" @@ -9013,7 +9292,8 @@ msgid "use a swap file for this buffer" msgstr "bu arabellek için bir takas dosyası kullan" msgid "\"sync\", \"fsync\" or empty; how to flush a swap file to disk" -msgstr "\"sync\", \"fsync\", veya boş; bir takas dosyasının diske\n" +msgstr "" +"\"sync\", \"fsync\", veya boş; bir takas dosyasının diske\n" "nice floşlanacağı" msgid "number of characters typed to cause a swap file update" @@ -9089,13 +9369,14 @@ msgid "characters to escape when 'shellxquote' is (" msgstr "'shellxquote' ( iken kaçırılacak karakterler" msgid "argument for 'shell' to execute a command" -msgstr "bir komut çalıştırmak için 'shell' için değişken" +msgstr "bir komut çalıştırmak için 'shell' için argüman" msgid "used to redirect command output to a file" msgstr "komut çıktısını bir dosyaya yeniden yönlendirmek için kullanılır" msgid "use a temp file for shell commands instead of using a pipe" -msgstr "bir veri yolu kullanımı yerine kabuk komutları için geçici\n" +msgstr "" +"bir veri yolu kullanımı yerine kabuk komutları için geçici\n" "bir dosya kullan" msgid "program used for \"=\" command" @@ -9108,7 +9389,8 @@ msgid "program used for the \"K\" command" msgstr "\"K\" komutu için kullanılan program" msgid "warn when using a shell command and a buffer has changes" -msgstr "bir kabuk komutu kullanılıyorsa ve arabellekte değişiklikler\n" +msgstr "" +"bir kabuk komutu kullanılıyorsa ve arabellekte değişiklikler\n" "varsa uyar" msgid "running make and jumping to errors (quickfix)" @@ -9124,7 +9406,8 @@ msgid "program used for the \":make\" command" msgstr "\":make\" komutu için kullanılan program" msgid "string used to put the output of \":make\" in the error file" -msgstr "\":make\" komutunun çıktısını hata dosyasına koymak için\n" +msgstr "" +"\":make\" komutunun çıktısını hata dosyasına koymak için\n" "kullanılan dizi" msgid "name of the errorfile for the 'makeprg' command" @@ -9179,7 +9462,8 @@ msgid "insert characters backwards" msgstr "karakterleri geriye doğru ekle" msgid "allow CTRL-_ in Insert and Command-line mode to toggle 'revins'" -msgstr "'revins' açıp kapatmak için Ekleme ve Komut Satırı kipinde\n" +msgstr "" +"'revins' açıp kapatmak için Ekleme ve Komut Satırı kipinde\n" "CTRL-_ izin ver" msgid "the ASCII code for the first letter of the Hebrew alphabet" @@ -9210,8 +9494,9 @@ msgid "apply 'langmap' to mapped characters" msgstr "eşlemlenen karakterlere 'langmap' uygula" msgid "when set never use IM; overrules following IM options" -msgstr "ayarlandığında hiçbir zaman IM kullanma; aşağıdaki IM seçeneklerini " -"geçersiz kılar" +msgstr "" +"ayarlandığında hiçbir zaman IM kullanma; aşağıdaki IM seçeneklerini geçersiz " +"kılar" msgid "in Insert mode: 1: use :lmap; 2: use IM; 0: neither" msgstr "Ekleme kipinde: 1: :lmap kullan; 2; IM kullan; 0: hiçbiri" diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 0cfb7c192f..e1ee5dc28f 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5549,8 +5549,7 @@ void ex_vimgrep(exarg_T *eap) // need to be done (again). But not the window-local // options! aucmd_prepbuf(&aco, buf); - apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, - buf->b_fname, TRUE, buf); + apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, true, buf); do_modelines(OPT_NOWIN); aucmd_restbuf(&aco); } @@ -5568,9 +5567,9 @@ void ex_vimgrep(exarg_T *eap) qf_update_buffer(qi, NULL); - if (au_name != NULL) - apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, - curbuf->b_fname, TRUE, curbuf); + if (au_name != NULL) { + apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf); + } // The QuickFixCmdPost autocmd may free the quickfix list. Check the list // is still valid. diff --git a/src/nvim/screen.c b/src/nvim/screen.c index cc0f0feef7..3257eac9a9 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -385,7 +385,7 @@ int update_screen(int type) // non-displayed part of msg_grid is considered invalid. for (int i = 0; i < MIN(msg_scrollsize(), msg_grid.Rows); i++) { grid_clear_line(&msg_grid, msg_grid.line_offset[i], - (int)msg_grid.Columns, false); + msg_grid.Columns, false); } } if (msg_use_msgsep()) { @@ -504,7 +504,7 @@ int update_screen(int type) } if (clear_cmdline) { // going to clear cmdline (done below) - check_for_delay(FALSE); + check_for_delay(false); } /* Force redraw when width of 'number' or 'relativenumber' column @@ -741,7 +741,7 @@ bool win_cursorline_standout(const win_T *wp) */ static void win_update(win_T *wp, Providers *providers) { - buf_T *buf = wp->w_buffer; + buf_T *buf = wp->w_buffer; int type; int top_end = 0; /* Below last row of the top area that needs updating. 0 when no top area updating. */ @@ -1999,16 +1999,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc long vcol = 0; // virtual column (for tabs) long vcol_sbr = -1; // virtual column after showbreak long vcol_prev = -1; // "vcol" of previous character - char_u *line; // current line - char_u *ptr; // current position in "line" + char_u *line; // current line + char_u *ptr; // current position in "line" int row; // row in the window, excl w_winrow ScreenGrid *grid = &wp->w_grid; // grid specific to the window char_u extra[57]; // sign, line number and 'fdc' must // fit in here int n_extra = 0; // number of extra chars - char_u *p_extra = NULL; // string of extra chars, plus NUL - char_u *p_extra_free = NULL; // p_extra needs to be freed + char_u *p_extra = NULL; // string of extra chars, plus NUL + char_u *p_extra_free = NULL; // p_extra needs to be freed int c_extra = NUL; // extra chars, all the same int c_final = NUL; // final char, mandatory if set int extra_attr = 0; // attributes when n_extra != 0 @@ -2021,7 +2021,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // saved "extra" items for when draw_state becomes WL_LINE (again) int saved_n_extra = 0; - char_u *saved_p_extra = NULL; + char_u *saved_p_extra = NULL; int saved_c_extra = 0; int saved_c_final = 0; int saved_char_attr = 0; @@ -2037,14 +2037,13 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc int tocol = MAXCOL; // end of inverting int fromcol_prev = -2; // start of inverting after cursor bool noinvcur = false; // don't invert the cursor - int lnum_in_visual_area = false; + bool lnum_in_visual_area = false; pos_T pos; long v; int char_attr = 0; // attributes for next character - int attr_pri = FALSE; // char_attr has priority - int area_highlighting = FALSE; /* Visual or incsearch highlighting - in this line */ + bool attr_pri = false; // char_attr has priority + bool area_highlighting = false; // Visual or incsearch highlighting in this line int attr = 0; // attributes for area highlighting int area_attr = 0; // attributes desired by highlighting int search_attr = 0; // attributes desired by 'hlsearch' @@ -2090,7 +2089,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc int line_attr_lowprio = 0; // low-priority attribute for the line int line_attr_lowprio_save; matchitem_T *cur; // points to the match list - match_T *shl; // points to search_hl or a match + match_T *shl; // points to search_hl or a match bool shl_flag; // flag to indicate whether search_hl // has been processed or not bool prevcol_hl_flag; // flag to indicate whether prevcol @@ -2363,7 +2362,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc diff_hlf = HLF_ADD; // added line } filler_lines = 0; - area_highlighting = TRUE; + area_highlighting = true; } if (lnum == wp->w_topline) { filler_lines = wp->w_topfill; @@ -2502,7 +2501,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc v = wp->w_leftcol; } if (v > 0 && !number_only) { - char_u *prev_ptr = ptr; + char_u *prev_ptr = ptr; while (vcol < v && *ptr != NUL) { c = win_lbr_chartabsize(wp, line, ptr, (colnr_T)vcol, NULL); vcol += c; @@ -2559,7 +2558,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc pos = wp->w_cursor; wp->w_cursor.lnum = lnum; wp->w_cursor.col = linecol; - len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf); + len = spell_move_to(wp, FORWARD, true, true, &spell_hlf); // spell_move_to() may call ml_get() and make "line" invalid line = ml_get_buf(wp->w_buffer, lnum, false); @@ -2628,7 +2627,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc shl->endcol = MAXCOL; shl->attr_cur = 0; shl->is_addpos = false; - v = (long)(ptr - line); + v = (ptr - line); if (cur != NULL) { cur->pos.cur = 0; } @@ -2850,7 +2849,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc } if (wp->w_briopt_sbr && draw_state == WL_BRI - 1 - && n_extra == 0 && *p_sbr != NUL) { + && n_extra == 0 && *get_showbreak_value(wp) != NUL) { // draw indent after showbreak value draw_state = WL_BRI; } else if (wp->w_briopt_sbr && draw_state == WL_SBR && n_extra == 0) { @@ -2909,19 +2908,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc } char_attr = win_hl_attr(wp, HLF_DED); } - if (*p_sbr != NUL && need_showbreak) { + char_u *const sbr = get_showbreak_value(wp); + if (*sbr != NUL && need_showbreak) { // Draw 'showbreak' at the start of each broken line. - p_extra = p_sbr; + p_extra = sbr; c_extra = NUL; c_final = NUL; - n_extra = (int)STRLEN(p_sbr); + n_extra = (int)STRLEN(sbr); char_attr = win_hl_attr(wp, HLF_AT); if (wp->w_skipcol == 0 || !wp->w_p_wrap) { need_showbreak = false; } - vcol_sbr = vcol + MB_CHARLEN(p_sbr); - /* Correct end of highlighted area for 'showbreak', - * required when 'linebreak' is also set. */ + vcol_sbr = vcol + MB_CHARLEN(sbr); + // Correct end of highlighted area for 'showbreak', + // required when 'linebreak' is also set. if (tocol == vcol) { tocol += n_extra; } @@ -3061,7 +3061,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc * Do this for 'search_hl' and the match list (ordered by * priority). */ - v = (long)(ptr - line); + v = (ptr - line); cur = wp->w_match_head; shl_flag = false; while (cur != NULL || !shl_flag) { @@ -3405,7 +3405,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc /* Get syntax attribute, unless still at the start of the line * (double-wide char that doesn't fit). */ - v = (long)(ptr - line); + v = (ptr - line); if (has_syntax && v > 0) { /* Get the syntax attribute for the character. If there * is an error, disable syntax highlighting. */ @@ -3453,7 +3453,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc * Only do this when there is no syntax highlighting, the * @Spell cluster is not used or the current syntax item * contains the @Spell cluster. */ - v = (long)(ptr - line); + v = (ptr - line); if (has_spell && v >= word_end && v > cur_checked_col) { spell_attr = 0; if (!attr_pri) { @@ -3553,6 +3553,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc 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; + + // We have just drawn the showbreak value, no need to add + // space for it again. + if (vcol == vcol_sbr) { + n_extra -= MB_CHARLEN(get_showbreak_value(wp)); + if (n_extra < 0) { + n_extra = 0; + } + } + if (c == TAB && n_extra + col > grid->Columns) { n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array) - 1; @@ -3619,10 +3629,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (c == TAB && (!wp->w_p_list || wp->w_p_lcs_chars.tab1)) { int tab_len = 0; long vcol_adjusted = vcol; // removed showbreak length + char_u *const sbr = get_showbreak_value(wp); + // Only adjust the tab_len, when at the first column after the // showbreak value was drawn. - if (*p_sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap) { - vcol_adjusted = vcol - MB_CHARLEN(p_sbr); + if (*sbr != NUL && vcol == vcol_sbr && wp->w_p_wrap) { + vcol_adjusted = vcol - MB_CHARLEN(sbr); } // tab amount depends on current column tab_len = tabstop_padding(vcol_adjusted, @@ -3932,7 +3944,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc // At end of the text line or just after the last character. if (c == NUL && eol_hl_off == 0) { - long prevcol = (long)(ptr - line) - 1; + long prevcol = (ptr - line) - 1; // we're not really at that column when skipping some text if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol) { @@ -4802,7 +4814,7 @@ static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol, */ void rl_mirror(char_u *str) { - char_u *p1, *p2; + char_u *p1, *p2; int t; for (p1 = str, p2 = str + STRLEN(str) - 1; p1 < p2; ++p1, --p2) { @@ -4953,19 +4965,19 @@ void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, in { #define L_MATCH(m) (showtail ? sm_gettail(matches[m], false) : matches[m]) int row; - char_u *buf; + char_u *buf; int len; int clen; // length in screen cells int fillchar; int attr; int i; bool highlight = true; - char_u *selstart = NULL; + char_u *selstart = NULL; int selstart_col = 0; - char_u *selend = NULL; + char_u *selend = NULL; static int first_match = 0; bool add_left = false; - char_u *s; + char_u *s; int emenu; int l; @@ -5135,7 +5147,7 @@ void win_redr_status_matches(expand_T *xp, int num_matches, char_u **matches, in static void win_redr_status(win_T *wp) { int row; - char_u *p; + char_u *p; int len; int fillchar; int attr; @@ -5283,7 +5295,7 @@ static void redraw_custom_statusline(win_T *wp) /// line of the window right of it. If not, then it's a vertical separator. bool stl_connected(win_T *wp) { - frame_T *fr; + frame_T *fr; fr = wp->w_frame; while (fr->fr_parent != NULL) { @@ -5309,16 +5321,16 @@ bool stl_connected(win_T *wp) /// @param len length of buffer bool get_keymap_str(win_T *wp, char_u *fmt, char_u *buf, int len) { - char_u *p; + char_u *p; if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP) { return false; } { - buf_T *old_curbuf = curbuf; - win_T *old_curwin = curwin; - char_u *s; + buf_T *old_curbuf = curbuf; + win_T *old_curwin = curwin; + char_u *s; curbuf = wp->w_buffer; curwin = wp; @@ -5360,12 +5372,12 @@ static void win_redr_custom(win_T *wp, bool draw_ruler) int len; int fillchar; char_u buf[MAXPATHL]; - char_u *stl; - char_u *p; + char_u *stl; + char_u *p; stl_hlrec_t *hltab; StlClickRecord *tabtab; int use_sandbox = false; - win_T *ewp; + win_T *ewp; int p_crb_save; ScreenGrid *grid = &default_grid; @@ -5734,7 +5746,7 @@ void grid_put_schar(ScreenGrid *grid, int row, int col, char_u *schar, int attr) void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row, int col, int attr) { unsigned off; - char_u *ptr = text; + char_u *ptr = text; int len = textlen; int c; unsigned max_off; @@ -5962,7 +5974,7 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum) FUNC_ATTR_NONNULL_ALL { matchitem_T *cur; // points to the match list - match_T *shl; // points to search_hl or a match + match_T *shl; // points to search_hl or a match bool shl_flag; // flag to indicate whether search_hl // has been processed or not @@ -6077,7 +6089,7 @@ static void next_search_hl(win_T *win, match_T *shl, linenr_T lnum, colnr_T minc } else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL || (shl->rm.endpos[0].lnum == 0 && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) { - char_u *ml; + char_u *ml; matchcol = shl->rm.startpos[0].col; ml = ml_get_buf(shl->buf, lnum, false) + matchcol; @@ -6289,11 +6301,9 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col, int } } -/* - * Check if there should be a delay. Used before clearing or redrawing the - * screen or the command line. - */ -void check_for_delay(int check_msg_scroll) +/// Check if there should be a delay. Used before clearing or redrawing the +/// screen or the command line. +void check_for_delay(bool check_msg_scroll) { if ((emsg_on_display || (check_msg_scroll && msg_scroll)) && !did_wait_return @@ -6477,9 +6487,9 @@ retry: * in case applying autocommands always changes Rows or Columns. */ if (starting == 0 && ++retry_count <= 3) { - apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf); - /* In rare cases, autocommands may have altered Rows or Columns, - * jump back to check if we need to allocate the screen again. */ + apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, false, curbuf); + // In rare cases, autocommands may have altered Rows or Columns, + // jump back to check if we need to allocate the screen again. goto retry; } @@ -6587,7 +6597,7 @@ void screenclear(void) // blank out the default grid for (i = 0; i < default_grid.Rows; i++) { grid_clear_line(&default_grid, default_grid.line_offset[i], - (int)default_grid.Columns, true); + default_grid.Columns, true); default_grid.line_wraps[i] = false; } @@ -6760,7 +6770,7 @@ void grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } grid->line_offset[j + line_count] = temp; grid->line_wraps[j + line_count] = false; - grid_clear_line(grid, temp, (int)grid->Columns, false); + grid_clear_line(grid, temp, grid->Columns, false); } } @@ -6812,7 +6822,7 @@ void grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col, } grid->line_offset[j - line_count] = temp; grid->line_wraps[j - line_count] = false; - grid_clear_line(grid, temp, (int)grid->Columns, false); + grid_clear_line(grid, temp, grid->Columns, false); } } @@ -6864,7 +6874,7 @@ int showmode(void) bool nwr_save = need_wait_return; // wait a bit before overwriting an important message - check_for_delay(FALSE); + check_for_delay(false); // if the cmdline is more than one line high, erase top lines need_clear = clear_cmdline; @@ -6909,7 +6919,7 @@ int showmode(void) } if (edit_submode_extra != NULL) { MSG_PUTS_ATTR(" ", attr); // Add a space in between. - if ((int)edit_submode_highl < (int)HLF_COUNT) { + if ((int)edit_submode_highl < HLF_COUNT) { sub_attr = win_hl_attr(curwin, edit_submode_highl); } else { sub_attr = attr; @@ -7082,15 +7092,15 @@ void draw_tabline(void) int col = 0; int scol = 0; int attr; - win_T *wp; - win_T *cwp; + win_T *wp; + win_T *cwp; int wincount; int modified; int c; int len; int attr_nosel = HL_ATTR(HLF_TP); int attr_fill = HL_ATTR(HLF_TPF); - char_u *p; + char_u *p; int room; int use_sep_chars = (t_colors < 8 ); diff --git a/src/nvim/search.c b/src/nvim/search.c index b0ee41b245..4be2402f1d 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -7,13 +7,11 @@ #include <assert.h> #include <inttypes.h> +#include <limits.h> // for INT_MAX on MSVC #include <stdbool.h> #include <string.h> -#include <limits.h> /* for INT_MAX on MSVC */ #include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/search.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -34,17 +32,19 @@ #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/move.h" #include "nvim/mouse.h" +#include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/os/time.h" #include "nvim/path.h" #include "nvim/regexp.h" #include "nvim/screen.h" +#include "nvim/search.h" #include "nvim/strings.h" #include "nvim/ui.h" +#include "nvim/vim.h" #include "nvim/window.h" -#include "nvim/os/time.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "search.c.generated.h" @@ -79,12 +79,12 @@ static struct spat spats[2] = { // Last used search pattern - [0] = {NULL, true, false, 0, {'/', false, false, 0L}, NULL}, + [0] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL }, // Last used substitute pattern - [1] = {NULL, true, false, 0, {'/', false, false, 0L}, NULL} + [1] = { NULL, true, false, 0, { '/', false, false, 0L }, NULL } }; -static int last_idx = 0; /* index in spats[] for RE_LAST */ +static int last_idx = 0; // index in spats[] for RE_LAST static char_u lastc[2] = { NUL, NUL }; // last character searched for static Direction lastcdir = FORWARD; // last direction of character search @@ -97,7 +97,7 @@ static struct spat saved_spats[2]; static int saved_spats_last_idx = 0; static bool saved_spats_no_hlsearch = false; -static char_u *mr_pattern = NULL; // pattern used by search_regcomp() +static char_u *mr_pattern = NULL; // pattern used by search_regcomp() static bool mr_pattern_alloced = false; // mr_pattern was allocated /* @@ -105,34 +105,27 @@ static bool mr_pattern_alloced = false; // mr_pattern was allocated * been searched already. */ typedef struct SearchedFile { - FILE *fp; /* File pointer */ - char_u *name; /* Full name of file */ - linenr_T lnum; /* Line we were up to in file */ - int matched; /* Found a match in this file */ + FILE *fp; // File pointer + char_u *name; // Full name of file + linenr_T lnum; // Line we were up to in file + int matched; // Found a match in this file } SearchedFile; -/* - * translate search pattern for vim_regcomp() - * - * pat_save == RE_SEARCH: save pat in spats[RE_SEARCH].pat (normal search cmd) - * pat_save == RE_SUBST: save pat in spats[RE_SUBST].pat (:substitute command) - * pat_save == RE_BOTH: save pat in both patterns (:global command) - * pat_use == RE_SEARCH: use previous search pattern if "pat" is NULL - * pat_use == RE_SUBST: use previous substitute pattern if "pat" is NULL - * pat_use == RE_LAST: use last used pattern if "pat" is NULL - * options & SEARCH_HIS: put search string in history - * options & SEARCH_KEEP: keep previous search pattern - * - * returns FAIL if failed, OK otherwise. - */ -int -search_regcomp( - char_u *pat, - int pat_save, - int pat_use, - int options, - regmmatch_T *regmatch /* return: pattern and ignore-case flag */ -) +/// translate search pattern for vim_regcomp() +/// +/// pat_save == RE_SEARCH: save pat in spats[RE_SEARCH].pat (normal search cmd) +/// pat_save == RE_SUBST: save pat in spats[RE_SUBST].pat (:substitute command) +/// pat_save == RE_BOTH: save pat in both patterns (:global command) +/// pat_use == RE_SEARCH: use previous search pattern if "pat" is NULL +/// pat_use == RE_SUBST: use previous substitute pattern if "pat" is NULL +/// pat_use == RE_LAST: use last used pattern if "pat" is NULL +/// options & SEARCH_HIS: put search string in history +/// options & SEARCH_KEEP: keep previous search pattern +/// +/// @param regmatch return: pattern and ignore-case flag +/// +/// @return FAIL if failed, OK otherwise. +int search_regcomp(char_u *pat, int pat_save, int pat_use, int options, regmmatch_T *regmatch) { int magic; int i; @@ -144,15 +137,17 @@ search_regcomp( * If no pattern given, use a previously defined pattern. */ if (pat == NULL || *pat == NUL) { - if (pat_use == RE_LAST) + if (pat_use == RE_LAST) { i = last_idx; - else + } else { i = pat_use; - if (spats[i].pat == NULL) { /* pattern was never defined */ - if (pat_use == RE_SUBST) + } + if (spats[i].pat == NULL) { // pattern was never defined + if (pat_use == RE_SUBST) { EMSG(_(e_nopresub)); - else + } else { EMSG(_(e_noprevre)); + } rc_did_emsg = true; return FAIL; } @@ -180,19 +175,22 @@ search_regcomp( * unless the pattern should not be remembered. */ if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) { - /* search or global command */ - if (pat_save == RE_SEARCH || pat_save == RE_BOTH) + // search or global command + if (pat_save == RE_SEARCH || pat_save == RE_BOTH) { save_re_pat(RE_SEARCH, pat, magic); - /* substitute or global command */ - if (pat_save == RE_SUBST || pat_save == RE_BOTH) + } + // substitute or global command + if (pat_save == RE_SUBST || pat_save == RE_BOTH) { save_re_pat(RE_SUBST, pat, magic); + } } regmatch->rmm_ic = ignorecase(pat); regmatch->rmm_maxcol = 0; regmatch->regprog = vim_regcomp(pat, magic ? RE_MAGIC : 0); - if (regmatch->regprog == NULL) + if (regmatch->regprog == NULL) { return FAIL; + } return OK; } @@ -239,9 +237,10 @@ void save_re_pat(int idx, char_u *pat, int magic) spats[idx].timestamp = os_time(); spats[idx].additional_data = NULL; last_idx = idx; - /* If 'hlsearch' set and search pat changed: need redraw. */ - if (p_hls) + // If 'hlsearch' set and search pat changed: need redraw. + if (p_hls) { redraw_all_later(SOME_VALID); + } set_no_hlsearch(false); } } @@ -256,11 +255,13 @@ void save_search_patterns(void) { if (save_level++ == 0) { saved_spats[0] = spats[0]; - if (spats[0].pat != NULL) + if (spats[0].pat != NULL) { saved_spats[0].pat = vim_strsave(spats[0].pat); + } saved_spats[1] = spats[1]; - if (spats[1].pat != NULL) + if (spats[1].pat != NULL) { saved_spats[1].pat = vim_strsave(spats[1].pat); + } saved_spats_last_idx = last_idx; saved_spats_no_hlsearch = no_hlsearch; } @@ -369,8 +370,8 @@ int ignorecase_opt(char_u *pat, int ic_in, int scs) { int ic = ic_in; if (ic && !no_smartcase && scs - && !(ctrl_x_mode_not_default() && curbuf->b_p_inf) - ) { + && !(ctrl_x_mode_not_default() && + curbuf->b_p_inf)) { ic = !pat_has_uppercase(pat); } no_smartcase = false; @@ -431,10 +432,11 @@ void set_last_csearch(int c, char_u *s, int len) { *lastc = c; lastc_bytelen = len; - if (len) + if (len) { memcpy(lastc_bytes, s, len); - else + } else { memset(lastc_bytes, 0, sizeof(lastc_bytes)); + } } void set_csearch_direction(Direction cdir) @@ -468,11 +470,12 @@ void reset_search_dir(void) void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) { free_spat(&spats[idx]); - /* An empty string means that nothing should be matched. */ - if (*s == NUL) + // An empty string means that nothing should be matched. + if (*s == NUL) { spats[idx].pat = NULL; - else - spats[idx].pat = (char_u *) xstrdup((char *) s); + } else { + spats[idx].pat = (char_u *)xstrdup((char *)s); + } spats[idx].timestamp = os_time(); spats[idx].additional_data = NULL; spats[idx].magic = magic; @@ -482,20 +485,23 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast) spats[idx].off.line = FALSE; spats[idx].off.end = FALSE; spats[idx].off.off = 0; - if (setlast) + if (setlast) { last_idx = idx; + } if (save_level) { free_spat(&saved_spats[idx]); saved_spats[idx] = spats[0]; - if (spats[idx].pat == NULL) + if (spats[idx].pat == NULL) { saved_spats[idx].pat = NULL; - else + } else { saved_spats[idx].pat = vim_strsave(spats[idx].pat); + } saved_spats_last_idx = last_idx; } - /* If 'hlsearch' set and search pat changed: need redraw. */ - if (p_hls && idx == last_idx && !no_hlsearch) + // If 'hlsearch' set and search pat changed: need redraw. + if (p_hls && idx == last_idx && !no_hlsearch) { redraw_all_later(SOME_VALID); + } } /* @@ -509,7 +515,7 @@ void last_pat_prog(regmmatch_T *regmatch) regmatch->regprog = NULL; return; } - ++emsg_off; /* So it doesn't beep if bad expr */ + ++emsg_off; // So it doesn't beep if bad expr (void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch); --emsg_off; } @@ -529,27 +535,21 @@ void last_pat_prog(regmmatch_T *regmatch) /// if (options & SEARCH_PEEK) check for typed char, cancel search /// if (options & SEARCH_COL) start at pos->col instead of zero /// -/// @returns FAIL (zero) for failure, non-zero for success. -/// the index of the first matching -/// subpattern plus one; one if there was none. -int searchit( - win_T *win, // window to search in; can be NULL for a - // buffer without a window! - buf_T *buf, - pos_T *pos, - pos_T *end_pos, // set to end of the match, unless NULL - Direction dir, - char_u *pat, - long count, - int options, - int pat_use, // which pattern to use when "pat" is empty - searchit_arg_T *extra_arg // optional extra arguments, can be NULL -) +/// @param win window to search in; can be NULL for a buffer without a window! +/// @param end_pos set to end of the match, unless NULL +/// @param pat_use which pattern to use when "pat" is empty +/// @param extra_arg optional extra arguments, can be NULL +/// +/// @returns FAIL (zero) for failure, non-zero for success. +/// the index of the first matching +/// subpattern plus one; one if there was none. +int searchit(win_T *win, buf_T *buf, pos_T *pos, pos_T *end_pos, Direction dir, char_u *pat, + long count, int options, int pat_use, searchit_arg_T *extra_arg) { int found; - linenr_T lnum; /* no init to shut up Apollo cc */ + linenr_T lnum; // no init to shut up Apollo cc regmmatch_T regmatch; - char_u *ptr; + char_u *ptr; colnr_T matchcol; lpos_T endpos; lpos_T matchpos; @@ -569,15 +569,16 @@ int searchit( int *timed_out = NULL; // set when timed out or NULL if (extra_arg != NULL) { - stop_lnum = extra_arg->sa_stop_lnum; - tm = extra_arg->sa_tm; - timed_out = &extra_arg->sa_timed_out; + stop_lnum = extra_arg->sa_stop_lnum; + tm = extra_arg->sa_tm; + timed_out = &extra_arg->sa_timed_out; } if (search_regcomp(pat, RE_SEARCH, pat_use, - (options & (SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL) { - if ((options & SEARCH_MSG) && !rc_did_emsg) + (options & (SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL) { + if ((options & SEARCH_MSG) && !rc_did_emsg) { EMSG2(_("E383: Invalid search string: %s"), mr_pattern); + } return FAIL; } @@ -585,7 +586,7 @@ int searchit( * find the string */ called_emsg = FALSE; - do { /* loop for count */ + do { // loop for count // When not accepting a match at the start position set "extra_col" to a // non-zero value. Don't do that when starting at MAXCOL, since MAXCOL + 1 // is zero. @@ -610,13 +611,13 @@ int searchit( extra_col = (options & SEARCH_START) ? start_char_len : 0; } - start_pos = *pos; /* remember start pos for detecting no match */ - found = 0; /* default: not found */ - at_first_line = TRUE; /* default: start in first line */ - if (pos->lnum == 0) { /* correct lnum for when starting in line 0 */ + start_pos = *pos; // remember start pos for detecting no match + found = 0; // default: not found + at_first_line = TRUE; // default: start in first line + if (pos->lnum == 0) { // correct lnum for when starting in line 0 pos->lnum = 1; pos->col = 0; - at_first_line = FALSE; /* not in first line now */ + at_first_line = FALSE; // not in first line now } /* @@ -630,19 +631,22 @@ int searchit( && (options & SEARCH_START) == 0) { lnum = pos->lnum - 1; at_first_line = FALSE; - } else + } else { lnum = pos->lnum; + } - for (loop = 0; loop <= 1; ++loop) { /* loop twice if 'wrapscan' set */ + for (loop = 0; loop <= 1; ++loop) { // loop twice if 'wrapscan' set for (; lnum > 0 && lnum <= buf->b_ml.ml_line_count; lnum += dir, at_first_line = FALSE) { - /* Stop after checking "stop_lnum", if it's set. */ + // Stop after checking "stop_lnum", if it's set. if (stop_lnum != 0 && (dir == FORWARD - ? lnum > stop_lnum : lnum < stop_lnum)) + ? lnum > stop_lnum : lnum < stop_lnum)) { break; - /* Stop after passing the "tm" time limit. */ - if (tm != NULL && profile_passed_limit(*tm)) + } + // Stop after passing the "tm" time limit. + if (tm != NULL && profile_passed_limit(*tm)) { break; + } // Look for a match somewhere in line "lnum". colnr_T col = at_first_line && (options & SEARCH_COL) ? pos->col : 0; @@ -657,7 +661,7 @@ int searchit( break; } if (nmatched > 0) { - /* match may actually be in another line when using \zs */ + // match may actually be in another line when using \zs matchpos = regmatch.startpos[0]; endpos = regmatch.endpos[0]; submatch = first_submatch(®match); @@ -740,8 +744,9 @@ int searchit( // have made it invalid. ptr = ml_get_buf(buf, lnum, false); } - if (!match_ok) + if (!match_ok) { continue; + } } if (dir == BACKWARD) { /* @@ -775,8 +780,9 @@ int searchit( matchpos = regmatch.startpos[0]; endpos = regmatch.endpos[0]; submatch = first_submatch(®match); - } else + } else { break; + } // We found a valid match, now check if there is // another one after it. @@ -804,16 +810,16 @@ int searchit( } } if (ptr[matchcol] == NUL - || (nmatched = vim_regexec_multi( - ®match, win, buf, lnum + matchpos.lnum, matchcol, - tm, timed_out)) == 0) { - // If the search timed out, we did find a match - // but it might be the wrong one, so that's not - // OK. - if (tm != NULL && profile_passed_limit(*tm)) { - match_ok = false; - } - break; + || (nmatched = + vim_regexec_multi(®match, win, buf, lnum + matchpos.lnum, matchcol, + tm, timed_out)) == 0) { + // If the search timed out, we did find a match + // but it might be the wrong one, so that's not + // OK. + if (tm != NULL && profile_passed_limit(*tm)) { + match_ok = false; + } + break; } // vim_regexec_multi() may clear "regprog" if (regmatch.regprog == NULL) { @@ -828,8 +834,9 @@ int searchit( * If there is only a match after the cursor, skip * this match. */ - if (!match_ok) + if (!match_ok) { continue; + } } /* With the SEARCH_END option move to the last character @@ -873,14 +880,15 @@ int searchit( found = 1; first_match = false; - /* Set variables used for 'incsearch' highlighting. */ + // Set variables used for 'incsearch' highlighting. search_match_lines = endpos.lnum - matchpos.lnum; search_match_endcol = endpos.col; break; } - line_breakcheck(); /* stop if ctrl-C typed */ - if (got_int) + line_breakcheck(); // stop if ctrl-C typed + if (got_int) { break; + } /* Cancel searching if a character was typed. Used for * 'incsearch'. Don't check too often, that would slowdown @@ -892,8 +900,9 @@ int searchit( break; } - if (loop && lnum == start_pos.lnum) - break; /* if second loop, stop where started */ + if (loop && lnum == start_pos.lnum) { + break; // if second loop, stop where started + } } at_first_line = FALSE; @@ -933,8 +942,7 @@ int searchit( } if (got_int || called_emsg || (timed_out != NULL && *timed_out) - || break_loop - ) { + || break_loop) { break; } } while (--count > 0 && found); // stop after count matches or no match @@ -943,23 +951,24 @@ int searchit( called_emsg |= save_called_emsg; - if (!found) { /* did not find it */ - if (got_int) + if (!found) { // did not find it + if (got_int) { EMSG(_(e_interr)); - else if ((options & SEARCH_MSG) == SEARCH_MSG) { - if (p_ws) + } else if ((options & SEARCH_MSG) == SEARCH_MSG) { + if (p_ws) { EMSG2(_(e_patnotf2), mr_pattern); - else if (lnum == 0) + } else if (lnum == 0) { EMSG2(_("E384: search hit TOP without match for: %s"), - mr_pattern); - else + mr_pattern); + } else { EMSG2(_("E385: search hit BOTTOM without match for: %s"), - mr_pattern); + mr_pattern); + } } return FAIL; } - /* A pattern like "\n\zs" may go past the last line. */ + // A pattern like "\n\zs" may go past the last line. if (pos->lnum > buf->b_ml.ml_line_count) { pos->lnum = buf->b_ml.ml_line_count; pos->col = (int)STRLEN(ml_get_buf(buf, pos->lnum, false)); @@ -988,8 +997,9 @@ static int first_submatch(regmmatch_T *rp) int submatch; for (submatch = 1;; ++submatch) { - if (rp->startpos[submatch].lnum >= 0) + if (rp->startpos[submatch].lnum >= 0) { break; + } if (submatch == 9) { submatch = 0; break; @@ -998,47 +1008,44 @@ static int first_submatch(regmmatch_T *rp) return submatch; } -/* - * Highest level string search function. - * Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc' - * If 'dirc' is 0: use previous dir. - * If 'pat' is NULL or empty : use previous string. - * If 'options & SEARCH_REV' : go in reverse of previous dir. - * If 'options & SEARCH_ECHO': echo the search command and handle options - * If 'options & SEARCH_MSG' : may give error message - * If 'options & SEARCH_OPT' : interpret optional flags - * If 'options & SEARCH_HIS' : put search pattern in history - * If 'options & SEARCH_NOOF': don't add offset to position - * If 'options & SEARCH_MARK': set previous context mark - * If 'options & SEARCH_KEEP': keep previous search pattern - * If 'options & SEARCH_START': accept match at curpos itself - * If 'options & SEARCH_PEEK': check for typed char, cancel search - * - * Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this - * makes the movement linewise without moving the match position. - * - * Return 0 for failure, 1 for found, 2 for found and line offset added. - */ -int do_search( - oparg_T *oap, // can be NULL - int dirc, // '/' or '?' - int search_delim, // delimiter for search, e.g. '%' in s%regex%replacement - char_u *pat, - long count, - int options, - searchit_arg_T *sia // optional arguments or NULL -) +/// Highest level string search function. +/// Search for the 'count'th occurrence of pattern 'pat' in direction 'dirc' +/// +/// Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this +/// makes the movement linewise without moving the match position. +/// +/// @param dirc if 0: use previous dir. +/// @param pat NULL or empty : use previous string. +/// @param options if TRUE and +/// SEARCH_REV == TRUE : go in reverse of previous dir. +/// SEARCH_ECHO == TRUE : echo the search command and handle options +/// SEARCH_MSG == TRUE : may give error message +/// SEARCH_OPT == TRUE : interpret optional flags +/// SEARCH_HIS == TRUE : put search pattern in history +/// SEARCH_NOOF == TRUE : don't add offset to position +/// SEARCH_MARK == TRUE : set previous context mark +/// SEARCH_KEEP == TRUE : keep previous search pattern +/// SEARCH_START == TRUE : accept match at curpos itself +/// SEARCH_PEEK == TRUE : check for typed char, cancel search +/// @param oap can be NULL +/// @param dirc '/' or '?' +/// @param search_delim delimiter for search, e.g. '%' in s%regex%replacement +/// @param sia optional arguments or NULL +/// +/// @return 0 for failure, 1 for found, 2 for found and line offset added. +int do_search(oparg_T *oap, int dirc, int search_delim, char_u *pat, long count, int options, + searchit_arg_T *sia) { - pos_T pos; /* position of the last match */ - char_u *searchstr; + pos_T pos; // position of the last match + char_u *searchstr; struct soffset old_off; - int retval; /* Return value */ - char_u *p; + int retval; // Return value + char_u *p; long c; - char_u *dircp; - char_u *strcopy = NULL; - char_u *ps; - char_u *msgbuf = NULL; + char_u *dircp; + char_u *strcopy = NULL; + char_u *ps; + char_u *msgbuf = NULL; size_t len; bool has_offset = false; @@ -1056,32 +1063,35 @@ int do_search( */ old_off = spats[0].off; - pos = curwin->w_cursor; /* start searching at the cursor position */ + pos = curwin->w_cursor; // start searching at the cursor position /* * Find out the direction of the search. */ - if (dirc == 0) + if (dirc == 0) { dirc = spats[0].off.dir; - else { + } else { spats[0].off.dir = dirc; set_vv_searchforward(); } if (options & SEARCH_REV) { - if (dirc == '/') + if (dirc == '/') { dirc = '?'; - else + } else { dirc = '/'; + } } /* If the cursor is in a closed fold, don't find another match in the same * fold. */ if (dirc == '/') { - if (hasFolding(pos.lnum, NULL, &pos.lnum)) - pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */ + if (hasFolding(pos.lnum, NULL, &pos.lnum)) { + pos.col = MAXCOL - 2; // avoid overflow when adding 1 + } } else { - if (hasFolding(pos.lnum, &pos.lnum, NULL)) + if (hasFolding(pos.lnum, &pos.lnum, NULL)) { pos.col = 0; + } } /* @@ -1110,12 +1120,12 @@ int do_search( goto end_do_search; } } else { - /* make search_regcomp() use spats[RE_SEARCH].pat */ + // make search_regcomp() use spats[RE_SEARCH].pat searchstr = (char_u *)""; } } - if (pat != NULL && *pat != NUL) { /* look for (new) offset */ + if (pat != NULL && *pat != NUL) { // look for (new) offset /* * Find end of regular expression. * If there is a matching '/' or '?', toss it. @@ -1123,7 +1133,7 @@ int do_search( ps = strcopy; p = skip_regexp(pat, search_delim, p_magic, &strcopy); if (strcopy != ps) { - /* made a copy of "pat" to change "\?" to "?" */ + // made a copy of "pat" to change "\?" to "?" searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy)); pat = strcopy; searchstr = strcopy; @@ -1148,28 +1158,30 @@ int do_search( } p++; } - if (ascii_isdigit(*p) || *p == '+' || *p == '-') { /* got an offset */ - /* 'nr' or '+nr' or '-nr' */ - if (ascii_isdigit(*p) || ascii_isdigit(*(p + 1))) + if (ascii_isdigit(*p) || *p == '+' || *p == '-') { // got an offset + // 'nr' or '+nr' or '-nr' + if (ascii_isdigit(*p) || ascii_isdigit(*(p + 1))) { spats[0].off.off = atol((char *)p); - else if (*p == '-') /* single '-' */ + } else if (*p == '-') { // single '-' spats[0].off.off = -1; - else /* single '+' */ + } else { // single '+' spats[0].off.off = 1; + } ++p; - while (ascii_isdigit(*p)) /* skip number */ + while (ascii_isdigit(*p)) { // skip number ++p; + } } - /* compute length of search command for get_address() */ + // compute length of search command for get_address() searchcmdlen += (int)(p - pat); - pat = p; /* put pat after search command */ + pat = p; // put pat after search command } if ((options & SEARCH_ECHO) && messaging() && !msg_silent && (!cmd_silent || !shortmess(SHM_SEARCHCOUNT))) { - char_u *trunc; + char_u *trunc; char_u off_buf[40]; size_t off_len = 0; @@ -1291,18 +1303,22 @@ int do_search( */ if (!spats[0].off.line && spats[0].off.off && pos.col < MAXCOL - 2) { if (spats[0].off.off > 0) { - for (c = spats[0].off.off; c; --c) - if (decl(&pos) == -1) + for (c = spats[0].off.off; c; --c) { + if (decl(&pos) == -1) { break; - if (c) { /* at start of buffer */ - pos.lnum = 0; /* allow lnum == 0 here */ + } + } + if (c) { // at start of buffer + pos.lnum = 0; // allow lnum == 0 here pos.col = MAXCOL; } } else { - for (c = spats[0].off.off; c; ++c) - if (incl(&pos) == -1) + for (c = spats[0].off.off; c; ++c) { + if (incl(&pos) == -1) { break; - if (c) { /* at end of buffer */ + } + } + if (c) { // at end of buffer pos.lnum = curbuf->b_ml.ml_line_count + 1; pos.col = 0; } @@ -1332,10 +1348,10 @@ int do_search( retval = 0; goto end_do_search; } - if (spats[0].off.end && oap != NULL) - oap->inclusive = true; /* 'e' includes last character */ - - retval = 1; /* pattern found */ + if (spats[0].off.end && oap != NULL) { + oap->inclusive = true; // 'e' includes last character + } + retval = 1; // pattern found /* * Add character and/or line offset @@ -1345,28 +1361,33 @@ int do_search( if (spats[0].off.line) { // Add the offset to the line number. c = pos.lnum + spats[0].off.off; - if (c < 1) + if (c < 1) { pos.lnum = 1; - else if (c > curbuf->b_ml.ml_line_count) + } else if (c > curbuf->b_ml.ml_line_count) { pos.lnum = curbuf->b_ml.ml_line_count; - else + } else { pos.lnum = c; + } pos.col = 0; - retval = 2; /* pattern found, line offset added */ - } else if (pos.col < MAXCOL - 2) { /* just in case */ - /* to the right, check for end of file */ + retval = 2; // pattern found, line offset added + } else if (pos.col < MAXCOL - 2) { // just in case + // to the right, check for end of file c = spats[0].off.off; if (c > 0) { - while (c-- > 0) - if (incl(&pos) == -1) + while (c-- > 0) { + if (incl(&pos) == -1) { break; + } + } } - /* to the left, check for start of file */ + // to the left, check for start of file else { - while (c++ < 0) - if (decl(&pos) == -1) + while (c++ < 0) { + if (decl(&pos) == -1) { break; + } + } } } if (!equalpos(pos, org_pos)) { @@ -1411,14 +1432,16 @@ int do_search( ++pat; } - if (options & SEARCH_MARK) + if (options & SEARCH_MARK) { setpcmark(); + } curwin->w_cursor = pos; curwin->w_set_curswant = TRUE; end_do_search: - if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) + if ((options & SEARCH_KEEP) || cmdmod.keeppatterns) { spats[0].off = old_off; + } xfree(msgbuf); return retval; @@ -1436,18 +1459,20 @@ end_do_search: int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) { linenr_T start = 0; - char_u *ptr; - char_u *p; + char_u *ptr; + char_u *p; - if (buf->b_ml.ml_line_count == 0) + if (buf->b_ml.ml_line_count == 0) { return FAIL; + } for (;; ) { pos->lnum += dir; if (pos->lnum < 1) { if (p_ws) { pos->lnum = buf->b_ml.ml_line_count; - if (!shortmess(SHM_SEARCH)) + if (!shortmess(SHM_SEARCH)) { give_warning((char_u *)_(top_bot_msg), true); + } } else { pos->lnum = 1; break; @@ -1455,20 +1480,23 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) } else if (pos->lnum > buf->b_ml.ml_line_count) { if (p_ws) { pos->lnum = 1; - if (!shortmess(SHM_SEARCH)) + if (!shortmess(SHM_SEARCH)) { give_warning((char_u *)_(bot_top_msg), true); + } } else { pos->lnum = 1; break; } } - if (pos->lnum == start) + if (pos->lnum == start) { break; - if (start == 0) + } + if (start == 0) { start = pos->lnum; + } ptr = ml_get_buf(buf, pos->lnum, false); p = skipwhite(ptr); - pos->col = (colnr_T) (p - ptr); + pos->col = (colnr_T)(p - ptr); /* when adding lines the matching line may be empty but it is not * ignored because we are interested in the next line -- Acevedo */ @@ -1481,8 +1509,9 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, Direction dir, char_u *pat) // Expanding lines or words. assert(compl_length >= 0); if ((p_ic ? mb_strnicmp(p, pat, (size_t)compl_length) - : STRNCMP(p, pat, compl_length)) == 0) + : STRNCMP(p, pat, compl_length)) == 0) { return OK; + } } } return FAIL; @@ -1505,12 +1534,12 @@ int searchc(cmdarg_T *cap, int t_cmd) int dir = cap->arg; // true for searching forward long count = cap->count1; // repeat count int col; - char_u *p; + char_u *p; int len; bool stop = true; - if (c != NUL) { /* normal search: remember args for repeat */ - if (!KeyStuffed) { /* don't remember when redoing */ + if (c != NUL) { // normal search: remember args for repeat + if (!KeyStuffed) { // don't remember when redoing *lastc = c; set_csearch_direction(dir); set_csearch_until(t_cmd); @@ -1535,7 +1564,7 @@ int searchc(cmdarg_T *cap, int t_cmd) } t_cmd = last_t_cmd; c = *lastc; - /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */ + // For multi-byte re-use last lastc_bytes[] and lastc_bytelen. /* Force a move of at least one char, so ";" and "," will move the * cursor, even if the cursor is right in front of char we are looking @@ -1545,10 +1574,11 @@ int searchc(cmdarg_T *cap, int t_cmd) } } - if (dir == BACKWARD) + if (dir == BACKWARD) { cap->oap->inclusive = false; - else + } else { cap->oap->inclusive = true; + } p = get_cursor_line_ptr(); col = curwin->w_cursor.col; @@ -1667,8 +1697,7 @@ static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos) /// If there is a match set "*initc" to the matching character and "*findc" to /// the opposite character. Set "*backwards" to the direction. /// When "switchit" is true swap the direction. -static void find_mps_values(int *initc, int *findc, bool *backwards, - bool switchit) +static void find_mps_values(int *initc, int *findc, bool *backwards, bool switchit) FUNC_ATTR_NONNULL_ALL { char_u *ptr = curbuf->b_p_mps; @@ -1734,7 +1763,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) bool backwards = false; // init for gcc bool raw_string = false; // search for raw string bool inquote = false; // true when inside quotes - char_u *ptr; + char_u *ptr; 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 @@ -1754,13 +1783,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) // 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) + // Direction to search when initc is '/', '*' or '#' + if (flags & FM_BACKWARD) { dir = BACKWARD; - else if (flags & FM_FORWARD) + } else if (flags & FM_FORWARD) { dir = FORWARD; - else + } else { dir = 0; + } /* * if initc given, look in the table for the matching character @@ -1770,8 +1800,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) */ if (initc == '/' || initc == '*' || initc == 'R') { comment_dir = dir; - if (initc == '/') + if (initc == '/') { ignore_cend = true; + } backwards = (dir == FORWARD) ? false : true; raw_string = (initc == 'R'); initc = NUL; @@ -1794,16 +1825,17 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) * Only check for special things when 'cpo' doesn't have '%'. */ if (!cpo_match) { - /* Are we before or at #if, #else etc.? */ + // Are we before or at #if, #else etc.? ptr = skipwhite(linep); if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep)) { ptr = skipwhite(ptr + 1); - if ( STRNCMP(ptr, "if", 2) == 0 - || STRNCMP(ptr, "endif", 5) == 0 - || STRNCMP(ptr, "el", 2) == 0) + if (STRNCMP(ptr, "if", 2) == 0 + || STRNCMP(ptr, "endif", 5) == 0 + || STRNCMP(ptr, "el", 2) == 0) { hash_dir = 1; + } } - /* Are we on a comment? */ + // Are we on a comment? else if (linep[pos.col] == '/') { if (linep[pos.col + 1] == '*') { comment_dir = FORWARD; @@ -1835,12 +1867,14 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) * If beyond the end of the line, use the last character in * the line. */ - if (linep[pos.col] == NUL && pos.col) + if (linep[pos.col] == NUL && pos.col) { --pos.col; + } for (;; ) { initc = PTR2CHAR(linep + pos.col); - if (initc == NUL) + if (initc == NUL) { break; + } find_mps_values(&initc, &findc, &backwards, false); if (findc) { @@ -1849,18 +1883,20 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) pos.col += utfc_ptr2len(linep + pos.col); } if (!findc) { - /* no brace in the line, maybe use " #if" then */ - if (!cpo_match && *skipwhite(linep) == '#') + // no brace in the line, maybe use " #if" then + if (!cpo_match && *skipwhite(linep) == '#') { hash_dir = 1; - else + } else { return NULL; + } } else if (!cpo_bsl) { int col, bslcnt = 0; /* Set "match_escaped" if there are an odd number of * backslashes. */ - for (col = pos.col; check_prevcol(linep, col, '\\', &col); ) + for (col = pos.col; check_prevcol(linep, col, '\\', &col); ) { bslcnt++; + } match_escaped = (bslcnt & 1); } } @@ -1874,49 +1910,58 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } if (initc != '#') { ptr = skipwhite(skipwhite(linep) + 1); - if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0) + if (STRNCMP(ptr, "if", 2) == 0 || STRNCMP(ptr, "el", 2) == 0) { hash_dir = 1; - else if (STRNCMP(ptr, "endif", 5) == 0) + } else if (STRNCMP(ptr, "endif", 5) == 0) { hash_dir = -1; - else + } else { return NULL; + } } pos.col = 0; while (!got_int) { if (hash_dir > 0) { - if (pos.lnum == curbuf->b_ml.ml_line_count) + if (pos.lnum == curbuf->b_ml.ml_line_count) { break; - } else if (pos.lnum == 1) + } + } else if (pos.lnum == 1) { break; + } pos.lnum += hash_dir; linep = ml_get(pos.lnum); - line_breakcheck(); /* check for CTRL-C typed */ + line_breakcheck(); // check for CTRL-C typed ptr = skipwhite(linep); - if (*ptr != '#') + if (*ptr != '#') { continue; - pos.col = (colnr_T) (ptr - linep); + } + pos.col = (colnr_T)(ptr - linep); ptr = skipwhite(ptr + 1); if (hash_dir > 0) { - if (STRNCMP(ptr, "if", 2) == 0) + if (STRNCMP(ptr, "if", 2) == 0) { count++; - else if (STRNCMP(ptr, "el", 2) == 0) { - if (count == 0) + } else if (STRNCMP(ptr, "el", 2) == 0) { + if (count == 0) { return &pos; + } } else if (STRNCMP(ptr, "endif", 5) == 0) { - if (count == 0) + if (count == 0) { return &pos; + } count--; } } else { if (STRNCMP(ptr, "if", 2) == 0) { - if (count == 0) + if (count == 0) { return &pos; + } count--; } else if (initc == '#' && STRNCMP(ptr, "el", 2) == 0) { - if (count == 0) + if (count == 0) { return &pos; - } else if (STRNCMP(ptr, "endif", 5) == 0) + } + } else if (STRNCMP(ptr, "endif", 5) == 0) { count++; + } } } return NULL; @@ -1935,11 +1980,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) pos_T match_pos; // Where last slash-star was found clearpos(&match_pos); - /* backward search: Check if this line contains a single-line comment */ + // backward search: Check if this line contains a single-line comment if ((backwards && comment_dir) - || lisp - ) + || lisp) { comment_col = check_linecomment(linep); + } if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) { lispcomm = true; // find match inside this comment } @@ -1949,58 +1994,63 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) * inc() and dec() here, but that is much slower */ if (backwards) { - /* char to match is inside of comment, don't search outside */ - if (lispcomm && pos.col < (colnr_T)comment_col) + // char to match is inside of comment, don't search outside + if (lispcomm && pos.col < (colnr_T)comment_col) { break; - if (pos.col == 0) { /* at start of line, go to prev. one */ - if (pos.lnum == 1) /* start of file */ + } + if (pos.col == 0) { // at start of line, go to prev. one + if (pos.lnum == 1) { // start of file break; + } --pos.lnum; - if (maxtravel > 0 && ++traveled > maxtravel) + if (maxtravel > 0 && ++traveled > maxtravel) { break; + } linep = ml_get(pos.lnum); - pos.col = (colnr_T)STRLEN(linep); /* pos.col on trailing NUL */ + pos.col = (colnr_T)STRLEN(linep); // pos.col on trailing NUL do_quotes = -1; line_breakcheck(); - /* Check if this line contains a single-line comment */ + // Check if this line contains a single-line comment if (comment_dir - || lisp - ) + || lisp) { comment_col = check_linecomment(linep); - /* skip comment */ - if (lisp && comment_col != MAXCOL) + } + // skip comment + if (lisp && comment_col != MAXCOL) { pos.col = comment_col; + } } else { pos.col--; pos.col -= utf_head_off(linep, linep + pos.col); } - } else { /* forward search */ + } else { // forward search if (linep[pos.col] == NUL - /* at end of line, go to next one */ - /* don't search for match in comment */ + // at end of line, go to next one + // don't search for match in comment || (lisp && comment_col != MAXCOL - && pos.col == (colnr_T)comment_col) - ) { - if (pos.lnum == curbuf->b_ml.ml_line_count /* end of file */ + && pos.col == (colnr_T)comment_col)) { + if (pos.lnum == curbuf->b_ml.ml_line_count // end of file /* line is exhausted and comment with it, * don't search for match in code */ - || lispcomm - ) + || lispcomm) { break; + } ++pos.lnum; - if (maxtravel && traveled++ > maxtravel) + if (maxtravel && traveled++ > maxtravel) { break; + } linep = ml_get(pos.lnum); pos.col = 0; do_quotes = -1; line_breakcheck(); - if (lisp) /* find comment pos in new line */ + if (lisp) { // find comment pos in new line comment_col = check_linecomment(linep); + } } else { pos.col += utfc_ptr2len(linep + pos.col); } @@ -2016,40 +2066,37 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } if (comment_dir) { - /* Note: comments do not nest, and we ignore quotes in them */ - /* TODO: ignore comment brackets inside strings */ + // Note: comments do not nest, and we ignore quotes in them + // TODO: ignore comment brackets inside strings if (comment_dir == FORWARD) { if (linep[pos.col] == '*' && linep[pos.col + 1] == '/') { pos.col++; return &pos; } - } else { /* Searching backwards */ + } else { // Searching backwards /* * A comment may contain / * or / /, it may also start or end * with / * /. Ignore a / * after / / and after *. */ - if (pos.col == 0) + if (pos.col == 0) { continue; - else if (raw_string) - { + } else if (raw_string) { if (linep[pos.col - 1] == 'R' && linep[pos.col] == '"' - && vim_strchr(linep + pos.col + 1, '(') != NULL) - { + && vim_strchr(linep + pos.col + 1, '(') != NULL) { /* Possible start of raw string. Now that we have the * delimiter we can check if it ends before where we * started searching, or before the previously found * raw string start. */ if (!find_rawstring_end(linep, &pos, - count > 0 ? &match_pos : &curwin->w_cursor)) - { + count > 0 ? &match_pos : &curwin->w_cursor)) { count++; match_pos = pos; match_pos.col--; } - linep = ml_get(pos.lnum); /* may have been released */ + linep = ml_get(pos.lnum); // may have been released } - } else if ( linep[pos.col - 1] == '/' + } else if (linep[pos.col - 1] == '/' && linep[pos.col] == '*' && (pos.col == 1 || linep[pos.col - 2] != '*') && (int)pos.col < comment_col) { @@ -2057,15 +2104,16 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) match_pos = pos; match_pos.col--; } else if (linep[pos.col - 1] == '*' && linep[pos.col] == '/') { - if (count > 0) + if (count > 0) { pos = match_pos; - else if (pos.col > 1 && linep[pos.col - 2] == '/' - && (int)pos.col <= comment_col) + } else if (pos.col > 1 && linep[pos.col - 2] == '/' + && (int)pos.col <= comment_col) { pos.col -= 2; - else if (ignore_cend) + } else if (ignore_cend) { continue; - else + } else { return NULL; + } return &pos; } } @@ -2077,24 +2125,27 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) * of quotes are ignored, but only if there is an even number of * quotes in the line. */ - if (cpo_match) + if (cpo_match) { do_quotes = 0; - else if (do_quotes == -1) { + } else if (do_quotes == -1) { /* * Count the number of quotes in the line, skipping \" and '"'. * Watch out for "\\". */ at_start = do_quotes; for (ptr = linep; *ptr; ++ptr) { - if (ptr == linep + pos.col + backwards) + if (ptr == linep + pos.col + backwards) { at_start = (do_quotes & 1); + } if (*ptr == '"' - && (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\'')) + && (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\'')) { ++do_quotes; - if (*ptr == '\\' && ptr[1] != NUL) + } + if (*ptr == '\\' && ptr[1] != NUL) { ++ptr; + } } - do_quotes &= 1; /* result is 1 with even number of quotes */ + do_quotes &= 1; // result is 1 with even number of quotes /* * If we find an uneven count, check current line and previous @@ -2126,7 +2177,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) } } - /* ml_get() only keeps one line, need to get linep again */ + // ml_get() only keeps one line, need to get linep again linep = ml_get(pos.lnum); } } @@ -2149,7 +2200,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) const int c = PTR2CHAR(linep + pos.col); switch (c) { case NUL: - /* at end of line without trailing backslash, reset inquote */ + // at end of line without trailing backslash, reset inquote if (pos.col == 0 || linep[pos.col - 1] != '\\') { inquote = false; start_in_quotes = kFalse; @@ -2162,9 +2213,11 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) if (do_quotes) { int col; - for (col = pos.col - 1; col >= 0; --col) - if (linep[col] != '\\') + for (col = pos.col - 1; col >= 0; --col) { + if (linep[col] != '\\') { break; + } + } if ((((int)pos.col - 1 - col) & 1) == 0) { inquote = !inquote; start_in_quotes = kFalse; @@ -2214,8 +2267,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) && vim_strchr((char_u *)"(){}[]", c) != NULL && pos.col > 1 && check_prevcol(linep, pos.col, '\\', NULL) - && check_prevcol(linep, pos.col - 1, '#', NULL)) + && check_prevcol(linep, pos.col - 1, '#', NULL)) { break; + } /* Check for match outside of quotes, and inside of * quotes when the start is also inside of quotes. */ @@ -2224,17 +2278,19 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) int col, bslcnt = 0; if (!cpo_bsl) { - for (col = pos.col; check_prevcol(linep, col, '\\', &col); ) + for (col = pos.col; check_prevcol(linep, col, '\\', &col); ) { bslcnt++; + } } /* Only accept a match when 'M' is in 'cpo' or when escaping * is what we expect. */ if (cpo_bsl || (bslcnt & 1) == match_escaped) { - if (c == initc) + if (c == initc) { count++; - else { - if (count == 0) + } else { + if (count == 0) { return &pos; + } count--; } } @@ -2246,7 +2302,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel) pos = match_pos; return &pos; } - return (pos_T *)NULL; /* never found it */ + return (pos_T *)NULL; // never found it } /* @@ -2279,34 +2335,35 @@ static int check_linecomment(const char_u *line) } p++; } - } else + } else { p = NULL; - } else + } + } else { while ((p = vim_strchr(p, '/')) != NULL) { /* accept a double /, unless it's preceded with * and followed by *, * because * / / * is an end and start of a C comment */ - if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')) + if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')) { break; + } ++p; } + } - if (p == NULL) + if (p == NULL) { return MAXCOL; + } return (int)(p - line); } -/* - * Move cursor briefly to character matching the one under the cursor. - * Used for Insert mode and "r" command. - * Show the match only if it is visible on the screen. - * If there isn't a match, then beep. - */ -void -showmatch( - int c // char to show match for -) +/// Move cursor briefly to character matching the one under the cursor. +/// Used for Insert mode and "r" command. +/// Show the match only if it is visible on the screen. +/// If there isn't a match, then beep. +/// +/// @param c char to show match for +void showmatch(int c) { - pos_T *lpos, save_cursor; + pos_T *lpos, save_cursor; pos_T mpos; colnr_T vcol; long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; @@ -2315,15 +2372,16 @@ showmatch( long save_siso; int save_state; colnr_T save_dollar_vcol; - char_u *p; + char_u *p; /* * Only show match for chars in the 'matchpairs' option. */ - /* 'matchpairs' is "x:y,x:y" */ + // 'matchpairs' is "x:y,x:y" for (p = curbuf->b_p_mps; *p != NUL; ++p) { - if (PTR2CHAR(p) == c && (curwin->w_p_rl ^ p_ri)) + if (PTR2CHAR(p) == c && (curwin->w_p_rl ^ p_ri)) { break; + } p += utfc_ptr2len(p) + 1; if (PTR2CHAR(p) == c && !(curwin->w_p_rl ^ p_ri)) { break; @@ -2340,7 +2398,7 @@ showmatch( if ((lpos = findmatch(NULL, NUL)) == NULL) { // no match, so beep vim_beep(BO_MATCH); } else if (lpos->lnum >= curwin->w_topline - && lpos->lnum < curwin->w_botline) { + && lpos->lnum < curwin->w_botline) { if (!curwin->w_p_wrap) { getvcol(curwin, lpos, NULL, &vcol, NULL); } @@ -2405,10 +2463,11 @@ int findsent(Direction dir, long count) bool noskip = false; // do not skip blanks pos = curwin->w_cursor; - if (dir == FORWARD) + if (dir == FORWARD) { func = incl; - else + } else { func = decl; + } while (count--) { const pos_T prev_pos = pos; @@ -2423,8 +2482,8 @@ int findsent(Direction dir, long count) if (dir == FORWARD) { goto found; } - // if on the start of a paragraph or a section and searching forward, - // go to the next line + // if on the start of a paragraph or a section and searching forward, + // go to the next line } else if (dir == FORWARD && pos.col == 0 && startPS(pos.lnum, NUL, false)) { if (pos.lnum == curbuf->b_ml.ml_line_count) { @@ -2447,11 +2506,11 @@ int findsent(Direction dir, long count) if (found_dot) { break; } - if (vim_strchr((char_u *) ".!?", c) != NULL) { + 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) { + if (vim_strchr((char_u *)")]\"'", c) != NULL + && vim_strchr((char_u *)".!?)]\"'", gchar_pos(&tpos)) == NULL) { break; } decl(&pos); @@ -2461,41 +2520,47 @@ int findsent(Direction dir, long count) const int startlnum = pos.lnum; const bool cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL; - for (;; ) { /* find end of sentence */ + for (;; ) { // find end of sentence c = gchar_pos(&pos); if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE))) { - if (dir == BACKWARD && pos.lnum != startlnum) + if (dir == BACKWARD && pos.lnum != startlnum) { ++pos.lnum; + } break; } if (c == '.' || c == '!' || c == '?') { tpos = pos; do - if ((c = inc(&tpos)) == -1) + if ((c = inc(&tpos)) == -1) { break; + } while (vim_strchr((char_u *)")]\"'", c = gchar_pos(&tpos)) != NULL); if (c == -1 || (!cpo_J && (c == ' ' || c == '\t')) || c == NUL || (cpo_J && (c == ' ' && inc(&tpos) >= 0 && gchar_pos(&tpos) == ' '))) { pos = tpos; - if (gchar_pos(&pos) == NUL) /* skip NUL at EOL */ + if (gchar_pos(&pos) == NUL) { // skip NUL at EOL inc(&pos); + } break; } } if ((*func)(&pos) == -1) { - if (count) + if (count) { return FAIL; + } noskip = true; break; } } found: - /* skip white space */ - while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) - if (incl(&pos) == -1) + // skip white space + while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) { + if (incl(&pos) == -1) { break; + } + } if (equalpos(prev_pos, pos)) { // didn't actually move, advance one character and try again @@ -2514,28 +2579,22 @@ found: return OK; } -/* - * Find the next paragraph or section in direction 'dir'. - * Paragraphs are currently supposed to be separated by empty lines. - * If 'what' is NUL we go to the next paragraph. - * If 'what' is '{' or '}' we go to the next section. - * If 'both' is TRUE also stop at '}'. - * Return TRUE if the next paragraph or section was found. - */ -bool -findpar ( - bool *pincl, /* Return: true if last char is to be included */ - int dir, - long count, - int what, - int both -) +/// Find the next paragraph or section in direction 'dir'. +/// Paragraphs are currently supposed to be separated by empty lines. +/// If 'what' is NUL we go to the next paragraph. +/// If 'what' is '{' or '}' we go to the next section. +/// If 'both' is TRUE also stop at '}'. +/// +/// @param pincl Return: true if last char is to be included +/// +/// @return TRUE if the next paragraph or section was found. +bool findpar(bool *pincl, int dir, long count, int what, int both) { linenr_T curr; - bool did_skip; /* true after separating lines have been skipped */ - bool first; /* true on first line */ - linenr_T fold_first; /* first line of a closed fold */ - linenr_T fold_last; /* last line of a closed fold */ + bool did_skip; // true after separating lines have been skipped + bool first; // true on first line + linenr_T fold_first; // first line of a closed fold + linenr_T fold_last; // last line of a closed fold bool fold_skipped; /* true if a closed fold was skipped this iteration */ @@ -2544,32 +2603,37 @@ findpar ( while (count--) { did_skip = false; for (first = true;; first = false) { - if (*ml_get(curr) != NUL) + if (*ml_get(curr) != NUL) { did_skip = true; + } - /* skip folded lines */ + // skip folded lines fold_skipped = false; if (first && hasFolding(curr, &fold_first, &fold_last)) { curr = ((dir > 0) ? fold_last : fold_first) + dir; fold_skipped = true; } - if (!first && did_skip && startPS(curr, what, both)) + if (!first && did_skip && startPS(curr, what, both)) { break; + } - if (fold_skipped) + if (fold_skipped) { curr -= dir; + } if ((curr += dir) < 1 || curr > curbuf->b_ml.ml_line_count) { - if (count) + if (count) { return false; + } curr -= dir; break; } } } setpcmark(); - if (both && *ml_get(curr) == '}') /* include line with '}' */ + if (both && *ml_get(curr) == '}') { // include line with '}' ++curr; + } curwin->w_cursor.lnum = curr; if (curr == curbuf->b_ml.ml_line_count && what != '}') { char_u *line = ml_get(curr); @@ -2581,8 +2645,9 @@ findpar ( curwin->w_cursor.col -= utf_head_off(line, line + curwin->w_cursor.col); *pincl = true; } - } else + } else { curwin->w_cursor.col = 0; + } return true; } @@ -2591,7 +2656,7 @@ findpar ( */ static int inmacro(char_u *opt, char_u *s) { - char_u *macro; + char_u *macro; for (macro = opt; macro[0]; ++macro) { /* Accept two characters in the option being equal to two characters @@ -2602,11 +2667,13 @@ static int inmacro(char_u *opt, char_u *s) && (s[0] == NUL || s[0] == ' '))) && (macro[1] == s[1] || ((macro[1] == NUL || macro[1] == ' ') - && (s[0] == NUL || s[1] == NUL || s[1] == ' ')))) + && (s[0] == NUL || s[1] == NUL || s[1] == ' ')))) { break; + } ++macro; - if (macro[0] == NUL) + if (macro[0] == NUL) { break; + } } return macro[0] != NUL; } @@ -2618,7 +2685,7 @@ static int inmacro(char_u *opt, char_u *s) */ int startPS(linenr_T lnum, int para, int both) { - char_u *s; + char_u *s; s = ml_get(lnum); if (*s == para || *s == '\f' || (both && *s == '}')) { @@ -2647,7 +2714,7 @@ int startPS(linenr_T lnum, int para, int both) * 2 or higher - keyword characters (letters, digits and underscore) */ -static int cls_bigword; /* TRUE for "W", "B" or "E" */ +static int cls_bigword; // TRUE for "W", "B" or "E" /* * cls() - returns the class of character at curwin->w_cursor @@ -2674,20 +2741,15 @@ static int cls(void) return c; } -/* - * fwd_word(count, type, eol) - move forward one word - * - * Returns FAIL if the cursor was already at the end of the file. - * If eol is TRUE, last word stops at end of line (for operators). - */ -int -fwd_word( - long count, - int bigword, /* "W", "E" or "B" */ - int eol -) +/// fwd_word(count, type, eol) - move forward one word +/// +/// @return FAIL if the cursor was already at the end of the file. +/// If eol is TRUE, last word stops at end of line (for operators). +/// +/// @param bigword "W", "E" or "B" +int fwd_word(long count, int bigword, int eol) { - int sclass; /* starting class */ + int sclass; // starting class int i; int last_line; @@ -2707,20 +2769,24 @@ fwd_word( */ last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count); i = inc_cursor(); - if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */ + if (i == -1 || (i >= 1 && last_line)) { // started at last char in file return FAIL; - if (i >= 1 && eol && count == 0) /* started at last char in line */ + } + if (i >= 1 && eol && count == 0) { // started at last char in line return OK; + } /* * Go one char past end of current word (if any) */ - if (sclass != 0) + if (sclass != 0) { while (cls() == sclass) { i = inc_cursor(); - if (i == -1 || (i >= 1 && eol && count == 0)) + if (i == -1 || (i >= 1 && eol && count == 0)) { return OK; + } } + } /* * go to next non-white @@ -2729,12 +2795,14 @@ fwd_word( /* * We'll stop if we land on a blank line */ - if (curwin->w_cursor.col == 0 && *get_cursor_line_ptr() == NUL) + if (curwin->w_cursor.col == 0 && *get_cursor_line_ptr() == NUL) { break; + } i = inc_cursor(); - if (i == -1 || (i >= 1 && eol && count == 0)) + if (i == -1 || (i >= 1 && eol && count == 0)) { return OK; + } } } return OK; @@ -2749,18 +2817,20 @@ fwd_word( */ int bck_word(long count, int bigword, int stop) { - int sclass; /* starting class */ + int sclass; // starting class curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { /* When inside a range of folded lines, move to the first char of the * first line. */ - if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL)) + if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL)) { curwin->w_cursor.col = 0; + } sclass = cls(); - if (dec_cursor() == -1) /* started at start of file */ + if (dec_cursor() == -1) { // started at start of file return FAIL; + } if (!stop || sclass == cls() || sclass == 0) { /* @@ -2780,11 +2850,12 @@ int bck_word(long count, int bigword, int stop) /* * Move backward to start of this word. */ - if (skip_chars(cls(), BACKWARD)) + if (skip_chars(cls(), BACKWARD)) { return OK; + } } - inc_cursor(); /* overshot - forward one */ + inc_cursor(); // overshot - forward one finished: stop = FALSE; } @@ -2808,7 +2879,7 @@ finished: */ int end_word(long count, int bigword, int stop, int empty) { - int sclass; /* starting class */ + int sclass; // starting class curwin->w_cursor.coladd = 0; cls_bigword = bigword; @@ -2819,8 +2890,9 @@ int end_word(long count, int bigword, int stop, int empty) coladvance(MAXCOL); } sclass = cls(); - if (inc_cursor() == -1) + if (inc_cursor() == -1) { return FAIL; + } /* * If we're in the middle of a word, we just have to move to the end @@ -2830,8 +2902,9 @@ int end_word(long count, int bigword, int stop, int empty) /* * Move forward to end of the current word */ - if (skip_chars(sclass, FORWARD)) + if (skip_chars(sclass, FORWARD)) { return FAIL; + } } else if (!stop || sclass == 0) { /* * We were at the end of a word. Go to the end of the next word. @@ -2850,12 +2923,13 @@ int end_word(long count, int bigword, int stop, int empty) /* * Move forward to the end of this word. */ - if (skip_chars(cls(), FORWARD)) + if (skip_chars(cls(), FORWARD)) { return FAIL; + } } - dec_cursor(); /* overshot - one char backward */ + dec_cursor(); // overshot - one char backward finished: - stop = FALSE; /* we move only one word less */ + stop = FALSE; // we move only one word less } return OK; } @@ -2868,25 +2942,29 @@ finished: /// @return FAIL if start of the file was reached. int bckend_word(long count, int bigword, bool eol) { - int sclass; /* starting class */ + int sclass; // starting class int i; curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { sclass = cls(); - if ((i = dec_cursor()) == -1) + if ((i = dec_cursor()) == -1) { return FAIL; - if (eol && i == 1) + } + if (eol && i == 1) { return OK; + } /* * Move backward to before the start of this word. */ if (sclass != 0) { - while (cls() == sclass) - if ((i = dec_cursor()) == -1 || (eol && i == 1)) + while (cls() == sclass) { + if ((i = dec_cursor()) == -1 || (eol && i == 1)) { return OK; + } + } } /* @@ -2922,14 +3000,15 @@ static bool skip_chars(int cclass, int dir) */ static void back_in_line(void) { - int sclass; /* starting class */ + int sclass; // starting class sclass = cls(); for (;; ) { - if (curwin->w_cursor.col == 0) /* stop at start of line */ + if (curwin->w_cursor.col == 0) { // stop at start of line break; + } dec_cursor(); - if (cls() != sclass) { /* stop at start of word */ + if (cls() != sclass) { // stop at start of word inc_cursor(); break; } @@ -2956,25 +3035,22 @@ static void findsent_forward(long count, bool at_start_sent) { while (count--) { findsent(FORWARD, 1L); - if (at_start_sent) + if (at_start_sent) { find_first_blank(&curwin->w_cursor); - if (count == 0 || at_start_sent) + } + if (count == 0 || at_start_sent) { decl(&curwin->w_cursor); + } at_start_sent = !at_start_sent; } } -/* - * Find word under cursor, cursor at end. - * Used while an operator is pending, and in Visual mode. - */ -int -current_word( - oparg_T *oap, - long count, - int include, /* TRUE: include word and white space */ - int bigword /* FALSE == word, TRUE == WORD */ -) +/// Find word under cursor, cursor at end. +/// Used while an operator is pending, and in Visual mode. +/// +/// @param include TRUE: include word and white space +/// @param bigword FALSE == word, TRUE == WORD +int current_word(oparg_T *oap, long count, int include, int bigword) { pos_T start_pos; pos_T pos; @@ -2984,9 +3060,10 @@ current_word( cls_bigword = bigword; clearpos(&start_pos); - /* Correct cursor when 'selection' is exclusive */ - if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) + // Correct cursor when 'selection' is exclusive + if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) { dec_cursor(); + } /* * When Visual mode is not active, or when the VIsual area is only one @@ -3005,8 +3082,9 @@ current_word( * not be included ("word"), find end of word. */ if ((cls() == 0) == include) { - if (end_word(1L, bigword, TRUE, TRUE) == FAIL) + if (end_word(1L, bigword, TRUE, TRUE) == FAIL) { return FAIL; + } } else { /* * If the start is not on white space, and white space should be @@ -3016,19 +3094,21 @@ current_word( * word) back up to end of the line. */ fwd_word(1L, bigword, TRUE); - if (curwin->w_cursor.col == 0) + if (curwin->w_cursor.col == 0) { decl(&curwin->w_cursor); - else + } else { oneleft(); + } - if (include) + if (include) { include_white = TRUE; + } } if (VIsual_active) { - /* should do something when inclusive == false ! */ + // should do something when inclusive == false ! VIsual = start_pos; - redraw_curbuf_later(INVERTED); /* update the inversion */ + redraw_curbuf_later(INVERTED); // update the inversion } else { oap->start = start_pos; oap->motion_type = kMTCharWise; @@ -3045,11 +3125,13 @@ current_word( /* * In Visual mode, with cursor at start: move cursor back. */ - if (decl(&curwin->w_cursor) == -1) + if (decl(&curwin->w_cursor) == -1) { return FAIL; + } if (include != (cls() != 0)) { - if (bck_word(1L, bigword, TRUE) == FAIL) + if (bck_word(1L, bigword, TRUE) == FAIL) { return FAIL; + } } else { if (bckend_word(1L, bigword, true) == FAIL) { return FAIL; @@ -3060,21 +3142,25 @@ current_word( /* * Move cursor forward one word and/or white area. */ - if (incl(&curwin->w_cursor) == -1) + if (incl(&curwin->w_cursor) == -1) { return FAIL; + } if (include != (cls() == 0)) { - if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1) + if (fwd_word(1L, bigword, TRUE) == FAIL && count > 1) { return FAIL; + } /* * If end is just past a new-line, we don't want to include * the first character on the line. * Put cursor on last char of white. */ - if (oneleft() == FAIL) + if (oneleft() == FAIL) { inclusive = false; + } } else { - if (end_word(1L, bigword, TRUE, TRUE) == FAIL) + if (end_word(1L, bigword, TRUE, TRUE) == FAIL) { return FAIL; + } } } --count; @@ -3090,29 +3176,32 @@ current_word( * (cursor is at start of next line). * But don't delete white space at start of line (indent). */ - pos = curwin->w_cursor; /* save cursor position */ + pos = curwin->w_cursor; // save cursor position curwin->w_cursor = start_pos; if (oneleft() == OK) { back_in_line(); if (cls() == 0 && curwin->w_cursor.col > 0) { - if (VIsual_active) + if (VIsual_active) { VIsual = curwin->w_cursor; - else + } else { oap->start = curwin->w_cursor; + } } } - curwin->w_cursor = pos; /* put cursor back at end */ + curwin->w_cursor = pos; // put cursor back at end } if (VIsual_active) { - if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor)) + if (*p_sel == 'e' && inclusive && ltoreq(VIsual, curwin->w_cursor)) { inc_cursor(); + } if (VIsual_mode == 'V') { VIsual_mode = 'v'; redraw_cmdline = true; // show mode later } - } else + } else { oap->inclusive = inclusive; + } return OK; } @@ -3132,7 +3221,7 @@ int current_sent(oparg_T *oap, long count, int include) start_pos = curwin->w_cursor; pos = start_pos; - findsent(FORWARD, 1L); /* Find start of next sentence. */ + findsent(FORWARD, 1L); // Find start of next sentence. /* * When the Visual area is bigger than one character: Extend it. @@ -3166,14 +3255,17 @@ extend: findsent(FORWARD, 1L); } } - if (include) /* "as" gets twice as much as "is" */ + if (include) { // "as" gets twice as much as "is" count *= 2; + } while (count--) { - if (at_start_sent) + if (at_start_sent) { find_first_blank(&curwin->w_cursor); + } c = gchar_cursor(); - if (!at_start_sent || (!include && !ascii_iswhite(c))) + if (!at_start_sent || (!include && !ascii_iswhite(c))) { findsent(BACKWARD, 1L); + } at_start_sent = !at_start_sent; } } else { @@ -3196,17 +3288,20 @@ extend: } incl(&pos); } - if (at_start_sent) /* in the sentence */ + if (at_start_sent) { // in the sentence findsent(BACKWARD, 1L); - else /* in/before white before a sentence */ + } else { // in/before white before a sentence curwin->w_cursor = start_pos; + } } - if (include) /* "as" gets twice as much as "is" */ + if (include) { // "as" gets twice as much as "is" count *= 2; + } findsent_forward(count, at_start_sent); - if (*p_sel == 'e') + if (*p_sel == 'e') { ++curwin->w_cursor.col; + } } return OK; } @@ -3215,8 +3310,9 @@ extend: * If the cursor started on a blank, check if it is just before the start * of the next sentence. */ - while (c = gchar_pos(&pos), ascii_iswhite(c)) + while (c = gchar_pos(&pos), ascii_iswhite(c)) { incl(&pos); + } if (equalpos(pos, curwin->w_cursor)) { start_blank = true; find_first_blank(&start_pos); // go back to first blank @@ -3225,12 +3321,13 @@ extend: findsent(BACKWARD, 1L); start_pos = curwin->w_cursor; } - if (include) + if (include) { ncount = count * 2; - else { + } else { ncount = count; - if (start_blank) + if (start_blank) { --ncount; + } } if (ncount > 0) { findsent_forward(ncount, true); @@ -3247,57 +3344,57 @@ extend: if (start_blank) { find_first_blank(&curwin->w_cursor); c = gchar_pos(&curwin->w_cursor); - if (ascii_iswhite(c)) + if (ascii_iswhite(c)) { decl(&curwin->w_cursor); - } else if (c = gchar_cursor(), !ascii_iswhite(c)) + } + } else if (c = gchar_cursor(), !ascii_iswhite(c)) { find_first_blank(&start_pos); + } } if (VIsual_active) { - /* Avoid getting stuck with "is" on a single space before a sentence. */ - if (equalpos(start_pos, curwin->w_cursor)) + // Avoid getting stuck with "is" on a single space before a sentence. + if (equalpos(start_pos, curwin->w_cursor)) { goto extend; - if (*p_sel == 'e') + } + if (*p_sel == 'e') { ++curwin->w_cursor.col; + } VIsual = start_pos; VIsual_mode = 'v'; redraw_cmdline = true; // show mode later redraw_curbuf_later(INVERTED); // update the inversion } else { - /* include a newline after the sentence, if there is one */ - if (incl(&curwin->w_cursor) == -1) + // include a newline after the sentence, if there is one + if (incl(&curwin->w_cursor) == -1) { oap->inclusive = true; - else + } else { oap->inclusive = false; + } oap->start = start_pos; oap->motion_type = kMTCharWise; } return OK; } -/* - * Find block under the cursor, cursor at end. - * "what" and "other" are two matching parenthesis/brace/etc. - */ -int -current_block( - oparg_T *oap, - long count, - int include, /* TRUE == include white space */ - int what, /* '(', '{', etc. */ - int other /* ')', '}', etc. */ -) +/// Find block under the cursor, cursor at end. +/// "what" and "other" are two matching parenthesis/brace/etc. +/// +/// @param include TRUE == include white space +/// @param what '(', '{', etc. +/// @param other ')', '}', etc. +int current_block(oparg_T *oap, long count, int include, int what, int other) { pos_T old_pos; - pos_T *pos = NULL; + pos_T *pos = NULL; pos_T start_pos; - pos_T *end_pos; + pos_T *end_pos; pos_T old_start, old_end; - char_u *save_cpo; + char_u *save_cpo; bool sol = false; // '{' at start of line old_pos = curwin->w_cursor; - old_end = curwin->w_cursor; /* remember where we started */ + old_end = curwin->w_cursor; // remember where we started old_start = old_end; /* @@ -3305,18 +3402,23 @@ current_block( */ if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) { setpcmark(); - if (what == '{') /* ignore indent */ - while (inindent(1)) - if (inc_cursor() != 0) + if (what == '{') { // ignore indent + while (inindent(1)) { + if (inc_cursor() != 0) { break; - if (gchar_cursor() == what) - /* cursor on '(' or '{', move cursor just after it */ + } + } + } + if (gchar_cursor() == what) { + // cursor on '(' or '{', move cursor just after it ++curwin->w_cursor.col; + } } else if (lt(VIsual, curwin->w_cursor)) { old_start = VIsual; - curwin->w_cursor = VIsual; /* cursor at low end of Visual */ - } else + curwin->w_cursor = VIsual; // cursor at low end of Visual + } else { old_end = VIsual; + } // Search backwards for unclosed '(', '{', etc.. // Put this position in start_pos. @@ -3377,8 +3479,9 @@ current_block( return FAIL; } curwin->w_cursor = *end_pos; - } else + } else { break; + } } if (VIsual_active) { @@ -3390,21 +3493,22 @@ current_block( } VIsual = start_pos; VIsual_mode = 'v'; - redraw_curbuf_later(INVERTED); /* update the inversion */ + redraw_curbuf_later(INVERTED); // update the inversion showmode(); } else { oap->start = start_pos; oap->motion_type = kMTCharWise; oap->inclusive = false; - if (sol) + if (sol) { incl(&curwin->w_cursor); - else if (ltoreq(start_pos, curwin->w_cursor)) - /* Include the character under the cursor. */ + } else if (ltoreq(start_pos, curwin->w_cursor)) { + // Include the character under the cursor. oap->inclusive = true; - else + } else { /* End is before the start (no text in between <>, [], etc.): don't * operate on any text. */ curwin->w_cursor = start_pos; + } } return OK; @@ -3416,8 +3520,8 @@ current_block( /// @return true if the cursor is on a "<aaa>" tag. Ignore "<aaa/>". static bool in_html_tag(bool end_tag) { - char_u *line = get_cursor_line_ptr(); - char_u *p; + char_u *line = get_cursor_line_ptr(); + char_u *p; int c; int lc = NUL; pos_T pos; @@ -3449,36 +3553,32 @@ static bool in_html_tag(bool end_tag) return false; } - /* check that the matching '>' is not preceded by '/' */ + // check that the matching '>' is not preceded by '/' for (;; ) { if (inc(&pos) < 0) { return false; } c = *ml_get_pos(&pos); - if (c == '>') + if (c == '>') { break; + } lc = c; } return lc != '/'; } -/* - * Find tag block under the cursor, cursor at end. - */ -int -current_tagblock( - oparg_T *oap, - long count_arg, - bool include // true == include white space -) +/// Find tag block under the cursor, cursor at end. +/// +/// @param include true == include white space +int current_tagblock(oparg_T *oap, long count_arg, bool include) { long count = count_arg; pos_T old_pos; pos_T start_pos; pos_T end_pos; pos_T old_start, old_end; - char_u *p; - char_u *cp; + char_u *p; + char_u *cp; int len; bool do_include = include; bool save_p_ws = p_ws; @@ -3488,21 +3588,23 @@ current_tagblock( p_ws = false; old_pos = curwin->w_cursor; - old_end = curwin->w_cursor; /* remember where we started */ + old_end = curwin->w_cursor; // remember where we started old_start = old_end; - if (!VIsual_active || *p_sel == 'e') - decl(&old_end); /* old_end is inclusive */ - + if (!VIsual_active || *p_sel == 'e') { + decl(&old_end); // old_end is inclusive + } /* * If we start on "<aaa>" select that block. */ if (!VIsual_active || equalpos(VIsual, curwin->w_cursor)) { setpcmark(); - /* ignore indent */ - while (inindent(1)) - if (inc_cursor() != 0) + // ignore indent + while (inindent(1)) { + if (inc_cursor() != 0) { break; + } + } if (in_html_tag(false)) { // cursor on start tag, move to its '>' @@ -3523,9 +3625,10 @@ current_tagblock( } } else if (lt(VIsual, curwin->w_cursor)) { old_start = VIsual; - curwin->w_cursor = VIsual; /* cursor at low end of Visual */ - } else + curwin->w_cursor = VIsual; // cursor at low end of Visual + } else { old_end = VIsual; + } again: /* @@ -3533,11 +3636,10 @@ again: * Put this position in start_pos. */ for (long n = 0; n < count; n++) { - if (do_searchpair( - "<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)", - "", - "</[^>]*>", BACKWARD, NULL, 0, - NULL, (linenr_T)0, 0L) <= 0) { + if (do_searchpair("<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)", + "", + "</[^>]*>", BACKWARD, NULL, 0, + NULL, (linenr_T)0, 0L) <= 0) { curwin->w_cursor = old_pos; goto theend; } @@ -3603,14 +3705,15 @@ again: end_pos = curwin->w_cursor; if (!do_include) { - /* Exclude the start tag. */ + // Exclude the start tag. curwin->w_cursor = start_pos; - while (inc_cursor() >= 0) + while (inc_cursor() >= 0) { if (*get_cursor_pos_ptr() == '>') { inc_cursor(); start_pos = curwin->w_cursor; break; } + } curwin->w_cursor = end_pos; // If we are in Visual mode and now have the same text as before set @@ -3635,7 +3738,7 @@ again: } VIsual = start_pos; VIsual_mode = 'v'; - redraw_curbuf_later(INVERTED); /* update the inversion */ + redraw_curbuf_later(INVERTED); // update the inversion showmode(); } else { oap->start = start_pos; @@ -3656,13 +3759,9 @@ theend: return retval; } -int -current_par( - oparg_T *oap, - long count, - int include, /* TRUE == include white space */ - int type /* 'p' for paragraph, 'S' for section */ -) +/// @param include TRUE == include white space +/// @param type 'p' for paragraph, 'S' for section +int current_par(oparg_T *oap, long count, int include, int type) { linenr_T start_lnum; linenr_T end_lnum; @@ -3675,8 +3774,9 @@ current_par( int t; int i; - if (type == 'S') /* not implemented yet */ + if (type == 'S') { // not implemented yet return FAIL; + } start_lnum = curwin->w_cursor.lnum; @@ -3685,10 +3785,11 @@ current_par( */ if (VIsual_active && start_lnum != VIsual.lnum) { extend: - if (start_lnum < VIsual.lnum) + if (start_lnum < VIsual.lnum) { dir = BACKWARD; - else + } else { dir = FORWARD; + } for (i = count; --i >= 0; ) { if (start_lnum == (dir == BACKWARD ? 1 : curbuf->b_ml.ml_line_count)) { @@ -3706,20 +3807,24 @@ extend: } for (;; ) { if (start_lnum == (dir == BACKWARD - ? 1 : curbuf->b_ml.ml_line_count)) + ? 1 : curbuf->b_ml.ml_line_count)) { break; + } if (start_is_white != linewhite(start_lnum + dir) || (!start_is_white && startPS(start_lnum + (dir > 0 - ? 1 : 0), 0, 0))) + ? 1 : 0), 0, 0))) { break; + } start_lnum += dir; } - if (!include) + if (!include) { break; + } if (start_lnum == (dir == BACKWARD - ? 1 : curbuf->b_ml.ml_line_count)) + ? 1 : curbuf->b_ml.ml_line_count)) { break; + } prev_start_is_white = start_is_white; } } @@ -3733,12 +3838,14 @@ extend: */ white_in_front = linewhite(start_lnum); while (start_lnum > 1) { - if (white_in_front) { /* stop at first white line */ - if (!linewhite(start_lnum - 1)) + if (white_in_front) { // stop at first white line + if (!linewhite(start_lnum - 1)) { break; - } else { /* stop at first non-white line of start of paragraph */ - if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0)) + } + } else { // stop at first non-white line of start of paragraph + if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0)) { break; + } } --start_lnum; } @@ -3747,19 +3854,23 @@ extend: * Move past the end of any white lines. */ end_lnum = start_lnum; - while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum)) + while (end_lnum <= curbuf->b_ml.ml_line_count && linewhite(end_lnum)) { ++end_lnum; + } --end_lnum; i = count; - if (!include && white_in_front) + if (!include && white_in_front) { --i; + } while (i--) { - if (end_lnum == curbuf->b_ml.ml_line_count) + if (end_lnum == curbuf->b_ml.ml_line_count) { return FAIL; + } - if (!include) + if (!include) { do_white = linewhite(end_lnum + 1); + } if (include || !do_white) { ++end_lnum; @@ -3768,29 +3879,35 @@ extend: */ while (end_lnum < curbuf->b_ml.ml_line_count && !linewhite(end_lnum + 1) - && !startPS(end_lnum + 1, 0, 0)) + && !startPS(end_lnum + 1, 0, 0)) { ++end_lnum; + } } - if (i == 0 && white_in_front && include) + if (i == 0 && white_in_front && include) { break; + } /* * skip to end of white lines after paragraph */ - if (include || do_white) + if (include || do_white) { while (end_lnum < curbuf->b_ml.ml_line_count - && linewhite(end_lnum + 1)) + && linewhite(end_lnum + 1)) { ++end_lnum; + } + } } /* * If there are no empty lines at the end, try to find some empty lines at * the start (unless that has been done already). */ - if (!white_in_front && !linewhite(end_lnum) && include) - while (start_lnum > 1 && linewhite(start_lnum - 1)) + if (!white_in_front && !linewhite(end_lnum) && include) { + while (start_lnum > 1 && linewhite(start_lnum - 1)) { --start_lnum; + } + } if (VIsual_active) { // Problem: when doing "Vipipip" nothing happens in a single white @@ -3799,11 +3916,11 @@ extend: goto extend; } if (VIsual.lnum != start_lnum) { - VIsual.lnum = start_lnum; - VIsual.col = 0; + VIsual.lnum = start_lnum; + VIsual.col = 0; } VIsual_mode = 'V'; - redraw_curbuf_later(INVERTED); /* update the inversion */ + redraw_curbuf_later(INVERTED); // update the inversion showmode(); } else { oap->start.lnum = start_lnum; @@ -3817,19 +3934,14 @@ extend: } -/* - * Search quote char from string line[col]. - * Quote character escaped by one of the characters in "escape" is not counted - * as a quote. - * Returns column number of "quotechar" or -1 when not found. - */ -static int -find_next_quote( - char_u *line, - int col, - int quotechar, - char_u *escape /* escape characters, can be NULL */ -) +/// Search quote char from string line[col]. +/// Quote character escaped by one of the characters in "escape" is not counted +/// as a quote. +/// +/// @param escape escape characters, can be NULL +/// +/// @return column number of "quotechar" or -1 when not found. +static int find_next_quote(char_u *line, int col, int quotechar, char_u *escape) { int c; @@ -3847,19 +3959,14 @@ find_next_quote( return col; } -/* - * Search backwards in "line" from column "col_start" to find "quotechar". - * Quote character escaped by one of the characters in "escape" is not counted - * as a quote. - * Return the found column or zero. - */ -static int -find_prev_quote( - char_u *line, - int col_start, - int quotechar, - char_u *escape /* escape characters, can be NULL */ -) +/// Search backwards in "line" from column "col_start" to find "quotechar". +/// Quote character escaped by one of the characters in "escape" is not counted +/// as a quote. +/// +/// @param escape escape characters, can be NULL +/// +/// @return the found column or zero. +static int find_prev_quote(char_u *line, int col_start, int quotechar, char_u *escape) { int n; @@ -3867,29 +3974,32 @@ find_prev_quote( col_start--; col_start -= utf_head_off(line, line + col_start); n = 0; - if (escape != NULL) + if (escape != NULL) { while (col_start - n > 0 && vim_strchr(escape, - line[col_start - n - 1]) != NULL) + line[col_start - n - 1]) != NULL) { ++n; - if (n & 1) - col_start -= n; /* uneven number of escape chars, skip it */ - else if (line[col_start] == quotechar) + } + } + if (n & 1) { + col_start -= n; // uneven number of escape chars, skip it + } else if (line[col_start] == + quotechar) { break; + } } return col_start; } -// Find quote under the cursor, cursor at end. -// Returns true if found, else false. -bool current_quote( - oparg_T *oap, - long count, - bool include, // true == include quote char - int quotechar // Quote character -) +/// Find quote under the cursor, cursor at end. +/// +/// @param include true == include quote char +/// @param quotechar Quote character +/// +/// @return true if found, else false. +bool current_quote(oparg_T *oap, long count, bool include, int quotechar) FUNC_ATTR_NONNULL_ALL { - char_u *line = get_cursor_line_ptr(); + char_u *line = get_cursor_line_ptr(); int col_end; int col_start = curwin->w_cursor.col; bool inclusive = false; @@ -3907,7 +4017,7 @@ bool current_quote( if (VIsual_active) { // this only works within one line if (VIsual.lnum != curwin->w_cursor.lnum) { - return false; + return false; } vis_bef_curs = lt(VIsual, curwin->w_cursor); @@ -3952,12 +4062,13 @@ bool current_quote( col_end = VIsual.col; } - /* Find out if we have a quote in the selection. */ - while (i <= col_end) + // Find out if we have a quote in the selection. + while (i <= col_end) { if (line[i++] == quotechar) { selected_quote = true; break; } + } } if (!vis_empty && line[col_start] == quotechar) { @@ -3971,9 +4082,9 @@ bool current_quote( goto abort_search; } col_end = find_next_quote(line, col_start + 1, quotechar, - curbuf->b_p_qe); + curbuf->b_p_qe); if (col_end < 0) { - /* We were on a starting quote perhaps? */ + // We were on a starting quote perhaps? col_end = col_start; col_start = curwin->w_cursor.col; } @@ -3983,23 +4094,23 @@ bool current_quote( goto abort_search; } col_start = find_prev_quote(line, col_end, quotechar, - curbuf->b_p_qe); + curbuf->b_p_qe); if (line[col_start] != quotechar) { - /* We were on an ending quote perhaps? */ + // We were on an ending quote perhaps? col_start = col_end; col_end = curwin->w_cursor.col; } } } else if (line[col_start] == quotechar - || !vis_empty - ) { + || !vis_empty) { int first_col = col_start; if (!vis_empty) { - if (vis_bef_curs) + if (vis_bef_curs) { first_col = find_next_quote(line, col_start, quotechar, NULL); - else + } else { first_col = find_prev_quote(line, col_start, quotechar, NULL); + } } /* The cursor is on a quote, we don't know if it's the opening or * closing quote. Search from the start of the line to find out. @@ -4007,14 +4118,14 @@ bool current_quote( * in between two strings. */ col_start = 0; for (;; ) { - /* Find open quote character. */ + // Find open quote character. col_start = find_next_quote(line, col_start, quotechar, NULL); if (col_start < 0 || col_start > first_col) { goto abort_search; } // Find close quote character. col_end = find_next_quote(line, col_start + 1, quotechar, - curbuf->b_p_qe); + curbuf->b_p_qe); if (col_end < 0) { goto abort_search; } @@ -4026,17 +4137,17 @@ bool current_quote( col_start = col_end + 1; } } else { - /* Search backward for a starting quote. */ + // Search backward for a starting quote. col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe); if (line[col_start] != quotechar) { - /* No quote before the cursor, look after the cursor. */ + // No quote before the cursor, look after the cursor. col_start = find_next_quote(line, col_start, quotechar, NULL); if (col_start < 0) { goto abort_search; } } - /* Find close quote character. */ + // Find close quote character. col_end = find_next_quote(line, col_start + 1, quotechar, curbuf->b_p_qe); if (col_end < 0) { @@ -4047,20 +4158,23 @@ bool current_quote( // When "include" is true, include spaces after closing quote or before // the starting quote. if (include) { - if (ascii_iswhite(line[col_end + 1])) - while (ascii_iswhite(line[col_end + 1])) + if (ascii_iswhite(line[col_end + 1])) { + while (ascii_iswhite(line[col_end + 1])) { ++col_end; - else - while (col_start > 0 && ascii_iswhite(line[col_start - 1])) + } + } else { + while (col_start > 0 && ascii_iswhite(line[col_start - 1])) { --col_start; + } + } } /* Set start position. After vi" another i" must include the ". * For v2i" include the quotes. */ if (!include && count < 2 - && (vis_empty || !inside_quotes) - ) + && (vis_empty || !inside_quotes)) { ++col_start; + } curwin->w_cursor.col = col_start; if (VIsual_active) { /* Set the start of the Visual area when the Visual area was empty, we @@ -4082,13 +4196,14 @@ bool current_quote( oap->motion_type = kMTCharWise; } - /* Set end position. */ + // Set end position. curwin->w_cursor.col = col_end; if ((include || count > 1 - /* After vi" another i" must include the ". */ + // After vi" another i" must include the ". || (!vis_empty && inside_quotes) - ) && inc_cursor() == 2) + ) && inc_cursor() == 2) { inclusive = true; + } if (VIsual_active) { if (vis_empty || vis_bef_curs) { // decrement cursor when 'selection' is not exclusive @@ -4114,7 +4229,7 @@ bool current_quote( redraw_cmdline = true; // show mode later } } else { - /* Set inclusive and other oap's flags. */ + // Set inclusive and other oap's flags. oap->inclusive = inclusive; } @@ -4126,10 +4241,10 @@ abort_search: inc_cursor(); } if (restore_vis_bef) { - pos_T t = curwin->w_cursor; + pos_T t = curwin->w_cursor; - curwin->w_cursor = VIsual; - VIsual = t; + curwin->w_cursor = VIsual; + VIsual = t; } } return false; @@ -4137,22 +4252,19 @@ abort_search: -/* - * Find next search match under cursor, cursor at end. - * Used while an operator is pending, and in Visual mode. - */ -int -current_search( - long count, - bool forward // true for forward, false for backward -) +/// Find next search match under cursor, cursor at end. +/// Used while an operator is pending, and in Visual mode. +/// +/// @param forward true for forward, false for backward +int current_search(long count, bool forward) { bool old_p_ws = p_ws; pos_T save_VIsual = VIsual; - /* Correct cursor when 'selection' is exclusive */ - if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) + // Correct cursor when 'selection' is exclusive + if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor)) { dec_cursor(); + } pos_T end_pos; // end position of the pattern match pos_T orig_pos; // position of the cursor at beginning @@ -4162,7 +4274,7 @@ current_search( // When searching forward and the cursor is at the start of the Visual // area, skip the first search backward, otherwise it doesn't move. const bool skip_first_backward = forward && VIsual_active - && lt(curwin->w_cursor, VIsual); + && lt(curwin->w_cursor, VIsual); orig_pos = pos = curwin->w_cursor; if (VIsual_active) { @@ -4220,8 +4332,9 @@ current_search( // selection works. if (i == 1 && !result) { // not found, abort */ curwin->w_cursor = orig_pos; - if (VIsual_active) + if (VIsual_active) { VIsual = save_VIsual; + } return FAIL; } else if (i == 0 && !result) { if (forward) { // try again from start of buffer @@ -4229,8 +4342,7 @@ current_search( } else { // try again from end of buffer // searching backwards, so set pos to last line and col pos.lnum = curwin->w_buffer->b_ml.ml_line_count; - pos.col = (colnr_T)STRLEN( - ml_get(curwin->w_buffer->b_ml.ml_line_count)); + pos.col = (colnr_T)STRLEN(ml_get(curwin->w_buffer->b_ml.ml_line_count)); } } } @@ -4283,8 +4395,7 @@ current_search( /// else from position "cur". /// "direction" is FORWARD or BACKWARD. /// Returns TRUE, FALSE or -1 for failure. -static int -is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction) +static int is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction) { regmmatch_T regmatch; int nmatched = 0; @@ -4298,8 +4409,9 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction) } if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH, - SEARCH_KEEP, ®match) == FAIL) + SEARCH_KEEP, ®match) == FAIL) { return -1; + } // init startcol correctly regmatch.startpos[0].col = -1; @@ -4346,7 +4458,7 @@ is_zero_width(char_u *pattern, int move, pos_T *cur, Direction direction) */ int linewhite(linenr_T lnum) { - char_u *p; + char_u *p; p = skipwhite(ml_get(lnum)); return *p == NUL; @@ -4354,64 +4466,63 @@ int linewhite(linenr_T lnum) // Add the search count "[3/19]" to "msgbuf". // See update_search_stat() for other arguments. -static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, - bool show_top_bot_msg, char_u *msgbuf, - bool recompute, int maxcount, long timeout) +static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, bool show_top_bot_msg, + char_u *msgbuf, bool recompute, int maxcount, long timeout) { - searchstat_T stat; - - update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount, - timeout); - if (stat.cur > 0) { - char t[SEARCH_STAT_BUF_LEN]; - - if (curwin->w_p_rl && *curwin->w_p_rlc == 's') { - if (stat.incomplete == 1) { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]"); - } else if (stat.cnt > maxcount && stat.cur > maxcount) { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]", - maxcount, maxcount); - } else if (stat.cnt > maxcount) { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]", - maxcount, stat.cur); - } else { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]", - stat.cnt, stat.cur); - } + searchstat_T stat; + + update_search_stat(dirc, pos, cursor_pos, &stat, recompute, maxcount, + timeout); + if (stat.cur > 0) { + char t[SEARCH_STAT_BUF_LEN]; + + if (curwin->w_p_rl && *curwin->w_p_rlc == 's') { + if (stat.incomplete == 1) { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]"); + } else if (stat.cnt > maxcount && stat.cur > maxcount) { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]", + maxcount, maxcount); + } else if (stat.cnt > maxcount) { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/%d]", + maxcount, stat.cur); } else { - if (stat.incomplete == 1) { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]"); - } else if (stat.cnt > maxcount && stat.cur > maxcount) { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]", - maxcount, maxcount); - } else if (stat.cnt > maxcount) { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]", - stat.cur, maxcount); - } else { - vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]", - stat.cur, stat.cnt); - } + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]", + stat.cnt, stat.cur); } - - size_t len = strlen(t); - if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) { - memmove(t + 2, t, len); - t[0] = 'W'; - t[1] = ' '; - len += 2; + } else { + if (stat.incomplete == 1) { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[?/??]"); + } else if (stat.cnt > maxcount && stat.cur > maxcount) { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[>%d/>%d]", + maxcount, maxcount); + } else if (stat.cnt > maxcount) { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/>%d]", + stat.cur, maxcount); + } else { + vim_snprintf(t, SEARCH_STAT_BUF_LEN, "[%d/%d]", + stat.cur, stat.cnt); } + } - memmove(msgbuf + STRLEN(msgbuf) - len, t, len); - if (dirc == '?' && stat.cur == maxcount + 1) { - stat.cur = -1; - } + size_t len = strlen(t); + if (show_top_bot_msg && len + 2 < SEARCH_STAT_BUF_LEN) { + memmove(t + 2, t, len); + t[0] = 'W'; + t[1] = ' '; + len += 2; + } - // keep the message even after redraw, but don't put in history - msg_hist_off = true; - msg_ext_set_kind("search_count"); - give_warning(msgbuf, false); - msg_hist_off = false; + memmove(msgbuf + STRLEN(msgbuf) - len, t, len); + if (dirc == '?' && stat.cur == maxcount + 1) { + stat.cur = -1; } + + // keep the message even after redraw, but don't put in history + msg_hist_off = true; + msg_ext_set_kind("search_count"); + give_warning(msgbuf, false); + msg_hist_off = false; + } } // Add the search count information to "stat". @@ -4420,258 +4531,253 @@ static void cmdline_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, // dirc == 0: don't find the next/previous match (only set the result to "stat") // dirc == '/': find the next match // dirc == '?': find the previous match -static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, - searchstat_T *stat, bool recompute, int maxcount, - long timeout) +static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchstat_T *stat, + bool recompute, int maxcount, long timeout) { - int save_ws = p_ws; - bool wraparound = false; - pos_T p = (*pos); - static pos_T lastpos = { 0, 0, 0 }; - static int cur = 0; - static int cnt = 0; - static bool exact_match = false; - static int incomplete = 0; - static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT; - static int chgtick = 0; - static char_u *lastpat = NULL; - static buf_T *lbuf = NULL; - proftime_T start; - - memset(stat, 0, sizeof(searchstat_T)); - - if (dirc == 0 && !recompute && !EMPTY_POS(lastpos)) { - stat->cur = cur; - stat->cnt = cnt; - stat->exact_match = exact_match; - stat->incomplete = incomplete; - stat->last_maxcount = last_maxcount; - return; - } - last_maxcount = maxcount; - wraparound = ((dirc == '?' && lt(lastpos, p)) - || (dirc == '/' && lt(p, lastpos))); - - // If anything relevant changed the count has to be recomputed. - // STRNICMP ignores case, but we should not ignore case. - // Unfortunately, there is no STRNICMP function. - // XXX: above comment should be "no MB_STRCMP function" ? - if (!(chgtick == buf_get_changedtick(curbuf) - && lastpat != NULL // suppress clang/NULL passed as nonnull parameter - && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0 - && STRLEN(lastpat) == STRLEN(spats[last_idx].pat) - && equalpos(lastpos, *cursor_pos) - && lbuf == curbuf) - || wraparound || cur < 0 || (maxcount > 0 && cur > maxcount) - || recompute) { - cur = 0; - cnt = 0; - exact_match = false; - incomplete = 0; - clearpos(&lastpos); - lbuf = curbuf; - } - - if (equalpos(lastpos, *cursor_pos) && !wraparound - && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) { - cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1; - } else { - bool done_search = false; - pos_T endpos = { 0, 0, 0 }; - p_ws = false; - if (timeout > 0) { - start = profile_setlimit(timeout); - } - while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos, - FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST, - NULL) != FAIL) { - done_search = true; - // Stop after passing the time limit. - if (timeout > 0 && profile_passed_limit(start)) { - incomplete = 1; - break; - } - cnt++; - if (ltoreq(lastpos, p)) { - cur = cnt; - if (lt(p, endpos)) { - exact_match = true; - } - } - fast_breakcheck(); - if (maxcount > 0 && cnt > maxcount) { - incomplete = 2; // max count exceeded - break; - } - } - if (got_int) { - cur = -1; // abort - } - if (done_search) { - xfree(lastpat); - lastpat = vim_strsave(spats[last_idx].pat); - chgtick = buf_get_changedtick(curbuf); - lbuf = curbuf; - lastpos = p; - } - } + int save_ws = p_ws; + bool wraparound = false; + pos_T p = (*pos); + static pos_T lastpos = { 0, 0, 0 }; + static int cur = 0; + static int cnt = 0; + static bool exact_match = false; + static int incomplete = 0; + static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT; + static int chgtick = 0; + static char_u *lastpat = NULL; + static buf_T *lbuf = NULL; + proftime_T start; + + memset(stat, 0, sizeof(searchstat_T)); + + if (dirc == 0 && !recompute && !EMPTY_POS(lastpos)) { stat->cur = cur; stat->cnt = cnt; stat->exact_match = exact_match; stat->incomplete = incomplete; stat->last_maxcount = last_maxcount; - p_ws = save_ws; + return; + } + last_maxcount = maxcount; + wraparound = ((dirc == '?' && lt(lastpos, p)) + || (dirc == '/' && lt(p, lastpos))); + + // If anything relevant changed the count has to be recomputed. + // STRNICMP ignores case, but we should not ignore case. + // Unfortunately, there is no STRNICMP function. + // XXX: above comment should be "no MB_STRCMP function" ? + if (!(chgtick == buf_get_changedtick(curbuf) + && lastpat != NULL // suppress clang/NULL passed as nonnull parameter + && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0 + && STRLEN(lastpat) == STRLEN(spats[last_idx].pat) + && equalpos(lastpos, *cursor_pos) + && lbuf == curbuf) + || wraparound || cur < 0 || (maxcount > 0 && cur > maxcount) + || recompute) { + cur = 0; + cnt = 0; + exact_match = false; + incomplete = 0; + clearpos(&lastpos); + lbuf = curbuf; + } + + if (equalpos(lastpos, *cursor_pos) && !wraparound + && (dirc == 0 || dirc == '/' ? cur < cnt : cur > 0)) { + cur += dirc == 0 ? 0 : dirc == '/' ? 1 : -1; + } else { + bool done_search = false; + pos_T endpos = { 0, 0, 0 }; + p_ws = false; + if (timeout > 0) { + start = profile_setlimit(timeout); + } + while (!got_int && searchit(curwin, curbuf, &lastpos, &endpos, + FORWARD, NULL, 1, SEARCH_KEEP, RE_LAST, + NULL) != FAIL) { + done_search = true; + // Stop after passing the time limit. + if (timeout > 0 && profile_passed_limit(start)) { + incomplete = 1; + break; + } + cnt++; + if (ltoreq(lastpos, p)) { + cur = cnt; + if (lt(p, endpos)) { + exact_match = true; + } + } + fast_breakcheck(); + if (maxcount > 0 && cnt > maxcount) { + incomplete = 2; // max count exceeded + break; + } + } + if (got_int) { + cur = -1; // abort + } + if (done_search) { + xfree(lastpat); + lastpat = vim_strsave(spats[last_idx].pat); + chgtick = buf_get_changedtick(curbuf); + lbuf = curbuf; + lastpos = p; + } + } + stat->cur = cur; + stat->cnt = cnt; + stat->exact_match = exact_match; + stat->incomplete = incomplete; + stat->last_maxcount = last_maxcount; + p_ws = save_ws; } // "searchcount()" function void f_searchcount(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - pos_T pos = curwin->w_cursor; - char_u *pattern = NULL; - int maxcount = SEARCH_STAT_DEF_MAX_COUNT; - long timeout = SEARCH_STAT_DEF_TIMEOUT; - bool recompute = true; - searchstat_T stat; + pos_T pos = curwin->w_cursor; + char_u *pattern = NULL; + int maxcount = SEARCH_STAT_DEF_MAX_COUNT; + long timeout = SEARCH_STAT_DEF_TIMEOUT; + bool recompute = true; + searchstat_T stat; - tv_dict_alloc_ret(rettv); + tv_dict_alloc_ret(rettv); - if (shortmess(SHM_SEARCHCOUNT)) { // 'shortmess' contains 'S' flag - recompute = true; - } + if (shortmess(SHM_SEARCHCOUNT)) { // 'shortmess' contains 'S' flag + recompute = true; + } - if (argvars[0].v_type != VAR_UNKNOWN) { - dict_T *dict; - dictitem_T *di; - listitem_T *li; - bool error = false; + if (argvars[0].v_type != VAR_UNKNOWN) { + dict_T *dict; + dictitem_T *di; + listitem_T *li; + bool error = false; - if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) { - EMSG(_(e_dictreq)); + if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL) { + EMSG(_(e_dictreq)); + return; + } + dict = argvars[0].vval.v_dict; + di = tv_dict_find(dict, (const char *)"timeout", -1); + if (di != NULL) { + timeout = (long)tv_get_number_chk(&di->di_tv, &error); + if (error) { return; } - dict = argvars[0].vval.v_dict; - di = tv_dict_find(dict, (const char *)"timeout", -1); - if (di != NULL) { - timeout = (long)tv_get_number_chk(&di->di_tv, &error); - if (error) { - return; - } + } + di = tv_dict_find(dict, (const char *)"maxcount", -1); + if (di != NULL) { + maxcount = (int)tv_get_number_chk(&di->di_tv, &error); + if (error) { + return; } - di = tv_dict_find(dict, (const char *)"maxcount", -1); - if (di != NULL) { - maxcount = (int)tv_get_number_chk(&di->di_tv, &error); - if (error) { - return; - } + } + di = tv_dict_find(dict, (const char *)"recompute", -1); + if (di != NULL) { + recompute = tv_get_number_chk(&di->di_tv, &error); + if (error) { + return; + } + } + di = tv_dict_find(dict, (const char *)"pattern", -1); + if (di != NULL) { + pattern = (char_u *)tv_get_string_chk(&di->di_tv); + if (pattern == NULL) { + return; + } + } + di = tv_dict_find(dict, (const char *)"pos", -1); + if (di != NULL) { + if (di->di_tv.v_type != VAR_LIST) { + EMSG2(_(e_invarg2), "pos"); + return; } - di = tv_dict_find(dict, (const char *)"recompute", -1); - if (di != NULL) { - recompute = tv_get_number_chk(&di->di_tv, &error); + if (tv_list_len(di->di_tv.vval.v_list) != 3) { + EMSG2(_(e_invarg2), "List format should be [lnum, col, off]"); + return; + } + li = tv_list_find(di->di_tv.vval.v_list, 0L); + if (li != NULL) { + pos.lnum = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); if (error) { return; } } - di = tv_dict_find(dict, (const char *)"pattern", -1); - if (di != NULL) { - pattern = (char_u *)tv_get_string_chk(&di->di_tv); - if (pattern == NULL) { + li = tv_list_find(di->di_tv.vval.v_list, 1L); + if (li != NULL) { + pos.col = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error) - 1; + if (error) { return; } } - di = tv_dict_find(dict, (const char *)"pos", -1); - if (di != NULL) { - if (di->di_tv.v_type != VAR_LIST) { - EMSG2(_(e_invarg2), "pos"); - return; - } - if (tv_list_len(di->di_tv.vval.v_list) != 3) { - EMSG2(_(e_invarg2), "List format should be [lnum, col, off]"); + li = tv_list_find(di->di_tv.vval.v_list, 2L); + if (li != NULL) { + pos.coladd = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); + if (error) { return; } - li = tv_list_find(di->di_tv.vval.v_list, 0L); - if (li != NULL) { - pos.lnum = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); - if (error) { - return; - } - } - li = tv_list_find(di->di_tv.vval.v_list, 1L); - if (li != NULL) { - pos.col = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error) - 1; - if (error) { - return; - } - } - li = tv_list_find(di->di_tv.vval.v_list, 2L); - if (li != NULL) { - pos.coladd = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error); - if (error) { - return; - } - } } } + } - save_last_search_pattern(); - if (pattern != NULL) { - if (*pattern == NUL) { - goto the_end; - } - xfree(spats[last_idx].pat); - spats[last_idx].pat = vim_strsave(pattern); - } - if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) { - goto the_end; // the previous pattern was never defined + save_last_search_pattern(); + if (pattern != NULL) { + if (*pattern == NUL) { + goto the_end; } + xfree(spats[last_idx].pat); + spats[last_idx].pat = vim_strsave(pattern); + } + if (spats[last_idx].pat == NULL || *spats[last_idx].pat == NUL) { + goto the_end; // the previous pattern was never defined + } - update_search_stat(0, &pos, &pos, &stat, recompute, maxcount, timeout); + update_search_stat(0, &pos, &pos, &stat, recompute, maxcount, timeout); - tv_dict_add_nr(rettv->vval.v_dict, S_LEN("current"), stat.cur); - tv_dict_add_nr(rettv->vval.v_dict, S_LEN("total"), stat.cnt); - tv_dict_add_nr(rettv->vval.v_dict, S_LEN("exact_match"), stat.exact_match); - tv_dict_add_nr(rettv->vval.v_dict, S_LEN("incomplete"), stat.incomplete); - tv_dict_add_nr(rettv->vval.v_dict, S_LEN("maxcount"), stat.last_maxcount); + tv_dict_add_nr(rettv->vval.v_dict, S_LEN("current"), stat.cur); + tv_dict_add_nr(rettv->vval.v_dict, S_LEN("total"), stat.cnt); + tv_dict_add_nr(rettv->vval.v_dict, S_LEN("exact_match"), stat.exact_match); + tv_dict_add_nr(rettv->vval.v_dict, S_LEN("incomplete"), stat.incomplete); + tv_dict_add_nr(rettv->vval.v_dict, S_LEN("maxcount"), stat.last_maxcount); the_end: - restore_last_search_pattern(); + restore_last_search_pattern(); } -/* - * Find identifiers or defines in included files. - * If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase. - */ -void -find_pattern_in_path( - char_u *ptr, // pointer to search pattern - Direction dir, // direction of expansion - size_t len, // length of search pattern - bool whole, // match whole words only - bool skip_comments, // don't match inside comments - int type, // Type of search; are we looking for a type? - // a macro? - long count, - int action, // What to do when we find it - linenr_T start_lnum, // first line to start searching - linenr_T end_lnum // last line for searching -) +/// Find identifiers or defines in included files. +/// If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase. +/// +/// @param ptr pointer to search pattern +/// @param dir direction of expansion +/// @param len length of search pattern +/// @param whole match whole words only +/// @param skip_comments don't match inside comments +/// @param type Type of search; are we looking for a type? a macro? +/// @param action What to do when we find it +/// @param start_lnum first line to start searching +/// @param end_lnum last line for searching +void find_pattern_in_path(char_u *ptr, Direction dir, size_t len, bool whole, bool skip_comments, + int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum) { - SearchedFile *files; /* Stack of included files */ - SearchedFile *bigger; /* When we need more space */ + SearchedFile *files; // Stack of included files + SearchedFile *bigger; // When we need more space int max_path_depth = 50; long match_count = 1; - char_u *pat; - char_u *new_fname; - char_u *curr_fname = curbuf->b_fname; - char_u *prev_fname = NULL; + char_u *pat; + char_u *new_fname; + char_u *curr_fname = curbuf->b_fname; + char_u *prev_fname = NULL; linenr_T lnum; int depth; - int depth_displayed; /* For type==CHECK_PATH */ + int depth_displayed; // For type==CHECK_PATH int old_files; int already_searched; - char_u *file_line; - char_u *line; - char_u *p; + char_u *file_line; + char_u *line; + char_u *p; char_u save_char; bool define_matched; regmatch_T regmatch; @@ -4681,10 +4787,10 @@ find_pattern_in_path( bool did_show = false; bool found = false; int i; - char_u *already = NULL; - char_u *startp = NULL; - char_u *inc_opt = NULL; - win_T *curwin_save = NULL; + char_u *already = NULL; + char_u *startp = NULL; + char_u *inc_opt = NULL; + win_T *curwin_save = NULL; const int l_g_do_tagpreview = g_do_tagpreview; regmatch.regprog = NULL; @@ -4696,41 +4802,45 @@ find_pattern_in_path( if (type != CHECK_PATH && type != FIND_DEFINE /* when CONT_SOL is set compare "ptr" with the beginning of the line * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */ - && !(compl_cont_status & CONT_SOL) - ) { + && !(compl_cont_status & CONT_SOL)) { pat = xmalloc(len + 5); assert(len <= INT_MAX); sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", (int)len, ptr); - /* ignore case according to p_ic, p_scs and pat */ + // ignore case according to p_ic, p_scs and pat regmatch.rm_ic = ignorecase(pat); regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); xfree(pat); - if (regmatch.regprog == NULL) + if (regmatch.regprog == NULL) { goto fpip_end; + } } inc_opt = (*curbuf->b_p_inc == NUL) ? p_inc : curbuf->b_p_inc; if (*inc_opt != NUL) { incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0); - if (incl_regmatch.regprog == NULL) + if (incl_regmatch.regprog == NULL) { goto fpip_end; - incl_regmatch.rm_ic = FALSE; /* don't ignore case in incl. pat. */ + } + incl_regmatch.rm_ic = FALSE; // don't ignore case in incl. pat. } if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) { def_regmatch.regprog = vim_regcomp(*curbuf->b_p_def == NUL ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0); - if (def_regmatch.regprog == NULL) + if (def_regmatch.regprog == NULL) { goto fpip_end; - def_regmatch.rm_ic = FALSE; /* don't ignore case in define pat. */ + } + def_regmatch.rm_ic = FALSE; // don't ignore case in define pat. } files = xcalloc(max_path_depth, sizeof(SearchedFile)); old_files = max_path_depth; depth = depth_displayed = -1; lnum = start_lnum; - if (end_lnum > curbuf->b_ml.ml_line_count) + if (end_lnum > curbuf->b_ml.ml_line_count) { end_lnum = curbuf->b_ml.ml_line_count; - if (lnum > end_lnum) /* do at least one line */ + } + if (lnum > end_lnum) { // do at least one line lnum = end_lnum; + } line = ml_get(lnum); for (;; ) { @@ -4739,17 +4849,18 @@ find_pattern_in_path( char_u *p_fname = (curr_fname == curbuf->b_fname) ? curbuf->b_ffname : curr_fname; - if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) - /* Use text from '\zs' to '\ze' (or end) of 'include'. */ + if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) { + // Use text from '\zs' to '\ze' (or end) of 'include'. new_fname = find_file_name_in_path(incl_regmatch.startp[0], (size_t)(incl_regmatch.endp[0] - incl_regmatch.startp[0]), FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname); - else - /* Use text after match with 'include'. */ + } else { + // Use text after match with 'include'. new_fname = file_name_in_line(incl_regmatch.endp[0], 0, - FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL); + FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL); + } already_searched = FALSE; if (new_fname != NULL) { // Check whether we have already searched in this file @@ -4794,15 +4905,17 @@ find_pattern_in_path( did_show = true; while (depth_displayed < depth && !got_int) { ++depth_displayed; - for (i = 0; i < depth_displayed; i++) + for (i = 0; i < depth_displayed; i++) { MSG_PUTS(" "); + } msg_home_replace(files[depth_displayed].name); MSG_PUTS(" -->\n"); } if (!got_int) { /* don't display if 'q' typed for "--more--" message */ - for (i = 0; i <= depth_displayed; i++) + for (i = 0; i <= depth_displayed; i++) { MSG_PUTS(" "); + } if (new_fname != NULL) { /* using "new_fname" is more reliable, e.g., when * 'includeexpr' is set. */ @@ -4814,21 +4927,23 @@ find_pattern_in_path( */ if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) { - /* pattern contains \zs, use the match */ + // pattern contains \zs, use the match p = incl_regmatch.startp[0]; i = (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]); } else { - /* find the file name after the end of the match */ + // find the file name after the end of the match for (p = incl_regmatch.endp[0]; - *p && !vim_isfilec(*p); p++) + *p && !vim_isfilec(*p); p++) { ; - for (i = 0; vim_isfilec(p[i]); i++) + } + for (i = 0; vim_isfilec(p[i]); i++) { ; + } } if (i == 0) { - /* Nothing found, use the rest of the line. */ + // Nothing found, use the rest of the line. p = incl_regmatch.endp[0]; i = (int)STRLEN(p); } @@ -4839,8 +4954,9 @@ find_pattern_in_path( --p; ++i; } - if (p[i] == '"' || p[i] == '>') + if (p[i] == '"' || p[i] == '>') { ++i; + } } save_char = p[i]; p[i] = NUL; @@ -4849,29 +4965,32 @@ find_pattern_in_path( } if (new_fname == NULL && action == ACTION_SHOW_ALL) { - if (already_searched) + if (already_searched) { MSG_PUTS(_(" (Already listed)")); - else + } else { MSG_PUTS(_(" NOT FOUND")); + } } } - ui_flush(); /* output each line directly */ + ui_flush(); // output each line directly } if (new_fname != NULL) { - /* Push the new file onto the file stack */ + // Push the new file onto the file stack if (depth + 1 == old_files) { bigger = xmalloc(max_path_depth * 2 * sizeof(SearchedFile)); - for (i = 0; i <= depth; i++) + for (i = 0; i <= depth; i++) { bigger[i] = files[i]; + } for (i = depth + 1; i < old_files + max_path_depth; i++) { bigger[i].fp = NULL; bigger[i].name = NULL; bigger[i].lnum = 0; bigger[i].matched = FALSE; } - for (i = old_files; i < max_path_depth; i++) + for (i = old_files; i < max_path_depth; i++) { bigger[i + max_path_depth] = files[i]; + } old_files += max_path_depth; max_path_depth *= 2; xfree(files); @@ -4898,10 +5017,9 @@ find_pattern_in_path( } else if (p_verbose >= 5) { verbose_enter(); smsg(_("Searching included file %s"), - (char *)new_fname); + (char *)new_fname); verbose_leave(); } - } } } else { @@ -4919,8 +5037,9 @@ search_line: * don't let it match beyond the end of this identifier. */ p = def_regmatch.endp[0]; - while (*p && !vim_iswordc(*p)) + while (*p && !vim_iswordc(*p)) { p++; + } define_matched = true; } @@ -4930,18 +5049,18 @@ search_line: */ if (def_regmatch.regprog == NULL || define_matched) { if (define_matched - || (compl_cont_status & CONT_SOL) - ) { - /* compare the first "len" chars from "ptr" */ + || (compl_cont_status & CONT_SOL)) { + // compare the first "len" chars from "ptr" startp = skipwhite(p); if (p_ic) { matched = !mb_strnicmp(startp, ptr, len); - } - else + } else { matched = !STRNCMP(startp, ptr, len); + } if (matched && define_matched && whole - && vim_iswordc(startp[len])) + && vim_iswordc(startp[len])) { matched = false; + } } else if (regmatch.regprog != NULL && vim_regexec(®match, line, (colnr_T)(p - line))) { matched = true; @@ -4964,7 +5083,7 @@ search_line: */ p = skipwhite(line); if (matched - || (p[0] == '/' && p[1] == '*') || p[0] == '*') + || (p[0] == '/' && p[1] == '*') || p[0] == '*') { for (p = line; *p && p < startp; ++p) { if (matched && p[0] == '/' @@ -4981,6 +5100,7 @@ search_line: p++; } } + } } } } @@ -4988,35 +5108,39 @@ search_line: if (matched) { if (action == ACTION_EXPAND) { bool cont_s_ipos = false; - char_u *aux; + char_u *aux; - if (depth == -1 && lnum == curwin->w_cursor.lnum) + if (depth == -1 && lnum == curwin->w_cursor.lnum) { break; + } found = true; aux = p = startp; if (compl_cont_status & CONT_ADDING) { p += compl_length; - if (vim_iswordp(p)) + if (vim_iswordp(p)) { goto exit_matched; + } p = find_word_start(p); } p = find_word_end(p); i = (int)(p - aux); if ((compl_cont_status & CONT_ADDING) && i == compl_length) { - /* IOSIZE > compl_length, so the STRNCPY works */ + // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); /* Get the next line: when "depth" < 0 from the current * buffer, otherwise from the included file. Jump to * exit_matched when past the last line. */ if (depth < 0) { - if (lnum >= end_lnum) + if (lnum >= end_lnum) { goto exit_matched; + } line = ml_get(++lnum); } else if (vim_fgets(line = file_line, - LSIZE, files[depth].fp)) + LSIZE, files[depth].fp)) { goto exit_matched; + } /* we read a line, set "already" to check this "line" later * if depth >= 0 we'll increase files[depth].lnum far @@ -5026,9 +5150,10 @@ search_line: p = find_word_end(p); if (p > aux) { if (*aux != ')' && IObuff[i-1] != TAB) { - if (IObuff[i-1] != ' ') + if (IObuff[i-1] != ' ') { IObuff[i++] = ' '; - /* IObuf =~ "\(\k\|\i\).* ", thus i >= 2*/ + } + // IObuf =~ "\(\k\|\i\).* ", thus i >= 2 if (p_js && (IObuff[i-2] == '.' || IObuff[i-2] == '?' @@ -5036,9 +5161,10 @@ search_line: IObuff[i++] = ' '; } } - /* copy as much as possible of the new word */ - if (p - aux >= IOSIZE - i) + // copy as much as possible of the new word + if (p - aux >= IOSIZE - i) { p = aux + IOSIZE - i - 1; + } STRNCPY(IObuff + i, aux, p - aux); i += (int)(p - aux); cont_s_ipos = true; @@ -5046,13 +5172,14 @@ search_line: IObuff[i] = NUL; aux = IObuff; - if (i == compl_length) + if (i == compl_length) { goto exit_matched; + } } - const int add_r = ins_compl_add_infercase( - aux, i, p_ic, curr_fname == curbuf->b_fname ? NULL : curr_fname, - dir, cont_s_ipos); + const int add_r = ins_compl_add_infercase(aux, i, p_ic, + curr_fname == curbuf->b_fname ? NULL : curr_fname, + dir, cont_s_ipos); if (add_r == OK) { // if dir was BACKWARD then honor it just once dir = FORWARD; @@ -5065,11 +5192,13 @@ search_line: gotocmdline(true); // cursor at status line } if (curr_fname != prev_fname) { - if (did_show) - msg_putchar('\n'); /* cursor below last one */ - if (!got_int) /* don't display if 'q' typed + if (did_show) { + msg_putchar('\n'); // cursor below last one + } + if (!got_int) { /* don't display if 'q' typed at "--more--" message */ msg_home_replace_hl(curr_fname); + } prev_fname = curr_fname; } did_show = true; @@ -5082,8 +5211,9 @@ search_line: /* Set matched flag for this file and all the ones that * include it */ - for (i = 0; i <= depth; ++i) + for (i = 0; i <= depth; ++i) { files[i].matched = TRUE; + } } else if (--count <= 0) { found = true; if (depth == -1 && lnum == curwin->w_cursor.lnum @@ -5095,14 +5225,15 @@ search_line: (depth == -1) ? &lnum : &files[depth].lnum, 1L); did_show = true; } else { - /* ":psearch" uses the preview window */ + // ":psearch" uses the preview window if (l_g_do_tagpreview != 0) { curwin_save = curwin; prepare_tagpreview(true); } if (action == ACTION_SPLIT) { - if (win_split(0, 0) == FAIL) + if (win_split(0, 0) == FAIL) { break; + } RESET_BINDING(curwin); } if (depth == -1) { @@ -5134,7 +5265,7 @@ search_line: if (l_g_do_tagpreview != 0 && curwin != curwin_save && win_valid(curwin_save)) { - /* Return cursor to where we were */ + // Return cursor to where we were validate_cursor(); redraw_later(curwin, VALID); win_enter(curwin_save, true); @@ -5154,10 +5285,12 @@ exit_matched: } } line_breakcheck(); - if (action == ACTION_EXPAND) + if (action == ACTION_EXPAND) { ins_compl_check_keys(30, false); - if (got_int || compl_interrupted) + } + if (got_int || compl_interrupted) { break; + } /* * Read the next line. When reading an included file and encountering @@ -5172,55 +5305,62 @@ exit_matched: files[old_files].matched = files[depth].matched; --depth; curr_fname = (depth == -1) ? curbuf->b_fname - : files[depth].name; - if (depth < depth_displayed) + : files[depth].name; + if (depth < depth_displayed) { depth_displayed = depth; + } } - if (depth >= 0) { /* we could read the line */ + if (depth >= 0) { // we could read the line files[depth].lnum++; - /* Remove any CR and LF from the line. */ + // Remove any CR and LF from the line. i = (int)STRLEN(line); - if (i > 0 && line[i - 1] == '\n') + if (i > 0 && line[i - 1] == '\n') { line[--i] = NUL; - if (i > 0 && line[i - 1] == '\r') + } + if (i > 0 && line[i - 1] == '\r') { line[--i] = NUL; + } } else if (!already) { - if (++lnum > end_lnum) + if (++lnum > end_lnum) { break; + } line = ml_get(lnum); } already = NULL; } - /* End of big for (;;) loop. */ + // End of big for (;;) loop. - /* Close any files that are still open. */ + // Close any files that are still open. for (i = 0; i <= depth; i++) { fclose(files[i].fp); xfree(files[i].name); } - for (i = old_files; i < max_path_depth; i++) + for (i = old_files; i < max_path_depth; i++) { xfree(files[i].name); + } xfree(files); if (type == CHECK_PATH) { if (!did_show) { - if (action != ACTION_SHOW_ALL) + if (action != ACTION_SHOW_ALL) { MSG(_("All included files were found")); - else + } else { MSG(_("No included files")); + } } } else if (!found - && action != ACTION_EXPAND - ) { - if (got_int || compl_interrupted) + && action != ACTION_EXPAND) { + if (got_int || compl_interrupted) { EMSG(_(e_interr)); - else if (type == FIND_DEFINE) + } else if (type == FIND_DEFINE) { EMSG(_("E388: Couldn't find definition")); - else + } else { EMSG(_("E389: Couldn't find pattern")); + } } - if (action == ACTION_SHOW || action == ACTION_SHOW_ALL) + if (action == ACTION_SHOW || action == ACTION_SHOW_ALL) { msg_end(); + } fpip_end: xfree(file_line); @@ -5229,11 +5369,11 @@ fpip_end: vim_regfree(def_regmatch.regprog); } -static void show_pat_in_path(char_u *line, int type, bool did_show, int action, - FILE *fp, linenr_T *lnum, long count) +static void show_pat_in_path(char_u *line, int type, bool did_show, int action, FILE *fp, + linenr_T *lnum, long count) FUNC_ATTR_NONNULL_ARG(1, 6) { - char_u *p; + char_u *p; if (did_show) { msg_putchar('\n'); // cursor below last one @@ -5246,11 +5386,13 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action, for (;; ) { p = line + STRLEN(line) - 1; if (fp != NULL) { - /* We used fgets(), so get rid of newline at end */ - if (p >= line && *p == '\n') + // We used fgets(), so get rid of newline at end + if (p >= line && *p == '\n') { --p; - if (p >= line && *p == '\r') + } + if (p >= line && *p == '\r') { --p; + } *(p + 1) = NUL; } if (action == ACTION_SHOW_ALL) { @@ -5262,19 +5404,22 @@ static void show_pat_in_path(char_u *line, int type, bool did_show, int action, msg_puts(" "); } msg_prt_line(line, FALSE); - ui_flush(); /* show one line at a time */ + ui_flush(); // show one line at a time - /* Definition continues until line that doesn't end with '\' */ - if (got_int || type != FIND_DEFINE || p < line || *p != '\\') + // Definition continues until line that doesn't end with '\' + if (got_int || type != FIND_DEFINE || p < line || *p != '\\') { break; + } if (fp != NULL) { - if (vim_fgets(line, LSIZE, fp)) /* end of file */ + if (vim_fgets(line, LSIZE, fp)) { // end of file break; + } ++*lnum; } else { - if (++*lnum > curbuf->b_ml.ml_line_count) + if (++*lnum > curbuf->b_ml.ml_line_count) { break; + } line = ml_get(*lnum); } msg_putchar('\n'); diff --git a/src/nvim/shada.c b/src/nvim/shada.c index c0e787380f..7d277fe5c8 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1653,6 +1653,13 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, break; } case kSDItemVariable: { + if (entry.data.global_var.value.v_type == VAR_TYPE_BLOB) { + // Strings and Blobs both pack as msgpack BINs; differentiate them by + // storing an additional VAR_TYPE_BLOB element alongside Blobs + list_T *const list = tv_list_alloc(1); + tv_list_append_number(list, VAR_TYPE_BLOB); + entry.data.global_var.additional_elements = list; + } const size_t arr_size = 2 + (size_t)( tv_list_len(entry.data.global_var.additional_elements)); msgpack_pack_array(spacker, arr_size); @@ -3937,15 +3944,38 @@ shada_read_next_item_start: entry->data.global_var.name = xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr, unpacked.data.via.array.ptr[0].via.bin.size); - if (msgpack_to_vim(unpacked.data.via.array.ptr[1], - &(entry->data.global_var.value)) == FAIL) { + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2, + entry->data.global_var.additional_elements, + "variable"); + bool is_blob = false; + // A msgpack BIN could be a String or Blob; an additional VAR_TYPE_BLOB + // element is stored with Blobs which can be used to differentiate them + if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_BIN) { + const listitem_T *type_item + = tv_list_first(entry->data.global_var.additional_elements); + if (type_item != NULL) { + const typval_T *type_tv = TV_LIST_ITEM_TV(type_item); + if (type_tv->v_type != VAR_NUMBER + || type_tv->vval.v_number != VAR_TYPE_BLOB) { + emsgf(_(READERR("variable", "has wrong variable type")), + initial_fpos); + goto shada_read_next_item_error; + } + is_blob = true; + } + } + if (is_blob) { + const msgpack_object_bin *const bin + = &unpacked.data.via.array.ptr[1].via.bin; + blob_T *const blob = tv_blob_alloc(); + ga_concat_len(&blob->bv_ga, bin->ptr, (size_t)bin->size); + tv_blob_set_ret(&entry->data.global_var.value, blob); + } else if (msgpack_to_vim(unpacked.data.via.array.ptr[1], + &(entry->data.global_var.value)) == FAIL) { emsgf(_(READERR("variable", "has value that cannot " "be converted to the VimL value")), initial_fpos); goto shada_read_next_item_error; } - SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2, - entry->data.global_var.additional_elements, - "variable"); break; } case kSDItemSubString: { diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 0363afe02d..79a3db4843 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -190,6 +190,7 @@ char_u *vim_strsave_shellescape(const char_u *string, char_u *escaped_string; size_t l; int csh_like; + bool fish_like; /* Only csh and similar shells expand '!' within single quotes. For sh and * the like we must not put a backslash before it, it will be taken @@ -197,6 +198,10 @@ char_u *vim_strsave_shellescape(const char_u *string, * Csh also needs to have "\n" escaped twice when do_special is set. */ csh_like = csh_like_shell(); + // Fish shell uses '\' as an escape character within single quotes, so '\' + // itself must be escaped to get a literal '\'. + fish_like = fish_like_shell(); + /* First count the number of extra bytes required. */ size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL for (const char_u *p = string; *p != NUL; MB_PTR_ADV(p)) { @@ -220,6 +225,9 @@ char_u *vim_strsave_shellescape(const char_u *string, ++length; /* insert backslash */ p += l - 1; } + if (*p == '\\' && fish_like) { + length++; // insert backslash + } } /* Allocate memory for the result and fill it. */ @@ -267,6 +275,11 @@ char_u *vim_strsave_shellescape(const char_u *string, *d++ = *p++; continue; } + if (*p == '\\' && fish_like) { + *d++ = '\\'; + *d++ = *p++; + continue; + } MB_COPY_CHAR(p, d); } diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index e5d4752760..64206b4269 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -9,13 +9,12 @@ #include <ctype.h> #include <inttypes.h> #include <stdbool.h> -#include <string.h> #include <stdlib.h> +#include <string.h> -#include "nvim/vim.h" -#include "nvim/ascii.h" #include "nvim/api/private/helpers.h" -#include "nvim/syntax.h" +#include "nvim/ascii.h" +#include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/cursor_shape.h" #include "nvim/eval.h" @@ -23,30 +22,31 @@ #include "nvim/ex_docmd.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/garray.h" #include "nvim/hashtab.h" #include "nvim/highlight.h" #include "nvim/indent_c.h" +#include "nvim/keymap.h" +#include "nvim/macros.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/misc1.h" -#include "nvim/keymap.h" -#include "nvim/garray.h" #include "nvim/option.h" +#include "nvim/os/os.h" +#include "nvim/os/time.h" #include "nvim/os_unix.h" #include "nvim/path.h" -#include "nvim/macros.h" #include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/sign.h" #include "nvim/strings.h" +#include "nvim/syntax.h" #include "nvim/syntax_defs.h" #include "nvim/terminal.h" #include "nvim/ui.h" -#include "nvim/os/os.h" -#include "nvim/os/time.h" -#include "nvim/buffer.h" +#include "nvim/vim.h" static bool did_syntax_onoff = false; @@ -54,8 +54,8 @@ static bool did_syntax_onoff = false; /// The ID of a highlight group is also called group ID. It is the index in /// the highlight_ga array PLUS ONE. typedef struct hl_group { - char_u *sg_name; ///< highlight group name - char *sg_name_u; ///< uppercase of sg_name + char_u *sg_name; ///< highlight group name + char *sg_name_u; ///< uppercase of sg_name bool sg_cleared; ///< "hi clear" was used int sg_attr; ///< Screen attr @see ATTR_ENTRY int sg_link; ///< link to this highlight group ID @@ -98,22 +98,22 @@ static inline struct hl_group * HL_TABLE(void) return ((struct hl_group *)((highlight_ga.ga_data))); } -#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */ +#define MAX_HL_ID 20000 // maximum value for a highlight ID. -/* different types of offsets that are possible */ -#define SPO_MS_OFF 0 /* match start offset */ -#define SPO_ME_OFF 1 /* match end offset */ -#define SPO_HS_OFF 2 /* highl. start offset */ -#define SPO_HE_OFF 3 /* highl. end offset */ -#define SPO_RS_OFF 4 /* region start offset */ -#define SPO_RE_OFF 5 /* region end offset */ -#define SPO_LC_OFF 6 /* leading context offset */ +// different types of offsets that are possible +#define SPO_MS_OFF 0 // match start offset +#define SPO_ME_OFF 1 // match end offset +#define SPO_HS_OFF 2 // highl. start offset +#define SPO_HE_OFF 3 // highl. end offset +#define SPO_RS_OFF 4 // region start offset +#define SPO_RE_OFF 5 // region end offset +#define SPO_LC_OFF 6 // leading context offset #define SPO_COUNT 7 -/* Flags to indicate an additional string for highlight name completion. */ -static int include_none = 0; /* when 1 include "nvim/None" */ -static int include_default = 0; /* when 1 include "nvim/default" */ -static int include_link = 0; /* when 2 include "nvim/link" and "clear" */ +// Flags to indicate an additional string for highlight name completion. +static int include_none = 0; // when 1 include "nvim/None" +static int include_default = 0; // when 1 include "nvim/default" +static int include_link = 0; // when 2 include "nvim/link" and "clear" /// The "term", "cterm" and "gui" arguments can be any combination of the /// following names, separated by commas (but no spaces!). @@ -215,12 +215,12 @@ typedef struct { proftime_T slowest; proftime_T average; int id; - char_u *pattern; + char_u *pattern; } time_entry_T; struct name_list { int flag; - char *name; + char *name; }; #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -228,40 +228,40 @@ struct name_list { #endif static char *(spo_name_tab[SPO_COUNT]) = -{"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="}; +{ "ms=", "me=", "hs=", "he=", "rs=", "re=", "lc=" }; /* The sp_off_flags are computed like this: * offset from the start of the matched text: (1 << SPO_XX_OFF) - * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT)) + * offset from the end of the matched text: (1 << (SPO_XX_OFF + SPO_COUNT)) * When both are present, only one is used. */ -#define SPTYPE_MATCH 1 /* match keyword with this group ID */ -#define SPTYPE_START 2 /* match a regexp, start of item */ -#define SPTYPE_END 3 /* match a regexp, end of item */ -#define SPTYPE_SKIP 4 /* match a regexp, skip within item */ +#define SPTYPE_MATCH 1 // match keyword with this group ID +#define SPTYPE_START 2 // match a regexp, start of item +#define SPTYPE_END 3 // match a regexp, end of item +#define SPTYPE_SKIP 4 // match a regexp, skip within item #define SYN_ITEMS(buf) ((synpat_T *)((buf)->b_syn_patterns.ga_data)) -#define NONE_IDX -2 /* value of sp_sync_idx for "NONE" */ +#define NONE_IDX -2 // value of sp_sync_idx for "NONE" /* * Flags for b_syn_sync_flags: */ -#define SF_CCOMMENT 0x01 /* sync on a C-style comment */ -#define SF_MATCH 0x02 /* sync by matching a pattern */ +#define SF_CCOMMENT 0x01 // sync on a C-style comment +#define SF_MATCH 0x02 // sync by matching a pattern #define SYN_STATE_P(ssp) ((bufstate_T *)((ssp)->ga_data)) -#define MAXKEYWLEN 80 /* maximum length of a keyword */ +#define MAXKEYWLEN 80 // maximum length of a keyword /* * The attributes of the syntax item that has been recognized. */ -static int current_attr = 0; /* attr of current syntax word */ -static int current_id = 0; /* ID of current char for syn_get_id() */ -static int current_trans_id = 0; /* idem, transparency removed */ +static int current_attr = 0; // attr of current syntax word +static int current_id = 0; // ID of current char for syn_get_id() +static int current_trans_id = 0; // idem, transparency removed static int current_flags = 0; static int current_seqnr = 0; static int current_sub_char = 0; @@ -269,9 +269,9 @@ static int current_sub_char = 0; /* * Methods of combining two clusters */ -#define CLUSTER_REPLACE 1 /* replace first list with second */ -#define CLUSTER_ADD 2 /* add second list to first */ -#define CLUSTER_SUBTRACT 3 /* subtract second list from first */ +#define CLUSTER_REPLACE 1 // replace first list with second +#define CLUSTER_ADD 2 // add second list to first +#define CLUSTER_SUBTRACT 3 // subtract second list from first #define SYN_CLSTR(buf) ((syn_cluster_T *)((buf)->b_syn_clusters.ga_data)) @@ -283,12 +283,12 @@ static int current_sub_char = 0; * 22000 - 22999 CONTAINED indicator (current_syn_inc_tag added) * 23000 - 32767 cluster IDs (subtract SYNID_CLUSTER for the cluster ID) */ -#define SYNID_ALLBUT MAX_HL_ID /* syntax group ID for contains=ALLBUT */ -#define SYNID_TOP 21000 /* syntax group ID for contains=TOP */ -#define SYNID_CONTAINED 22000 /* syntax group ID for contains=CONTAINED */ -#define SYNID_CLUSTER 23000 /* first syntax group ID for clusters */ +#define SYNID_ALLBUT MAX_HL_ID // syntax group ID for contains=ALLBUT +#define SYNID_TOP 21000 // syntax group ID for contains=TOP +#define SYNID_CONTAINED 22000 // syntax group ID for contains=CONTAINED +#define SYNID_CLUSTER 23000 // first syntax group ID for clusters -#define MAX_SYN_INC_TAG 999 /* maximum before the above overflow */ +#define MAX_SYN_INC_TAG 999 // maximum before the above overflow #define MAX_CLUSTER_ID (32767 - SYNID_CLUSTER) /* @@ -334,7 +334,7 @@ static char msg_no_items[] = N_("No Syntax items defined for this buffer"); // 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 */ +static int next_seqnr = 1; // value to use for si_seqnr /* * The next possible match in the current line for any pattern is remembered, @@ -343,15 +343,15 @@ static int next_seqnr = 1; /* value to use for si_seqnr */ * If next_match_col == MAXCOL, no match found in this line. * (All end positions have the column of the char after the end) */ -static int next_match_col; /* column for start of next match */ -static lpos_T next_match_m_endpos; /* position for end of next match */ -static lpos_T next_match_h_startpos; /* pos. for highl. start of next match */ -static lpos_T next_match_h_endpos; /* pos. for highl. end of next match */ -static int next_match_idx; /* index of matched item */ -static long next_match_flags; /* flags for next match */ -static lpos_T next_match_eos_pos; /* end of start pattn (start region) */ -static lpos_T next_match_eoe_pos; /* pos. for end of end pattern */ -static int next_match_end_idx; /* ID of group for end pattn or zero */ +static int next_match_col; // column for start of next match +static lpos_T next_match_m_endpos; // position for end of next match +static lpos_T next_match_h_startpos; // pos. for highl. start of next match +static lpos_T next_match_h_endpos; // pos. for highl. end of next match +static int next_match_idx; // index of matched item +static long next_match_flags; // flags for next match +static lpos_T next_match_eos_pos; // end of start pattn (start region) +static lpos_T next_match_eoe_pos; // pos. for end of end pattern +static int next_match_end_idx; // ID of group for end pattn or zero static reg_extmatch_T *next_match_extmatch = NULL; /* @@ -365,8 +365,8 @@ static reg_extmatch_T *next_match_extmatch = NULL; * The current state (within the line) of the recognition engine. * When current_state.ga_itemsize is 0 the current state is invalid. */ -static win_T *syn_win; // current window for highlighting -static buf_T *syn_buf; // current buffer for highlighting +static win_T *syn_win; // current window for highlighting +static buf_T *syn_buf; // current buffer for highlighting static synblock_T *syn_block; // current buffer for highlighting static proftime_T *syn_tm; // timeout limit static linenr_T current_lnum = 0; // lnum of current state @@ -396,19 +396,19 @@ void syn_set_timeout(proftime_T *tm) * Start the syntax recognition for a line. This function is normally called * from the screen updating, once for each displayed line. * The buffer is remembered in syn_buf, because get_syntax_attr() doesn't get - * it. Careful: curbuf and curwin are likely to point to another buffer and + * it. Careful: curbuf and curwin are likely to point to another buffer and * window. */ void syntax_start(win_T *wp, linenr_T lnum) { - synstate_T *p; - synstate_T *last_valid = NULL; - synstate_T *last_min_valid = NULL; - synstate_T *sp, *prev = NULL; + synstate_T *p; + synstate_T *last_valid = NULL; + synstate_T *last_min_valid = NULL; + synstate_T *sp, *prev = NULL; linenr_T parsed_lnum; linenr_T first_stored; int dist; - static int changedtick = 0; /* remember the last change ID */ + static int changedtick = 0; // remember the last change ID current_sub_char = NUL; @@ -431,8 +431,9 @@ void syntax_start(win_T *wp, linenr_T lnum) * Allocate syntax stack when needed. */ syn_stack_alloc(); - if (syn_block->b_sst_array == NULL) - return; /* out of memory */ + if (syn_block->b_sst_array == NULL) { + return; // out of memory + } syn_block->b_sst_lasttick = display_tick; /* @@ -452,29 +453,33 @@ void syntax_start(win_T *wp, linenr_T lnum) * state (this happens very often!). Otherwise invalidate * current_state and figure it out below. */ - if (current_lnum != lnum) + if (current_lnum != lnum) { invalidate_current_state(); - } else + } + } else { invalidate_current_state(); + } /* * Try to synchronize from a saved state in b_sst_array[]. * Only do this if lnum is not before and not to far beyond a saved state. */ if (INVALID_STATE(¤t_state) && syn_block->b_sst_array != NULL) { - /* Find last valid saved state before start_lnum. */ + // Find last valid saved state before start_lnum. for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) { if (p->sst_lnum > lnum) { break; } if (p->sst_change_lnum == 0) { last_valid = p; - if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines) + if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines) { last_min_valid = p; + } } } - if (last_min_valid != NULL) + if (last_min_valid != NULL) { load_current_state(last_min_valid); + } } /* @@ -483,24 +488,27 @@ void syntax_start(win_T *wp, linenr_T lnum) */ if (INVALID_STATE(¤t_state)) { syn_sync(wp, lnum, last_valid); - if (current_lnum == 1) - /* First line is always valid, no matter "minlines". */ + if (current_lnum == 1) { + // First line is always valid, no matter "minlines". first_stored = 1; - else + } else { /* Need to parse "minlines" lines before state can be considered * valid to store. */ first_stored = current_lnum + syn_block->b_syn_sync_minlines; - } else + } + } else { first_stored = current_lnum; + } /* * Advance from the sync point or saved state until the current line. * Save some entries for syncing with later on. */ - if (syn_block->b_sst_len <= Rows) + if (syn_block->b_sst_len <= Rows) { dist = 999999; - else + } else { dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1; + } while (current_lnum < lnum) { syn_start_line(); (void)syn_finish_line(false); @@ -512,26 +520,30 @@ void syntax_start(win_T *wp, linenr_T lnum) /* Check if the saved state entry is for the current line and is * equal to the current state. If so, then validate all saved * states that depended on a change before the parsed line. */ - if (prev == NULL) + if (prev == NULL) { prev = syn_stack_find_entry(current_lnum - 1); - if (prev == NULL) + } + if (prev == NULL) { sp = syn_block->b_sst_first; - else + } else { sp = prev; - while (sp != NULL && sp->sst_lnum < current_lnum) + } + while (sp != NULL && sp->sst_lnum < current_lnum) { sp = sp->sst_next; + } if (sp != NULL && sp->sst_lnum == current_lnum && syn_stack_equal(sp)) { parsed_lnum = current_lnum; prev = sp; while (sp != NULL && sp->sst_change_lnum <= parsed_lnum) { - if (sp->sst_lnum <= lnum) - /* valid state before desired line, use this one */ + if (sp->sst_lnum <= lnum) { + // valid state before desired line, use this one prev = sp; - else if (sp->sst_change_lnum == 0) - /* past saved states depending on change, break here. */ + } else if (sp->sst_change_lnum == 0) { + // past saved states depending on change, break here. break; + } sp->sst_change_lnum = 0; sp = sp->sst_next; } @@ -542,8 +554,9 @@ void syntax_start(win_T *wp, linenr_T lnum) * saved state. But only when parsed at least 'minlines'. */ else if (prev == NULL || current_lnum == lnum - || current_lnum >= prev->sst_lnum + dist) + || current_lnum >= prev->sst_lnum + dist) { prev = store_current_state(); + } } /* This can take a long time: break when CTRL-C pressed. The current @@ -594,8 +607,8 @@ static void clear_current_state(void) */ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) { - buf_T *curbuf_save; - win_T *curwin_save; + buf_T *curbuf_save; + win_T *curwin_save; pos_T cursor_save; int idx; linenr_T lnum; @@ -603,8 +616,8 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) linenr_T break_lnum; bool had_sync_point; stateitem_T *cur_si; - synpat_T *spp; - char_u *line; + synpat_T *spp; + char_u *line; int found_flags = 0; int found_match_idx = 0; linenr_T found_current_lnum = 0; @@ -625,22 +638,25 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) * where N is minlines * 1.5, or minlines * 2 if minlines is small. * Watch out for overflow when minlines is MAXLNUM. */ - if (syn_block->b_syn_sync_minlines > start_lnum) + if (syn_block->b_syn_sync_minlines > start_lnum) { start_lnum = 1; - else { - if (syn_block->b_syn_sync_minlines == 1) + } else { + if (syn_block->b_syn_sync_minlines == 1) { lnum = 1; - else if (syn_block->b_syn_sync_minlines < 10) + } else if (syn_block->b_syn_sync_minlines < 10) { lnum = syn_block->b_syn_sync_minlines * 2; - else + } else { lnum = syn_block->b_syn_sync_minlines * 3 / 2; + } if (syn_block->b_syn_sync_maxlines != 0 - && lnum > syn_block->b_syn_sync_maxlines) + && lnum > syn_block->b_syn_sync_maxlines) { lnum = syn_block->b_syn_sync_maxlines; - if (lnum >= start_lnum) + } + if (lnum >= start_lnum) { start_lnum = 1; - else + } else { start_lnum -= lnum; + } } current_lnum = start_lnum; @@ -660,12 +676,13 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) */ for (; start_lnum > 1; --start_lnum) { line = ml_get(start_lnum - 1); - if (*line == NUL || *(line + STRLEN(line) - 1) != '\\') + if (*line == NUL || *(line + STRLEN(line) - 1) != '\\') { break; + } } current_lnum = start_lnum; - /* set cursor to start of search */ + // set cursor to start of search cursor_save = wp->w_cursor; wp->w_cursor.lnum = start_lnum; wp->w_cursor.col = 0; @@ -676,7 +693,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) * Restrict the search for the end of a comment to b_syn_sync_maxlines. */ if (find_start_comment((int)syn_block->b_syn_sync_maxlines) != NULL) { - for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) + for (idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) { if (SYN_ITEMS(syn_block)[idx].sp_syn.id == syn_block->b_syn_sync_id && SYN_ITEMS(syn_block)[idx].sp_type == SPTYPE_START) { @@ -685,9 +702,10 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) update_si_attr(current_state.ga_len - 1); break; } + } } - /* restore cursor and buffer */ + // restore cursor and buffer wp->w_cursor = cursor_save; curwin = curwin_save; curbuf = curbuf_save; @@ -697,17 +715,18 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) */ else if (syn_block->b_syn_sync_flags & SF_MATCH) { if (syn_block->b_syn_sync_maxlines != 0 - && start_lnum > syn_block->b_syn_sync_maxlines) + && start_lnum > syn_block->b_syn_sync_maxlines) { break_lnum = start_lnum - syn_block->b_syn_sync_maxlines; - else + } else { break_lnum = 0; + } found_m_endpos.lnum = 0; found_m_endpos.col = 0; end_lnum = start_lnum; lnum = start_lnum; while (--lnum > break_lnum) { - /* This can take a long time: break when CTRL-C pressed. */ + // This can take a long time: break when CTRL-C pressed. line_breakcheck(); if (got_int) { invalidate_current_state(); @@ -715,7 +734,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) break; } - /* Check if we have run into a valid saved state stack now. */ + // Check if we have run into a valid saved state stack now. if (last_valid != NULL && lnum == last_valid->sst_lnum) { load_current_state(last_valid); break; @@ -724,8 +743,9 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) /* * Check if the previous line has the line-continuation pattern. */ - if (lnum > 1 && syn_match_linecont(lnum - 1)) + if (lnum > 1 && syn_match_linecont(lnum - 1)) { continue; + } /* * Start with nothing on the state stack @@ -741,12 +761,12 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) if (had_sync_point && current_state.ga_len) { cur_si = &CUR_STATE(current_state.ga_len - 1); if (cur_si->si_m_endpos.lnum > start_lnum) { - /* ignore match that goes to after where started */ + // ignore match that goes to after where started current_lnum = end_lnum; break; } if (cur_si->si_idx < 0) { - /* Cannot happen? */ + // Cannot happen? found_flags = 0; found_match_idx = KEYWORD_IDX; } else { @@ -764,23 +784,27 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) if (found_m_endpos.lnum > current_lnum) { current_lnum = found_m_endpos.lnum; current_col = found_m_endpos.col; - if (current_lnum >= end_lnum) + if (current_lnum >= end_lnum) { break; - } else if (found_m_endpos.col > current_col) + } + } else if (found_m_endpos.col > current_col) { current_col = found_m_endpos.col; - else + } else { ++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. */ prev_current_col = current_col; - if (syn_getcurline()[current_col] != NUL) + if (syn_getcurline()[current_col] != NUL) { ++current_col; + } check_state_ends(); current_col = prev_current_col; - } else + } else { break; + } } } @@ -828,7 +852,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid) invalidate_current_state(); } - /* Ran into start of the file or exceeded maximum number of lines */ + // Ran into start of the file or exceeded maximum number of lines if (lnum <= break_lnum) { invalidate_current_state(); current_lnum = break_lnum + 1; @@ -934,10 +958,13 @@ static void syn_update_ends(bool startofline) * Then check for items ending in column 0. */ int i = current_state.ga_len - 1; - if (keepend_level >= 0) - for (; i > keepend_level; --i) - if (CUR_STATE(i).si_flags & HL_EXTEND) + if (keepend_level >= 0) { + for (; i > keepend_level; --i) { + if (CUR_STATE(i).si_flags & HL_EXTEND) { break; + } + } + } bool seen_keepend = false; for (; i < current_state.ga_len; i++) { @@ -945,11 +972,12 @@ static void syn_update_ends(bool startofline) if ((cur_si->si_flags & HL_KEEPEND) || (seen_keepend && !startofline) || (i == current_state.ga_len - 1 && startofline)) { - cur_si->si_h_startpos.col = 0; /* start highl. in col 0 */ + cur_si->si_h_startpos.col = 0; // start highl. in col 0 cur_si->si_h_startpos.lnum = current_lnum; - if (!(cur_si->si_flags & HL_MATCHCONT)) + if (!(cur_si->si_flags & HL_MATCHCONT)) { update_si_end(cur_si, (int)current_col, !startofline); + } if (!startofline && (cur_si->si_flags & HL_KEEPEND)) { seen_keepend = true; @@ -997,7 +1025,7 @@ static void syn_update_ends(bool startofline) static void syn_stack_free_block(synblock_T *block) { - synstate_T *p; + synstate_T *p; if (block->b_sst_array != NULL) { for (p = block->b_sst_first; p != NULL; p = p->sst_next) { @@ -1016,7 +1044,7 @@ void syn_stack_free_all(synblock_T *block) { syn_stack_free_block(block); - /* When using "syntax" fold method, must update all folds. */ + // When using "syntax" fold method, must update all folds. FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { if (wp->w_s == block && foldmethodIsSyntax(wp)) { foldUpdateAll(wp); @@ -1033,31 +1061,35 @@ void syn_stack_free_all(synblock_T *block) static void syn_stack_alloc(void) { long len; - synstate_T *to, *from; - synstate_T *sstp; + synstate_T *to, *from; + synstate_T *sstp; len = syn_buf->b_ml.ml_line_count / SST_DIST + Rows * 2; - if (len < SST_MIN_ENTRIES) + if (len < SST_MIN_ENTRIES) { len = SST_MIN_ENTRIES; - else if (len > SST_MAX_ENTRIES) + } else if (len > SST_MAX_ENTRIES) { len = SST_MAX_ENTRIES; + } if (syn_block->b_sst_len > len * 2 || syn_block->b_sst_len < len) { - /* Allocate 50% too much, to avoid reallocating too often. */ + // Allocate 50% too much, to avoid reallocating too often. len = syn_buf->b_ml.ml_line_count; len = (len + len / 2) / SST_DIST + Rows * 2; - if (len < SST_MIN_ENTRIES) + if (len < SST_MIN_ENTRIES) { len = SST_MIN_ENTRIES; - else if (len > SST_MAX_ENTRIES) + } else if (len > SST_MAX_ENTRIES) { len = SST_MAX_ENTRIES; + } if (syn_block->b_sst_array != NULL) { /* When shrinking the array, cleanup the existing stack. * Make sure that all valid entries fit in the new array. */ while (syn_block->b_sst_len - syn_block->b_sst_freecount + 2 > len - && syn_stack_cleanup()) + && syn_stack_cleanup()) { ; - if (len < syn_block->b_sst_len - syn_block->b_sst_freecount + 2) + } + if (len < syn_block->b_sst_len - syn_block->b_sst_freecount + 2) { len = syn_block->b_sst_len - syn_block->b_sst_freecount + 2; + } } assert(len >= 0); @@ -1065,7 +1097,7 @@ static void syn_stack_alloc(void) to = sstp - 1; if (syn_block->b_sst_array != NULL) { - /* Move the states from the old array to the new one. */ + // Move the states from the old array to the new one. for (from = syn_block->b_sst_first; from != NULL; from = from->sst_next) { ++to; @@ -1082,10 +1114,11 @@ static void syn_stack_alloc(void) syn_block->b_sst_freecount = len; } - /* Create the list of free entries. */ + // Create the list of free entries. syn_block->b_sst_firstfree = to + 1; - while (++to < sstp + len) + while (++to < sstp + len) { to->sst_next = to + 1; + } (sstp + len - 1)->sst_next = NULL; xfree(syn_block->b_sst_array); @@ -1113,7 +1146,7 @@ void syn_stack_apply_changes(buf_T *buf) static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf) { - synstate_T *p, *prev, *np; + synstate_T *p, *prev, *np; linenr_T n; prev = NULL; @@ -1121,12 +1154,13 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf) if (p->sst_lnum + block->b_syn_sync_linebreaks > buf->b_mod_top) { n = p->sst_lnum + buf->b_mod_xlines; if (n <= buf->b_mod_bot) { - /* this state is inside the changed area, remove it */ + // this state is inside the changed area, remove it np = p->sst_next; - if (prev == NULL) + if (prev == NULL) { block->b_sst_first = np; - else + } else { prev->sst_next = np; + } syn_stack_free_entry(block, p); p = np; continue; @@ -1135,14 +1169,16 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf) * that needs to be parsed before this entry can be made valid * again. */ if (p->sst_change_lnum != 0 && p->sst_change_lnum > buf->b_mod_top) { - if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) + if (p->sst_change_lnum + buf->b_mod_xlines > buf->b_mod_top) { p->sst_change_lnum += buf->b_mod_xlines; - else + } else { p->sst_change_lnum = buf->b_mod_top; + } } if (p->sst_change_lnum == 0 - || p->sst_change_lnum < buf->b_mod_bot) + || p->sst_change_lnum < buf->b_mod_bot) { p->sst_change_lnum = buf->b_mod_bot; + } p->sst_lnum = n; } @@ -1156,7 +1192,7 @@ static void syn_stack_apply_changes_block(synblock_T *block, buf_T *buf) /// @return true if at least one entry was freed. static bool syn_stack_cleanup(void) { - synstate_T *p, *prev; + synstate_T *p, *prev; disptick_T tick; int dist; bool retval = false; @@ -1165,11 +1201,12 @@ static bool syn_stack_cleanup(void) return retval; } - /* Compute normal distance between non-displayed entries. */ - if (syn_block->b_sst_len <= Rows) + // Compute normal distance between non-displayed entries. + if (syn_block->b_sst_len <= Rows) { dist = 999999; - else + } else { dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1; + } /* * Go through the list to find the "tick" for the oldest entry that can @@ -1182,8 +1219,9 @@ static bool syn_stack_cleanup(void) for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next) { if (prev->sst_lnum + dist > p->sst_lnum) { if (p->sst_tick > syn_block->b_sst_lasttick) { - if (!above || p->sst_tick < tick) + if (!above || p->sst_tick < tick) { tick = p->sst_tick; + } above = true; } else if (!above && p->sst_tick < tick) { tick = p->sst_tick; @@ -1198,7 +1236,7 @@ static bool syn_stack_cleanup(void) prev = syn_block->b_sst_first; for (p = prev->sst_next; p != NULL; prev = p, p = p->sst_next) { if (p->sst_tick == tick && prev->sst_lnum + dist > p->sst_lnum) { - /* Move this entry from used list to free list */ + // Move this entry from used list to free list prev->sst_next = p->sst_next; syn_stack_free_entry(syn_block, p); p = prev; @@ -1226,14 +1264,16 @@ static void syn_stack_free_entry(synblock_T *block, synstate_T *p) */ static synstate_T *syn_stack_find_entry(linenr_T lnum) { - synstate_T *p, *prev; + synstate_T *p, *prev; prev = NULL; for (p = syn_block->b_sst_first; p != NULL; prev = p, p = p->sst_next) { - if (p->sst_lnum == lnum) + if (p->sst_lnum == lnum) { return p; - if (p->sst_lnum > lnum) + } + if (p->sst_lnum > lnum) { break; + } } return prev; } @@ -1245,10 +1285,10 @@ static synstate_T *syn_stack_find_entry(linenr_T lnum) static synstate_T *store_current_state(void) { int i; - synstate_T *p; - bufstate_T *bp; + synstate_T *p; + bufstate_T *bp; stateitem_T *cur_si; - synstate_T *sp = syn_stack_find_entry(current_lnum); + synstate_T *sp = syn_stack_find_entry(current_lnum); /* * If the current state contains a start or end pattern that continues @@ -1260,51 +1300,55 @@ static synstate_T *store_current_state(void) || cur_si->si_m_endpos.lnum >= current_lnum || cur_si->si_h_endpos.lnum >= current_lnum || (cur_si->si_end_idx - && cur_si->si_eoe_pos.lnum >= current_lnum)) + && cur_si->si_eoe_pos.lnum >= current_lnum)) { break; + } } if (i >= 0) { if (sp != NULL) { - /* find "sp" in the list and remove it */ - if (syn_block->b_sst_first == sp) - /* it's the first entry */ + // find "sp" in the list and remove it + if (syn_block->b_sst_first == sp) { + // it's the first entry syn_block->b_sst_first = sp->sst_next; - else { - /* find the entry just before this one to adjust sst_next */ - for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) - if (p->sst_next == sp) + } else { + // find the entry just before this one to adjust sst_next + for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) { + if (p->sst_next == sp) { break; - if (p != NULL) /* just in case */ + } + } + if (p != NULL) { // just in case p->sst_next = sp->sst_next; + } } syn_stack_free_entry(syn_block, sp); sp = NULL; } - } else if (sp == NULL || sp->sst_lnum != current_lnum) { + } else if (sp == NULL || sp->sst_lnum != current_lnum) { /* * Add a new entry */ - /* If no free items, cleanup the array first. */ + // If no free items, cleanup the array first. if (syn_block->b_sst_freecount == 0) { (void)syn_stack_cleanup(); - /* "sp" may have been moved to the freelist now */ + // "sp" may have been moved to the freelist now sp = syn_stack_find_entry(current_lnum); } - /* Still no free items? Must be a strange problem... */ - if (syn_block->b_sst_freecount == 0) + // Still no free items? Must be a strange problem... + if (syn_block->b_sst_freecount == 0) { sp = NULL; - else { + } else { /* Take the first item from the free list and put it in the used * list, after *sp */ p = syn_block->b_sst_firstfree; syn_block->b_sst_firstfree = p->sst_next; --syn_block->b_sst_freecount; if (sp == NULL) { - /* Insert in front of the list */ + // Insert in front of the list p->sst_next = syn_block->b_sst_first; syn_block->b_sst_first = p; } else { - /* insert in list after *sp */ + // insert in list after *sp p->sst_next = sp->sst_next; sp->sst_next = p; } @@ -1314,7 +1358,7 @@ static synstate_T *store_current_state(void) } } if (sp != NULL) { - /* When overwriting an existing state stack, clear it first */ + // When overwriting an existing state stack, clear it first clear_syn_state(sp); sp->sst_stacksize = current_state.ga_len; if (current_state.ga_len > SST_FIX_STATES) { @@ -1324,8 +1368,9 @@ static synstate_T *store_current_state(void) ga_grow(&sp->sst_union.sst_ga, current_state.ga_len); sp->sst_union.sst_ga.ga_len = current_state.ga_len; bp = SYN_STATE_P(&(sp->sst_union.sst_ga)); - } else + } else { bp = sp->sst_union.sst_stack; + } for (i = 0; i < sp->sst_stacksize; ++i) { bp[i].bs_idx = CUR_STATE(i).si_idx; bp[i].bs_flags = CUR_STATE(i).si_flags; @@ -1348,32 +1393,35 @@ static synstate_T *store_current_state(void) static void load_current_state(synstate_T *from) { int i; - bufstate_T *bp; + bufstate_T *bp; clear_current_state(); validate_current_state(); keepend_level = -1; if (from->sst_stacksize) { ga_grow(¤t_state, from->sst_stacksize); - if (from->sst_stacksize > SST_FIX_STATES) + if (from->sst_stacksize > SST_FIX_STATES) { bp = SYN_STATE_P(&(from->sst_union.sst_ga)); - else + } else { bp = from->sst_union.sst_stack; + } for (i = 0; i < from->sst_stacksize; ++i) { CUR_STATE(i).si_idx = bp[i].bs_idx; CUR_STATE(i).si_flags = bp[i].bs_flags; CUR_STATE(i).si_seqnr = bp[i].bs_seqnr; CUR_STATE(i).si_cchar = bp[i].bs_cchar; CUR_STATE(i).si_extmatch = ref_extmatch(bp[i].bs_extmatch); - if (keepend_level < 0 && (CUR_STATE(i).si_flags & HL_KEEPEND)) + if (keepend_level < 0 && (CUR_STATE(i).si_flags & HL_KEEPEND)) { keepend_level = i; + } CUR_STATE(i).si_ends = FALSE; CUR_STATE(i).si_m_lnum = 0; - if (CUR_STATE(i).si_idx >= 0) + if (CUR_STATE(i).si_idx >= 0) { CUR_STATE(i).si_next_list = (SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_next_list; - else + } else { CUR_STATE(i).si_next_list = NULL; + } update_si_attr(i); } current_state.ga_len = from->sst_stacksize; @@ -1388,26 +1436,28 @@ static void load_current_state(synstate_T *from) /// @return true when they are equal. static bool syn_stack_equal(synstate_T *sp) { - bufstate_T *bp; - reg_extmatch_T *six, *bsx; + bufstate_T *bp; + reg_extmatch_T *six, *bsx; - /* First a quick check if the stacks have the same size end nextlist. */ + // First a quick check if the stacks have the same size end nextlist. if (sp->sst_stacksize != current_state.ga_len || sp->sst_next_list != current_next_list) { return false; } - /* Need to compare all states on both stacks. */ - if (sp->sst_stacksize > SST_FIX_STATES) + // Need to compare all states on both stacks. + if (sp->sst_stacksize > SST_FIX_STATES) { bp = SYN_STATE_P(&(sp->sst_union.sst_ga)); - else + } else { bp = sp->sst_union.sst_stack; + } int i; for (i = current_state.ga_len; --i >= 0; ) { - /* If the item has another index the state is different. */ - if (bp[i].bs_idx != CUR_STATE(i).si_idx) + // If the item has another index the state is different. + if (bp[i].bs_idx != CUR_STATE(i).si_idx) { break; + } if (bp[i].bs_extmatch == CUR_STATE(i).si_extmatch) { continue; } @@ -1418,8 +1468,9 @@ static bool syn_stack_equal(synstate_T *sp) six = CUR_STATE(i).si_extmatch; /* If one of the extmatch pointers is NULL the states are * different. */ - if (bsx == NULL || six == NULL) + if (bsx == NULL || six == NULL) { break; + } int j; for (j = 0; j < NSUBEXP; ++j) { /* Check each referenced match string. They must all be @@ -1438,8 +1489,9 @@ static bool syn_stack_equal(synstate_T *sp) } } } - if (j != NSUBEXP) + if (j != NSUBEXP) { break; + } } if (i < 0) { return true; @@ -1453,21 +1505,23 @@ static bool syn_stack_equal(synstate_T *sp) * this line depended on a change before it, it now depends on the line below * the last parsed line. * The window looks like this: - * line which changed - * displayed line - * displayed line + * line which changed + * displayed line + * displayed line * lnum -> line below window */ void syntax_end_parsing(linenr_T lnum) { - synstate_T *sp; + synstate_T *sp; sp = syn_stack_find_entry(lnum); - if (sp != NULL && sp->sst_lnum < lnum) + if (sp != NULL && sp->sst_lnum < lnum) { sp = sp->sst_next; + } - if (sp != NULL && sp->sst_change_lnum != 0) + if (sp != NULL && sp->sst_change_lnum != 0) { sp->sst_change_lnum = lnum; + } } /* @@ -1477,7 +1531,7 @@ void syntax_end_parsing(linenr_T lnum) static void invalidate_current_state(void) { clear_current_state(); - current_state.ga_itemsize = 0; /* mark current_state invalid */ + current_state.ga_itemsize = 0; // mark current_state invalid current_next_list = NULL; keepend_level = -1; } @@ -1495,7 +1549,7 @@ static void validate_current_state(void) bool syntax_check_changed(linenr_T lnum) { bool retval = true; - synstate_T *sp; + synstate_T *sp; /* * Check the state stack when: @@ -1532,16 +1586,13 @@ bool syntax_check_changed(linenr_T lnum) return retval; } -/* - * Finish the current line. - * This doesn't return any attributes, it only gets the state at the end of - * the line. It can start anywhere in the line, as long as the current state - * is valid. - */ -static bool -syn_finish_line( - const bool syncing // called for syncing -) +/// Finish the current line. +/// This doesn't return any attributes, it only gets the state at the end of +/// the line. It can start anywhere in the line, as long as the current state +/// is valid. +/// +/// @param syncing called for syncing +static bool syn_finish_line(const bool syncing) { while (!current_finished) { (void)syn_current_attr(syncing, false, NULL, false); @@ -1571,36 +1622,35 @@ syn_finish_line( return false; } -/* - * Return highlight attributes for next character. - * Must first call syntax_start() once for the line. - * "col" is normally 0 for the first use in a line, and increments by one each - * time. It's allowed to skip characters and to stop before the end of the - * line. But only a "col" after a previously used column is allowed. - * When "can_spell" is not NULL set it to TRUE when spell-checking should be - * done. - */ -int -get_syntax_attr( - const colnr_T col, - bool *const can_spell, - const bool keep_state // keep state of char at "col" -) +/// Gets highlight attributes for next character. +/// Must first call syntax_start() once for the line. +/// "col" is normally 0 for the first use in a line, and increments by one each +/// time. It's allowed to skip characters and to stop before the end of the +/// line. But only a "col" after a previously used column is allowed. +/// When "can_spell" is not NULL set it to TRUE when spell-checking should be +/// done. +/// +/// @param keep_state keep state of char at "col" +/// +/// @return highlight attributes for next character. +int get_syntax_attr(const colnr_T col, bool *const can_spell, const bool keep_state) { int attr = 0; - if (can_spell != NULL) + if (can_spell != NULL) { /* Default: Only do spelling when there is no @Spell cluster or when * ":syn spell toplevel" was used. */ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); + } - /* check for out of memory situation */ - if (syn_block->b_sst_array == NULL) + // check for out of memory situation + if (syn_block->b_sst_array == NULL) { return 0; + } - /* After 'synmaxcol' the attribute is always zero. */ + // After 'synmaxcol' the attribute is always zero. if (syn_buf->b_p_smc > 0 && col >= (colnr_T)syn_buf->b_p_smc) { clear_current_state(); current_id = 0; @@ -1610,9 +1660,10 @@ get_syntax_attr( return 0; } - /* Make sure current_state is valid */ - if (INVALID_STATE(¤t_state)) + // Make sure current_state is valid + if (INVALID_STATE(¤t_state)) { validate_current_state(); + } /* * Skip from the current column to "col", get the attributes for "col". @@ -1626,15 +1677,14 @@ get_syntax_attr( return attr; } -/* - * Get syntax attributes for current_lnum, current_col. - */ -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 -) +/// Get syntax attributes for current_lnum, current_col. +/// +/// @param syncing When true: called for syncing +/// @param displaying result will be displayed +/// @param can_spell return: do spell checking +/// @param keep_state keep syntax stack afterwards +static int syn_current_attr(const bool syncing, const bool displaying, bool *const can_spell, + const bool keep_state) { lpos_T endpos; // was: char_u *endp; lpos_T hl_startpos; // was: int hl_startcol; @@ -1654,8 +1704,8 @@ static int syn_current_attr( lpos_T pos; 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! + char_u *line; // current line. NOTE: becomes invalid after + // looking for a pattern match! // variables for zero-width matches that have a "nextgroup" argument bool keep_next_list; @@ -1681,7 +1731,7 @@ static int syn_current_attr( return 0; } - /* if the current or next character is NUL, we will finish the line now */ + // if the current or next character is NUL, we will finish the line now if (line[current_col] == NUL || line[current_col + 1] == NUL) { current_finished = true; current_state_stored = false; @@ -1699,8 +1749,8 @@ static int syn_current_attr( // 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); + && (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. */ @@ -1726,23 +1776,25 @@ static int syn_current_attr( * Always need to check for contained items if some item has the * "containedin" argument (takes extra time!). */ - if (current_state.ga_len) + if (current_state.ga_len) { cur_si = &CUR_STATE(current_state.ga_len - 1); - else + } else { cur_si = NULL; + } if (syn_block->b_syn_containedin || cur_si == NULL || cur_si->si_cont_list != NULL) { /* * 2. Check for keywords, if on a keyword char after a non-keyword - * char. Don't do this when syncing. + * char. Don't do this when syncing. */ if (do_keywords) { line = syn_getcurline(); 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))) { + && (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) { @@ -1751,7 +1803,7 @@ static int syn_current_attr( cur_si = &CUR_STATE(current_state.ga_len - 1); cur_si->si_m_startcol = current_col; cur_si->si_h_startpos.lnum = current_lnum; - cur_si->si_h_startpos.col = 0; /* starts right away */ + cur_si->si_h_startpos.col = 0; // starts right away cur_si->si_m_endpos.lnum = current_lnum; cur_si->si_m_endpos.col = endcol; cur_si->si_h_endpos.lnum = current_lnum; @@ -1761,10 +1813,11 @@ static int syn_current_attr( cur_si->si_flags = flags; cur_si->si_seqnr = next_seqnr++; cur_si->si_cchar = cchar; - if (current_state.ga_len > 1) + if (current_state.ga_len > 1) { cur_si->si_flags |= CUR_STATE(current_state.ga_len - 2).si_flags & HL_CONCEAL; + } cur_si->si_id = syn_id; cur_si->si_trans_id = syn_id; if (flags & HL_TRANSP) { @@ -1772,10 +1825,8 @@ static int syn_current_attr( cur_si->si_attr = 0; cur_si->si_trans_id = 0; } else { - cur_si->si_attr = CUR_STATE( - current_state.ga_len - 2).si_attr; - cur_si->si_trans_id = CUR_STATE( - current_state.ga_len - 2).si_trans_id; + cur_si->si_attr = CUR_STATE(current_state.ga_len - 2).si_attr; + cur_si->si_trans_id = CUR_STATE(current_state.ga_len - 2).si_trans_id; } } else { cur_si->si_attr = syn_id2attr(syn_id); @@ -1803,28 +1854,29 @@ static int syn_current_attr( * pattern takes quite a bit of time, thus we want to * avoid doing it when it's not needed. */ - next_match_idx = 0; /* no match in this line yet */ + 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; ) { 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 - || spp->sp_type == SPTYPE_START) - && (current_next_list != NULL + if (spp->sp_syncing == syncing + && (displaying || !(spp->sp_flags & HL_DISPLAY)) + && (spp->sp_type == SPTYPE_MATCH + || spp->sp_type == SPTYPE_START) + && (current_next_list != NULL ? in_id_list(NULL, current_next_list, - &spp->sp_syn, 0) + &spp->sp_syn, 0) : (cur_si == NULL ? !(spp->sp_flags & HL_CONTAINED) : in_id_list(cur_si, - cur_si->si_cont_list, &spp->sp_syn, - spp->sp_flags & HL_CONTAINED)))) { + cur_si->si_cont_list, &spp->sp_syn, + spp->sp_flags & HL_CONTAINED)))) { /* If we already tried matching in this line, and * there isn't a match before next_match_col, skip * this item. */ if (spp->sp_line_id == current_line_id - && spp->sp_startcol >= next_match_col) + && spp->sp_startcol >= next_match_col) { continue; + } spp->sp_line_id = current_line_id; colnr_T lc_col = current_col - spp->sp_offsets[SPO_LC_OFF]; @@ -1838,7 +1890,7 @@ static int syn_current_attr( IF_SYN_TIME(&spp->sp_time)); spp->sp_prog = regmatch.regprog; if (!r) { - /* no match in this line, try another one */ + // no match in this line, try another one spp->sp_startcol = MAXCOL; continue; } @@ -1847,7 +1899,7 @@ static int syn_current_attr( * Compute the first column of the match. */ syn_add_start_off(&pos, ®match, - spp, SPO_MS_OFF, -1); + spp, SPO_MS_OFF, -1); if (pos.lnum > current_lnum) { /* must have used end of match in a next line, * we can't handle that */ @@ -1864,8 +1916,9 @@ static int syn_current_attr( * If a previously found match starts at a lower * column number, don't use this one. */ - if (startcol >= next_match_col) + if (startcol >= next_match_col) { continue; + } /* * If we matched this pattern at this position @@ -1880,14 +1933,14 @@ static int syn_current_attr( endpos.lnum = regmatch.endpos[0].lnum; endpos.col = regmatch.endpos[0].col; - /* Compute the highlight start. */ + // Compute the highlight start. syn_add_start_off(&hl_startpos, ®match, - spp, SPO_HS_OFF, -1); + spp, SPO_HS_OFF, -1); - /* Compute the region start. */ - /* Default is to use the end of the match. */ + // Compute the region start. + // Default is to use the end of the match. syn_add_end_off(&eos_pos, ®match, - spp, SPO_RS_OFF, 0); + spp, SPO_RS_OFF, 0); /* * Grab the external submatches before they get @@ -1898,7 +1951,7 @@ static int syn_current_attr( re_extmatch_out = NULL; flags = 0; - eoe_pos.lnum = 0; /* avoid warning */ + eoe_pos.lnum = 0; // avoid warning eoe_pos.col = 0; end_idx = 0; hl_endpos.lnum = 0; @@ -1915,9 +1968,10 @@ static int syn_current_attr( startpos = endpos; find_endpos(idx, &startpos, &endpos, &hl_endpos, - &flags, &eoe_pos, &end_idx, cur_extmatch); - if (endpos.lnum == 0) - continue; /* not found */ + &flags, &eoe_pos, &end_idx, cur_extmatch); + if (endpos.lnum == 0) { + continue; // not found + } } /* * For a "match" the size must be > 0 after the @@ -1926,9 +1980,9 @@ static int syn_current_attr( */ else if (spp->sp_type == SPTYPE_MATCH) { syn_add_end_off(&hl_endpos, ®match, spp, - SPO_HE_OFF, 0); + SPO_HE_OFF, 0); syn_add_end_off(&endpos, ®match, spp, - SPO_ME_OFF, 0); + SPO_ME_OFF, 0); if (endpos.lnum == current_lnum && (int)endpos.col + syncing < startcol) { /* @@ -1948,8 +2002,9 @@ static int syn_current_attr( /* Highlighting must start after startpos and end * before endpos. */ if (hl_startpos.lnum == current_lnum - && (int)hl_startpos.col < startcol) + && (int)hl_startpos.col < startcol) { hl_startpos.col = startcol; + } limit_pos_zero(&hl_endpos, &endpos); next_match_idx = idx; @@ -1972,7 +2027,7 @@ static int syn_current_attr( * If we found a match at the current column, use it. */ if (next_match_idx >= 0 && next_match_col == (int)current_col) { - synpat_T *lspp; + synpat_T *lspp; /* When a zero-width item matched which has a nextgroup, * don't push the item but set nextgroup. */ @@ -2012,8 +2067,9 @@ static int syn_current_attr( if (((current_next_flags & HL_SKIPWHITE) && ascii_iswhite(line[current_col])) || ((current_next_flags & HL_SKIPEMPTY) - && *line == NUL)) + && *line == NUL)) { break; + } } /* @@ -2030,7 +2086,6 @@ static int syn_current_attr( found_match = true; } } - } while (found_match); restore_chartab(buf_chartab); @@ -2075,9 +2130,9 @@ static int syn_current_attr( /* There is no @Spell cluster: Do spelling for items without * @NoSpell cluster. */ if (syn_block->b_nospell_cluster_id == 0 - || current_trans_id == 0) + || current_trans_id == 0) { *can_spell = (syn_block->b_syn_spell != SYNSPL_NOTOP); - else { + } else { sps.inc_tag = 0; sps.id = syn_block->b_nospell_cluster_id; sps.cont_in_list = NULL; @@ -2088,9 +2143,9 @@ static int syn_current_attr( * the @Spell cluster. But not when @NoSpell is also there. * At the toplevel only spell check when ":syn spell toplevel" * was used. */ - if (current_trans_id == 0) + if (current_trans_id == 0) { *can_spell = (syn_block->b_syn_spell == SYNSPL_TOP); - else { + } else { sps.inc_tag = 0; sps.id = syn_block->b_spell_cluster_id; sps.cont_in_list = NULL; @@ -2098,8 +2153,9 @@ static int syn_current_attr( if (syn_block->b_nospell_cluster_id != 0) { sps.id = syn_block->b_nospell_cluster_id; - if (in_id_list(sip, sip->si_cont_list, &sps, 0)) + if (in_id_list(sip, sip->si_cont_list, &sps, 0)) { *can_spell = false; + } } } } @@ -2123,14 +2179,15 @@ static int syn_current_attr( --current_col; } } - } else if (can_spell != NULL) + } else if (can_spell != NULL) { /* Default: Only do spelling when there is no @Spell cluster or when * ":syn spell toplevel" was used. */ *can_spell = syn_block->b_syn_spell == SYNSPL_DEFAULT ? (syn_block->b_spell_cluster_id == 0) : (syn_block->b_syn_spell == SYNSPL_TOP); + } - /* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */ + // nextgroup ends at end of line, unless "skipnl" or "skipempty" present if (current_next_list != NULL && (line = syn_getcurline())[current_col] != NUL && line[current_col + 1] == NUL @@ -2138,10 +2195,11 @@ static int syn_current_attr( current_next_list = NULL; } - if (!GA_EMPTY(&zero_width_next_ga)) + if (!GA_EMPTY(&zero_width_next_ga)) { ga_clear(&zero_width_next_ga); + } - /* No longer need external matches. But keep next_match_extmatch. */ + // No longer need external matches. But keep next_match_extmatch. unref_extmatch(re_extmatch_out); re_extmatch_out = NULL; unref_extmatch(cur_extmatch); @@ -2199,9 +2257,10 @@ static stateitem_T *push_next_match(void) cur_si->si_flags = spp->sp_flags; cur_si->si_seqnr = next_seqnr++; cur_si->si_cchar = spp->sp_cchar; - if (current_state.ga_len > 1) + if (current_state.ga_len > 1) { cur_si->si_flags |= CUR_STATE(current_state.ga_len - 2).si_flags & HL_CONCEAL; + } cur_si->si_next_list = spp->sp_next_list; cur_si->si_extmatch = ref_extmatch(next_match_extmatch); if (spp->sp_type == SPTYPE_START && !(spp->sp_flags & HL_ONELINE)) { @@ -2216,8 +2275,9 @@ static stateitem_T *push_next_match(void) cur_si->si_eoe_pos = next_match_eoe_pos; cur_si->si_end_idx = next_match_end_idx; } - if (keepend_level < 0 && (cur_si->si_flags & HL_KEEPEND)) + if (keepend_level < 0 && (cur_si->si_flags & HL_KEEPEND)) { keepend_level = current_state.ga_len - 1; + } check_keepend(); update_si_attr(current_state.ga_len - 1); @@ -2239,15 +2299,16 @@ static stateitem_T *push_next_match(void) cur_si->si_flags = HL_MATCH; cur_si->si_seqnr = next_seqnr++; cur_si->si_flags |= save_flags; - if (cur_si->si_flags & HL_CONCEALENDS) + if (cur_si->si_flags & HL_CONCEALENDS) { cur_si->si_flags |= HL_CONCEAL; + } cur_si->si_next_list = NULL; check_keepend(); update_si_attr(current_state.ga_len - 1); } } - next_match_idx = -1; /* try other match next time */ + next_match_idx = -1; // try other match next time return cur_si; } @@ -2282,14 +2343,15 @@ static void check_state_ends(void) cur_si->si_h_endpos = cur_si->si_eoe_pos; cur_si->si_flags |= HL_MATCH; cur_si->si_seqnr = next_seqnr++; - if (cur_si->si_flags & HL_CONCEALENDS) + if (cur_si->si_flags & HL_CONCEALENDS) { cur_si->si_flags |= HL_CONCEAL; + } update_si_attr(current_state.ga_len - 1); - /* nextgroup= should not match in the end pattern */ + // nextgroup= should not match in the end pattern current_next_list = NULL; - /* what matches next may be different now, clear it */ + // what matches next may be different now, clear it next_match_idx = 0; next_match_col = MAXCOL; break; @@ -2299,8 +2361,9 @@ static void check_state_ends(void) current_next_list = cur_si->si_next_list; current_next_flags = cur_si->si_flags; if (!(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)) - && syn_getcurline()[current_col] == NUL) + && syn_getcurline()[current_col] == NUL) { current_next_list = NULL; + } /* When the ended item has "extend", another item with * "keepend" now needs to check for its end. */ @@ -2308,8 +2371,9 @@ static void check_state_ends(void) pop_current_state(); - if (GA_EMPTY(¤t_state)) + if (GA_EMPTY(¤t_state)) { break; + } if (had_extend && keepend_level >= 0) { syn_update_ends(false); @@ -2337,12 +2401,14 @@ static void check_state_ends(void) check_keepend(); if ((current_next_flags & HL_HAS_EOL) && keepend_level < 0 - && syn_getcurline()[current_col] == NUL) + && syn_getcurline()[current_col] == NUL) { break; + } } } - } else + } else { break; + } } } @@ -2353,23 +2419,26 @@ static void check_state_ends(void) static void update_si_attr(int idx) { stateitem_T *sip = &CUR_STATE(idx); - synpat_T *spp; + synpat_T *spp; - /* This should not happen... */ - if (sip->si_idx < 0) + // This should not happen... + if (sip->si_idx < 0) { return; + } spp = &(SYN_ITEMS(syn_block)[sip->si_idx]); - if (sip->si_flags & HL_MATCH) + if (sip->si_flags & HL_MATCH) { sip->si_id = spp->sp_syn_match_id; - else + } else { sip->si_id = spp->sp_syn.id; + } sip->si_attr = syn_id2attr(sip->si_id); sip->si_trans_id = sip->si_id; - if (sip->si_flags & HL_MATCH) + if (sip->si_flags & HL_MATCH) { sip->si_cont_list = NULL; - else + } else { sip->si_cont_list = spp->sp_cont_list; + } /* * For transparent items, take attr from outer item. @@ -2380,8 +2449,9 @@ static void update_si_attr(int idx) if (idx == 0) { sip->si_attr = 0; sip->si_trans_id = 0; - if (sip->si_cont_list == NULL) + if (sip->si_cont_list == NULL) { sip->si_cont_list = ID_LIST_ALL; + } } else { sip->si_attr = CUR_STATE(idx - 1).si_attr; sip->si_trans_id = CUR_STATE(idx - 1).si_trans_id; @@ -2410,17 +2480,20 @@ static void check_keepend(void) * This check can consume a lot of time; only do it from the level where * there really is a keepend. */ - if (keepend_level < 0) + if (keepend_level < 0) { return; + } /* * Find the last index of an "extend" item. "keepend" items before that * won't do anything. If there is no "extend" item "i" will be * "keepend_level" and all "keepend" items will work normally. */ - for (i = current_state.ga_len - 1; i > keepend_level; --i) - if (CUR_STATE(i).si_flags & HL_EXTEND) + for (i = current_state.ga_len - 1; i > keepend_level; --i) { + if (CUR_STATE(i).si_flags & HL_EXTEND) { break; + } + } maxpos.lnum = 0; maxpos.col = 0; @@ -2438,13 +2511,15 @@ static void check_keepend(void) if (maxpos.lnum == 0 || maxpos.lnum > sip->si_m_endpos.lnum || (maxpos.lnum == sip->si_m_endpos.lnum - && maxpos.col > sip->si_m_endpos.col)) + && maxpos.col > sip->si_m_endpos.col)) { maxpos = sip->si_m_endpos; + } if (maxpos_h.lnum == 0 || maxpos_h.lnum > sip->si_h_endpos.lnum || (maxpos_h.lnum == sip->si_h_endpos.lnum - && maxpos_h.col > sip->si_h_endpos.col)) + && maxpos_h.col > sip->si_h_endpos.col)) { maxpos_h = sip->si_h_endpos; + } } } } @@ -2461,15 +2536,17 @@ static void update_si_end(stateitem_T *sip, int startcol, bool force) lpos_T hl_endpos; lpos_T end_endpos; - /* return quickly for a keyword */ - if (sip->si_idx < 0) + // return quickly for a keyword + if (sip->si_idx < 0) { return; + } /* Don't update when it's already done. Can be a match of an end pattern * that started in a previous line. Watch out: can also be a "keepend" * from a containing item. */ - if (!force && sip->si_m_endpos.lnum >= current_lnum) + if (!force && sip->si_m_endpos.lnum >= current_lnum) { return; + } /* * We need to find the end of the region. It may continue in the next @@ -2482,23 +2559,23 @@ static void update_si_end(stateitem_T *sip, int startcol, bool force) }; lpos_T endpos = { 0 }; find_endpos(sip->si_idx, &startpos, &endpos, &hl_endpos, - &(sip->si_flags), &end_endpos, &end_idx, sip->si_extmatch); + &(sip->si_flags), &end_endpos, &end_idx, sip->si_extmatch); if (endpos.lnum == 0) { - /* No end pattern matched. */ + // No end pattern matched. if (SYN_ITEMS(syn_block)[sip->si_idx].sp_flags & HL_ONELINE) { - /* a "oneline" never continues in the next line */ + // a "oneline" never continues in the next line sip->si_ends = TRUE; sip->si_m_endpos.lnum = current_lnum; sip->si_m_endpos.col = (colnr_T)STRLEN(syn_getcurline()); } else { - /* continues in the next line */ + // continues in the next line sip->si_ends = FALSE; sip->si_m_endpos.lnum = 0; } sip->si_h_endpos = sip->si_m_endpos; } else { - /* match within this line */ + // match within this line sip->si_m_endpos = endpos; sip->si_h_endpos = hl_endpos; sip->si_eoe_pos = end_endpos; @@ -2527,49 +2604,49 @@ static void pop_current_state(void) unref_extmatch(CUR_STATE(current_state.ga_len - 1).si_extmatch); --current_state.ga_len; } - /* after the end of a pattern, try matching a keyword or pattern */ + // after the end of a pattern, try matching a keyword or pattern next_match_idx = -1; - /* if first state with "keepend" is popped, reset keepend_level */ - if (keepend_level >= current_state.ga_len) + // if first state with "keepend" is popped, reset keepend_level + if (keepend_level >= current_state.ga_len) { keepend_level = -1; + } } -/* - * Find the end of a start/skip/end syntax region after "startpos". - * Only checks one line. - * Also handles a match item that continued from a previous line. - * If not found, the syntax item continues in the next line. m_endpos->lnum - * will be 0. - * If found, the end of the region and the end of the highlighting is - * computed. - */ -static void -find_endpos( - int idx, // index of the pattern - lpos_T *startpos, // where to start looking for an END match - lpos_T *m_endpos, // return: end of match - lpos_T *hl_endpos, // return: end of highlighting - long *flagsp, // return: flags of matching END - lpos_T *end_endpos, // return: end of end pattern match - int *end_idx, // return: group ID for end pat. match, or 0 - reg_extmatch_T *start_ext // submatches from the start pattern -) +/// Find the end of a start/skip/end syntax region after "startpos". +/// Only checks one line. +/// Also handles a match item that continued from a previous line. +/// If not found, the syntax item continues in the next line. m_endpos->lnum +/// will be 0. +/// If found, the end of the region and the end of the highlighting is +/// computed. +/// +/// @param idx index of the pattern +/// @param startpos where to start looking for an END match +/// @param m_endpos return: end of match +/// @param hl_endpos return: end of highlighting +/// @param flagsp return: flags of matching END +/// @param end_endpos return: end of end pattern match +/// @param end_idx return: group ID for end pat. match, or 0 +/// @param start_ext submatches from the start pattern +static void find_endpos(int idx, lpos_T *startpos, lpos_T *m_endpos, lpos_T *hl_endpos, + long *flagsp, lpos_T *end_endpos, int *end_idx, reg_extmatch_T *start_ext) { colnr_T matchcol; - synpat_T *spp, *spp_skip; + synpat_T *spp, *spp_skip; int start_idx; int best_idx; regmmatch_T regmatch; - regmmatch_T best_regmatch; /* startpos/endpos of best match */ + regmmatch_T best_regmatch; // startpos/endpos of best match lpos_T pos; - char_u *line; + char_u *line; bool had_match = false; char_u buf_chartab[32]; // chartab array for syn option iskeyword - /* just in case we are invoked for a keyword */ - if (idx < 0) + // just in case we are invoked for a keyword + if (idx < 0) { return; + } /* * Check for being called with a START pattern. @@ -2587,21 +2664,23 @@ find_endpos( */ for (;; ) { spp = &(SYN_ITEMS(syn_block)[idx]); - if (spp->sp_type != SPTYPE_START) + if (spp->sp_type != SPTYPE_START) { break; + } ++idx; } /* - * Lookup the SKIP pattern (if present) + * Lookup the SKIP pattern (if present) */ if (spp->sp_type == SPTYPE_SKIP) { spp_skip = spp; ++idx; - } else + } else { spp_skip = NULL; + } - /* Setup external matches for syn_regexec(). */ + // Setup external matches for syn_regexec(). unref_extmatch(re_extmatch_in); re_extmatch_in = ref_extmatch(start_ext); @@ -2621,11 +2700,13 @@ find_endpos( int lc_col = matchcol; spp = &(SYN_ITEMS(syn_block)[idx]); - if (spp->sp_type != SPTYPE_END) /* past last END pattern */ + if (spp->sp_type != SPTYPE_END) { // past last END pattern break; + } lc_col -= spp->sp_offsets[SPO_LC_OFF]; - if (lc_col < 0) + if (lc_col < 0) { lc_col = 0; + } regmatch.rmm_ic = spp->sp_ic; regmatch.regprog = spp->sp_prog; @@ -2646,8 +2727,9 @@ find_endpos( * If all end patterns have been tried, and there is no match, the * item continues until end-of-line. */ - if (best_idx == -1) + if (best_idx == -1) { break; + } /* * If the skip pattern matches before the end pattern, @@ -2656,8 +2738,9 @@ find_endpos( if (spp_skip != NULL) { int lc_col = matchcol - spp_skip->sp_offsets[SPO_LC_OFF]; - if (lc_col < 0) + if (lc_col < 0) { lc_col = 0; + } regmatch.rmm_ic = spp_skip->sp_ic; regmatch.regprog = spp_skip->sp_prog; int r = syn_regexec(®match, startpos->lnum, lc_col, @@ -2704,16 +2787,18 @@ find_endpos( */ spp = &(SYN_ITEMS(syn_block)[best_idx]); syn_add_end_off(m_endpos, &best_regmatch, spp, SPO_ME_OFF, 1); - /* can't end before the start */ - if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col) + // can't end before the start + if (m_endpos->lnum == startpos->lnum && m_endpos->col < startpos->col) { m_endpos->col = startpos->col; + } syn_add_end_off(end_endpos, &best_regmatch, spp, SPO_HE_OFF, 1); - /* can't end before the start */ + // can't end before the start if (end_endpos->lnum == startpos->lnum - && end_endpos->col < startpos->col) + && end_endpos->col < startpos->col) { end_endpos->col = startpos->col; - /* can't end after the match */ + } + // can't end after the match limit_pos(end_endpos, m_endpos); /* @@ -2730,10 +2815,11 @@ find_endpos( } hl_endpos->col += spp->sp_offsets[SPO_RE_OFF]; - /* can't end before the start */ + // can't end before the start if (hl_endpos->lnum == startpos->lnum - && hl_endpos->col < startpos->col) + && hl_endpos->col < startpos->col) { hl_endpos->col = startpos->col; + } limit_pos(hl_endpos, m_endpos); /* now the match ends where the highlighting ends, it is turned @@ -2750,13 +2836,14 @@ find_endpos( break; } - /* no match for an END pattern in this line */ - if (!had_match) + // no match for an END pattern in this line + if (!had_match) { m_endpos->lnum = 0; + } restore_chartab(buf_chartab); - /* Remove external matches. */ + // Remove external matches. unref_extmatch(re_extmatch_in); re_extmatch_in = NULL; } @@ -2766,10 +2853,11 @@ find_endpos( */ static void limit_pos(lpos_T *pos, lpos_T *limit) { - if (pos->lnum > limit->lnum) + if (pos->lnum > limit->lnum) { *pos = *limit; - else if (pos->lnum == limit->lnum && pos->col > limit->col) + } else if (pos->lnum == limit->lnum && pos->col > limit->col) { pos->col = limit->col; + } } /* @@ -2777,28 +2865,27 @@ static void limit_pos(lpos_T *pos, lpos_T *limit) */ static void limit_pos_zero(lpos_T *pos, lpos_T *limit) { - if (pos->lnum == 0) + if (pos->lnum == 0) { *pos = *limit; - else + } else { limit_pos(pos, limit); + } } -/* - * Add offset to matched text for end of match or highlight. - */ -static void -syn_add_end_off( - lpos_T *result, // returned position - regmmatch_T *regmatch, // start/end of match - synpat_T *spp, // matched pattern - int idx, // index of offset - int extra // extra chars for offset to start -) +/// Add offset to matched text for end of match or highlight. +/// +/// @param result returned position +/// @param regmatch start/end of match +/// @param spp matched pattern +/// @param idx index of offset +/// @param extra extra chars for offset to start +static void syn_add_end_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, + int extra) { int col; int off; - char_u *base; - char_u *p; + char_u *base; + char_u *p; if (spp->sp_off_flags & (1 << idx)) { result->lnum = regmatch->startpos[0].lnum; @@ -2830,23 +2917,19 @@ syn_add_end_off( result->col = col; } -/* - * Add offset to matched text for start of match or highlight. - * Avoid resulting column to become negative. - */ -static void -syn_add_start_off( - lpos_T *result, // returned position - regmmatch_T *regmatch, // start/end of match - synpat_T *spp, - int idx, - int extra // extra chars for offset to end -) +/// Add offset to matched text for start of match or highlight. +/// Avoid resulting column to become negative. +/// +/// @param result returned position +/// @param regmatch start/end of match +/// @param extra extra chars for offset to end +static void syn_add_start_off(lpos_T *result, regmmatch_T *regmatch, synpat_T *spp, int idx, + int extra) { int col; int off; - char_u *base; - char_u *p; + char_u *base; + char_u *p; if (spp->sp_off_flags & (1 << (idx + SPO_COUNT))) { result->lnum = regmatch->endpos[0].lnum; @@ -2858,7 +2941,7 @@ syn_add_start_off( off = spp->sp_offsets[idx]; } if (result->lnum > syn_buf->b_ml.ml_line_count) { - /* a "\n" at the end of the pattern may take us below the last line */ + // a "\n" at the end of the pattern may take us below the last line result->lnum = syn_buf->b_ml.ml_line_count; col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, false)); } @@ -2920,8 +3003,9 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T st->slowest = pt; } ++st->count; - if (r > 0) + if (r > 0) { ++st->match; + } } if (timed_out && !syn_win->w_s->b_syn_slow) { syn_win->w_s->b_syn_slow = true; @@ -2936,20 +3020,19 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T return FALSE; } -/* - * Check one position in a line for a matching keyword. - * 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 *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 -) +/// Check one position in a line for a matching keyword. +/// The caller must check if a keyword can start at startcol. +/// Return its ID if found, 0 otherwise. +/// +/// @param startcol position in line to check for keyword +/// @param endcolp return: character after found keyword +/// @param flagsp return: flags of matching keyword +/// @param next_listp return: next_list of matching keyword +/// @param cur_si item at the top of the stack +/// @param ccharp conceal substitution char +static int check_keyword_id(char_u *const line, const int startcol, int *const endcolp, + long *const flagsp, int16_t **const next_listp, + stateitem_T *const cur_si, int *const ccharp) { // Find first character after the keyword. First character was already // checked. @@ -2997,11 +3080,10 @@ static int check_keyword_id( /// When current_next_list is non-zero accept only that group, otherwise: /// Accept a not-contained keyword at toplevel. /// Accept a keyword at other levels only if it is in the contains list. -static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht, - stateitem_T *cur_si) +static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht, stateitem_T *cur_si) { hashitem_T *hi = hash_find(ht, keyword); - if (!HASHITEM_EMPTY(hi)) + if (!HASHITEM_EMPTY(hi)) { for (keyentry_T *kp = HI2KE(hi); kp != NULL; kp = kp->ke_next) { if (current_next_list != 0 ? in_id_list(NULL, current_next_list, &kp->k_syn, 0) @@ -3012,6 +3094,7 @@ static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht, return kp; } } + } return NULL; } @@ -3020,12 +3103,13 @@ static keyentry_T *match_keyword(char_u *keyword, hashtab_T *ht, */ static void syn_cmd_conceal(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *next; + char_u *arg = eap->arg; + char_u *next; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } next = skiptowhite(arg); if (*arg == NUL) { @@ -3048,12 +3132,13 @@ static void syn_cmd_conceal(exarg_T *eap, int syncing) */ static void syn_cmd_case(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *next; + char_u *arg = eap->arg; + char_u *next; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } next = skiptowhite(arg); if (*arg == NUL) { @@ -3078,14 +3163,18 @@ static void syn_cmd_foldlevel(exarg_T *eap, int syncing) char_u *arg_end; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } if (*arg == NUL) { switch (curwin->w_s->b_syn_foldlevel) { - case SYNFLD_START: MSG(_("syntax foldlevel start")); break; - case SYNFLD_MINIMUM: MSG(_("syntax foldlevel minimum")); break; - default: break; + case SYNFLD_START: + MSG(_("syntax foldlevel start")); break; + case SYNFLD_MINIMUM: + MSG(_("syntax foldlevel minimum")); break; + default: + break; } return; } @@ -3111,12 +3200,13 @@ static void syn_cmd_foldlevel(exarg_T *eap, int syncing) */ static void syn_cmd_spell(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *next; + char_u *arg = eap->arg; + char_u *next; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } next = skiptowhite(arg); if (*arg == NUL) { @@ -3195,17 +3285,17 @@ void syntax_clear(synblock_T *block) block->b_syn_containedin = false; block->b_syn_conceal = false; - /* free the keywords */ + // free the keywords clear_keywtab(&block->b_keywtab); clear_keywtab(&block->b_keywtab_ic); - /* free the syntax patterns */ + // free the syntax patterns for (int i = block->b_syn_patterns.ga_len; --i >= 0; ) { syn_clear_pattern(block, i); } ga_clear(&block->b_syn_patterns); - /* free the syntax clusters */ + // free the syntax clusters for (int i = block->b_syn_clusters.ga_len; --i >= 0; ) { syn_clear_cluster(block, i); } @@ -3224,11 +3314,11 @@ void syntax_clear(synblock_T *block) block->b_syn_folditems = 0; clear_string_option(&block->b_syn_isk); - /* free the stored states */ + // free the stored states syn_stack_free_all(block); invalidate_current_state(); - /* Reset the counter for ":syn include" */ + // Reset the counter for ":syn include" running_syn_inc_tag = 0; } @@ -3249,7 +3339,7 @@ void reset_synblock(win_T *wp) */ static void syntax_sync_clear(void) { - /* free the syntax patterns */ + // free the syntax patterns for (int i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) { if (SYN_ITEMS(curwin->w_s)[i].sp_syncing) { syn_remove_pattern(curwin->w_s, i); @@ -3266,7 +3356,7 @@ static void syntax_sync_clear(void) XFREE_CLEAR(curwin->w_s->b_syn_linecont_pat); clear_string_option(&curwin->w_s->b_syn_isk); - syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ + syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } /* @@ -3274,14 +3364,15 @@ static void syntax_sync_clear(void) */ static void syn_remove_pattern(synblock_T *block, int idx) { - synpat_T *spp; + synpat_T *spp; spp = &(SYN_ITEMS(block)[idx]); - if (spp->sp_flags & HL_FOLD) + if (spp->sp_flags & HL_FOLD) { --block->b_syn_folditems; + } syn_clear_pattern(block, idx); memmove(spp, spp + 1, - sizeof(synpat_T) * (block->b_syn_patterns.ga_len - idx - 1)); + sizeof(synpat_T) * (block->b_syn_patterns.ga_len - idx - 1)); --block->b_syn_patterns.ga_len; } @@ -3293,7 +3384,7 @@ static void syn_clear_pattern(synblock_T *block, int i) { xfree(SYN_ITEMS(block)[i].sp_pattern); vim_regfree(SYN_ITEMS(block)[i].sp_prog); - /* Only free sp_cont_list and sp_next_list of first start pattern */ + // Only free sp_cont_list and sp_next_list of first start pattern if (i == 0 || SYN_ITEMS(block)[i - 1].sp_type != SPTYPE_START) { xfree(SYN_ITEMS(block)[i].sp_cont_list); xfree(SYN_ITEMS(block)[i].sp_next_list); @@ -3316,13 +3407,14 @@ static void syn_clear_cluster(synblock_T *block, int i) */ static void syn_cmd_clear(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *arg_end; + char_u *arg = eap->arg; + char_u *arg_end; int id; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } /* * We have to disable this within ":syn include @group filename", @@ -3330,16 +3422,17 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) * Only required for Vim 5.x syntax files, 6.0 ones don't contain ":syn * clear". */ - if (curwin->w_s->b_syn_topgrp != 0) + if (curwin->w_s->b_syn_topgrp != 0) { return; + } if (ends_excmd(*arg)) { /* * No argument: Clear all syntax items. */ - if (syncing) + if (syncing) { syntax_sync_clear(); - else { + } else { syntax_clear(curwin->w_s); if (curwin->w_s == &curwin->w_buffer->b_s) { do_unlet(S_LEN("b:current_syntax"), true); @@ -3370,14 +3463,15 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) if (id == 0) { EMSG2(_(e_nogroup), arg); break; - } else + } else { syn_clear_one(id, syncing); + } } arg = skipwhite(arg_end); } } redraw_curbuf_later(SOME_VALID); - syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ + syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } /* @@ -3385,19 +3479,20 @@ static void syn_cmd_clear(exarg_T *eap, int syncing) */ static void syn_clear_one(const int id, const bool syncing) { - synpat_T *spp; + synpat_T *spp; - /* Clear keywords only when not ":syn sync clear group-name" */ + // Clear keywords only when not ":syn sync clear group-name" if (!syncing) { syn_clear_keyword(id, &curwin->w_s->b_keywtab); syn_clear_keyword(id, &curwin->w_s->b_keywtab_ic); } - /* clear the patterns for "id" */ + // clear the patterns for "id" for (int idx = curwin->w_s->b_syn_patterns.ga_len; --idx >= 0; ) { spp = &(SYN_ITEMS(curwin->w_s)[idx]); - if (spp->sp_syn.id != id || spp->sp_syncing != syncing) + if (spp->sp_syn.id != id || spp->sp_syncing != syncing) { continue; + } syn_remove_pattern(curwin->w_s, idx); } } @@ -3461,21 +3556,18 @@ void syn_maybe_enable(void) } } -/* - * Handle ":syntax [list]" command: list current syntax words. - */ -static void -syn_cmd_list( - exarg_T *eap, - int syncing /* when TRUE: list syncing items */ -) +/// Handle ":syntax [list]" command: list current syntax words. +/// +/// @param syncing when TRUE: list syncing items +static void syn_cmd_list(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *arg_end; + char_u *arg = eap->arg; + char_u *arg_end; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } if (!syntax_present(curwin)) { MSG(_(msg_no_items)); @@ -3488,7 +3580,7 @@ syn_cmd_list( syn_lines_msg(); syn_match_msg(); return; - } else if (!(curwin->w_s->b_syn_sync_flags & SF_MATCH)) { + } else if (!(curwin->w_s->b_syn_sync_flags & SF_MATCH)) { if (curwin->w_s->b_syn_sync_minlines == 0) { MSG_PUTS(_("no syncing")); } else { @@ -3511,8 +3603,9 @@ syn_cmd_list( syn_lines_msg(); syn_match_msg(); } - } else + } else { MSG_PUTS_TITLE(_("\n--- Syntax items ---")); + } if (ends_excmd(*arg)) { /* * No argument: List all group IDs and all syntax clusters. @@ -3531,10 +3624,11 @@ syn_cmd_list( arg_end = skiptowhite(arg); if (*arg == '@') { int id = syn_scl_namen2id(arg + 1, (int)(arg_end - arg - 1)); - if (id == 0) + if (id == 0) { EMSG2(_("E392: No such syntax cluster: %s"), arg); - else + } else { syn_list_cluster(id - SYNID_CLUSTER); + } } else { int id = syn_name2id_len(arg, (int)(arg_end - arg)); if (id == 0) { @@ -3585,37 +3679,33 @@ static void syn_match_msg(void) static int last_matchgroup; -/* - * List one syntax item, for ":syntax" or "syntax list syntax_name". - */ -static void -syn_list_one( - const int id, - const bool syncing, // when true: list syncing items - const bool link_only // when true; list link-only too -) +/// List one syntax item, for ":syntax" or "syntax list syntax_name". +/// +/// @param syncing when true: list syncing items +/// @param link_only when true; list link-only too +static void syn_list_one(const int id, const bool syncing, const bool link_only) { bool did_header = false; static struct name_list namelist1[] = { - {HL_DISPLAY, "display"}, - {HL_CONTAINED, "contained"}, - {HL_ONELINE, "oneline"}, - {HL_KEEPEND, "keepend"}, - {HL_EXTEND, "extend"}, - {HL_EXCLUDENL, "excludenl"}, - {HL_TRANSP, "transparent"}, - {HL_FOLD, "fold"}, - {HL_CONCEAL, "conceal"}, - {HL_CONCEALENDS, "concealends"}, - {0, NULL} + { HL_DISPLAY, "display" }, + { HL_CONTAINED, "contained" }, + { HL_ONELINE, "oneline" }, + { HL_KEEPEND, "keepend" }, + { HL_EXTEND, "extend" }, + { HL_EXCLUDENL, "excludenl" }, + { HL_TRANSP, "transparent" }, + { HL_FOLD, "fold" }, + { HL_CONCEAL, "conceal" }, + { HL_CONCEALENDS, "concealends" }, + { 0, NULL } }; static struct name_list namelist2[] = { - {HL_SKIPWHITE, "skipwhite"}, - {HL_SKIPNL, "skipnl"}, - {HL_SKIPEMPTY, "skipempty"}, - {0, NULL} + { HL_SKIPWHITE, "skipwhite" }, + { HL_SKIPNL, "skipnl" }, + { HL_SKIPEMPTY, "skipempty" }, + { 0, NULL } }; const int attr = HL_ATTR(HLF_D); // highlight like directories @@ -3642,14 +3732,17 @@ syn_list_one( if (spp->sp_type == SPTYPE_MATCH) { put_pattern("match", ' ', spp, attr); msg_putchar(' '); - } else if (spp->sp_type == SPTYPE_START) { - while (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_START) + } else if (spp->sp_type == SPTYPE_START) { + while (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_START) { put_pattern("start", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr); - if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP) + } + if (SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_SKIP) { put_pattern("skip", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr); + } while (idx < curwin->w_s->b_syn_patterns.ga_len - && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END) + && SYN_ITEMS(curwin->w_s)[idx].sp_type == SPTYPE_END) { put_pattern("end", '=', &SYN_ITEMS(curwin->w_s)[idx++], attr); + } --idx; msg_putchar(' '); } @@ -3674,16 +3767,17 @@ syn_list_one( msg_puts_attr("groupthere", attr); } msg_putchar(' '); - if (spp->sp_sync_idx >= 0) + if (spp->sp_sync_idx >= 0) { msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s) [spp->sp_sync_idx].sp_syn.id - 1].sg_name); - else + } else { MSG_PUTS("NONE"); + } msg_putchar(' '); } } - /* list the link, if there is one */ + // list the link, if there is one if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int) { (void)syn_list_header(did_header, 0, id, true); msg_puts_attr("links to", attr); @@ -3696,11 +3790,12 @@ static void syn_list_flags(struct name_list *nlist, int flags, int attr) { int i; - for (i = 0; nlist[i].flag != 0; ++i) + for (i = 0; nlist[i].flag != 0; ++i) { if (flags & nlist[i].flag) { msg_puts_attr(nlist[i].name, attr); msg_putchar(' '); } + } } /* @@ -3710,14 +3805,16 @@ static void syn_list_cluster(int id) { int endcol = 15; - /* slight hack: roughly duplicate the guts of syn_list_header() */ + // slight hack: roughly duplicate the guts of syn_list_header() msg_putchar('\n'); msg_outtrans(SYN_CLSTR(curwin->w_s)[id].scl_name); - if (msg_col >= endcol) /* output at least one space */ + if (msg_col >= endcol) { // output at least one space endcol = msg_col + 1; - if (Columns <= endcol) /* avoid hang for tiny window */ + } + if (Columns <= endcol) { // avoid hang for tiny window endcol = Columns - 1; + } msg_advance(endcol); if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) { @@ -3728,9 +3825,7 @@ static void syn_list_cluster(int id) } } -static void put_id_list(const char *const name, - const int16_t *const list, - const int attr) +static void put_id_list(const char *const name, const int16_t *const list, const int attr) { msg_puts_attr(name, attr); msg_putchar('='); @@ -3741,38 +3836,40 @@ static void put_id_list(const char *const name, } else { msg_puts("ALL"); } - } else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) { + } else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) { msg_puts("TOP"); - } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) { + } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) { msg_puts("CONTAINED"); - } else if (*p >= SYNID_CLUSTER) { + } else if (*p >= SYNID_CLUSTER) { int scl_id = *p - SYNID_CLUSTER; msg_putchar('@'); msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name); - } else + } else { msg_outtrans(HL_TABLE()[*p - 1].sg_name); - if (p[1]) + } + if (p[1]) { msg_putchar(','); + } } msg_putchar(' '); } -static void put_pattern(const char *const s, const int c, - const synpat_T *const spp, const int attr) +static void put_pattern(const char *const s, const int c, const synpat_T *const spp, const int attr) { static const char *const sepchars = "/+=-#@\"|'^&"; int i; - /* May have to write "matchgroup=group" */ + // May have to write "matchgroup=group" if (last_matchgroup != spp->sp_syn_match_id) { last_matchgroup = spp->sp_syn_match_id; msg_puts_attr("matchgroup", attr); msg_putchar('='); - if (last_matchgroup == 0) + if (last_matchgroup == 0) { msg_outtrans((char_u *)"NONE"); - else + } else { msg_outtrans(HL_TABLE()[last_matchgroup - 1].sg_name); + } msg_putchar(' '); } @@ -3780,12 +3877,13 @@ static void put_pattern(const char *const s, const int c, msg_puts_attr(s, attr); msg_putchar(c); - /* output the pattern, in between a char that is not in the pattern */ - for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; ) + // output the pattern, in between a char that is not in the pattern + for (i = 0; vim_strchr(spp->sp_pattern, sepchars[i]) != NULL; ) { if (sepchars[++i] == NUL) { - i = 0; /* no good char found, just use the first one */ + i = 0; // no good char found, just use the first one break; } + } msg_putchar(sepchars[i]); msg_outtrans(spp->sp_pattern); msg_putchar(sepchars[i]); @@ -3803,12 +3901,14 @@ static void put_pattern(const char *const s, const int c, msg_puts(spo_name_tab[i]); const long n = spp->sp_offsets[i]; if (i != SPO_LC_OFF) { - if (spp->sp_off_flags & mask) + if (spp->sp_off_flags & mask) { msg_putchar('s'); - else + } else { msg_putchar('e'); - if (n > 0) + } + if (n > 0) { msg_putchar('+'); + } } if (n || i == SPO_LC_OFF) { msg_outnum(n); @@ -3818,14 +3918,13 @@ static void put_pattern(const char *const s, const int c, msg_putchar(' '); } -// 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 -) +/// List or clear the keywords for one syntax group. +/// +/// @param did_header header has already been printed +/// +/// @return true if the header has been printed. +static bool syn_list_keywords(const int id, const hashtab_T *const ht, bool did_header, + const int attr) { int prev_contained = 0; const int16_t *prev_next_list = NULL; @@ -3852,7 +3951,7 @@ static bool syn_list_keywords( || prev_skipempty != (kp->flags & HL_SKIPEMPTY) || prev_cont_in_list != kp->k_syn.cont_in_list || prev_next_list != kp->next_list) { - force_newline = true; + force_newline = true; } else { outlen = (int)STRLEN(kp->keyword); } @@ -3906,10 +4005,10 @@ static bool syn_list_keywords( static void syn_clear_keyword(int id, hashtab_T *ht) { - hashitem_T *hi; - keyentry_T *kp; - keyentry_T *kp_prev; - keyentry_T *kp_next; + hashitem_T *hi; + keyentry_T *kp; + keyentry_T *kp_prev; + keyentry_T *kp_next; int todo; hash_lock(ht); @@ -3924,12 +4023,14 @@ static void syn_clear_keyword(int id, hashtab_T *ht) if (kp->k_syn.id == id) { kp_next = kp->ke_next; if (kp_prev == NULL) { - if (kp_next == NULL) + if (kp_next == NULL) { hash_remove(ht, hi); - else + } else { hi->hi_key = KE2HIKEY(kp_next); - } else + } + } else { kp_prev->ke_next = kp_next; + } xfree(kp->next_list); xfree(kp->k_syn.cont_in_list); xfree(kp); @@ -3948,10 +4049,10 @@ static void syn_clear_keyword(int id, hashtab_T *ht) */ static void clear_keywtab(hashtab_T *ht) { - hashitem_T *hi; + hashitem_T *hi; int todo; - keyentry_T *kp; - keyentry_T *kp_next; + keyentry_T *kp; + keyentry_T *kp_next; todo = (int)ht->ht_used; for (hi = ht->ht_array; todo > 0; ++hi) { @@ -3976,11 +4077,8 @@ 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 *const name, - const int id, - const int flags, - int16_t *const cont_in_list, - int16_t *const next_list, +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]; @@ -4022,18 +4120,16 @@ static void add_keyword(char_u *const name, } } -/* - * Get the start and end of the group name argument. - * Return a pointer to the first argument. - * Return NULL if the end of the command was found instead of further args. - */ -static char_u * -get_group_name ( - char_u *arg, /* start of the argument */ - char_u **name_end /* pointer to end of the name */ -) +/// Get the start and end of the group name argument. +/// +/// @param arg start of the argument +/// @param name_end pointer to end of the name +/// +/// @return a pointer to the first argument. +/// Return NULL if the end of the command was found instead of further args. +static char_u *get_group_name(char_u *arg, char_u **name_end) { - char_u *rest; + char_u *rest; *name_end = skiptowhite(arg); rest = skipwhite(*name_end); @@ -4042,62 +4138,62 @@ get_group_name ( * Check if there are enough arguments. The first argument may be a * pattern, where '|' is allowed, so only check for NUL. */ - if (ends_excmd(*arg) || *rest == NUL) + if (ends_excmd(*arg) || *rest == NUL) { return NULL; + } return rest; } -/* - * Check for syntax command option arguments. - * This can be called at any place in the list of arguments, and just picks - * out the arguments that are known. Can be called several times in a row to - * collect all options in between other arguments. - * Return a pointer to the next argument (which isn't an option). - * Return NULL for any error; - */ -static char_u * -get_syn_options( - char_u *arg, // next argument to be checked - syn_opt_arg_T *opt, // various things - int *conceal_char, - int skip // TRUE if skipping over command -) -{ - char_u *gname_start, *gname; +/// Check for syntax command option arguments. +/// This can be called at any place in the list of arguments, and just picks +/// out the arguments that are known. Can be called several times in a row to +/// collect all options in between other arguments. +/// +/// @param arg next argument to be checked +/// @param opt various things +/// @param skip TRUE if skipping over command +/// +/// @return a pointer to the next argument (which isn't an option). +/// Return NULL for any error; +static char_u *get_syn_options(char_u *arg, syn_opt_arg_T *opt, int *conceal_char, int skip) +{ + char_u *gname_start, *gname; int syn_id; int len = 0; - char *p; + char *p; int fidx; static const struct flag { - char *name; + char *name; int argtype; int flags; - } flagtab[] = { {"cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED}, - {"oOnNeElLiInNeE", 0, HL_ONELINE}, - {"kKeEeEpPeEnNdD", 0, HL_KEEPEND}, - {"eExXtTeEnNdD", 0, HL_EXTEND}, - {"eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL}, - {"tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP}, - {"sSkKiIpPnNlL", 0, HL_SKIPNL}, - {"sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE}, - {"sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY}, - {"gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE}, - {"gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE}, - {"dDiIsSpPlLaAyY", 0, HL_DISPLAY}, - {"fFoOlLdD", 0, HL_FOLD}, - {"cCoOnNcCeEaAlL", 0, HL_CONCEAL}, - {"cCoOnNcCeEaAlLeEnNdDsS", 0, HL_CONCEALENDS}, - {"cCcChHaArR", 11, 0}, - {"cCoOnNtTaAiInNsS", 1, 0}, - {"cCoOnNtTaAiInNeEdDiInN", 2, 0}, - {"nNeExXtTgGrRoOuUpP", 3, 0},}; + } flagtab[] = { { "cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED }, + { "oOnNeElLiInNeE", 0, HL_ONELINE }, + { "kKeEeEpPeEnNdD", 0, HL_KEEPEND }, + { "eExXtTeEnNdD", 0, HL_EXTEND }, + { "eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL }, + { "tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP }, + { "sSkKiIpPnNlL", 0, HL_SKIPNL }, + { "sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE }, + { "sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY }, + { "gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE }, + { "gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE }, + { "dDiIsSpPlLaAyY", 0, HL_DISPLAY }, + { "fFoOlLdD", 0, HL_FOLD }, + { "cCoOnNcCeEaAlL", 0, HL_CONCEAL }, + { "cCoOnNcCeEaAlLeEnNdDsS", 0, HL_CONCEALENDS }, + { "cCcChHaArR", 11, 0 }, + { "cCoOnNtTaAiInNsS", 1, 0 }, + { "cCoOnNtTaAiInNeEdDiInN", 2, 0 }, + { "nNeExXtTgGrRoOuUpP", 3, 0 }, }; static const char *const first_letters = "cCoOkKeEtTsSgGdDfFnN"; - if (arg == NULL) /* already detected error */ + if (arg == NULL) { // already detected error return NULL; + } - if (curwin->w_s->b_syn_conceal) + if (curwin->w_s->b_syn_conceal) { opt->flags |= HL_CONCEAL; + } for (;; ) { /* @@ -4105,15 +4201,17 @@ get_syn_options( * Need to skip quickly when no option name is found. * Also avoid tolower(), it's slow. */ - if (strchr(first_letters, *arg) == NULL) + if (strchr(first_letters, *arg) == NULL) { break; + } for (fidx = ARRAY_SIZE(flagtab); --fidx >= 0; ) { p = flagtab[fidx].name; int i; for (i = 0, len = 0; p[i] != NUL; i += 2, ++len) { - if (arg[len] != p[i] && arg[len] != p[i + 1]) + if (arg[len] != p[i] && arg[len] != p[i + 1]) { break; + } } if (p[i] == NUL && (ascii_iswhite(arg[len]) || (flagtab[fidx].argtype > 0 @@ -4122,14 +4220,16 @@ get_syn_options( if (opt->keyword && (flagtab[fidx].flags == HL_DISPLAY || flagtab[fidx].flags == HL_FOLD - || flagtab[fidx].flags == HL_EXTEND)) - /* treat "display", "fold" and "extend" as a keyword */ + || flagtab[fidx].flags == HL_EXTEND)) { + // treat "display", "fold" and "extend" as a keyword fidx = -1; + } break; } } - if (fidx < 0) /* no match found */ + if (fidx < 0) { // no match found break; + } if (flagtab[fidx].argtype == 1) { if (!opt->has_cont_list) { @@ -4139,15 +4239,15 @@ get_syn_options( if (get_id_list(&arg, 8, &opt->cont_list, skip) == FAIL) { return NULL; } - } else if (flagtab[fidx].argtype == 2) { + } else if (flagtab[fidx].argtype == 2) { if (get_id_list(&arg, 11, &opt->cont_in_list, skip) == FAIL) { return NULL; } - } else if (flagtab[fidx].argtype == 3) { + } else if (flagtab[fidx].argtype == 3) { if (get_id_list(&arg, 9, &opt->next_list, skip) == FAIL) { return NULL; } - } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') { + } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') { // cchar=? *conceal_char = utf_ptr2char(arg + 6); arg += mb_ptr2len(arg + 6) - 1; @@ -4168,20 +4268,22 @@ get_syn_options( } gname_start = arg; arg = skiptowhite(arg); - if (gname_start == arg) + if (gname_start == arg) { return NULL; + } gname = vim_strnsave(gname_start, arg - gname_start); if (STRCMP(gname, "NONE") == 0) { *opt->sync_idx = NONE_IDX; } else { syn_id = syn_name2id(gname); int i; - for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) + for (i = curwin->w_s->b_syn_patterns.ga_len; --i >= 0; ) { if (SYN_ITEMS(curwin->w_s)[i].sp_syn.id == syn_id && SYN_ITEMS(curwin->w_s)[i].sp_type == SPTYPE_START) { *opt->sync_idx = i; break; } + } if (i < 0) { EMSG2(_("E394: Didn't find region item for %s"), gname); xfree(gname); @@ -4192,9 +4294,10 @@ get_syn_options( xfree(gname); arg = skipwhite(arg); } else if (flagtab[fidx].flags == HL_FOLD - && foldmethodIsSyntax(curwin)) - /* Need to update folds later. */ + && foldmethodIsSyntax(curwin)) { + // Need to update folds later. foldUpdateAll(curwin); + } } } @@ -4208,8 +4311,9 @@ get_syn_options( */ static void syn_incl_toplevel(int id, int *flagsp) { - if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0) + if ((*flagsp & HL_CONTAINED) || curwin->w_s->b_syn_topgrp == 0) { 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. @@ -4219,7 +4323,7 @@ static void syn_incl_toplevel(int id, int *flagsp) grp_list[0] = id; grp_list[1] = 0; syn_combine_list(&SYN_CLSTR(curwin->w_s)[tlg_id].scl_list, &grp_list, - CLUSTER_ADD); + CLUSTER_ADD); } } @@ -4228,18 +4332,19 @@ static void syn_incl_toplevel(int id, int *flagsp) */ static void syn_cmd_include(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; + char_u *arg = eap->arg; int sgl_id = 1; - char_u *group_name_end; - char_u *rest; - char_u *errormsg = NULL; + char_u *group_name_end; + char_u *rest; + char_u *errormsg = NULL; int prev_toplvl_grp; int prev_syn_inc_tag; bool source = false; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } if (arg[0] == '@') { ++arg; @@ -4249,9 +4354,10 @@ static void syn_cmd_include(exarg_T *eap, int syncing) return; } sgl_id = syn_check_cluster(arg, (int)(group_name_end - arg)); - if (sgl_id == 0) + if (sgl_id == 0) { return; - /* separate_nextcmd() and expand_filename() depend on this */ + } + // separate_nextcmd() and expand_filename() depend on this eap->arg = rest; } @@ -4267,8 +4373,9 @@ static void syn_cmd_include(exarg_T *eap, int syncing) // ":runtime!" is used. source = true; if (expand_filename(eap, syn_cmdlinep, &errormsg) == FAIL) { - if (errormsg != NULL) + if (errormsg != NULL) { EMSG(errormsg); + } return; } } @@ -4299,13 +4406,13 @@ static void syn_cmd_include(exarg_T *eap, int syncing) */ static void syn_cmd_keyword(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *group_name_end; + char_u *arg = eap->arg; + char_u *group_name_end; int syn_id; - char_u *rest; - char_u *keyword_copy = NULL; - char_u *p; - char_u *kw; + char_u *rest; + char_u *keyword_copy = NULL; + char_u *p; + char_u *kw; syn_opt_arg_T syn_opt_arg; int cnt; int conceal_char = NUL; @@ -4395,39 +4502,36 @@ error: } } - if (rest != NULL) + if (rest != NULL) { eap->nextcmd = check_nextcmd(rest); - else + } else { EMSG2(_(e_invarg2), arg); + } redraw_curbuf_later(SOME_VALID); - syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ + syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } -/* - * Handle ":syntax match {name} [{options}] {pattern} [{options}]". - * - * Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .." - */ -static void -syn_cmd_match( - exarg_T *eap, - int syncing /* TRUE for ":syntax sync match .. " */ -) -{ - char_u *arg = eap->arg; - char_u *group_name_end; - char_u *rest; - synpat_T item; /* the item found in the line */ +/// Handle ":syntax match {name} [{options}] {pattern} [{options}]". +/// +/// Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .." +/// +/// @param syncing TRUE for ":syntax sync match .. " +static void syn_cmd_match(exarg_T *eap, int syncing) +{ + char_u *arg = eap->arg; + char_u *group_name_end; + char_u *rest; + synpat_T item; // the item found in the line int syn_id; syn_opt_arg_T syn_opt_arg; int sync_idx = 0; int conceal_char = NUL; - /* Isolate the group name, check for validity */ + // Isolate the group name, check for validity rest = get_group_name(arg, &group_name_end); - /* Get options before the pattern */ + // Get options before the pattern syn_opt_arg.flags = 0; syn_opt_arg.keyword = false; syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL; @@ -4437,7 +4541,7 @@ syn_cmd_match( syn_opt_arg.next_list = NULL; rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); - /* get the pattern. */ + // get the pattern. init_syn_patterns(); memset(&item, 0, sizeof(item)); rest = get_syn_pattern(rest, &item); @@ -4448,14 +4552,14 @@ syn_cmd_match( // Get options after the pattern rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip); - if (rest != NULL) { /* all arguments are valid */ + if (rest != NULL) { // all arguments are valid /* * Check for trailing command and illegal trailing arguments. */ eap->nextcmd = check_nextcmd(rest); - if (!ends_excmd(*rest) || eap->skip) + if (!ends_excmd(*rest) || eap->skip) { rest = NULL; - else { + } else { if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) { syn_incl_toplevel(syn_id, &syn_opt_arg.flags); /* @@ -4473,19 +4577,22 @@ syn_cmd_match( spp->sp_cont_list = syn_opt_arg.cont_list; spp->sp_syn.cont_in_list = syn_opt_arg.cont_in_list; spp->sp_cchar = conceal_char; - if (syn_opt_arg.cont_in_list != NULL) + if (syn_opt_arg.cont_in_list != NULL) { curwin->w_s->b_syn_containedin = TRUE; + } spp->sp_next_list = syn_opt_arg.next_list; - /* remember that we found a match for syncing on */ - if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE)) + // remember that we found a match for syncing on + if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE)) { curwin->w_s->b_syn_sync_flags |= SF_MATCH; - if (syn_opt_arg.flags & HL_FOLD) + } + if (syn_opt_arg.flags & HL_FOLD) { ++curwin->w_s->b_syn_folditems; + } redraw_curbuf_later(SOME_VALID); - syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ - return; /* don't free the progs and patterns now */ + syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. + return; // don't free the progs and patterns now } } } @@ -4499,40 +4606,37 @@ syn_cmd_match( xfree(syn_opt_arg.cont_in_list); xfree(syn_opt_arg.next_list); - if (rest == NULL) + if (rest == NULL) { EMSG2(_(e_invarg2), arg); + } } -/* - * Handle ":syntax region {group-name} [matchgroup={group-name}] - * start {start} .. [skip {skip}] end {end} .. [{options}]". - */ -static void -syn_cmd_region( - exarg_T *eap, - int syncing /* TRUE for ":syntax sync region .." */ -) -{ - char_u *arg = eap->arg; - char_u *group_name_end; - char_u *rest; /* next arg, NULL on error */ - char_u *key_end; - char_u *key = NULL; - char_u *p; +/// Handle ":syntax region {group-name} [matchgroup={group-name}] +/// start {start} .. [skip {skip}] end {end} .. [{options}]". +/// +/// @param syncing TRUE for ":syntax sync region .." +static void syn_cmd_region(exarg_T *eap, int syncing) +{ + char_u *arg = eap->arg; + char_u *group_name_end; + char_u *rest; // next arg, NULL on error + char_u *key_end; + char_u *key = NULL; + char_u *p; int item; #define ITEM_START 0 #define ITEM_SKIP 1 #define ITEM_END 2 #define ITEM_MATCHGROUP 3 struct pat_ptr { - synpat_T *pp_synp; /* pointer to syn_pattern */ - int pp_matchgroup_id; /* matchgroup ID */ - struct pat_ptr *pp_next; /* pointer to next pat_ptr */ + synpat_T *pp_synp; // pointer to syn_pattern + int pp_matchgroup_id; // matchgroup ID + struct pat_ptr *pp_next; // pointer to next pat_ptr } *(pat_ptrs[3]); - /* patterns found in the line */ - struct pat_ptr *ppp; - struct pat_ptr *ppp_next; - int pat_count = 0; /* nr of syn_patterns found */ + // patterns found in the line + struct pat_ptr *ppp; + struct pat_ptr *ppp_next; + int pat_count = 0; // nr of syn_patterns found int syn_id; int matchgroup_id = 0; bool not_enough = false; // not enough arguments @@ -4541,7 +4645,7 @@ syn_cmd_region( syn_opt_arg_T syn_opt_arg; int conceal_char = NUL; - /* Isolate the group name, check for validity */ + // Isolate the group name, check for validity rest = get_group_name(arg, &group_name_end); pat_ptrs[0] = NULL; @@ -4566,10 +4670,11 @@ syn_cmd_region( break; } - /* must be a pattern or matchgroup then */ + // must be a pattern or matchgroup then key_end = rest; - while (*key_end && !ascii_iswhite(*key_end) && *key_end != '=') + while (*key_end && !ascii_iswhite(*key_end) && *key_end != '=') { ++key_end; + } xfree(key); key = vim_strnsave_up(rest, key_end - rest); if (STRCMP(key, "MATCHGROUP") == 0) { @@ -4601,9 +4706,9 @@ syn_cmd_region( if (item == ITEM_MATCHGROUP) { p = skiptowhite(rest); - if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip) + if ((p - rest == 4 && STRNCMP(rest, "NONE", 4) == 0) || eap->skip) { matchgroup_id = 0; - else { + } else { matchgroup_id = syn_check_group(rest, (int)(p - rest)); if (matchgroup_id == 0) { illegal = true; @@ -4642,8 +4747,9 @@ syn_cmd_region( } } xfree(key); - if (illegal || not_enough) + if (illegal || not_enough) { rest = NULL; + } // Must have a "start" and "end" pattern. if (rest != NULL && (pat_ptrs[ITEM_START] == NULL @@ -4658,9 +4764,9 @@ syn_cmd_region( * If OK, add the item. */ eap->nextcmd = check_nextcmd(rest); - if (!ends_excmd(*rest) || eap->skip) + if (!ends_excmd(*rest) || eap->skip) { rest = NULL; - else { + } else { ga_grow(&(curwin->w_s->b_syn_patterns), pat_count); if ((syn_id = syn_check_group(arg, (int)(group_name_end - arg))) != 0) { syn_incl_toplevel(syn_id, &syn_opt_arg.flags); @@ -4687,15 +4793,17 @@ syn_cmd_region( syn_opt_arg.cont_list; SYN_ITEMS(curwin->w_s)[idx].sp_syn.cont_in_list = syn_opt_arg.cont_in_list; - if (syn_opt_arg.cont_in_list != NULL) + if (syn_opt_arg.cont_in_list != NULL) { curwin->w_s->b_syn_containedin = TRUE; + } SYN_ITEMS(curwin->w_s)[idx].sp_next_list = syn_opt_arg.next_list; } ++curwin->w_s->b_syn_patterns.ga_len; ++idx; - if (syn_opt_arg.flags & HL_FOLD) + if (syn_opt_arg.flags & HL_FOLD) { ++curwin->w_s->b_syn_folditems; + } } } @@ -4709,7 +4817,7 @@ syn_cmd_region( /* * Free the allocated memory. */ - for (item = ITEM_START; item <= ITEM_END; ++item) + for (item = ITEM_START; item <= ITEM_END; ++item) { for (ppp = pat_ptrs[item]; ppp != NULL; ppp = ppp_next) { if (!success && ppp->pp_synp != NULL) { vim_regfree(ppp->pp_synp->sp_prog); @@ -4719,15 +4827,17 @@ syn_cmd_region( ppp_next = ppp->pp_next; xfree(ppp); } + } if (!success) { xfree(syn_opt_arg.cont_list); xfree(syn_opt_arg.cont_in_list); xfree(syn_opt_arg.next_list); - if (not_enough) + if (not_enough) { EMSG2(_("E399: Not enough arguments: syntax region %s"), arg); - else if (illegal || rest == NULL) + } else if (illegal || rest == NULL) { EMSG2(_(e_invarg2), arg); + } } } @@ -4742,8 +4852,7 @@ static int syn_compare_stub(const void *const v1, const void *const v2) // 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) +static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, const int list_op) { size_t count1 = 0; size_t count2 = 0; @@ -4754,15 +4863,18 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, /* * Handle degenerate cases. */ - if (*clstr2 == NULL) + if (*clstr2 == NULL) { return; + } if (*clstr1 == NULL || list_op == CLUSTER_REPLACE) { - if (list_op == CLUSTER_REPLACE) + if (list_op == CLUSTER_REPLACE) { xfree(*clstr1); - if (list_op == CLUSTER_REPLACE || list_op == CLUSTER_ADD) + } + if (list_op == CLUSTER_REPLACE || list_op == CLUSTER_ADD) { *clstr1 = *clstr2; - else + } else { xfree(*clstr2); + } return; } @@ -4794,8 +4906,9 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, * We always want to add from the first list. */ if (*g1 < *g2) { - if (round == 2) + if (round == 2) { clstr[count] = *g1; + } count++; g1++; continue; @@ -4805,12 +4918,14 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, * lists. */ if (list_op == CLUSTER_ADD) { - if (round == 2) + if (round == 2) { clstr[count] = *g2; + } count++; } - if (*g1 == *g2) + if (*g1 == *g2) { g1++; + } g2++; } @@ -4819,13 +4934,18 @@ static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2, * first. As before, we only want to add from the second list if * we're adding the lists. */ - for (; *g1; g1++, count++) - if (round == 2) + for (; *g1; g1++, count++) { + if (round == 2) { clstr[count] = *g1; - if (list_op == CLUSTER_ADD) - for (; *g2; g2++, count++) - if (round == 2) + } + } + if (list_op == CLUSTER_ADD) { + for (; *g2; g2++, count++) { + if (round == 2) { clstr[count] = *g2; + } + } + } if (round == 1) { /* @@ -4885,15 +5005,16 @@ static int syn_scl_namen2id(char_u *linep, int len) static int syn_check_cluster(char_u *pp, int len) { int id; - char_u *name; + char_u *name; name = vim_strnsave(pp, len); id = syn_scl_name2id(name); - if (id == 0) /* doesn't exist yet */ + if (id == 0) { // doesn't exist yet id = syn_add_cluster(name); - else + } else { xfree(name); + } return id; } @@ -4924,30 +5045,33 @@ static int syn_add_cluster(char_u *name) scp->scl_name_u = vim_strsave_up(name); scp->scl_list = NULL; - if (STRICMP(name, "Spell") == 0) + if (STRICMP(name, "Spell") == 0) { curwin->w_s->b_spell_cluster_id = len + SYNID_CLUSTER; - if (STRICMP(name, "NoSpell") == 0) + } + if (STRICMP(name, "NoSpell") == 0) { curwin->w_s->b_nospell_cluster_id = len + SYNID_CLUSTER; + } return len + SYNID_CLUSTER; } /* * Handle ":syntax cluster {cluster-name} [contains={groupname},..] - * [add={groupname},..] [remove={groupname},..]". + * [add={groupname},..] [remove={groupname},..]". */ static void syn_cmd_cluster(exarg_T *eap, int syncing) { - char_u *arg = eap->arg; - char_u *group_name_end; - char_u *rest; + char_u *arg = eap->arg; + char_u *group_name_end; + char_u *rest; bool got_clstr = false; int opt_len; int list_op; eap->nextcmd = find_nextcmd(arg); - if (eap->skip) + if (eap->skip) { return; + } rest = get_group_name(arg, &group_name_end); @@ -4971,8 +5095,9 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing) && (ascii_iswhite(rest[8]) || rest[8] == '=')) { opt_len = 8; list_op = CLUSTER_REPLACE; - } else + } else { break; + } int16_t *clstr_list = NULL; if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL) { @@ -4990,14 +5115,16 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing) if (got_clstr) { redraw_curbuf_later(SOME_VALID); - syn_stack_free_all(curwin->w_s); /* Need to recompute all. */ + syn_stack_free_all(curwin->w_s); // Need to recompute all. } } - if (!got_clstr) + if (!got_clstr) { EMSG(_("E400: No cluster specified")); - if (rest == NULL || !ends_excmd(*rest)) + } + if (rest == NULL || !ends_excmd(*rest)) { EMSG2(_(e_invarg2), arg); + } } /* @@ -5016,10 +5143,10 @@ static void init_syn_patterns(void) */ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci) { - char_u *end; - int *p; + char_u *end; + int *p; int idx; - char_u *cpo_save; + char_u *cpo_save; // need at least three chars if (arg == NULL || arg[0] == NUL || arg[1] == NUL || arg[2] == NUL) { @@ -5027,21 +5154,22 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci) } end = skip_regexp(arg + 1, *arg, TRUE, NULL); - if (*end != *arg) { /* end delimiter not found */ + if (*end != *arg) { // end delimiter not found EMSG2(_("E401: Pattern delimiter not found: %s"), arg); return NULL; } // store the pattern and compiled regexp program ci->sp_pattern = vim_strnsave(arg + 1, end - arg - 1); - /* Make 'cpoptions' empty, to avoid the 'l' flag */ + // Make 'cpoptions' empty, to avoid the 'l' flag cpo_save = p_cpo; p_cpo = (char_u *)""; ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC); p_cpo = cpo_save; - if (ci->sp_prog == NULL) + if (ci->sp_prog == NULL) { return NULL; + } ci->sp_ic = curwin->w_s->b_syn_ic; syn_clear_time(&ci->sp_time); @@ -5050,41 +5178,49 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci) */ ++end; do { - for (idx = SPO_COUNT; --idx >= 0; ) - if (STRNCMP(end, spo_name_tab[idx], 3) == 0) + for (idx = SPO_COUNT; --idx >= 0; ) { + if (STRNCMP(end, spo_name_tab[idx], 3) == 0) { break; + } + } if (idx >= 0) { p = &(ci->sp_offsets[idx]); - if (idx != SPO_LC_OFF) + if (idx != SPO_LC_OFF) { switch (end[3]) { - case 's': break; - case 'b': break; - case 'e': idx += SPO_COUNT; break; - default: idx = -1; break; + case 's': + break; + case 'b': + break; + case 'e': + idx += SPO_COUNT; break; + default: + idx = -1; break; } + } if (idx >= 0) { ci->sp_off_flags |= (1 << idx); - if (idx == SPO_LC_OFF) { /* lc=99 */ + if (idx == SPO_LC_OFF) { // lc=99 end += 3; *p = getdigits_int(&end, true, 0); - /* "lc=" offset automatically sets "ms=" offset */ + // "lc=" offset automatically sets "ms=" offset if (!(ci->sp_off_flags & (1 << SPO_MS_OFF))) { ci->sp_off_flags |= (1 << SPO_MS_OFF); ci->sp_offsets[SPO_MS_OFF] = *p; } - } else { /* yy=x+99 */ + } else { // yy=x+99 end += 4; if (*end == '+') { end++; *p = getdigits_int(&end, true, 0); // positive offset - } else if (*end == '-') { + } else if (*end == '-') { end++; *p = -getdigits_int(&end, true, 0); // negative offset } } - if (*end != ',') + if (*end != ',') { break; + } ++end; } } @@ -5102,14 +5238,14 @@ static char_u *get_syn_pattern(char_u *arg, synpat_T *ci) */ static void syn_cmd_sync(exarg_T *eap, int syncing) { - char_u *arg_start = eap->arg; - char_u *arg_end; - char_u *key = NULL; - char_u *next_arg; + char_u *arg_start = eap->arg; + char_u *arg_end; + char_u *key = NULL; + char_u *next_arg; int illegal = FALSE; int finished = FALSE; long n; - char_u *cpo_save; + char_u *cpo_save; if (ends_excmd(*arg_start)) { syn_cmd_list(eap, TRUE); @@ -5122,45 +5258,50 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) xfree(key); key = vim_strnsave_up(arg_start, arg_end - arg_start); if (STRCMP(key, "CCOMMENT") == 0) { - if (!eap->skip) + if (!eap->skip) { curwin->w_s->b_syn_sync_flags |= SF_CCOMMENT; + } if (!ends_excmd(*next_arg)) { arg_end = skiptowhite(next_arg); - if (!eap->skip) + if (!eap->skip) { curwin->w_s->b_syn_sync_id = syn_check_group(next_arg, - (int)(arg_end - next_arg)); + (int)(arg_end - next_arg)); + } next_arg = skipwhite(arg_end); - } else if (!eap->skip) + } else if (!eap->skip) { curwin->w_s->b_syn_sync_id = syn_name2id((char_u *)"Comment"); - } else if ( STRNCMP(key, "LINES", 5) == 0 - || STRNCMP(key, "MINLINES", 8) == 0 - || STRNCMP(key, "MAXLINES", 8) == 0 - || STRNCMP(key, "LINEBREAKS", 10) == 0) { - if (key[4] == 'S') + } + } else if (STRNCMP(key, "LINES", 5) == 0 + || STRNCMP(key, "MINLINES", 8) == 0 + || STRNCMP(key, "MAXLINES", 8) == 0 + || STRNCMP(key, "LINEBREAKS", 10) == 0) { + if (key[4] == 'S') { arg_end = key + 6; - else if (key[0] == 'L') + } else if (key[0] == 'L') { arg_end = key + 11; - else + } else { arg_end = key + 9; + } if (arg_end[-1] != '=' || !ascii_isdigit(*arg_end)) { illegal = TRUE; break; } n = getdigits_long(&arg_end, false, 0); if (!eap->skip) { - if (key[4] == 'B') + if (key[4] == 'B') { curwin->w_s->b_syn_sync_linebreaks = n; - else if (key[1] == 'A') + } else if (key[1] == 'A') { curwin->w_s->b_syn_sync_maxlines = n; - else + } else { curwin->w_s->b_syn_sync_minlines = n; + } } - } else if (STRCMP(key, "FROMSTART") == 0) { + } else if (STRCMP(key, "FROMSTART") == 0) { if (!eap->skip) { curwin->w_s->b_syn_sync_minlines = MAXLNUM; curwin->w_s->b_syn_sync_maxlines = 0; } - } else if (STRCMP(key, "LINECONT") == 0) { + } else if (STRCMP(key, "LINECONT") == 0) { if (*next_arg == NUL) { // missing pattern illegal = true; break; @@ -5171,18 +5312,18 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) break; } arg_end = skip_regexp(next_arg + 1, *next_arg, TRUE, NULL); - if (*arg_end != *next_arg) { /* end delimiter not found */ + if (*arg_end != *next_arg) { // end delimiter not found illegal = TRUE; break; } if (!eap->skip) { - /* store the pattern and compiled regexp program */ + // store the pattern and compiled regexp program curwin->w_s->b_syn_linecont_pat = vim_strnsave(next_arg + 1, arg_end - next_arg - 1); curwin->w_s->b_syn_linecont_ic = curwin->w_s->b_syn_ic; - /* Make 'cpoptions' empty, to avoid the 'l' flag */ + // Make 'cpoptions' empty, to avoid the 'l' flag cpo_save = p_cpo; p_cpo = (char_u *)""; curwin->w_s->b_syn_linecont_prog = @@ -5199,47 +5340,43 @@ static void syn_cmd_sync(exarg_T *eap, int syncing) next_arg = skipwhite(arg_end + 1); } else { eap->arg = next_arg; - if (STRCMP(key, "MATCH") == 0) + if (STRCMP(key, "MATCH") == 0) { syn_cmd_match(eap, TRUE); - else if (STRCMP(key, "REGION") == 0) + } else if (STRCMP(key, "REGION") == 0) { syn_cmd_region(eap, TRUE); - else if (STRCMP(key, "CLEAR") == 0) + } else if (STRCMP(key, "CLEAR") == 0) { syn_cmd_clear(eap, TRUE); - else + } else { illegal = TRUE; + } finished = TRUE; break; } arg_start = next_arg; } xfree(key); - if (illegal) + if (illegal) { EMSG2(_("E404: Illegal arguments: %s"), arg_start); - else if (!finished) { + } else if (!finished) { eap->nextcmd = check_nextcmd(arg_start); redraw_curbuf_later(SOME_VALID); - syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ + syn_stack_free_all(curwin->w_s); // Need to recompute all syntax. } } -/* - * Convert a line of highlight group names into a list of group ID numbers. - * "arg" should point to the "contains" or "nextgroup" keyword. - * "arg" is advanced to after the last group name. - * Careful: the argument is modified (NULs added). - * returns FAIL for some error, OK for success. - */ -static int -get_id_list( - 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; +/// Convert a line of highlight group names into a list of group ID numbers. +/// "arg" should point to the "contains" or "nextgroup" keyword. +/// "arg" is advanced to after the last group name. +/// Careful: the argument is modified (NULs added). +/// +/// @param keylen length of keyword +/// @param list where to store the resulting list, if not NULL, the list is silently skipped! +/// +/// @return FAIL for some error, OK for success. +static int get_id_list(char_u **const arg, const int keylen, int16_t **const list, const bool skip) +{ + char_u *p = NULL; + char_u *end; int total_count = 0; int16_t *retval = NULL; regmatch_T regmatch; @@ -5271,10 +5408,10 @@ get_id_list( } 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 - || STRCMP(name + 1, "TOP") == 0 - || STRCMP(name + 1, "CONTAINED") == 0) { + if (STRCMP(name + 1, "ALLBUT") == 0 + || STRCMP(name + 1, "ALL") == 0 + || STRCMP(name + 1, "TOP") == 0 + || STRCMP(name + 1, "CONTAINED") == 0) { if (TOUPPER_ASC(**arg) != 'C') { EMSG2(_("E407: %s not allowed here"), name + 1); failed = true; @@ -5299,7 +5436,7 @@ get_id_list( } else { id = SYNID_CONTAINED + current_syn_inc_tag; } - } else if (name[1] == '@') { + } else if (name[1] == '@') { if (skip) { id = -1; } else { @@ -5364,12 +5501,14 @@ get_id_list( ++count; } p = skipwhite(end); - if (*p != ',') + if (*p != ',') { break; - p = skipwhite(p + 1); /* skip comma in between arguments */ + } + p = skipwhite(p + 1); // skip comma in between arguments } while (!ends_excmd(*p)); - if (failed) + if (failed) { break; + } if (round == 1) { retval = xmalloc((count + 1) * sizeof(*retval)); retval[count] = 0; // zero means end of the list @@ -5383,11 +5522,11 @@ get_id_list( return FAIL; } - if (*list == NULL) + if (*list == NULL) { *list = retval; - else - xfree(retval); /* list already found, don't overwrite it */ - + } else { + xfree(retval); // list already found, don't overwrite it + } return OK; } @@ -5410,20 +5549,17 @@ static int16_t *copy_id_list(const int16_t *const list) return retval; } -/* - * Check if syntax group "ssp" is in the ID list "list" of "cur_si". - * "cur_si" can be NULL if not checking the "containedin" list. - * Used to check if a syntax item is in the "contains" or "nextgroup" list of - * the current item. - * This function is called very often, keep it fast!! - */ -static int -in_id_list( - stateitem_T *cur_si, // current item or NULL - int16_t *list, // id list - struct sp_syn *ssp, // group id and ":syn include" tag of group - int contained // group id is contained -) +/// Check if syntax group "ssp" is in the ID list "list" of "cur_si". +/// "cur_si" can be NULL if not checking the "containedin" list. +/// Used to check if a syntax item is in the "contains" or "nextgroup" list of +/// the current item. +/// This function is called very often, keep it fast!! +/// +/// @param cur_si current item or NULL +/// @param list id list +/// @param ssp group id and ":syn include" tag of group +/// @param contained group id is contained +static int in_id_list(stateitem_T *cur_si, int16_t *list, struct sp_syn *ssp, int contained) { int retval; int16_t *scl_list; @@ -5432,30 +5568,35 @@ in_id_list( static int depth = 0; int r; - /* If ssp has a "containedin" list and "cur_si" is in it, return TRUE. */ + // If ssp has a "containedin" list and "cur_si" is in it, return TRUE. if (cur_si != NULL && ssp->cont_in_list != NULL && !(cur_si->si_flags & HL_MATCH)) { /* Ignore transparent items without a contains argument. Double check * that we don't go back past the first one. */ while ((cur_si->si_flags & HL_TRANS_CONT) - && cur_si > (stateitem_T *)(current_state.ga_data)) + && cur_si > (stateitem_T *)(current_state.ga_data)) { --cur_si; - /* cur_si->si_idx is -1 for keywords, these never contain anything. */ + } + // cur_si->si_idx is -1 for keywords, these never contain anything. if (cur_si->si_idx >= 0 && in_id_list(NULL, ssp->cont_in_list, - &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn), - SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & HL_CONTAINED)) + &(SYN_ITEMS(syn_block)[cur_si->si_idx].sp_syn), + SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags & + HL_CONTAINED)) { return TRUE; + } } - if (list == NULL) + if (list == NULL) { return FALSE; + } /* * If list is ID_LIST_ALL, we are in a transparent item that isn't * inside anything. Only allow not-contained groups. */ - if (list == ID_LIST_ALL) + if (list == ID_LIST_ALL) { return !contained; + } /* * If the first item is "ALLBUT", return TRUE if "id" is NOT in the @@ -5465,29 +5606,34 @@ in_id_list( item = *list; if (item >= SYNID_ALLBUT && item < SYNID_CLUSTER) { if (item < SYNID_TOP) { - /* ALL or ALLBUT: accept all groups in the same file */ - if (item - SYNID_ALLBUT != ssp->inc_tag) + // ALL or ALLBUT: accept all groups in the same file + if (item - SYNID_ALLBUT != ssp->inc_tag) { return FALSE; - } else if (item < SYNID_CONTAINED) { - /* TOP: accept all not-contained groups in the same file */ - if (item - SYNID_TOP != ssp->inc_tag || contained) + } + } else if (item < SYNID_CONTAINED) { + // TOP: accept all not-contained groups in the same file + if (item - SYNID_TOP != ssp->inc_tag || contained) { return FALSE; + } } else { - /* CONTAINED: accept all contained groups in the same file */ - if (item - SYNID_CONTAINED != ssp->inc_tag || !contained) + // CONTAINED: accept all contained groups in the same file + if (item - SYNID_CONTAINED != ssp->inc_tag || !contained) { return FALSE; + } } item = *++list; retval = FALSE; - } else + } else { retval = TRUE; + } /* * Return "retval" if id is in the contains list. */ while (item != 0) { - if (item == id) + if (item == id) { return retval; + } if (item >= SYNID_CLUSTER) { scl_list = SYN_CLSTR(syn_block)[item - SYNID_CLUSTER].scl_list; /* restrict recursiveness to 30 to avoid an endless loop for a @@ -5496,8 +5642,9 @@ in_id_list( ++depth; r = in_id_list(NULL, scl_list, ssp, contained); --depth; - if (r) + if (r) { return retval; + } } } item = *++list; @@ -5506,8 +5653,8 @@ in_id_list( } struct subcommand { - char *name; /* subcommand name */ - void (*func)(exarg_T *, int); /* function to call */ + char *name; // subcommand name + void (*func)(exarg_T *, int); // function to call }; static struct subcommand subcommands[] = @@ -5541,8 +5688,8 @@ static struct subcommand subcommands[] = */ void ex_syntax(exarg_T *eap) { - char_u *arg = eap->arg; - char_u *subcmd_end; + char_u *arg = eap->arg; + char_u *subcmd_end; syn_cmdlinep = eap->cmdlinep; @@ -5565,14 +5712,15 @@ void ex_syntax(exarg_T *eap) } } xfree(subcmd_name); - if (eap->skip) + if (eap->skip) { --emsg_skip; + } } void ex_ownsyntax(exarg_T *eap) { - char_u *old_value; - char_u *new_value; + char_u *old_value; + char_u *new_value; if (curwin->w_s == &curwin->w_buffer->b_s) { curwin->w_s = xmalloc(sizeof(synblock_T)); @@ -5595,9 +5743,8 @@ void ex_ownsyntax(exarg_T *eap) old_value = vim_strsave(old_value); } - /* Apply the "syntax" autocommand event, this finds and loads the syntax - * file. */ - apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf); + // Apply the "syntax" autocommand event, this finds and loads the syntax file. + apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, true, curbuf); // Move value of b:current_syntax to w:current_syntax. new_value = get_var_value("b:current_syntax"); @@ -5662,7 +5809,7 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) include_link = 0; include_default = 0; - /* (part of) subcommand already typed */ + // (part of) subcommand already typed if (*arg != NUL) { const char *p = (const char *)skiptowhite((const char_u *)arg); if (*p != NUL) { // Past first word. @@ -5694,47 +5841,44 @@ void set_context_in_syntax_cmd(expand_T *xp, const char *arg) char_u *get_syntax_name(expand_T *xp, int idx) { switch (expand_what) { - case EXP_SUBCMD: - return (char_u *)subcommands[idx].name; - case EXP_CASE: { - static char *case_args[] = { "match", "ignore", NULL }; - return (char_u *)case_args[idx]; + case EXP_SUBCMD: + return (char_u *)subcommands[idx].name; + case EXP_CASE: { + static char *case_args[] = { "match", "ignore", NULL }; + return (char_u *)case_args[idx]; } - case EXP_SPELL: { - static char *spell_args[] = - { "toplevel", "notoplevel", "default", NULL }; - return (char_u *)spell_args[idx]; + case EXP_SPELL: { + static char *spell_args[] = + { "toplevel", "notoplevel", "default", NULL }; + return (char_u *)spell_args[idx]; } - case EXP_SYNC: { - static char *sync_args[] = - { "ccomment", "clear", "fromstart", - "linebreaks=", "linecont", "lines=", "match", - "maxlines=", "minlines=", "region", NULL }; - return (char_u *)sync_args[idx]; + case EXP_SYNC: { + static char *sync_args[] = + { "ccomment", "clear", "fromstart", + "linebreaks=", "linecont", "lines=", "match", + "maxlines=", "minlines=", "region", NULL }; + return (char_u *)sync_args[idx]; } } return NULL; } -// Function called for expression evaluation: get syntax ID at file position. -int syn_get_id( - win_T *wp, - long lnum, - colnr_T col, - int trans, // remove transparency - bool *spellp, // return: can do spell checking - int keep_state // keep state of char at "col" -) +/// Function called for expression evaluation: get syntax ID at file position. +/// +/// @param trans remove transparency +/// @param spellp return: can do spell checking +/// @param keep_state keep state of char at "col" +int syn_get_id(win_T *wp, long lnum, colnr_T col, int trans, bool *spellp, int keep_state) { // When the position is not after the current position and in the same // line of the same buffer, need to restart parsing. if (wp->w_buffer != syn_buf || lnum != current_lnum || col < current_col) { syntax_start(wp, lnum); } else if (col > current_col) { - // next_match may not be correct when moving around, e.g. with the - // "skip" expression in searchpair() - next_match_idx = -1; + // next_match may not be correct when moving around, e.g. with the + // "skip" expression in searchpair() + next_match_idx = -1; } (void)get_syntax_attr(col, spellp, keep_state); @@ -5842,8 +5986,9 @@ int syn_get_foldlevel(win_T *wp, long lnum) } if (level > wp->w_p_fdn) { level = wp->w_p_fdn; - if (level < 0) + if (level < 0) { level = 0; + } } return level; } @@ -5879,7 +6024,7 @@ static void syn_clear_time(syn_time_T *st) */ static void syntime_clear(void) { - synpat_T *spp; + synpat_T *spp; if (!syntax_present(curwin)) { MSG(_(msg_no_items)); @@ -5898,18 +6043,22 @@ static void syntime_clear(void) char_u *get_syntime_arg(expand_T *xp, int idx) { switch (idx) { - case 0: return (char_u *)"on"; - case 1: return (char_u *)"off"; - case 2: return (char_u *)"clear"; - case 3: return (char_u *)"report"; + case 0: + return (char_u *)"on"; + case 1: + return (char_u *)"off"; + case 2: + return (char_u *)"clear"; + case 3: + return (char_u *)"report"; } return NULL; } static int syn_compare_syntime(const void *v1, const void *v2) { - const time_entry_T *s1 = v1; - const time_entry_T *s2 = v2; + const time_entry_T *s1 = v1; + const time_entry_T *s2 = v2; return profile_cmp(s1->total, s2->total); } @@ -5954,14 +6103,13 @@ static void syntime_report(void) syn_compare_syntime); } - MSG_PUTS_TITLE(_( - " TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN")); + MSG_PUTS_TITLE(_(" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN")); MSG_PUTS("\n"); for (int idx = 0; idx < ga.ga_len && !got_int; ++idx) { p = ((time_entry_T *)ga.ga_data) + idx; MSG_PUTS(profile_msg(p->total)); - MSG_PUTS(" "); /* make sure there is always a separating space */ + MSG_PUTS(" "); // make sure there is always a separating space msg_advance(13); msg_outnum(p->count); MSG_PUTS(" "); @@ -5980,12 +6128,14 @@ static void syntime_report(void) msg_advance(69); int len; - if (Columns < 80) - len = 20; /* will wrap anyway */ - else + if (Columns < 80) { + len = 20; // will wrap anyway + } else { len = Columns - 70; - if (len > (int)STRLEN(p->pattern)) + } + if (len > (int)STRLEN(p->pattern)) { len = (int)STRLEN(p->pattern); + } msg_outtrans_len(p->pattern, len); MSG_PUTS("\n"); } @@ -6000,7 +6150,7 @@ static void syntime_report(void) } /************************************** -* Highlighting stuff * +* Highlighting stuff * **************************************/ // The default highlight groups. These are compiled-in for fast startup and @@ -6009,8 +6159,7 @@ static void syntime_report(void) // When making changes here, also change runtime/colors/default.vim! static const char *highlight_init_both[] = { - "Conceal " - "ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey", + "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey", "Cursor guibg=fg guifg=bg", "lCursor guibg=fg guifg=bg", "DiffText cterm=bold ctermbg=Red gui=bold guibg=Red", @@ -6042,10 +6191,8 @@ static const char *highlight_init_both[] = { "RedrawDebugClear ctermbg=Yellow guibg=Yellow", "RedrawDebugComposed ctermbg=Green guibg=Green", "RedrawDebugRecompose ctermbg=Red guibg=Red", - "Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE " - "guifg=White guibg=Red", - "Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE " - "guifg=Blue guibg=Yellow", + "Error term=reverse cterm=NONE ctermfg=White ctermbg=Red gui=NONE guifg=White guibg=Red", + "Todo term=standout cterm=NONE ctermfg=Black ctermbg=Yellow gui=NONE guifg=Blue guibg=Yellow", "default link String Constant", "default link Character Constant", "default link Number Constant", @@ -6103,24 +6250,15 @@ static const char *highlight_init_light[] = { "Title ctermfg=DarkMagenta gui=bold guifg=Magenta", "Visual guibg=LightGrey", "WarningMsg ctermfg=DarkRed guifg=Red", - "Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE " - "gui=NONE guifg=Blue guibg=NONE", - "Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE " - "gui=NONE guifg=Magenta guibg=NONE", - "Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE " - "gui=NONE guifg=#6a5acd guibg=NONE", - "Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE " - "gui=NONE guifg=DarkCyan guibg=NONE", - "Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE " - "gui=bold guifg=Brown guibg=NONE", - "PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE " - "gui=NONE guifg=#6a0dad guibg=NONE", - "Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE " - "gui=bold guifg=SeaGreen guibg=NONE", - "Underlined term=underline cterm=underline ctermfg=DarkMagenta " - "gui=underline guifg=SlateBlue", - "Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE " - "gui=NONE guifg=bg guibg=NONE", + "Comment term=bold cterm=NONE ctermfg=DarkBlue ctermbg=NONE gui=NONE guifg=Blue guibg=NONE", + "Constant term=underline cterm=NONE ctermfg=DarkRed ctermbg=NONE gui=NONE guifg=Magenta guibg=NONE", + "Special term=bold cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a5acd guibg=NONE", + "Identifier term=underline cterm=NONE ctermfg=DarkCyan ctermbg=NONE gui=NONE guifg=DarkCyan guibg=NONE", + "Statement term=bold cterm=NONE ctermfg=Brown ctermbg=NONE gui=bold guifg=Brown guibg=NONE", + "PreProc term=underline cterm=NONE ctermfg=DarkMagenta ctermbg=NONE gui=NONE guifg=#6a0dad guibg=NONE", + "Type term=underline cterm=NONE ctermfg=DarkGreen ctermbg=NONE gui=bold guifg=SeaGreen guibg=NONE", + "Underlined term=underline cterm=underline ctermfg=DarkMagenta gui=underline guifg=SlateBlue", + "Ignore term=NONE cterm=NONE ctermfg=white ctermbg=NONE gui=NONE guifg=bg guibg=NONE", NULL }; @@ -6154,24 +6292,15 @@ static const char *highlight_init_dark[] = { "Title ctermfg=LightMagenta gui=bold guifg=Magenta", "Visual guibg=DarkGrey", "WarningMsg ctermfg=LightRed guifg=Red", - "Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE " - "gui=NONE guifg=#80a0ff guibg=NONE", - "Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE " - "gui=NONE guifg=#ffa0a0 guibg=NONE", - "Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE " - "gui=NONE guifg=Orange guibg=NONE", - "Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE " - "gui=NONE guifg=#40ffff guibg=NONE", - "Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE " - "gui=bold guifg=#ffff60 guibg=NONE", - "PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE " - "gui=NONE guifg=#ff80ff guibg=NONE", - "Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE " - "gui=bold guifg=#60ff60 guibg=NONE", - "Underlined term=underline cterm=underline ctermfg=LightBlue " - "gui=underline guifg=#80a0ff", - "Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE " - "gui=NONE guifg=bg guibg=NONE", + "Comment term=bold cterm=NONE ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#80a0ff guibg=NONE", + "Constant term=underline cterm=NONE ctermfg=Magenta ctermbg=NONE gui=NONE guifg=#ffa0a0 guibg=NONE", + "Special term=bold cterm=NONE ctermfg=LightRed ctermbg=NONE gui=NONE guifg=Orange guibg=NONE", + "Identifier term=underline cterm=bold ctermfg=Cyan ctermbg=NONE gui=NONE guifg=#40ffff guibg=NONE", + "Statement term=bold cterm=NONE ctermfg=Yellow ctermbg=NONE gui=bold guifg=#ffff60 guibg=NONE", + "PreProc term=underline cterm=NONE ctermfg=LightBlue ctermbg=NONE gui=NONE guifg=#ff80ff guibg=NONE", + "Type term=underline cterm=NONE ctermfg=LightGreen ctermbg=NONE gui=bold guifg=#60ff60 guibg=NONE", + "Underlined term=underline cterm=underline ctermfg=LightBlue gui=underline guifg=#80a0ff", + "Ignore term=NONE cterm=NONE ctermfg=black ctermbg=NONE gui=NONE guifg=bg guibg=NONE", NULL }; @@ -6278,12 +6407,9 @@ const char *const highlight_init_cmdline[] = { "default link NvimInvalidAssignment NvimInvalid", "default link NvimInvalidPlainAssignment NvimInvalidAssignment", "default link NvimInvalidAugmentedAssignment NvimInvalidAssignment", - "default link NvimInvalidAssignmentWithAddition " - "NvimInvalidAugmentedAssignment", - "default link NvimInvalidAssignmentWithSubtraction " - "NvimInvalidAugmentedAssignment", - "default link NvimInvalidAssignmentWithConcatenation " - "NvimInvalidAugmentedAssignment", + "default link NvimInvalidAssignmentWithAddition NvimInvalidAugmentedAssignment", + "default link NvimInvalidAssignmentWithSubtraction NvimInvalidAugmentedAssignment", + "default link NvimInvalidAssignmentWithConcatenation NvimInvalidAugmentedAssignment", "default link NvimInvalidOperator NvimInvalid", @@ -6345,7 +6471,7 @@ const char *const highlight_init_cmdline[] = { "default link NvimInvalidOptionName NvimInvalidIdentifier", "default link NvimInvalidOptionScope NvimInvalidIdentifierScope", "default link NvimInvalidOptionScopeDelimiter " - "NvimInvalidIdentifierScopeDelimiter", + "NvimInvalidIdentifierScopeDelimiter", "default link NvimInvalidEnvironmentSigil NvimInvalidOptionSigil", "default link NvimInvalidEnvironmentName NvimInvalidIdentifier", @@ -6403,7 +6529,7 @@ void init_highlight(bool both, bool reset) bool okay = load_colors(copy_p); xfree(copy_p); if (okay) { - return; + return; } } @@ -6436,8 +6562,7 @@ void init_highlight(bool both, bool reset) * to avoid Statement highlighted text disappears. * Clear the attributes, needed when changing the t_Co value. */ if (t_colors > 8) { - do_highlight( - (*p_bg == 'l' + do_highlight((*p_bg == 'l' ? "Visual cterm=NONE ctermbg=LightGrey" : "Visual cterm=NONE ctermbg=DarkGrey"), false, true); } else { @@ -6456,7 +6581,7 @@ void init_highlight(bool both, bool reset) */ int load_colors(char_u *name) { - char_u *buf; + char_u *buf; int retval = FAIL; static bool recursive = false; @@ -6478,7 +6603,7 @@ int load_colors(char_u *name) retval = source_runtime(buf, DIP_START + DIP_OPT); } xfree(buf); - apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); + apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, false, curbuf); recursive = false; @@ -6492,46 +6617,47 @@ static char *(color_names[28]) = { "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 + "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 }; + 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 }; + 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, 3, - 248, 248, 7, 7, - 242, 242, - 12, 81, 10, 121, - 14, 159, 9, 224, 13, - 225, 11, 229, 15, -1 }; + 1, 5, 130, 3, + 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 }; + 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[]. @@ -6849,7 +6975,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) if (error) { break; } - if (*key == 'C') { + if (*key == 'C') { if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) { if (!init) { HL_TABLE()[idx].sg_set |= SG_CTERM; @@ -6865,7 +6991,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) HL_TABLE()[idx].sg_gui = attr; } } - } else if (STRCMP(key, "FONT") == 0) { + } else if (STRCMP(key, "FONT") == 0) { // in non-GUI fonts are simply ignored } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) { if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) { @@ -6881,7 +7007,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } if (ascii_isdigit(*arg)) { - color = atoi((char *)arg); + color = atoi(arg); } else if (STRICMP(arg, "fg") == 0) { if (cterm_normal_fg_color) { color = cterm_normal_fg_color - 1; @@ -6890,10 +7016,10 @@ void do_highlight(const char *line, const bool forceit, const bool init) error = true; break; } - } else if (STRICMP(arg, "bg") == 0) { - if (cterm_normal_bg_color > 0) + } else if (STRICMP(arg, "bg") == 0) { + if (cterm_normal_bg_color > 0) { color = cterm_normal_bg_color - 1; - else { + } else { EMSG(_("E420: BG color unknown")); error = true; break; @@ -6960,7 +7086,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) } } } - } else if (strcmp(key, "GUIFG") == 0) { + } else if (strcmp(key, "GUIFG") == 0) { char **namep = &HL_TABLE()[idx].sg_rgb_fg_name; if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { @@ -6984,7 +7110,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) if (is_normal_group) { normal_fg = HL_TABLE()[idx].sg_rgb_fg; } - } else if (STRCMP(key, "GUIBG") == 0) { + } else if (STRCMP(key, "GUIBG") == 0) { char **const namep = &HL_TABLE()[idx].sg_rgb_bg_name; if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { @@ -7008,7 +7134,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) if (is_normal_group) { normal_bg = HL_TABLE()[idx].sg_rgb_bg; } - } else if (strcmp(key, "GUISP") == 0) { + } else if (strcmp(key, "GUISP") == 0) { char **const namep = &HL_TABLE()[idx].sg_rgb_sp_name; if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { @@ -7032,9 +7158,9 @@ void do_highlight(const char *line, const bool forceit, const bool init) if (is_normal_group) { normal_sp = HL_TABLE()[idx].sg_rgb_sp; } - } else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) { + } else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) { // Ignored for now - } else if (strcmp(key, "BLEND") == 0) { + } else if (strcmp(key, "BLEND") == 0) { if (strcmp(arg, "NONE") != 0) { HL_TABLE()[idx].sg_blend = strtol(arg, NULL, 10); } else { @@ -7134,13 +7260,13 @@ void restore_cterm_colors(void) static int hl_has_settings(int idx, bool check_link) { return HL_TABLE()[idx].sg_cleared == 0 - && (HL_TABLE()[idx].sg_attr != 0 - || HL_TABLE()[idx].sg_cterm_fg != 0 - || HL_TABLE()[idx].sg_cterm_bg != 0 - || HL_TABLE()[idx].sg_rgb_fg_name != NULL - || HL_TABLE()[idx].sg_rgb_bg_name != NULL - || HL_TABLE()[idx].sg_rgb_sp_name != NULL - || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK))); + && (HL_TABLE()[idx].sg_attr != 0 + || HL_TABLE()[idx].sg_cterm_fg != 0 + || HL_TABLE()[idx].sg_cterm_bg != 0 + || HL_TABLE()[idx].sg_rgb_fg_name != NULL + || HL_TABLE()[idx].sg_rgb_bg_name != NULL + || HL_TABLE()[idx].sg_rgb_sp_name != NULL + || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK))); } /* @@ -7188,18 +7314,18 @@ static void highlight_list_one(const int id) } didh = highlight_list_arg(id, didh, LIST_ATTR, - sgp->sg_cterm, NULL, "cterm"); + sgp->sg_cterm, NULL, "cterm"); didh = highlight_list_arg(id, didh, LIST_INT, - sgp->sg_cterm_fg, NULL, "ctermfg"); + sgp->sg_cterm_fg, NULL, "ctermfg"); didh = highlight_list_arg(id, didh, LIST_INT, - sgp->sg_cterm_bg, NULL, "ctermbg"); + sgp->sg_cterm_bg, NULL, "ctermbg"); didh = highlight_list_arg(id, didh, LIST_ATTR, - sgp->sg_gui, NULL, "gui"); + sgp->sg_gui, NULL, "gui"); didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_rgb_fg_name, "guifg"); + 0, sgp->sg_rgb_fg_name, "guifg"); didh = highlight_list_arg(id, didh, LIST_STRING, - 0, sgp->sg_rgb_bg_name, "guibg"); + 0, sgp->sg_rgb_bg_name, "guibg"); didh = highlight_list_arg(id, didh, LIST_STRING, 0, sgp->sg_rgb_sp_name, "guisp"); @@ -7245,9 +7371,8 @@ Dictionary get_global_hl_defs(void) /// @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 bool highlight_list_arg( - const int id, bool didh, const int type, int iarg, - char *const sarg, const char *const name) +static bool highlight_list_arg(const int id, bool didh, const int type, int iarg, char *const sarg, + const char *const name) { char buf[100]; @@ -7264,10 +7389,11 @@ static bool highlight_list_arg( buf[0] = NUL; for (int i = 0; hl_attr_table[i] != 0; i++) { if (iarg & hl_attr_table[i]) { - if (buf[0] != NUL) + if (buf[0] != NUL) { xstrlcat((char *)buf, ",", 100); + } xstrlcat((char *)buf, hl_name_table[i], 100); - iarg &= ~hl_attr_table[i]; /* don't want "inverse" */ + iarg &= ~hl_attr_table[i]; // don't want "inverse" } } } @@ -7320,8 +7446,7 @@ const char *highlight_has_attr(const int id, const int flag, const int modec) /// /// @return color name, possibly in a static buffer. Buffer will be overwritten /// on next highlight_color() call. May return NULL. -const char *highlight_color(const int id, const char *const what, - const int modec) +const char *highlight_color(const int id, const char *const what, const int modec) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { static char name[20]; @@ -7347,11 +7472,11 @@ const char *highlight_color(const int id, const char *const what, if (modec == 'g') { if (what[2] == '#' && ui_rgb_attached()) { if (fg) { - n = HL_TABLE()[id - 1].sg_rgb_fg; + n = HL_TABLE()[id - 1].sg_rgb_fg; } else if (sp) { - n = HL_TABLE()[id - 1].sg_rgb_sp; + n = HL_TABLE()[id - 1].sg_rgb_sp; } else { - n = HL_TABLE()[id - 1].sg_rgb_bg; + n = HL_TABLE()[id - 1].sg_rgb_bg; } if (n < 0 || n > 0xffffff) { return NULL; @@ -7393,8 +7518,8 @@ const char *highlight_color(const int id, const char *const what, /// @param id highlight group id /// @param force_newline always start a new line /// @return true when started a new line. -static bool syn_list_header(const bool did_header, const int outlen, - const int id, bool force_newline) +static bool syn_list_header(const bool did_header, const int outlen, const int id, + bool force_newline) { int endcol = 19; bool newline = true; @@ -7410,7 +7535,7 @@ static bool syn_list_header(const bool did_header, const int outlen, } else if ((ui_has(kUIMessages) || msg_silent) && !force_newline) { msg_putchar(' '); adjust = false; - } else if (msg_col + outlen + 1 >= Columns || force_newline) { + } else if (msg_col + outlen + 1 >= Columns || force_newline) { msg_putchar('\n'); if (got_int) { return true; @@ -7430,7 +7555,7 @@ static bool syn_list_header(const bool did_header, const int outlen, msg_advance(endcol); } - /* Show "xxx" with the attributes. */ + // Show "xxx" with the attributes. if (!did_header) { msg_puts_attr("xxx", syn_id2attr(id)); msg_putchar(' '); @@ -7445,7 +7570,7 @@ static bool syn_list_header(const bool did_header, const int outlen, static void set_hl_attr(int idx) { HlAttrs at_en = HLATTRS_INIT; - struct hl_group *sgp = HL_TABLE() + idx; + struct hl_group *sgp = HL_TABLE() + idx; at_en.cterm_ae_attr = sgp->sg_cterm; at_en.cterm_fg_color = sgp->sg_cterm_fg; @@ -7525,8 +7650,9 @@ int highlight_exists(const char_u *name) */ char_u *syn_id2name(int id) { - if (id <= 0 || id > highlight_ga.ga_len) + if (id <= 0 || id > highlight_ga.ga_len) { return (char_u *)""; + } return HL_TABLE()[id - 1].sg_name; } @@ -7554,15 +7680,15 @@ int syn_check_group(const char_u *name, int len) /// @see syn_check_group syn_unadd_group static int syn_add_group(char_u *name) { - char_u *p; + char_u *p; - /* Check that the name is ASCII letters, digits and underscore. */ + // Check that the name is ASCII letters, digits and underscore. for (p = name; *p != NUL; ++p) { if (!vim_isprintc(*p)) { EMSG(_("E669: Unprintable character in group name")); xfree(name); return 0; - } else if (!ASCII_ISALNUM(*p) && *p != '_') { + } else if (!ASCII_ISALNUM(*p) && *p != '_') { /* This is an error, but since there previously was no check only * give a warning. */ msg_source(HL_ATTR(HLF_W)); @@ -7588,7 +7714,7 @@ static int syn_add_group(char_u *name) char *const name_up = (char *)vim_strsave_up(name); // Append another syntax_highlight entry. - struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); + struct hl_group * hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); memset(hlgp, 0, sizeof(*hlgp)); hlgp->sg_name = name; hlgp->sg_rgb_bg = -1; @@ -7640,9 +7766,9 @@ int syn_get_final_id(int hl_id) { int count; - if (hl_id > highlight_ga.ga_len || hl_id < 1) - return 0; /* Can be called from eval!! */ - + if (hl_id > highlight_ga.ga_len || hl_id < 1) { + return 0; // Can be called from eval!! + } /* * Follow links until there is no more. * Look out for loops! Break after 100 links. @@ -7690,8 +7816,7 @@ void highlight_attr_set_all(void) } // Apply difference between User[1-9] and HLF_S to HLF_SNC. -static void combine_stl_hlt(int id, int id_S, int id_alt, int hlcnt, int i, - int hlf, int *table) +static void combine_stl_hlt(int id, int id_S, int id_alt, int hlcnt, int i, int hlf, int *table) FUNC_ATTR_NONNULL_ALL { struct hl_group *const hlt = HL_TABLE(); @@ -7742,20 +7867,20 @@ void highlight_changed(void) need_highlight_changed = false; /// Translate builtin highlight groups into attributes for quick lookup. - for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) { + for (int hlf = 0; hlf < HLF_COUNT; hlf++) { id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf])); if (id == 0) { abort(); } int final_id = syn_get_final_id(id); - if (hlf == (int)HLF_SNC) { + if (hlf == HLF_SNC) { id_SNC = final_id; - } else if (hlf == (int)HLF_S) { + } else if (hlf == HLF_S) { id_S = final_id; } highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id, - hlf == (int)HLF_INACTIVE); + hlf == HLF_INACTIVE); if (highlight_attr[hlf] != highlight_attr_last[hlf]) { if (hlf == HLF_MSG) { @@ -7808,7 +7933,7 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg) include_link = 2; include_default = 1; - /* (part of) subcommand already typed */ + // (part of) subcommand already typed if (*arg != NUL) { const char *p = (const char *)skiptowhite((const char_u *)arg); if (*p != NUL) { // Past "default" or group name. @@ -7818,7 +7943,7 @@ void set_context_in_highlight_cmd(expand_T *xp, const char *arg) xp->xp_pattern = (char_u *)arg; p = (const char *)skiptowhite((const char_u *)arg); } - if (*p != NUL) { /* past group name */ + if (*p != NUL) { // past group name include_link = 0; if (arg[1] == 'i' && arg[0] == 'N') { highlight_list(); @@ -8597,7 +8722,6 @@ color_name_table_T color_name_table[] = { /// return the hex value or -1 if could not find a correct value RgbValue name_to_color(const char *name) { - if (name[0] == '#' && isxdigit(name[1]) && isxdigit(name[2]) && isxdigit(name[3]) && isxdigit(name[4]) && isxdigit(name[5]) && isxdigit(name[6]) && name[7] == NUL) { @@ -8620,5 +8744,5 @@ RgbValue name_to_color(const char *name) /************************************** -* End of Highlighting stuff * +* End of Highlighting stuff * **************************************/ diff --git a/src/nvim/testdir/test_blob.vim b/src/nvim/testdir/test_blob.vim new file mode 100644 index 0000000000..20758b0c0a --- /dev/null +++ b/src/nvim/testdir/test_blob.vim @@ -0,0 +1,349 @@ +" Tests for the Blob types + +func TearDown() + " Run garbage collection after every test + call test_garbagecollect_now() +endfunc + +" Tests for Blob type + +" Blob creation from constant +func Test_blob_create() + let b = 0zDEADBEEF + call assert_equal(v:t_blob, type(b)) + call assert_equal(4, len(b)) + call assert_equal(0xDE, b[0]) + call assert_equal(0xAD, b[1]) + call assert_equal(0xBE, b[2]) + call assert_equal(0xEF, b[3]) + call assert_fails('let x = b[4]') + + call assert_equal(0xDE, get(b, 0)) + call assert_equal(0xEF, get(b, 3)) + + call assert_fails('let b = 0z1', 'E973:') + call assert_fails('let b = 0z1x', 'E973:') + call assert_fails('let b = 0z12345', 'E973:') + + call assert_equal(0z, v:_null_blob) + + let b = 0z001122.33445566.778899.aabbcc.dd + call assert_equal(0z00112233445566778899aabbccdd, b) + call assert_fails('let b = 0z1.1') + call assert_fails('let b = 0z.') + call assert_fails('let b = 0z001122.') + call assert_fails('call get("", 1)', 'E896:') + call assert_equal(0, len(v:_null_blob)) +endfunc + +" assignment to a blob +func Test_blob_assign() + let b = 0zDEADBEEF + let b2 = b[1:2] + call assert_equal(0zADBE, b2) + + let bcopy = b[:] + call assert_equal(b, bcopy) + call assert_false(b is bcopy) + + let b = 0zDEADBEEF + let b2 = b + call assert_true(b is b2) + let b[:] = 0z11223344 + call assert_equal(0z11223344, b) + call assert_equal(0z11223344, b2) + call assert_true(b is b2) + + let b = 0zDEADBEEF + let b[3:] = 0z66 + call assert_equal(0zDEADBE66, b) + let b[:1] = 0z8899 + call assert_equal(0z8899BE66, b) + + call assert_fails('let b[2:3] = 0z112233', 'E972:') + call assert_fails('let b[2:3] = 0z11', 'E972:') + call assert_fails('let b[3:2] = 0z', 'E979:') + + let b = 0zDEADBEEF + let b += 0z99 + call assert_equal(0zDEADBEEF99, b) + + call assert_fails('let b .= 0z33', 'E734:') + call assert_fails('let b .= "xx"', 'E734:') + call assert_fails('let b += "xx"', 'E734:') + call assert_fails('let b[1:1] .= 0z55', 'E734:') + + let l = [0z12] + let m = deepcopy(l) + let m[0] = 0z34 " E742 or E741 should not occur. +endfunc + +func Test_blob_get_range() + let b = 0z0011223344 + call assert_equal(0z2233, b[2:3]) + call assert_equal(0z223344, b[2:-1]) + call assert_equal(0z00, b[0:-5]) + call assert_equal(0z, b[0:-11]) + call assert_equal(0z44, b[-1:]) + call assert_equal(0z0011223344, b[:]) + call assert_equal(0z0011223344, b[:-1]) + call assert_equal(0z, b[5:6]) +endfunc + +func Test_blob_get() + let b = 0z0011223344 + call assert_equal(0x00, get(b, 0)) + call assert_equal(0x22, get(b, 2, 999)) + call assert_equal(0x44, get(b, 4)) + call assert_equal(0x44, get(b, -1)) + call assert_equal(-1, get(b, 5)) + call assert_equal(999, get(b, 5, 999)) + call assert_equal(-1, get(b, -8)) + call assert_equal(999, get(b, -8, 999)) + call assert_equal(10, get(v:_null_blob, 2, 10)) + + call assert_equal(0x00, b[0]) + call assert_equal(0x22, b[2]) + call assert_equal(0x44, b[4]) + call assert_equal(0x44, b[-1]) + call assert_fails('echo b[5]', 'E979:') + call assert_fails('echo b[-8]', 'E979:') +endfunc + +func Test_blob_to_string() + let b = 0z00112233445566778899aabbccdd + call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b)) + call assert_equal(b, eval(string(b))) + call remove(b, 4, -1) + call assert_equal('0z00112233', string(b)) + call remove(b, 0, 3) + call assert_equal('0z', string(b)) +endfunc + +func Test_blob_compare() + let b1 = 0z0011 + let b2 = 0z1100 + let b3 = 0z001122 + call assert_true(b1 == b1) + call assert_false(b1 == b2) + call assert_false(b1 == b3) + call assert_true(b1 != b2) + call assert_true(b1 != b3) + call assert_true(b1 == 0z0011) + call assert_fails('echo b1 == 9', 'E977:') + call assert_fails('echo b1 != 9', 'E977:') + + call assert_false(b1 is b2) + let b2 = b1 + call assert_true(b1 == b2) + call assert_true(b1 is b2) + let b2 = copy(b1) + call assert_true(b1 == b2) + call assert_false(b1 is b2) + let b2 = b1[:] + call assert_true(b1 == b2) + call assert_false(b1 is b2) + + call assert_fails('let x = b1 > b2') + call assert_fails('let x = b1 < b2') + call assert_fails('let x = b1 - b2') + call assert_fails('let x = b1 / b2') + call assert_fails('let x = b1 * b2') +endfunc + +" test for range assign +func Test_blob_range_assign() + let b = 0z00 + let b[1] = 0x11 + let b[2] = 0x22 + call assert_equal(0z001122, b) + call assert_fails('let b[4] = 0x33', 'E979:') +endfunc + +func Test_blob_for_loop() + let blob = 0z00010203 + let i = 0 + for byte in blob + call assert_equal(i, byte) + let i += 1 + endfor + call assert_equal(4, i) + + let blob = 0z00 + call remove(blob, 0) + call assert_equal(0, len(blob)) + for byte in blob + call assert_error('loop over empty blob') + endfor + + let blob = 0z0001020304 + let i = 0 + for byte in blob + call assert_equal(i, byte) + if i == 1 + call remove(blob, 0) + elseif i == 3 + call remove(blob, 3) + endif + let i += 1 + endfor + call assert_equal(5, i) +endfunc + +func Test_blob_concatenate() + let b = 0z0011 + let b += 0z2233 + call assert_equal(0z00112233, b) + + call assert_fails('let b += "a"') + call assert_fails('let b += 88') + + let b = 0zDEAD + 0zBEEF + call assert_equal(0zDEADBEEF, b) +endfunc + +func Test_blob_add() + let b = 0z0011 + call add(b, 0x22) + call assert_equal(0z001122, b) + call add(b, '51') + call assert_equal(0z00112233, b) + + call assert_fails('call add(b, [9])', 'E745:') + call assert_fails('call add("", 0x01)', 'E897:') +endfunc + +func Test_blob_empty() + call assert_false(empty(0z001122)) + call assert_true(empty(0z)) + call assert_true(empty(v:_null_blob)) +endfunc + +" Test removing items in blob +func Test_blob_func_remove() + " Test removing 1 element + let b = 0zDEADBEEF + call assert_equal(0xDE, remove(b, 0)) + call assert_equal(0zADBEEF, b) + + let b = 0zDEADBEEF + call assert_equal(0xEF, remove(b, -1)) + call assert_equal(0zDEADBE, b) + + let b = 0zDEADBEEF + call assert_equal(0xAD, remove(b, 1)) + call assert_equal(0zDEBEEF, b) + + " Test removing range of element(s) + let b = 0zDEADBEEF + call assert_equal(0zBE, remove(b, 2, 2)) + call assert_equal(0zDEADEF, b) + + let b = 0zDEADBEEF + call assert_equal(0zADBE, remove(b, 1, 2)) + call assert_equal(0zDEEF, b) + + " Test invalid cases + let b = 0zDEADBEEF + call assert_fails("call remove(b, 5)", 'E979:') + call assert_fails("call remove(b, 1, 5)", 'E979:') + call assert_fails("call remove(b, 3, 2)", 'E979:') + call assert_fails("call remove(1, 0)", 'E896:') + call assert_fails("call remove(b, b)", 'E974:') + call assert_fails("call remove(v:_null_blob, 1, 2)", 'E979:') + + " Translated from v8.2.3284 + let b = 0zDEADBEEF + lockvar b + call assert_fails('call remove(b, 0)', 'E741:') + unlockvar b +endfunc + +func Test_blob_read_write() + let b = 0zDEADBEEF + call writefile(b, 'Xblob') + let br = readfile('Xblob', 'B') + call assert_equal(b, br) + call delete('Xblob') + + " This was crashing when calling readfile() with a directory. + call assert_fails("call readfile('.', 'B')", 'E17: "." is a directory') +endfunc + +" filter() item in blob +func Test_blob_filter() + call assert_equal(0z, filter(0zDEADBEEF, '0')) + call assert_equal(0zADBEEF, filter(0zDEADBEEF, 'v:val != 0xDE')) + call assert_equal(0zDEADEF, filter(0zDEADBEEF, 'v:val != 0xBE')) + call assert_equal(0zDEADBE, filter(0zDEADBEEF, 'v:val != 0xEF')) + call assert_equal(0zDEADBEEF, filter(0zDEADBEEF, '1')) + call assert_equal(0z01030103, filter(0z010203010203, 'v:val != 0x02')) + call assert_equal(0zADEF, filter(0zDEADBEEF, 'v:key % 2')) +endfunc + +" map() item in blob +func Test_blob_map() + call assert_equal(0zDFAEBFF0, map(0zDEADBEEF, 'v:val + 1')) + call assert_equal(0z00010203, map(0zDEADBEEF, 'v:key')) + call assert_equal(0zDEAEC0F2, map(0zDEADBEEF, 'v:key + v:val')) + + call assert_fails("call map(0z00, '[9]')", 'E978:') +endfunc + +func Test_blob_index() + call assert_equal(2, index(0zDEADBEEF, 0xBE)) + call assert_equal(-1, index(0zDEADBEEF, 0)) + call assert_equal(2, index(0z11111111, 0x11, 2)) + call assert_equal(3, index(0z11110111, 0x11, 2)) + call assert_equal(2, index(0z11111111, 0x11, -2)) + call assert_equal(3, index(0z11110111, 0x11, -2)) + + call assert_fails('call index("asdf", 0)', 'E897:') +endfunc + +func Test_blob_insert() + let b = 0zDEADBEEF + call insert(b, 0x33) + call assert_equal(0z33DEADBEEF, b) + + let b = 0zDEADBEEF + call insert(b, 0x33, 2) + call assert_equal(0zDEAD33BEEF, b) + + call assert_fails('call insert(b, -1)', 'E475:') + call assert_fails('call insert(b, 257)', 'E475:') + call assert_fails('call insert(b, 0, [9])', 'E745:') + call assert_equal(0, insert(v:_null_blob, 0x33)) + + " Translated from v8.2.3284 + let b = 0zDEADBEEF + lockvar b + call assert_fails('call insert(b, 3)', 'E741:') + unlockvar b +endfunc + +func Test_blob_reverse() + call assert_equal(0zEFBEADDE, reverse(0zDEADBEEF)) + call assert_equal(0zBEADDE, reverse(0zDEADBE)) + call assert_equal(0zADDE, reverse(0zDEAD)) + call assert_equal(0zDE, reverse(0zDE)) + call assert_equal(0z, reverse(v:_null_blob)) +endfunc + +func Test_blob_lock() + let b = 0z112233 + lockvar b + call assert_fails('let b = 0z44', 'E741:') + unlockvar b + let b = 0z44 +endfunc + +func Test_blob_sort() + if has('float') + call assert_fails('call sort([1.0, 0z11], "f")', 'E975:') + else + call assert_fails('call sort(["abc", 0z11], "f")', 'E702:') + endif +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim index 5542746a04..97b570e64f 100644 --- a/src/nvim/testdir/test_breakindent.vim +++ b/src/nvim/testdir/test_breakindent.vim @@ -67,7 +67,8 @@ endfunc func Test_breakindent02() " simple breakindent test with showbreak set - call s:test_windows('setl briopt=min:0 sbr=>>') + set sbr=>> + call s:test_windows('setl briopt=min:0 sbr=') let lines = s:screen_lines(line('.'),8) let expect = [ \ " abcd", @@ -127,7 +128,8 @@ endfunc func Test_breakindent04() " breakindent set with min width 18 - call s:test_windows('setl sbr= briopt=min:18') + set sbr=<<< + call s:test_windows('setl sbr=NONE briopt=min:18') let lines = s:screen_lines(line('.'),8) let expect = [ \ " abcd", @@ -137,6 +139,7 @@ func Test_breakindent04() call s:compare_lines(expect, lines) " clean up call s:close_windows('set sbr=') + set sbr= endfunc func Test_breakindent04_vartabs() @@ -868,4 +871,22 @@ func Test_breakindent20_list() call s:close_windows('set breakindent& briopt& linebreak& list& listchars& showbreak&') endfunc +" The following used to crash Vim. This is fixed by 8.2.3391. +" This is a regression introduced by 8.2.2903. +func Test_window_resize_with_linebreak() + new + 53vnew + set linebreak + set showbreak=>> + set breakindent + set breakindentopt=shift:4 + call setline(1, "\naaaaaaaaa\n\na\naaaaa\n¯aaaaaaaaaa\naaaaaaaaaaaa\naaa\n\"a:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - aaaaaaaa\"\naaaaaaaa\n\"a") + redraw! + call assert_equal([" >>aa^@\"a: "], ScreenLines(2, 14)) + vertical resize 52 + redraw! + call assert_equal([" >>aaa^@\"a:"], ScreenLines(2, 14)) + %bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_const.vim b/src/nvim/testdir/test_const.vim index ea69c8cba4..0d064617a5 100644 --- a/src/nvim/testdir/test_const.vim +++ b/src/nvim/testdir/test_const.vim @@ -244,18 +244,33 @@ func Test_const_with_eval_name() call assert_fails('const {s2} = "bar"', 'E995:') endfunc -func Test_lock_depth_is_1() - const l = [1, 2, 3] - const d = {'foo': 10} - - " Modify list - setting item is OK, adding/removing items not - let l[0] = 42 +func Test_lock_depth_is_2() + " Modify list - error when changing item or adding/removing items + const l = [1, 2, [3, 4]] + call assert_fails('let l[0] = 42', 'E741:') + call assert_fails('let l[2][0] = 42', 'E741:') call assert_fails('call add(l, 4)', 'E741:') call assert_fails('unlet l[1]', 'E741:') - " Modify dict - changing item is OK, adding/removing items not - let d['foo'] = 'hello' - let d.foo = 44 + " Modify blob - error when changing + const b = 0z001122 + call assert_fails('let b[0] = 42', 'E741:') + + " Modify dict - error when changing item or adding/removing items + const d = {'foo': 10} + call assert_fails("let d['foo'] = 'hello'", 'E741:') + call assert_fails("let d.foo = 'hello'", 'E741:') call assert_fails("let d['bar'] = 'hello'", 'E741:') call assert_fails("unlet d['foo']", 'E741:') + + " Modifying list or dict item contents is OK. + let lvar = ['a', 'b'] + let bvar = 0z1122 + const l2 = [0, lvar, bvar] + let l2[1][0] = 'c' + let l2[2][1] = 0x33 + call assert_equal([0, ['c', 'b'], 0z1133], l2) + + const d2 = #{a: 0, b: lvar, c: 4} + let d2.b[1] = 'd' endfunc diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim index d1464e9d3b..a396efc09e 100644 --- a/src/nvim/testdir/test_debugger.vim +++ b/src/nvim/testdir/test_debugger.vim @@ -267,9 +267,7 @@ func Test_Debugger() call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()']) call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a']) call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr']) - call RunDbgCmd(buf, 'breakd expr x', [ - \ 'E121: Undefined variable: x', - \ 'E161: Breakpoint not found: expr x']) + call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x']) " finish the current function call RunDbgCmd(buf, 'finish', [ @@ -314,9 +312,12 @@ func Test_Debugger() call RunDbgCmd(buf, 'enew! | only!') call StopVimInTerminal(buf) +endfunc +func Test_Debugger_breakadd() " Tests for :breakadd file and :breakadd here " Breakpoints should be set before sourcing the file + CheckRunVimInTerminal let lines =<< trim END let var1 = 10 @@ -337,6 +338,10 @@ func Test_Debugger() call StopVimInTerminal(buf) call delete('Xtest.vim') + %bw! + + call assert_fails('breakadd here', 'E32:') + call assert_fails('breakadd file Xtest.vim /\)/', 'E55:') endfunc func Test_Backtrace_Through_Source() diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim index c702b44b88..12327f34d6 100644 --- a/src/nvim/testdir/test_display.vim +++ b/src/nvim/testdir/test_display.vim @@ -262,3 +262,21 @@ func Test_display_scroll_at_topline() call StopVimInTerminal(buf) endfunc + +func Test_display_linebreak_breakat() + new + vert resize 25 + let _breakat = &breakat + setl signcolumn=yes linebreak breakat=) showbreak=+\ + call setline(1, repeat('x', winwidth(0) - 2) .. ')abc') + let lines = ScreenLines([1, 2], 25) + let expected = [ + \ ' xxxxxxxxxxxxxxxxxxxxxxx', + \ ' + )abc ' + \ ] + call assert_equal(expected, lines) + %bw! + let &breakat=_breakat +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim index 4870b9a60a..f7b6704610 100644 --- a/src/nvim/testdir/test_eval_stuff.vim +++ b/src/nvim/testdir/test_eval_stuff.vim @@ -12,25 +12,18 @@ func Test_catch_return_with_error() call assert_equal(1, s:foo()) endfunc -func Test_E963() - " These commands used to cause an internal error prior to vim 8.1.0563 - let v_e = v:errors - let v_o = v:oldfiles - call assert_fails("let v:errors=''", 'E963:') - call assert_equal(v_e, v:errors) - call assert_fails("let v:oldfiles=''", 'E963:') - call assert_equal(v_o, v:oldfiles) -endfunc - -func Test_for_invalid() - call assert_fails("for x in 99", 'E714:') - call assert_fails("for x in function('winnr')", 'E714:') - call assert_fails("for x in {'a': 9}", 'E714:') - - if 0 - /1/5/2/s/\n - endif - redraw +func Test_nocatch_restore_silent_emsg() + silent! try + throw 1 + catch + endtry + echoerr 'wrong' + let c1 = nr2char(screenchar(&lines, 1)) + let c2 = nr2char(screenchar(&lines, 2)) + let c3 = nr2char(screenchar(&lines, 3)) + let c4 = nr2char(screenchar(&lines, 4)) + let c5 = nr2char(screenchar(&lines, 5)) + call assert_equal('wrong', c1 . c2 . c3 . c4 . c5) endfunc func Test_mkdir_p() @@ -61,6 +54,54 @@ func Test_line_continuation() call assert_equal([5, 6], array) endfunc +func Test_E963() + " These commands used to cause an internal error prior to vim 8.1.0563 + let v_e = v:errors + let v_o = v:oldfiles + call assert_fails("let v:errors=''", 'E963:') + call assert_equal(v_e, v:errors) + call assert_fails("let v:oldfiles=''", 'E963:') + call assert_equal(v_o, v:oldfiles) +endfunc + +func Test_for_invalid() + " Vim gives incorrect emsg here until v8.2.3284, but the exact emsg from that + " patch cannot be used until v8.2.2658 is ported (for loop over Strings) + call assert_fails("for x in 99", 'E897:') + call assert_fails("for x in function('winnr')", 'E897:') + call assert_fails("for x in {'a': 9}", 'E897:') + + if 0 + /1/5/2/s/\n + endif + redraw +endfunc + +func Test_readfile_binary() + new + call setline(1, ['one', 'two', 'three']) + setlocal ff=dos + silent write XReadfile + let lines = readfile('XReadfile') + call assert_equal(['one', 'two', 'three'], lines) + let lines = readfile('XReadfile', '', 2) + call assert_equal(['one', 'two'], lines) + let lines = readfile('XReadfile', 'b') + call assert_equal(["one\r", "two\r", "three\r", ""], lines) + let lines = readfile('XReadfile', 'b', 2) + call assert_equal(["one\r", "two\r"], lines) + + bwipe! + call delete('XReadfile') +endfunc + +func Test_let_errmsg() + call assert_fails('let v:errmsg = []', 'E730:') + let v:errmsg = '' + call assert_fails('let v:errmsg = []', 'E730:') + let v:errmsg = '' +endfunc + func Test_string_concatenation() call assert_equal('ab', 'a'.'b') call assert_equal('ab', 'a' .'b') @@ -90,27 +131,6 @@ func Test_string_concatenation() call assert_equal('ab', a) endfunc -func Test_nocatch_restore_silent_emsg() - silent! try - throw 1 - catch - endtry - echoerr 'wrong' - let c1 = nr2char(screenchar(&lines, 1)) - let c2 = nr2char(screenchar(&lines, 2)) - let c3 = nr2char(screenchar(&lines, 3)) - let c4 = nr2char(screenchar(&lines, 4)) - let c5 = nr2char(screenchar(&lines, 5)) - call assert_equal('wrong', c1 . c2 . c3 . c4 . c5) -endfunc - -func Test_let_errmsg() - call assert_fails('let v:errmsg = []', 'E730:') - let v:errmsg = '' - call assert_fails('let v:errmsg = []', 'E730:') - let v:errmsg = '' -endfunc - " Test fix for issue #4507 func Test_skip_after_throw() try @@ -120,6 +140,31 @@ func Test_skip_after_throw() endtry endfunc +" scriptversion 1 +func Test_string_concat_scriptversion1() + call assert_true(has('vimscript-1')) + let a = 'a' + let b = 'b' + + echo a . b + let a .= b + let vers = 1.2.3 + call assert_equal('123', vers) + + if has('float') + call assert_fails('let f = .5', 'E15:') + endif +endfunc + +" scriptversion 1 +func Test_vvar_scriptversion1() + call assert_equal(15, 017) + call assert_equal(15, 0o17) + call assert_equal(15, 0O17) + call assert_equal(18, 018) + call assert_equal(511, 0o777) +endfunc + func Test_number_max_min_size() " This will fail on systems without 64 bit number support or when not " configured correctly. diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index 0b41a1127a..c49285621a 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -502,6 +502,17 @@ func Test_empty_concatenate() call assert_equal('b', 'b' . 'a'[4:0]) endfunc +func Test_broken_number() + let X = 'bad' + call assert_fails('echo 1X', 'E15:') + call assert_fails('echo 0b1X', 'E15:') + call assert_fails('echo 0b12', 'E15:') + call assert_fails('echo 0x1X', 'E15:') + call assert_fails('echo 011X', 'E15:') + call assert_equal(2, str2nr('2a')) + call assert_fails('inoremap <Char-0b1z> b', 'E474:') +endfunc + func Test_eval_after_if() let s:val = '' func SetVal(x) diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 5326d3460f..cc789cb6bd 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -398,6 +398,7 @@ let s:filename_checks = { \ 'psf': ['file.psf'], \ 'psl': ['file.psl'], \ 'puppet': ['file.pp'], + \ 'pyret': ['file.arr'], \ 'pyrex': ['file.pyx', 'file.pxd'], \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi', 'SConstruct'], \ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg', 'baseq2/file.cfg', 'id1/file.cfg', 'quake1/file.cfg', 'some-baseq2/file.cfg', 'some-id1/file.cfg', 'some-quake1/file.cfg'], @@ -429,7 +430,7 @@ let s:filename_checks = { \ 'sather': ['file.sa'], \ 'sbt': ['file.sbt'], \ 'scala': ['file.scala', 'file.sc'], - \ 'scheme': ['file.scm', 'file.ss', 'file.rkt'], + \ 'scheme': ['file.scm', 'file.ss', 'file.rkt', 'file.rktd', 'file.rktl'], \ 'scilab': ['file.sci', 'file.sce'], \ 'screen': ['.screenrc', 'screenrc'], \ 'sexplib': ['file.sexp'], @@ -867,16 +868,6 @@ func Test_m_file() call assert_equal('octave', &filetype) bwipe! - call writefile(['#{', 'Octave block comment', '#}'], 'Xfile.m') - split Xfile.m - call assert_equal('octave', &filetype) - bwipe! - - call writefile(['%{', 'Octave block comment', '%}'], 'Xfile.m') - split Xfile.m - call assert_equal('octave', &filetype) - bwipe! - call writefile(['%!test "Octave test"'], 'Xfile.m') split Xfile.m call assert_equal('octave', &filetype) @@ -887,7 +878,7 @@ func Test_m_file() call assert_equal('octave', &filetype) bwipe! - call writefile(['function test(); 42; endfunction'], 'Xfile.m') + call writefile(['try; 42; end_try_catch'], 'Xfile.m') split Xfile.m call assert_equal('octave', &filetype) bwipe! @@ -899,6 +890,13 @@ func Test_m_file() call assert_equal('mma', &filetype) bwipe! + " MATLAB + + call writefile(['% MATLAB line comment'], 'Xfile.m') + split Xfile.m + call assert_equal('matlab', &filetype) + bwipe! + " Murphi call writefile(['-- Murphi comment'], 'Xfile.m') diff --git a/src/nvim/testdir/test_filter_map.vim b/src/nvim/testdir/test_filter_map.vim index a15567bcf2..a52a66ac2f 100644 --- a/src/nvim/testdir/test_filter_map.vim +++ b/src/nvim/testdir/test_filter_map.vim @@ -81,7 +81,11 @@ func Test_filter_map_dict_expr_funcref() call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), function('s:filter4'))) endfunc -func Test_map_fails() +func Test_map_filter_fails() call assert_fails('call map([1], "42 +")', 'E15:') call assert_fails('call filter([1], "42 +")', 'E15:') + call assert_fails("let l = map('abc', '\"> \" . v:val')", 'E896:') + call assert_fails("let l = filter('abc', '\"> \" . v:val')", 'E896:') endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_fnamemodify.vim b/src/nvim/testdir/test_fnamemodify.vim index 116d23ba88..fe1df8fd4a 100644 --- a/src/nvim/testdir/test_fnamemodify.vim +++ b/src/nvim/testdir/test_fnamemodify.vim @@ -72,4 +72,8 @@ func Test_fnamemodify_er() " :e never includes the whole filename, so "a.b":e:e:e --> "b" call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e')) call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e:e')) + + call assert_equal('', fnamemodify(v:_null_string, v:_null_string)) endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 6cb3e24201..e82fefc7fc 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -152,6 +152,10 @@ func Test_str2nr() call assert_equal(65, str2nr('0101', 8)) call assert_equal(-65, str2nr('-101', 8)) call assert_equal(-65, str2nr('-0101', 8)) + call assert_equal(65, str2nr('0o101', 8)) + call assert_equal(65, str2nr('0O0101', 8)) + call assert_equal(-65, str2nr('-0O101', 8)) + call assert_equal(-65, str2nr('-0o0101', 8)) call assert_equal(11259375, str2nr('abcdef', 16)) call assert_equal(11259375, str2nr('ABCDEF', 16)) @@ -161,8 +165,16 @@ func Test_str2nr() call assert_equal(11259375, str2nr('0XABCDEF', 16)) call assert_equal(-11259375, str2nr('-0xABCDEF', 16)) + call assert_equal(1, str2nr("1'000'000", 10, 0)) + call assert_equal(256, str2nr("1'0000'0000", 2, 1)) + call assert_equal(262144, str2nr("1'000'000", 8, 1)) + call assert_equal(1000000, str2nr("1'000'000", 10, 1)) + call assert_equal(1000, str2nr("1'000''000", 10, 1)) + call assert_equal(65536, str2nr("1'00'00", 16, 1)) + call assert_equal(0, str2nr('0x10')) call assert_equal(0, str2nr('0b10')) + call assert_equal(0, str2nr('0o10')) call assert_equal(1, str2nr('12', 2)) call assert_equal(1, str2nr('18', 8)) call assert_equal(1, str2nr('1g', 16)) @@ -1160,6 +1172,29 @@ func Test_shellescape() call assert_equal("'te\\\nxt'", shellescape("te\nxt")) call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1)) + set shell=fish + call assert_equal("'text'", shellescape('text')) + call assert_equal("'te\"xt'", shellescape('te"xt')) + call assert_equal("'te'\\''xt'", shellescape("te'xt")) + + call assert_equal("'te%xt'", shellescape("te%xt")) + call assert_equal("'te\\%xt'", shellescape("te%xt", 1)) + call assert_equal("'te#xt'", shellescape("te#xt")) + call assert_equal("'te\\#xt'", shellescape("te#xt", 1)) + call assert_equal("'te!xt'", shellescape("te!xt")) + call assert_equal("'te\\!xt'", shellescape("te!xt", 1)) + + call assert_equal("'te\\\\xt'", shellescape("te\\xt")) + call assert_equal("'te\\\\xt'", shellescape("te\\xt", 1)) + call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt")) + call assert_equal("'te\\\\'\\''xt'", shellescape("te\\'xt", 1)) + call assert_equal("'te\\\\!xt'", shellescape("te\\!xt")) + call assert_equal("'te\\\\\\!xt'", shellescape("te\\!xt", 1)) + call assert_equal("'te\\\\%xt'", shellescape("te\\%xt")) + call assert_equal("'te\\\\\\%xt'", shellescape("te\\%xt", 1)) + call assert_equal("'te\\\\#xt'", shellescape("te\\#xt")) + call assert_equal("'te\\\\\\#xt'", shellescape("te\\#xt", 1)) + let &shell = save_shell endfunc diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim index 24c9c3580e..6fd9477ce9 100644 --- a/src/nvim/testdir/test_highlight.vim +++ b/src/nvim/testdir/test_highlight.vim @@ -426,6 +426,7 @@ func Test_highlight_eol_with_cursorline_breakindent() let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine() call NewWindow('topleft 5', 10) + set showbreak=xxx setlocal breakindent breakindentopt=min:0,shift:1 showbreak=> call setline(1, ' ' . repeat('a', 9) . 'bcd') call matchadd('Search', '\n') @@ -483,6 +484,7 @@ func Test_highlight_eol_with_cursorline_breakindent() call CloseWindow() set showbreak= + setlocal showbreak= exe hiCursorLine endfunc diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index 0fb026f6b0..ce75799551 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -497,6 +497,133 @@ func Test_ins_compl_tag_sft() %bwipe! endfunc +" Test for completing special characters +func Test_complete_special_chars() + new + call setline(1, 'int .*[-\^$ func float') + call feedkeys("oin\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>", 'xt') + call assert_equal('int .*[-\^$ func float', getline(2)) + close! +endfunc + +" Test for completion when text is wrapped across lines. +func Test_complete_across_line() + new + call setline(1, ['red green blue', 'one two three']) + setlocal textwidth=20 + exe "normal 2G$a re\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>\<C-X>\<C-P>" + call assert_equal(['one two three red', 'green blue one'], getline(2, '$')) + close! +endfunc + +" Test for using CTRL-L to add one character when completing matching +func Test_complete_add_onechar() + new + call setline(1, ['wool', 'woodwork']) + call feedkeys("Gowoo\<C-P>\<C-P>\<C-P>\<C-L>f", 'xt') + call assert_equal('woof', getline(3)) + + " use 'ignorecase' and backspace to erase characters from the prefix string + " and then add letters using CTRL-L + %d + set ignorecase backspace=2 + setlocal complete=. + call setline(1, ['workhorse', 'workload']) + normal Go + exe "normal aWOR\<C-P>\<bs>\<bs>\<bs>\<bs>\<bs>\<bs>\<C-L>r\<C-L>\<C-L>" + call assert_equal('workh', getline(3)) + set ignorecase& backspace& + close! +endfunc + +" Test insert completion with 'cindent' (adjust the indent) +func Test_complete_with_cindent() + new + setlocal cindent + call setline(1, ['if (i == 1)', " j = 2;"]) + exe "normal Go{\<CR>i\<C-X>\<C-L>\<C-X>\<C-L>\<CR>}" + call assert_equal(['{', "\tif (i == 1)", "\t\tj = 2;", '}'], getline(3, '$')) + + %d + call setline(1, ['when while', '{', '']) + setlocal cinkeys+==while + exe "normal Giwh\<C-P> " + call assert_equal("\twhile ", getline('$')) + close! +endfunc + +" Test for <CTRL-X> <CTRL-V> completion. Complete commands and functions +func Test_complete_cmdline() + new + exe "normal icaddb\<C-X>\<C-V>" + call assert_equal('caddbuffer', getline(1)) + exe "normal ocall getqf\<C-X>\<C-V>" + call assert_equal('call getqflist(', getline(2)) + exe "normal oabcxyz(\<C-X>\<C-V>" + call assert_equal('abcxyz(', getline(3)) + com! -buffer TestCommand1 echo 'TestCommand1' + com! -buffer TestCommand2 echo 'TestCommand2' + write TestCommand1Test + write TestCommand2Test + " Test repeating <CTRL-X> <CTRL-V> and switching to another CTRL-X mode + exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<C-X>\<C-F>\<Esc>" + call assert_equal('TestCommand2Test', getline(4)) + call delete('TestCommand1Test') + call delete('TestCommand2Test') + delcom TestCommand1 + delcom TestCommand2 + close! +endfunc + +" Test for <CTRL-X> <CTRL-Z> stopping completion without changing the match +func Test_complete_stop() + new + func Save_mode1() + let g:mode1 = mode(1) + return '' + endfunc + func Save_mode2() + let g:mode2 = mode(1) + return '' + endfunc + inoremap <F1> <C-R>=Save_mode1()<CR> + inoremap <F2> <C-R>=Save_mode2()<CR> + call setline(1, ['aaa bbb ccc ']) + exe "normal A\<C-N>\<C-P>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>" + call assert_equal('ic', g:mode1) + call assert_equal('i', g:mode2) + call assert_equal('aaa bbb ccc ', getline(1)) + exe "normal A\<C-N>\<Down>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>" + call assert_equal('ic', g:mode1) + call assert_equal('i', g:mode2) + call assert_equal('aaa bbb ccc aaa', getline(1)) + set completeopt+=noselect + exe "normal A \<C-N>\<Down>\<Down>\<C-L>\<C-L>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>" + call assert_equal('ic', g:mode1) + call assert_equal('i', g:mode2) + call assert_equal('aaa bbb ccc aaa bb', getline(1)) + set completeopt& + exe "normal A d\<C-N>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>" + call assert_equal('ic', g:mode1) + call assert_equal('i', g:mode2) + call assert_equal('aaa bbb ccc aaa bb d', getline(1)) + com! -buffer TestCommand1 echo 'TestCommand1' + com! -buffer TestCommand2 echo 'TestCommand2' + exe "normal oT\<C-X>\<C-V>\<C-X>\<C-V>\<F1>\<C-X>\<C-Z>\<F2>\<Esc>" + call assert_equal('ic', g:mode1) + call assert_equal('i', g:mode2) + call assert_equal('TestCommand2', getline(2)) + delcom TestCommand1 + delcom TestCommand2 + unlet g:mode1 + unlet g:mode2 + iunmap <F1> + iunmap <F2> + delfunc Save_mode1 + delfunc Save_mode2 + close! +endfunc + " Test to ensure 'Scanning...' messages are not recorded in messages history func Test_z1_complete_no_history() new diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim index 5152af8f58..ae035fa519 100644 --- a/src/nvim/testdir/test_listdict.vim +++ b/src/nvim/testdir/test_listdict.vim @@ -139,7 +139,7 @@ func Test_list_func_remove() 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(1, 0)", 'E896:') call assert_fails("call remove(l, l)", 'E745:') endfunc @@ -616,6 +616,8 @@ func Test_reverse_sort_uniq() call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1)) call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i')) call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l))) + + call assert_fails('call reverse("")', 'E899:') endfunc " splitting a string to a List diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim index 7a6e6aa19d..d34448e09e 100644 --- a/src/nvim/testdir/test_method.vim +++ b/src/nvim/testdir/test_method.vim @@ -46,11 +46,8 @@ func Test_dict_method() call assert_equal(#{one: 1, two: 2, three: 3, four: 4}, d->extend(#{four: 4})) call assert_equal(#{one: 1, two: 2, three: 3}, d->filter('v:val != 4')) call assert_equal(2, d->get('two')) - " Nvim doesn't support Blobs yet; expect a different emsg - " call assert_fails("let x = d->index(2)", 'E897:') - " call assert_fails("let x = d->insert(0)", 'E899:') - call assert_fails("let x = d->index(2)", 'E714:') - call assert_fails("let x = d->insert(0)", 'E686:') + call assert_fails("let x = d->index(2)", 'E897:') + call assert_fails("let x = d->insert(0)", 'E899:') call assert_true(d->has_key('two')) call assert_equal([['one', 1], ['two', 2], ['three', 3]], d->items()) call assert_fails("let x = d->join()", 'E714:') @@ -63,9 +60,7 @@ func Test_dict_method() call assert_equal(2, d->remove("two")) let d.two = 2 call assert_fails('let x = d->repeat(2)', 'E731:') - " Nvim doesn't support Blobs yet; expect a different emsg - " call assert_fails('let x = d->reverse()', 'E899:') - call assert_fails('let x = d->reverse()', 'E686:') + call assert_fails('let x = d->reverse()', 'E899:') call assert_fails('let x = d->sort()', 'E686:') call assert_equal("{'one': 1, 'two': 2, 'three': 3}", d->string()) call assert_equal(v:t_dict, d->type()) diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 283e7bbafe..18587b9b2c 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -2221,6 +2221,10 @@ func Xproperty_tests(cchar) call g:Xsetlist([], 'a', {'context':246}) let d = g:Xgetlist({'context':1}) call assert_equal(246, d.context) + " set other Vim data types as context + call g:Xsetlist([], 'a', {'context' : v:_null_blob}) + call g:Xsetlist([], 'a', {'context' : ''}) + call test_garbagecollect_now() if a:cchar == 'l' " Test for copying context across two different location lists new | only diff --git a/src/nvim/testdir/test_rename.vim b/src/nvim/testdir/test_rename.vim index e4228188bd..2311caf790 100644 --- a/src/nvim/testdir/test_rename.vim +++ b/src/nvim/testdir/test_rename.vim @@ -95,7 +95,6 @@ func Test_rename_copy() endfunc func Test_rename_fails() - throw 'skipped: TODO: ' call writefile(['foo'], 'Xrenamefile') " Can't rename into a non-existing directory. diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 02bc297de1..e3101d4e44 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -168,7 +168,6 @@ func Test_swapname() endfunc func Test_swapfile_delete() - throw 'skipped: need the "blob" feature for this test' autocmd! SwapExists function s:swap_exists() let v:swapchoice = s:swap_choice diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim index 54caed3983..c7dcaa0f36 100644 --- a/src/nvim/testdir/test_undo.vim +++ b/src/nvim/testdir/test_undo.vim @@ -368,7 +368,6 @@ endfunc " Check that reading a truncted undo file doesn't hang. func Test_undofile_truncated() - throw 'skipped: TODO: ' new call setline(1, 'hello') set ul=100 diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index d5837e88c9..b18ce563d3 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -1152,6 +1152,10 @@ func Test_type() call assert_equal(v:t_float, type(0.0)) call assert_equal(v:t_bool, type(v:false)) call assert_equal(v:t_bool, type(v:true)) + call assert_equal(v:t_string, type(v:_null_string)) + call assert_equal(v:t_list, type(v:_null_list)) + call assert_equal(v:t_dict, type(v:_null_dict)) + call assert_equal(v:t_blob, type(v:_null_blob)) endfunc "------------------------------------------------------------------------------- diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim index 6922e2185d..2504fcb14e 100644 --- a/src/nvim/testdir/test_writefile.vim +++ b/src/nvim/testdir/test_writefile.vim @@ -17,6 +17,8 @@ func Test_writefile() call assert_equal("morning", l[3]) call assert_equal("vimmers", l[4]) call delete(f) + + call assert_fails('call writefile("text", "Xfile")', 'E475: Invalid argument: writefile() first argument must be a List or a Blob') endfunc func Test_writefile_ignore_regexp_error() diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 6705ab98c2..ec277f7a4e 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -2,19 +2,19 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com -#include "nvim/tui/input.h" -#include "nvim/vim.h" -#include "nvim/api/vim.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/vim.h" #include "nvim/ascii.h" -#include "nvim/charset.h" -#include "nvim/main.h" -#include "nvim/macros.h" #include "nvim/aucmd.h" +#include "nvim/charset.h" #include "nvim/ex_docmd.h" +#include "nvim/macros.h" +#include "nvim/main.h" #include "nvim/option.h" -#include "nvim/os/os.h" #include "nvim/os/input.h" +#include "nvim/os/os.h" +#include "nvim/tui/input.h" +#include "nvim/vim.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif @@ -53,7 +53,7 @@ void tinput_init(TermInput *input, Loop *loop) // ls *.md | xargs nvim #ifdef WIN32 if (!os_isatty(input->in_fd)) { - input->in_fd = os_get_conin_fd(); + input->in_fd = os_get_conin_fd(); } #else if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) { @@ -279,25 +279,25 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key) } switch (ev) { - case TERMKEY_MOUSE_PRESS: - if (button == 4) { - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp"); - } else if (button == 5) { - len += (size_t)snprintf(buf + len, sizeof(buf) - len, - "ScrollWheelDown"); - } else { - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse"); - last_pressed_button = button; - } - break; - case TERMKEY_MOUSE_DRAG: - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag"); - break; - case TERMKEY_MOUSE_RELEASE: - len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release"); - break; - case TERMKEY_MOUSE_UNKNOWN: - abort(); + case TERMKEY_MOUSE_PRESS: + if (button == 4) { + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp"); + } else if (button == 5) { + len += (size_t)snprintf(buf + len, sizeof(buf) - len, + "ScrollWheelDown"); + } else { + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse"); + last_pressed_button = button; + } + break; + case TERMKEY_MOUSE_DRAG: + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag"); + break; + case TERMKEY_MOUSE_RELEASE: + len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release"); + break; + case TERMKEY_MOUSE_UNKNOWN: + abort(); } len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row); @@ -428,7 +428,7 @@ static bool handle_forced_escape(TermInput *input) // skip the ESC and NUL and push one <esc> to the input buffer size_t rcnt; termkey_push_bytes(input->tk, rbuffer_read_ptr(input->read_stream.buffer, - &rcnt), 1); + &rcnt), 1); rbuffer_consumed(input->read_stream.buffer, 2); tk_getkeys(input, true); return true; @@ -618,8 +618,7 @@ static void handle_raw_buffer(TermInput *input, bool force) } while (rbuffer_size(input->read_stream.buffer)); } -static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, - void *data, bool eof) +static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof) { TermInput *input = data; @@ -637,7 +636,7 @@ static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, // If 'ttimeout' is not set, start the timer with a timeout of 0 to process // the next input. long ms = input->ttimeout ? - (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0; + (input->ttimeoutlen >= 0 ? input->ttimeoutlen : 0) : 0; // Stop the current timer if already running time_watcher_stop(&input->timer_handle); time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0); diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index ff2a357752..ce48059b94 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -5,11 +5,10 @@ #include <stdbool.h> #include <string.h> - #include <unibilium.h> -#include "nvim/log.h" #include "nvim/globals.h" +#include "nvim/log.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" @@ -29,12 +28,12 @@ bool terminfo_is_term_family(const char *term, const char *family) size_t tlen = strlen(term); size_t flen = strlen(family); return tlen >= flen - && 0 == memcmp(term, family, flen) - // Per commentary in terminfo, minus is the only valid suffix separator. - // The screen terminfo may have a terminal name like screen.xterm. By making - // the dot(.) a valid separator, such terminal names will also be the - // terminal family of the screen. - && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]); + && 0 == memcmp(term, family, flen) + // Per commentary in terminfo, minus is the only valid suffix separator. + // The screen terminfo may have a terminal name like screen.xterm. By making + // the dot(.) a valid separator, such terminal names will also be the + // terminal family of the screen. + && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]); } bool terminfo_is_bsd_console(const char *term) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index dcc086a0cf..fb5e12c20e 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -4,47 +4,45 @@ // Terminal UI functions. Invoked (by ui_bridge.c) on the TUI thread. #include <assert.h> +#include <limits.h> #include <stdbool.h> #include <stdio.h> -#include <limits.h> - -#include <uv.h> #include <unibilium.h> +#include <uv.h> #if defined(HAVE_TERMIOS_H) # include <termios.h> #endif -#include "nvim/lib/kvec.h" - +#include "nvim/api/private/helpers.h" +#include "nvim/api/vim.h" #include "nvim/ascii.h" -#include "nvim/vim.h" -#include "nvim/log.h" -#include "nvim/ui.h" +#include "nvim/event/loop.h" +#include "nvim/event/signal.h" #include "nvim/highlight.h" -#include "nvim/map.h" +#include "nvim/lib/kvec.h" +#include "nvim/log.h" #include "nvim/main.h" +#include "nvim/map.h" #include "nvim/memory.h" #include "nvim/option.h" -#include "nvim/api/vim.h" -#include "nvim/api/private/helpers.h" -#include "nvim/event/loop.h" -#include "nvim/event/signal.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/signal.h" #include "nvim/os/tty.h" +#include "nvim/ui.h" +#include "nvim/vim.h" #ifdef WIN32 # include "nvim/os/os_win_console.h" #endif +#include "nvim/cursor_shape.h" +#include "nvim/macros.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/macros.h" +#include "nvim/tui/tui.h" +#include "nvim/ugrid.h" +#include "nvim/ui_bridge.h" // Space reserved in two output buffers to make the cursor normal or invisible // when flushing. No existing terminal will require 32 bytes to do that. @@ -53,17 +51,17 @@ #define TOO_MANY_EVENTS 1000000 #define STARTS_WITH(str, prefix) \ - (strlen(str) >= (sizeof(prefix) - 1) \ - && 0 == memcmp((str), (prefix), sizeof(prefix) - 1)) + (strlen(str) >= (sizeof(prefix) - 1) \ + && 0 == memcmp((str), (prefix), sizeof(prefix) - 1)) #define TMUX_WRAP(is_tmux, seq) \ - ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq) + ((is_tmux) ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq) #define LINUXSET0C "\x1b[?0c" #define LINUXSET1C "\x1b[?1c" #ifdef NVIM_UNIBI_HAS_VAR_FROM #define UNIBI_SET_NUM_VAR(var, num) \ do { \ - (var) = unibi_var_from_num((num)); \ + (var) = unibi_var_from_num((num)); \ } while (0) #else #define UNIBI_SET_NUM_VAR(var, num) (var).i = (num); @@ -180,8 +178,7 @@ UI *tui_start(void) return ui_bridge_attach(ui, tui_main, tui_scheduler); } -static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, - char * buf, size_t len) +static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char * buf, size_t len) { const char *str = unibi_get_str(data->ut, unibi_index); if (!str) { @@ -263,10 +260,10 @@ static void terminfo_start(UI *ui) long vtev = vte_version_env ? strtol(vte_version_env, NULL, 10) : 0; bool iterm_env = termprg && strstr(termprg, "iTerm.app"); bool nsterm = (termprg && strstr(termprg, "Apple_Terminal")) - || terminfo_is_term_family(term, "nsterm"); + || terminfo_is_term_family(term, "nsterm"); bool konsole = terminfo_is_term_family(term, "konsole") - || os_getenv("KONSOLE_PROFILE_NAME") - || os_getenv("KONSOLE_DBUS_SESSION"); + || os_getenv("KONSOLE_PROFILE_NAME") + || os_getenv("KONSOLE_DBUS_SESSION"); const char *konsolev_env = os_getenv("KONSOLE_VERSION"); long konsolev = konsolev_env ? strtol(konsolev_env, NULL, 10) : (konsole ? 1 : 0); @@ -508,15 +505,15 @@ static bool attrs_differ(UI *ui, int id1, int id2, bool rgb) if (rgb) { 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_sp_color != a2.rgb_sp_color; + || a1.rgb_bg_color != a2.rgb_bg_color + || 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 & (HL_UNDERLINE|HL_UNDERCURL) - && a1.rgb_sp_color != a2.rgb_sp_color); + || a1.cterm_bg_color != a2.cterm_bg_color + || a1.cterm_ae_attr != a2.cterm_ae_attr + || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL) + && a1.rgb_sp_color != a2.rgb_sp_color); } } @@ -593,10 +590,10 @@ static void update_attrs(UI *ui, int attr_id) if ((undercurl || underline) && data->unibi_ext.set_underline_color != -1) { 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); + 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); } } @@ -639,14 +636,14 @@ static void update_attrs(UI *ui, int attr_id) data->default_attr = fg == -1 && bg == -1 - && !bold && !italic && !underline && !undercurl && !reverse && !standout - && !strikethrough; + && !bold && !italic && !underline && !undercurl && !reverse && !standout + && !strikethrough; // Non-BCE terminals can't clear with non-default background color. Some BCE // terminals don't support attributes either, so don't rely on it. But assume // italic and bold has no effect if there is no text. data->can_clear_attr = !reverse && !standout && !underline && !undercurl - && !strikethrough && (data->bce || bg == -1); + && !strikethrough && (data->bce || bg == -1); } static void final_column_wrap(UI *ui) @@ -802,8 +799,7 @@ safe_move: ugrid_goto(grid, row, col); } -static void clear_region(UI *ui, int top, int bot, int left, int right, - int attr_id) +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; @@ -1006,7 +1002,7 @@ static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args) static void tui_update_menu(UI *ui) { - // Do nothing; menus are for GUI only + // Do nothing; menus are for GUI only } static void tui_busy_start(UI *ui) @@ -1096,10 +1092,14 @@ static void tui_set_mode(UI *ui, ModeShape mode) int shape; switch (c.shape) { - default: abort(); break; - case SHAPE_BLOCK: shape = 1; break; - case SHAPE_HOR: shape = 3; break; - case SHAPE_VER: shape = 5; break; + default: + abort(); break; + case SHAPE_BLOCK: + shape = 1; break; + case SHAPE_HOR: + shape = 3; break; + case SHAPE_VER: + shape = 5; break; } UNIBI_SET_NUM_VAR(data->params[0], shape + (int)(c.blinkon == 0)); unibi_out_ext(ui, data->unibi_ext.set_cursor_style); @@ -1124,8 +1124,8 @@ static void tui_mode_change(UI *ui, String mode, Integer mode_idx) } static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 - Integer endrow, Integer startcol, Integer endcol, - Integer rows, Integer cols FUNC_ATTR_UNUSED) + Integer endrow, Integer startcol, Integer endcol, Integer rows, + Integer cols FUNC_ATTR_UNUSED) { TUIData *data = ui->data; UGrid *grid = &data->grid; @@ -1134,16 +1134,16 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 bool fullwidth = left == 0 && right == ui->width-1; data->scroll_region_is_full_screen = fullwidth - && top == 0 && bot == ui->height-1; + && top == 0 && bot == ui->height-1; ugrid_scroll(grid, top, bot, left, right, (int)rows); bool can_scroll = data->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))); + && (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 @@ -1184,8 +1184,7 @@ static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, // -V751 } } -static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, - HlAttrs cterm_attrs, Array info) +static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs, HlAttrs cterm_attrs, Array info) { TUIData *data = ui->data; kv_a(data->attrs, (size_t)id) = attrs; @@ -1201,8 +1200,7 @@ static void tui_visual_bell(UI *ui) unibi_out(ui, unibi_flash_screen); } -static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, - Integer rgb_sp, +static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg, Integer rgb_sp, Integer cterm_fg, Integer cterm_bg) { TUIData *data = ui->data; @@ -1379,9 +1377,8 @@ static void tui_option_set(UI *ui, String name, Object value) } } -static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, - Integer endcol, Integer clearcol, Integer clearattr, - LineFlags flags, const schar_T *chunk, +static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol, Integer endcol, + Integer clearcol, Integer clearattr, LineFlags flags, const schar_T *chunk, const sattr_T *attrs) { TUIData *data = ui->data; @@ -1461,8 +1458,8 @@ static void tui_guess_size(UI *ui) did_user_set_dimensions = true; assert(Columns >= INT_MIN && Columns <= INT_MAX); assert(Rows >= INT_MIN && Rows <= INT_MAX); - width = (int)Columns; - height = (int)Rows; + width = Columns; + height = Rows; goto end; } @@ -1561,8 +1558,7 @@ static void out(void *ctx, const char *str, size_t len) data->bufpos += len; } -static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str, - const char *val) +static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str, const char *val) { if (!unibi_get_str(ut, str)) { unibi_set_str(ut, str, val); @@ -1596,9 +1592,8 @@ static int unibi_find_ext_bool(unibi_term *ut, const char *name) /// 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. -static void patch_terminfo_bugs(TUIData *data, const char *term, - const char *colorterm, long vte_version, - long konsolev, bool iterm_env, bool nsterm) +static void patch_terminfo_bugs(TUIData *data, const char *term, const char *colorterm, + long vte_version, long konsolev, bool iterm_env, bool nsterm) { unibi_term *ut = data->ut; const char *xterm_version = os_getenv("XTERM_VERSION"); @@ -1606,8 +1601,8 @@ 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") - // Treat Terminal.app as generic xterm-like, for now. - || nsterm; + // Treat Terminal.app as generic xterm-like, for now. + || nsterm; bool kitty = terminfo_is_term_family(term, "xterm-kitty"); bool linuxvt = terminfo_is_term_family(term, "linux"); bool bsdvt = terminfo_is_bsd_console(term); @@ -1618,18 +1613,18 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); bool st = terminfo_is_term_family(term, "st"); bool gnome = terminfo_is_term_family(term, "gnome") - || terminfo_is_term_family(term, "vte"); + || terminfo_is_term_family(term, "vte"); bool iterm = terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iterm2") - || terminfo_is_term_family(term, "iTerm.app") - || terminfo_is_term_family(term, "iTerm2.app"); + || 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 gnome_pretending_xterm = xterm && colorterm - && strstr(colorterm, "gnome-terminal"); + && strstr(colorterm, "gnome-terminal"); bool mate_pretending_xterm = xterm && colorterm - && strstr(colorterm, "mate-terminal"); + && strstr(colorterm, "mate-terminal"); bool true_xterm = xterm && !!xterm_version && !bsdvt; bool cygwin = terminfo_is_term_family(term, "cygwin"); @@ -1839,8 +1834,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q"); if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b[ q"); @@ -1849,25 +1844,25 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // does not support DECSCUSR. // See http://linuxgazette.net/137/anonymous.html for more info data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", - "\x1b[?" - "%?" - // The parameter passed to Ss is the DECSCUSR parameter, so the - // terminal capability has to translate into the Linux idiosyncratic - // parameter. - // - // linuxvt only supports block and underline. It is also only - // possible to have a steady block (no steady underline) - "%p1%{2}%<" "%t%{8}" // blink block - "%e%p1%{2}%=" "%t%{112}" // steady block - "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block) - "%e%p1%{4}%=" "%t%{4}" // steady underline - "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline) - "%e%p1%{6}%=" "%t%{2}" // steady bar - "%e%{0}" // anything else - "%;" "%dc"); + "\x1b[?" + "%?" + // The parameter passed to Ss is the DECSCUSR parameter, so the + // terminal capability has to translate into the Linux idiosyncratic + // parameter. + // + // linuxvt only supports block and underline. It is also only + // possible to have a steady block (no steady underline) + "%p1%{2}%<" "%t%{8}" // blink block + "%e%p1%{2}%=" "%t%{112}" // steady block + "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block) + "%e%p1%{4}%=" "%t%{4}" // steady underline + "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline) + "%e%p1%{6}%=" "%t%{2}" // steady bar + "%e%{0}" // anything else + "%;" "%dc"); if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, "\x1b[?c"); @@ -1875,34 +1870,34 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // Konsole before version 18.07.70: set up a nonce profile. This has // side-effects on temporary font resizing. #6798 data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss", - TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?" - "%p1%{3}%<" "%t%{0}" // block - "%e%p1%{5}%<" "%t%{2}" // underline - "%e%{1}" // everything else is bar - "%;%d;BlinkingCursorEnabled=%?" - "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special, - "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag. - "%;%d\x07")); + TMUX_WRAP(tmux, + "\x1b]50;CursorShape=%?" + "%p1%{3}%<" "%t%{0}" // block + "%e%p1%{5}%<" "%t%{2}" // underline + "%e%{1}" // everything else is bar + "%;%d;BlinkingCursorEnabled=%?" + "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special, + "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag. + "%;%d\x07")); if (-1 == data->unibi_ext.reset_cursor_style) { - data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", - ""); + data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se", + ""); } unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style, - "\x1b]50;\x07"); + "\x1b]50;\x07"); } } } /// This adds stuff that is not in standard terminfo as extended unibilium /// capabilities. -static void augment_terminfo(TUIData *data, const char *term, - long vte_version, - long konsolev, bool iterm_env, bool nsterm) +static void augment_terminfo(TUIData *data, const char *term, long vte_version, long konsolev, + bool iterm_env, bool nsterm) { unibi_term *ut = data->ut; bool xterm = terminfo_is_term_family(term, "xterm") - // Treat Terminal.app as generic xterm-like, for now. - || nsterm; + // Treat Terminal.app as generic xterm-like, for now. + || nsterm; bool bsdvt = terminfo_is_bsd_console(term); bool dtterm = terminfo_is_term_family(term, "dtterm"); bool rxvt = terminfo_is_term_family(term, "rxvt"); @@ -1911,9 +1906,9 @@ static void augment_terminfo(TUIData *data, const char *term, bool screen = terminfo_is_term_family(term, "screen"); bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX"); bool iterm = terminfo_is_term_family(term, "iterm") - || terminfo_is_term_family(term, "iterm2") - || terminfo_is_term_family(term, "iTerm.app") - || terminfo_is_term_family(term, "iTerm2.app"); + || 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; @@ -1928,19 +1923,18 @@ static void augment_terminfo(TUIData *data, const char *term, || teraterm // per TeraTerm "Supported Control Functions" doco || rxvt) { // per command.C data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut, - "ext.resize_screen", - "\x1b[8;%p1%d;%p2%dt"); + "ext.resize_screen", + "\x1b[8;%p1%d;%p2%dt"); } if (putty || xterm || rxvt) { data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut, - "ext.reset_scroll_region", - "\x1b[r"); + "ext.reset_scroll_region", + "\x1b[r"); } // terminfo describes strikethrough modes as rmxx/smxx with respect // to the ECMA-48 strikeout/crossed-out attributes. - data->unibi_ext.enter_strikethrough_mode = (int)unibi_find_ext_str( - ut, "smxx"); + data->unibi_ext.enter_strikethrough_mode = unibi_find_ext_str(ut, "smxx"); // Dickey ncurses terminfo does not include the setrgbf and setrgbb // capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. Adding @@ -1955,29 +1949,29 @@ static void augment_terminfo(TUIData *data, const char *term, // can use colons like ISO 8613-6:1994/ITU T.416:1993 says. bool has_colon_rgb = !tmux && !screen - && !vte_version // VTE colon-support has a big memory leak. #7573 - && (iterm || iterm_pretending_xterm // per VT100Terminal.m - // per http://invisible-island.net/xterm/xterm.log.html#xterm_282 - || true_xterm); + && !vte_version // VTE colon-support has a big memory leak. #7573 + && (iterm || iterm_pretending_xterm // per VT100Terminal.m + // per http://invisible-island.net/xterm/xterm.log.html#xterm_282 + || true_xterm); data->unibi_ext.set_rgb_foreground = unibi_find_ext_str(ut, "setrgbf"); if (-1 == data->unibi_ext.set_rgb_foreground) { if (has_colon_rgb) { data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf", - "\x1b[38:2:%p1%d:%p2%d:%p3%dm"); + "\x1b[38:2:%p1%d:%p2%d:%p3%dm"); } else { data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf", - "\x1b[38;2;%p1%d;%p2%d;%p3%dm"); + "\x1b[38;2;%p1%d;%p2%d;%p3%dm"); } } data->unibi_ext.set_rgb_background = unibi_find_ext_str(ut, "setrgbb"); if (-1 == data->unibi_ext.set_rgb_background) { if (has_colon_rgb) { data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb", - "\x1b[48:2:%p1%d:%p2%d:%p3%dm"); + "\x1b[48:2:%p1%d:%p2%d:%p3%dm"); } else { data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb", - "\x1b[48;2;%p1%d;%p2%d;%p3%dm"); + "\x1b[48;2;%p1%d;%p2%d;%p3%dm"); } } @@ -1985,63 +1979,59 @@ static void augment_terminfo(TUIData *data, const char *term, // FIXME: Bypassing tmux like this affects the cursor colour globally, in // all panes, which is not particularly desirable. A better approach // 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\\")); + data->unibi_ext.set_cursor_color = + (int)unibi_add_ext_str(ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\")); } else if ((xterm || rxvt || tmux || alacritty) && (vte_version == 0 || vte_version >= 3900)) { // Supported in urxvt, newer VTE. - data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( - ut, "ext.set_cursor_color", "\033]12;#%p1%06x\007"); + data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(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"); + data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str(ut, "ext.reset_cursor_color", + "\x1b]112\x07"); } - data->unibi_ext.save_title = (int)unibi_add_ext_str( - ut, "ext.save_title", "\x1b[22;0t"); - data->unibi_ext.restore_title = (int)unibi_add_ext_str( - ut, "ext.restore_title", "\x1b[23;0t"); + data->unibi_ext.save_title = (int)unibi_add_ext_str(ut, "ext.save_title", "\x1b[22;0t"); + data->unibi_ext.restore_title = (int)unibi_add_ext_str(ut, "ext.restore_title", "\x1b[23;0t"); /// Terminals usually ignore unrecognized private modes, and there is no /// known ambiguity with these. So we just set them unconditionally. - data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str( - ut, "ext.enable_lr_margin", "\x1b[?69h"); - data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str( - ut, "ext.disable_lr_margin", "\x1b[?69l"); - data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str( - ut, "ext.enable_bpaste", "\x1b[?2004h"); - data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str( - ut, "ext.disable_bpaste", "\x1b[?2004l"); + data->unibi_ext.enable_lr_margin = + (int)unibi_add_ext_str(ut, "ext.enable_lr_margin", "\x1b[?69h"); + data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(ut, "ext.disable_lr_margin", + "\x1b[?69l"); + data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, "ext.enable_bpaste", + "\x1b[?2004h"); + data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, "ext.disable_bpaste", + "\x1b[?2004l"); // For urxvt send BOTH xterm and old urxvt sequences. #8695 - data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str( - ut, "ext.enable_focus", - rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h"); - data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str( - ut, "ext.disable_focus", - rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l"); - data->unibi_ext.enable_mouse = (int)unibi_add_ext_str( - 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"); + data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, "ext.enable_focus", + rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h"); + data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, "ext.disable_focus", + rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l"); + data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(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"); // Extended underline. // terminfo will have Smulx for this (but no support for colors yet). data->unibi_ext.set_underline_style = unibi_find_ext_str(ut, "Smulx"); if (data->unibi_ext.set_underline_style == -1) { - 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.set_underline_style = (int)unibi_add_ext_str( - ut, "ext.set_underline_style", "\x1b[4:%p1%dm"); - } + 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.set_underline_style = (int)unibi_add_ext_str(ut, "ext.set_underline_style", + "\x1b[4:%p1%dm"); + } } if (data->unibi_ext.set_underline_style != -1) { - // Only support colon syntax. #9270 - 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"); + // Only support colon syntax. #9270 + 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"); } } @@ -2134,8 +2124,7 @@ static const char *tui_get_stty_erase(void) /// libtermkey hook to override terminfo entries. /// @see TermInput.tk_ti_hook_fn -static const char *tui_tk_ti_getstr(const char *name, const char *value, - void *data) +static const char *tui_tk_ti_getstr(const char *name, const char *value, void *data) { static const char *stty_erase = NULL; if (stty_erase == NULL) { diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 94b6e9e39d..09709d0f43 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -69,9 +69,16 @@ static int pending_has_mouse = -1; #else static size_t uilog_seen = 0; static char uilog_last_event[1024] = { 0 }; + +#ifndef EXITFREE +#define entered_free_all_mem false +#endif + # define UI_LOG(funname) \ do { \ - if (strequal(uilog_last_event, STR(funname))) { \ + if (entered_free_all_mem) { \ + /* do nothing, we cannot log now */ \ + } else if (strequal(uilog_last_event, STR(funname))) { \ uilog_seen++; \ } else { \ if (uilog_seen > 0) { \ @@ -107,6 +114,10 @@ static char uilog_last_event[1024] = { 0 }; # include "ui_events_call.generated.h" #endif +#ifndef EXITFREE +#undef entered_free_all_mem +#endif + void ui_init(void) { default_grid.handle = 1; diff --git a/src/nvim/vim.h b/src/nvim/vim.h index c719c064e2..d84979f6fe 100644 --- a/src/nvim/vim.h +++ b/src/nvim/vim.h @@ -102,6 +102,7 @@ typedef enum { #define VAR_TYPE_FLOAT 5 #define VAR_TYPE_BOOL 6 #define VAR_TYPE_SPECIAL 7 +#define VAR_TYPE_BLOB 10 // values for xp_context when doing command line completion diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c index e9d82ca87d..f5bd5479c4 100644 --- a/src/nvim/viml/parser/expressions.c +++ b/src/nvim/viml/parser/expressions.c @@ -351,7 +351,7 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags) } if (exp_start) { vim_str2nr(pline.data + exp_start, NULL, NULL, 0, NULL, &exp_part, - (int)(ret.len - exp_start)); + (int)(ret.len - exp_start), false); } if (exp_negative) { exp_part += frac_size; @@ -369,7 +369,7 @@ LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags) int len; int prep; vim_str2nr(pline.data, &prep, &len, STR2NR_ALL, NULL, - &ret.data.num.val.integer, (int)pline.size); + &ret.data.num.val.integer, (int)pline.size, false); ret.len = (size_t)len; const uint8_t bases[] = { [0] = 10, diff --git a/src/nvim/window.c b/src/nvim/window.c index 222c1363dc..75ecf90b14 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -73,8 +73,8 @@ static char *m_onlyone = N_("Already only one window"); void do_window(int nchar, long Prenum, int xchar) { long Prenum1; - win_T *wp; - char_u *ptr; + win_T *wp; + char_u *ptr; linenr_T lnum = -1; int type = FIND_DEFINE; size_t len; @@ -287,8 +287,8 @@ newwindow: if (one_window()) { MSG(_(m_onlyone)); } else { - tabpage_T *oldtab = curtab; - tabpage_T *newtab; + tabpage_T *oldtab = curtab; + tabpage_T *newtab; /* First create a new tab with the window, then go back to * the old tab and close the window there. */ @@ -737,6 +737,37 @@ void win_config_float(win_T *wp, FloatConfig fconfig) redraw_later(wp, NOT_VALID); } + // compute initial position + if (wp->w_float_config.relative == kFloatRelativeWindow) { + int row = wp->w_float_config.row; + int col = wp->w_float_config.col; + Error dummy = ERROR_INIT; + win_T *parent = find_window_by_handle(wp->w_float_config.window, &dummy); + if (parent) { + row += parent->w_winrow; + col += parent->w_wincol; + ScreenGrid *grid = &parent->w_grid; + int row_off = 0, col_off = 0; + screen_adjust_grid(&grid, &row_off, &col_off); + row += row_off; + col += col_off; + } + api_clear_error(&dummy); + if (wp->w_float_config.bufpos.lnum >= 0) { + pos_T pos = { wp->w_float_config.bufpos.lnum + 1, + wp->w_float_config.bufpos.col, 0 }; + int trow, tcol, tcolc, tcole; + textpos2screenpos(wp, &pos, &trow, &tcol, &tcolc, &tcole, true); + row += trow - 1; + col += tcol - 1; + } + wp->w_winrow = row; + wp->w_wincol = col; + } else { + wp->w_winrow = fconfig.row; + wp->w_wincol = fconfig.col; + } + // changing border style while keeping border only requires redrawing border if (fconfig.border) { wp->w_redr_border = true; @@ -770,7 +801,6 @@ int win_fdccol_count(win_T *wp) } } - void ui_ext_win_position(win_T *wp) { if (!wp->w_floating) { @@ -817,6 +847,8 @@ void ui_ext_win_position(win_T *wp) int comp_row = (int)row - (south ? wp->w_height : 0); int comp_col = (int)col - (east ? wp->w_width : 0); + comp_row += grid->comp_row; + comp_col += grid->comp_col; comp_row = MAX(MIN(comp_row, Rows-wp->w_height_outer-1), 0); comp_col = MAX(MIN(comp_col, Columns-wp->w_width_outer), 0); wp->w_winrow = comp_row; @@ -840,14 +872,15 @@ void ui_ext_win_viewport(win_T *wp) { if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) { int botline = wp->w_botline; - if (botline == wp->w_buffer->b_ml.ml_line_count+1 - && wp->w_empty_rows == 0) { + int line_count = wp->w_buffer->b_ml.ml_line_count; + if (botline == line_count+1 && wp->w_empty_rows == 0) { // TODO(bfredl): The might be more cases to consider, like how does this // interact with incomplete final line? Diff filler lines? botline = wp->w_buffer->b_ml.ml_line_count; } ui_call_win_viewport(wp->w_grid_alloc.handle, wp->handle, wp->w_topline-1, - botline, wp->w_cursor.lnum-1, wp->w_cursor.col); + botline, wp->w_cursor.lnum-1, wp->w_cursor.col, + line_count); wp->w_viewport_invalid = false; } } @@ -900,8 +933,8 @@ int win_split(int size, int flags) */ int win_split_ins(int size, int flags, win_T *new_wp, int dir) { - win_T *wp = new_wp; - win_T *oldwin; + win_T *wp = new_wp; + win_T *oldwin; int new_size = size; int i; int need_status = 0; @@ -910,7 +943,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir) int available; int oldwin_height = 0; int layout; - frame_T *frp, *curfrp, *frp2, *prevfrp; + frame_T *frp, *curfrp, *frp2, *prevfrp; int before; int minheight; int wmh1; @@ -1607,10 +1640,10 @@ int make_windows(int count, bool vertical) */ static void win_exchange(long Prenum) { - frame_T *frp; - frame_T *frp2; - win_T *wp; - win_T *wp2; + frame_T *frp; + frame_T *frp2; + win_T *wp; + win_T *wp2; int temp; if (curwin->w_floating) { @@ -1706,9 +1739,9 @@ static void win_exchange(long Prenum) // if upwards false the first window becomes the second one static void win_rotate(bool upwards, int count) { - win_T *wp1; - win_T *wp2; - frame_T *frp; + win_T *wp1; + win_T *wp2; + frame_T *frp; int n; if (curwin->w_floating) { @@ -1918,7 +1951,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int int n, m; int extra_sep = 0; int wincount, totwincount = 0; - frame_T *fr; + frame_T *fr; int next_curwin_size = 0; int room = 0; int new_size; @@ -2205,7 +2238,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int /// @param keep_curwin don't close `curwin` void close_windows(buf_T *buf, int keep_curwin) { - tabpage_T *tp, *nexttp; + tabpage_T *tp, *nexttp; int h = tabline_height(); ++RedrawingDisabled; @@ -2305,7 +2338,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev if (!ONE_WINDOW) { return false; } - buf_T *old_curbuf = curbuf; + buf_T *old_curbuf = curbuf; Terminal *term = win->w_buffer ? win->w_buffer->terminal : NULL; if (term) { @@ -2356,12 +2389,12 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf, tabpage_T *prev // Returns FAIL when the window was not closed. int win_close(win_T *win, bool free_buf) { - win_T *wp; + win_T *wp; bool other_buffer = false; bool close_curwin = false; int dir; bool help_window = false; - tabpage_T *prev_curtab = curtab; + tabpage_T *prev_curtab = curtab; frame_T *win_frame = win->w_floating ? NULL : win->w_frame->fr_parent; const bool had_diffmode = win->w_p_diff; @@ -2426,7 +2459,7 @@ int win_close(win_T *win, bool free_buf) if (wp->w_buffer != curbuf) { other_buffer = true; win->w_closing = true; - apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf); if (!win_valid(win)) { return FAIL; } @@ -2651,7 +2684,7 @@ static void do_autocmd_winclosed(win_T *win) void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) { int dir; - tabpage_T *ptp = NULL; + tabpage_T *ptp = NULL; bool free_tp = false; // Get here with win->w_buffer == NULL when win_close() detects the tab page @@ -2739,8 +2772,8 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp) /// @return a pointer to the window that got the freed up space. static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp) { - frame_T *frp; - win_T *wp; + frame_T *frp; + win_T *wp; if (!win->w_floating) { // Remove the window and its frame from the tree of frames. @@ -2812,9 +2845,9 @@ void win_free_all(void) /// @return a pointer to the window that got the freed up space. win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) { - frame_T *frp, *frp2, *frp3; - frame_T *frp_close = win->w_frame; - win_T *wp; + frame_T *frp, *frp2, *frp3; + frame_T *frp_close = win->w_frame; + win_T *wp; /* * If there is only one window there is nothing to remove. @@ -2963,7 +2996,7 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp) /// is left over after "win" is closed. static frame_T *win_altframe(win_T *win, tabpage_T *tp) { - frame_T *frp; + frame_T *frp; if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) { return alt_tabpage()->tp_curwin->w_frame; @@ -3005,7 +3038,7 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp) */ static tabpage_T *alt_tabpage(void) { - tabpage_T *tp; + tabpage_T *tp; // Use the next tab page if possible. if (curtab->tp_next != NULL) { @@ -3058,7 +3091,7 @@ static bool frame_has_win(const frame_T *frp, const win_T *wp) static void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) FUNC_ATTR_NONNULL_ALL { - frame_T *frp; + frame_T *frp; int extra_lines; int h; @@ -3214,7 +3247,7 @@ static bool frame_fixed_width(frame_T *frp) */ static void frame_add_statusline(frame_T *frp) { - win_T *wp; + win_T *wp; if (frp->fr_layout == FR_LEAF) { wp = frp->fr_win; @@ -3246,10 +3279,10 @@ static void frame_add_statusline(frame_T *frp) /// may cause the width not to be set. static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw) { - frame_T *frp; + frame_T *frp; int extra_cols; int w; - win_T *wp; + win_T *wp; if (topfrp->fr_layout == FR_LEAF) { // Simple case: just one window. @@ -3345,7 +3378,7 @@ static void frame_new_width(frame_T *topfrp, int width, bool leftfirst, bool wfw static void frame_add_vsep(const frame_T *frp) FUNC_ATTR_NONNULL_ARG(1) { - win_T *wp; + win_T *wp; if (frp->fr_layout == FR_LEAF) { wp = frp->fr_win; @@ -3397,7 +3430,7 @@ static void frame_fix_height(win_T *wp) */ static int frame_minheight(frame_T *topfrp, win_T *next_curwin) { - frame_T *frp; + frame_T *frp; int m; int n; @@ -3442,7 +3475,7 @@ static int frame_minheight(frame_T *topfrp, win_T *next_curwin) /// @param next_curwin use p_wh and p_wiw for next_curwin static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) { - frame_T *frp; + frame_T *frp; int m, n; if (topfrp->fr_win != NULL) { @@ -3486,8 +3519,8 @@ static int frame_minwidth(frame_T *topfrp, win_T *next_curwin) /// @param forceit always hide all other windows void close_others(int message, int forceit) { - win_T *wp; - win_T *nextwp; + win_T *wp; + win_T *nextwp; int r; if (curwin->w_floating) { @@ -3715,8 +3748,8 @@ void free_tabpage(tabpage_T *tp) /// @return Was the new tabpage created successfully? FAIL or OK. int win_new_tabpage(int after, char_u *filename) { - tabpage_T *old_curtab = curtab; - tabpage_T *newtp; + tabpage_T *old_curtab = curtab; + tabpage_T *newtp; int n; newtp = alloc_tabpage(); @@ -3740,7 +3773,7 @@ int win_new_tabpage(int after, char_u *filename) newtp->tp_next = first_tabpage; first_tabpage = newtp; } else { - tabpage_T *tp = old_curtab; + tabpage_T *tp = old_curtab; if (after > 0) { // Put new tab page before tab page "after". @@ -3887,7 +3920,7 @@ void close_tabpage(tabpage_T *tab) */ tabpage_T *find_tabpage(int n) { - tabpage_T *tp; + tabpage_T *tp; int i = 1; for (tp = first_tabpage; tp != NULL && i != n; tp = tp->tp_next) { @@ -3903,7 +3936,7 @@ tabpage_T *find_tabpage(int n) int tabpage_index(tabpage_T *ftp) { int i = 1; - tabpage_T *tp; + tabpage_T *tp; for (tp = first_tabpage; tp != NULL && tp != ftp; tp = tp->tp_next) { ++i; @@ -3921,21 +3954,21 @@ int tabpage_index(tabpage_T *ftp) /// @param trigger_leave_autocmds when true trigger *Leave autocommands. static int leave_tabpage(buf_T *new_curbuf, bool trigger_leave_autocmds) { - tabpage_T *tp = curtab; + tabpage_T *tp = curtab; reset_VIsual_and_resel(); // stop Visual mode if (trigger_leave_autocmds) { if (new_curbuf != curbuf) { - apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf); if (curtab != tp) { return FAIL; } } - apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf); if (curtab != tp) { return FAIL; } - apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_TABLEAVE, NULL, NULL, false, curbuf); if (curtab != tp) { return FAIL; } @@ -3960,7 +3993,7 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a bool trigger_leave_autocmds) { int old_off = tp->tp_firstwin->w_winrow; - win_T *next_prevwin = tp->tp_prevwin; + win_T *next_prevwin = tp->tp_prevwin; tabpage_T *old_curtab = curtab; curtab = tp; @@ -4011,9 +4044,9 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a /* Apply autocommands after updating the display, when 'rows' and * 'columns' have been set correctly. */ if (trigger_enter_autocmds) { - apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf); if (old_curbuf != curbuf) { - apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf); } } @@ -4055,8 +4088,8 @@ static void tabpage_check_windows(tabpage_T *old_curtab) */ void goto_tabpage(int n) { - tabpage_T *tp = NULL; // shut up compiler - tabpage_T *ttp; + tabpage_T *tp = NULL; // shut up compiler + tabpage_T *ttp; int i; if (text_locked()) { @@ -4215,7 +4248,7 @@ void tabpage_move(int nr) */ void win_goto(win_T *wp) { - win_T *owp = curwin; + win_T *owp = curwin; if (text_locked()) { beep_flush(); @@ -4268,9 +4301,9 @@ tabpage_T *win_find_tabpage(win_T *win) /// @return found window win_T *win_vert_neighbor(tabpage_T *tp, win_T *wp, bool up, long count) { - frame_T *fr; - frame_T *nfr; - frame_T *foundfr; + frame_T *fr; + frame_T *nfr; + frame_T *foundfr; foundfr = wp->w_frame; @@ -4351,9 +4384,9 @@ static void win_goto_ver(bool up, long count) /// @return found window win_T *win_horz_neighbor(tabpage_T *tp, win_T *wp, bool left, long count) { - frame_T *fr; - frame_T *nfr; - frame_T *foundfr; + frame_T *fr; + frame_T *nfr; + frame_T *foundfr; foundfr = wp->w_frame; @@ -4439,7 +4472,7 @@ void win_enter(win_T *wp, bool undo_sync) static void win_enter_ext(win_T *wp, bool undo_sync, bool curwin_invalid, bool trigger_new_autocmds, bool trigger_enter_autocmds, bool trigger_leave_autocmds) { - int other_buffer = FALSE; + bool other_buffer = false; if (wp == curwin && !curwin_invalid) { // nothing to do return; @@ -4450,13 +4483,13 @@ static void win_enter_ext(win_T *wp, bool undo_sync, bool curwin_invalid, bool t * Be careful: If autocommands delete the window, return now. */ if (wp->w_buffer != curbuf) { - apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); - other_buffer = TRUE; + apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf); + other_buffer = true; if (!win_valid(wp)) { return; } } - apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf); + apply_autocmds(EVENT_WINLEAVE, NULL, NULL, false, curbuf); if (!win_valid(wp)) { return; } @@ -4704,7 +4737,7 @@ void free_wininfo(wininfo_T *wip, buf_T *bp) static void win_free(win_T *wp, tabpage_T *tp) { int i; - wininfo_T *wip; + wininfo_T *wip; pmap_del(handle_T)(&window_handles, wp->handle); clearFolding(wp); @@ -4813,7 +4846,7 @@ void win_free_grid(win_T *wp, bool reinit) */ void win_append(win_T *after, win_T *wp) { - win_T *before; + win_T *before; if (after == NULL) { // after NULL is in front of the first before = firstwin; @@ -5054,8 +5087,8 @@ void win_reconfig_floats(void) */ static void frame_comp_pos(frame_T *topfrp, int *row, int *col) { - win_T *wp; - frame_T *frp; + win_T *wp; + frame_T *frp; int startcol; int startrow; @@ -5156,7 +5189,7 @@ static void frame_setheight(frame_T *curfrp, int height) int take; // number of lines taken from other windows int room_cmdline; // lines available from cmdline int run; - frame_T *frp; + frame_T *frp; int h; int room_reserved; @@ -5353,7 +5386,7 @@ static void frame_setwidth(frame_T *curfrp, int width) int room; // total number of lines available int take; // number of lines taken from other windows int run; - frame_T *frp; + frame_T *frp; int w; int room_reserved; @@ -5520,8 +5553,8 @@ void win_setminwidth(void) /// Status line of dragwin is dragged "offset" lines down (negative is up). void win_drag_status_line(win_T *dragwin, int offset) { - frame_T *curfr; - frame_T *fr; + frame_T *curfr; + frame_T *fr; int room; int row; bool up; // if true, drag status line up, otherwise down @@ -5647,8 +5680,8 @@ void win_drag_status_line(win_T *dragwin, int offset) */ void win_drag_vsep_line(win_T *dragwin, int offset) { - frame_T *curfr; - frame_T *fr; + frame_T *curfr; + frame_T *fr; int room; bool left; // if true, drag separator line left, otherwise right int n; @@ -5980,7 +6013,7 @@ void win_comp_scroll(win_T *wp) void command_height(void) { int h; - frame_T *frp; + frame_T *frp; int old_p_ch = curtab->tp_ch_used; /* Use the value of p_ch that we remembered. This is needed for when the @@ -6072,7 +6105,7 @@ char_u *grab_file_name(long count, linenr_T *file_lnum) int options = FNAME_MESS | FNAME_EXP | FNAME_REL | FNAME_UNESC; if (VIsual_active) { size_t len; - char_u *ptr; + char_u *ptr; if (get_visual_text(NULL, &ptr, &len) == FAIL) { return NULL; } @@ -6114,7 +6147,7 @@ char_u *file_name_at_cursor(int options, long count, linenr_T *file_lnum) char_u *file_name_in_line(char_u *line, int col, int options, long count, char_u *rel_fname, linenr_T *file_lnum) { - char_u *ptr; + char_u *ptr; size_t len; bool in_type = true; bool is_url = false; @@ -6226,8 +6259,8 @@ void last_status(bool morewin) static void last_status_rec(frame_T *fr, bool statusline) { - frame_T *fp; - win_T *wp; + frame_T *fp; + win_T *wp; if (fr->fr_layout == FR_LEAF) { wp = fr->fr_win; @@ -6444,7 +6477,7 @@ static void clear_snapshot_rec(frame_T *fr) /// @param close_curwin closing current window void restore_snapshot(int idx, int close_curwin) { - win_T *wp; + win_T *wp; if (curtab->tp_snapshot[idx] != NULL && curtab->tp_snapshot[idx]->fr_width == topframe->fr_width @@ -6484,8 +6517,8 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr) */ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) { - win_T *wp = NULL; - win_T *wp2; + win_T *wp = NULL; + win_T *wp2; fr->fr_height = sn->fr_height; fr->fr_width = sn->fr_width; @@ -6645,7 +6678,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, int prio, matchitem_T *prev; matchitem_T *m; int hlg_id; - regprog_T *regprog = NULL; + regprog_T *regprog = NULL; int rtype = SOME_VALID; if (*grp == NUL || (pat != NULL && *pat == NUL)) { |
