Repository: neovim/neovim
File: runtime/lua/vim/shared.lua (Lua)

Code before:
--- every iteration, instead this function will re-index  the table exactly
--- once.
---
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
---
---@param t any[]
---@param first integer
---@param last integer
function vim._list_remove(t, first, last)
  local n = #t
  for i = 0, n - first do
    t[first + i] = t[last + 1 + i]
    t[last + 1 + i] = nil
  end
end

--- Trim whitespace (Lua pattern "%s") from both sides of a string.
---
---@see |lua-pattern|s
---@see https://www.lua.org/pil/20.2.html
---@param s string String to trim
---@return string String with whitespace removed from its beginning and end
function vim.trim(s)
  vim.validate('s', s, 'string')
  -- `s:match('^%s*(.*%S)')` is slow for long whitespace strings,
  -- so we are forced to split it into to parts to prevent this
  return s:gsub('^%s+', ''):match('^.*%S') or ''
end

--- Escapes magic chars in |lua-pattern|s.
---
---@see https://github.com/rxi/lume
---@param s string String to escape
---@return string %-escaped pattern string
function vim.pesc(s)
  vim.validate('s', s, 'string')
  return (s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1'))
end

--- Tests if `s` starts with `prefix`.
---
---@param s string String
---@param prefix string Prefix to match
---@return boolean `true` if `prefix` is a prefix of `s`
function vim.startswith(s, prefix)
  vim.validate('s', s, 'string')
  vim.validate('prefix', prefix, 'string')
  return s:sub(1, #prefix) == prefix
end

--- Tests if `s` ends with `suffix`.

Review comment (performance):
Maybe also mention `gsub('%s+$', '')` case (as it is not intuitive)?

```suggestion
  -- `match('^%s*(.*%S)')` is slow for long whitespace strings
  -- `gsub('%s+$', '')` is slow for strings with many whitespace characters
  -- See PR #34122 for more details
```

Code after:
--- every iteration, instead this function will re-index  the table exactly
--- once.
---
--- Based on https://stackoverflow.com/questions/12394841/safely-remove-items-from-an-array-table-while-iterating/53038524#53038524
---
---@param t any[]
---@param first integer
---@param last integer
function vim._list_remove(t, first, last)
  local n = #t
  for i = 0, n - first do
    t[first + i] = t[last + 1 + i]
    t[last + 1 + i] = nil
  end
end

--- Trim whitespace (Lua pattern "%s") from both sides of a string.
---
---@see |lua-pattern|s
---@see https://www.lua.org/pil/20.2.html
---@param s string String to trim
---@return string String with whitespace removed from its beginning and end
function vim.trim(s)
  vim.validate('s', s, 'string')
  -- `s:match('^%s*(.*%S)')` is slow for long whitespace strings,
  -- so we are forced to split it into two parts to prevent this
  return s:gsub('^%s+', ''):match('^.*%S') or ''
end

--- Escapes magic chars in |lua-pattern|s.
---
---@see https://github.com/rxi/lume
---@param s string String to escape
---@return string %-escaped pattern string
function vim.pesc(s)
  vim.validate('s', s, 'string')
  return (s:gsub('[%(%)%.%%%+%-%*%?%[%]%^%$]', '%%%1'))
end

--- Tests if `s` starts with `prefix`.
---
---@param s string String
---@param prefix string Prefix to match
---@return boolean `true` if `prefix` is a prefix of `s`
function vim.startswith(s, prefix)
  vim.validate('s', s, 'string')
  vim.validate('prefix', prefix, 'string')
  return s:sub(1, #prefix) == prefix
end

--- Tests if `s` ends with `suffix`.