diff options
| author | Gregory Anders <8965202+gpanders@users.noreply.github.com> | 2022-04-13 08:04:56 -0600 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-13 08:04:56 -0600 | 
| commit | e463eb81465978b5de77e207af9ee1b416ca0053 (patch) | |
| tree | da86f1a31a332690c2c265a24e321e6255b0c1fa /src/nvim/ex_docmd.c | |
| parent | 4dc09f38ee709cadc745ac44a1cc24c4c526ecaf (diff) | |
| download | rneovim-e463eb81465978b5de77e207af9ee1b416ca0053.tar.gz rneovim-e463eb81465978b5de77e207af9ee1b416ca0053.tar.bz2 rneovim-e463eb81465978b5de77e207af9ee1b416ca0053.zip | |
fix(api): correctly pass f-args for nvim_create_user_command (#18098)
Skip runs of whitespace and do not include `\` characters when
followed by another `\` or whitespace. This matches the behavior
of <f-args> when used with `:command`.
Diffstat (limited to 'src/nvim/ex_docmd.c')
| -rw-r--r-- | src/nvim/ex_docmd.c | 52 | 
1 files changed, 35 insertions, 17 deletions
| diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 482bf69f67..cbfe6e3789 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -5774,26 +5774,44 @@ static void ex_delcommand(exarg_T *eap)  /// Split a string by unescaped whitespace (space & tab), used for f-args on Lua commands callback.  /// Similar to uc_split_args(), but does not allocate, add quotes, add commas and is an iterator.  /// -/// @note  If no separator is found start = 0 and end = length - 1 -/// @param[in]  arg  String to split -/// @param[in]  iter Iteration counter -/// @param[out]  start Start of the split -/// @param[out]  end End of the split -/// @param[in]  length Length of the string +/// @param[in]  arg String to split +/// @param[in]  arglen Length of {arg} +/// @param[inout] end Index of last character of previous iteration +/// @param[out] buf Buffer to copy string into +/// @param[out] len Length of string in {buf}  /// -/// @return  false if it's the last split (don't call again), true otherwise (call again). -bool uc_split_args_iter(const char_u *arg, int iter, int *start, int *end, int length) -{ -  int pos; -  *start = *end + (iter > 1 ? 2 : 0);  // Skip whitespace after the first split -  for (pos = *start; pos < length - 2; pos++) { -    if (arg[pos] != '\\' && ascii_iswhite(arg[pos + 1])) { -      *end = pos; -      return true; +/// @return true if iteration is complete, else false +bool uc_split_args_iter(const char_u *arg, size_t arglen, size_t *end, char *buf, size_t *len) +{ +  if (!arglen) { +    return true; +  } + +  size_t pos = *end; +  while (pos < arglen && ascii_iswhite(arg[pos])) { +    pos++; +  } + +  size_t l = 0; +  for (; pos < arglen - 1; pos++) { +    if (arg[pos] == '\\' && (arg[pos + 1] == '\\' || ascii_iswhite(arg[pos + 1]))) { +      buf[l++] = arg[++pos]; +    } else { +      buf[l++] = arg[pos]; +      if (ascii_iswhite(arg[pos + 1])) { +        *end = pos + 1; +        *len = l; +        return false; +      }      }    } -  *end = length - 1; -  return false; + +  if (pos < arglen && !ascii_iswhite(arg[pos])) { +    buf[l++] = arg[pos]; +  } + +  *len = l; +  return true;  }  /// split and quote args for <f-args> | 
