diff options
Diffstat (limited to 'runtime/lua/vim')
| -rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 3 | ||||
| -rw-r--r-- | runtime/lua/vim/lsp/util.lua | 69 | 
2 files changed, 70 insertions, 2 deletions
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 0f440d6d70..7e43eb84de 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -749,6 +749,9 @@ function protocol.make_client_capabilities()        };        workspaceFolders = true;        applyEdit = true; +      workspaceEdit = { +        resourceOperations = {'rename', 'create', 'delete',}, +      };      };      callHierarchy = {        dynamicRegistration = false; diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 4b528d7090..6945d0f1ec 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -612,6 +612,62 @@ function M.text_document_completion_list_to_complete_items(result, prefix)    return matches  end + +--- Rename old_fname to new_fname +-- +--@param opts (table) +--         overwrite? bool +--         ignoreIfExists? bool +function M.rename(old_fname, new_fname, opts) +  opts = opts or {} +  local bufnr = vim.fn.bufadd(old_fname) +  vim.fn.bufload(bufnr) +  local target_exists = vim.loop.fs_stat(new_fname) ~= nil +  if target_exists and not opts.overwrite or opts.ignoreIfExists then +    vim.notify('Rename target already exists. Skipping rename.') +    return +  end +  local ok, err = os.rename(old_fname, new_fname) +  assert(ok, err) +  api.nvim_buf_call(bufnr, function() +    vim.cmd('saveas! ' .. vim.fn.fnameescape(new_fname)) +  end) +end + + +local function create_file(change) +  local opts = change.options or {} +  -- from spec: Overwrite wins over `ignoreIfExists` +  local fname = vim.uri_to_fname(change.uri) +  if not opts.ignoreIfExists or opts.overwrite then +    local file = io.open(fname, 'w') +    file:close() +  end +  vim.fn.bufadd(fname) +end + + +local function delete_file(change) +  local opts = change.options or {} +  local fname = vim.uri_to_fname(change.uri) +  local stat = vim.loop.fs_stat(fname) +  if opts.ignoreIfNotExists and not stat then +    return +  end +  assert(stat, "Cannot delete not existing file or folder " .. fname) +  local flags +  if stat and stat.type == 'directory' then +    flags = opts.recursive and 'rf' or 'd' +  else +    flags = '' +  end +  local bufnr = vim.fn.bufadd(fname) +  local result = tonumber(vim.fn.delete(fname, flags)) +  assert(result == 0, 'Could not delete file: ' .. fname .. ', stat: ' .. vim.inspect(stat)) +  api.nvim_buf_delete(bufnr, { force = true }) +end + +  --- Applies a `WorkspaceEdit`.  ---  --@param workspace_edit (table) `WorkspaceEdit` @@ -619,8 +675,17 @@ end  function M.apply_workspace_edit(workspace_edit)    if workspace_edit.documentChanges then      for idx, change in ipairs(workspace_edit.documentChanges) do -      if change.kind then -        -- TODO(ashkan) handle CreateFile/RenameFile/DeleteFile +      if change.kind == "rename" then +        M.rename( +          vim.uri_to_fname(change.oldUri), +          vim.uri_to_fname(change.newUri), +          change.options +        ) +      elseif change.kind == 'create' then +        create_file(change) +      elseif change.kind == 'delete' then +        delete_file(change) +      elseif change.kind then          error(string.format("Unsupported change: %q", vim.inspect(change)))        else          M.apply_text_document_edit(change, idx)  | 
