Skip to content

Commit

Permalink
Merge pull request #224 from pmizio/feature/221-v2
Browse files Browse the repository at this point in the history
feat: implement `Move to file` code action
  • Loading branch information
KostkaBrukowa authored Nov 21, 2024
2 parents d03a0a5 + 10e003b commit 346062e
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 7 deletions.
1 change: 1 addition & 0 deletions lua/typescript-tools/capabilities.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ local function make_capabilities()
c.InternalCommands.CallApiFunction,
c.InternalCommands.RequestReferences,
c.InternalCommands.RequestImplementations,
c.InternalCommands.InteractiveCodeAction,
},
},
renameProvider = {
Expand Down
41 changes: 41 additions & 0 deletions lua/typescript-tools/integrations.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
local M = {}

---@param picker function
---@param callback fun(err: boolean|nil, file: string?)
function M.telescope_picker(picker, callback)
local ok, actions = pcall(require, "telescope.actions")

if not ok then
vim.notify("Telescope need to be installed to call this integration", vim.log.levels.WARN)
callback(true, nil)
return
end

local action_state = require "telescope.actions.state"
picker = picker or require("telescope.builtin").find_files

picker {
attach_mappings = function(prompt_bufnr)
local selected = nil

actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
selected = true

if selection then
selected = vim.fs.joinpath(vim.loop.cwd(), selection.value)
end

actions.close(prompt_bufnr)
end)
actions.close:enhance {
post = function()
callback(nil, selected)
end,
}
return true
end,
}
end

return M
42 changes: 42 additions & 0 deletions lua/typescript-tools/internal_commands.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
local api = vim.api
local a = require "plenary.async"

local c = require "typescript-tools.protocol.constants"
local plugin_api = require "typescript-tools.api"
local async = require "typescript-tools.async"
local integrations = require "typescript-tools.integrations"

local M = {}

Expand Down Expand Up @@ -57,4 +60,43 @@ M[c.InternalCommands.RequestImplementations] = function(params)
vim.lsp.buf_request(0, c.LspMethods.Implementation, params.arguments)
end

M[c.InternalCommands.InteractiveCodeAction] = function(params)
local request = unpack(params.arguments)
a.void(function()
---@type string|boolean|nil
local target_file

local telescope_err, file = a.wrap(integrations.telescope_picker, 2)()

if telescope_err then
target_file = async.ui_input { prompt = "Move to file: " }
else
target_file = file
end

if target_file == nil or not vim.fn.filereadable(target_file) then
vim.notify("This refactor require existing file", vim.log.levels.WARN)
return
end

local err, result = async.buf_request_isomorphic(
false,
0,
c.LspMethods.CodeActionResolve,
vim.tbl_deep_extend(
"force",
request,
{ data = { interactiveRefactorArguments = { targetFile = target_file } } }
)
)

if err or not result or not result.edit or (result.edit and vim.tbl_isempty(result.edit)) then
vim.notify("No refactors available", vim.log.levels.WARN)
return
end

vim.lsp.util.apply_workspace_edit(result.edit, "utf-16")
end)()
end

return M
1 change: 1 addition & 0 deletions lua/typescript-tools/protocol/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ return {
CallApiFunction = "call_api_function",
RequestReferences = "request_references",
RequestImplementations = "request_implementations",
InteractiveCodeAction = "interactive_codeaction",
},
---@enum CommandTypes
CommandTypes = {
Expand Down
30 changes: 25 additions & 5 deletions lua/typescript-tools/protocol/text_document/code_action/init.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
local TsserverProvider = require "typescript-tools.tsserver_provider"
local proto_utils = require "typescript-tools.protocol.utils"
local c = require "typescript-tools.protocol.constants"
local utils = require "typescript-tools.protocol.utils"
local plugin_config = require "typescript-tools.config"
local utils = require "typescript-tools.utils"

local M = {}

local ALL_CODE_ACTIONS_KEY = "all"

local interactive_codeactions = {
"Move to file",
}
utils.add_reverse_lookup(interactive_codeactions)

local internal_commands_map = {
fix_all = { name = "Fix all problems" },
remove_unused = { name = "Remove unused" },
Expand Down Expand Up @@ -33,16 +40,19 @@ end

---@type TsserverProtocolHandler
function M.handler(request, response, params, ctx)
local tsserver_provider = TsserverProvider.get_instance()
local version = tsserver_provider:get_version()
local text_document = params.textDocument

local range = utils.convert_lsp_range_to_tsserver(params.range)
local range = proto_utils.convert_lsp_range_to_tsserver(params.range)

local request_range = {
file = vim.uri_to_fname(text_document.uri),
startLine = range.start.line,
startOffset = range.start.offset,
endLine = range["end"].line,
endOffset = range["end"].offset,
includeInteractiveActions = utils.version_compare("gt", version, { 5, 1 }),
}

ctx.dependent_seq = {
Expand Down Expand Up @@ -74,15 +84,25 @@ function M.handler(request, response, params, ctx)
local kind = make_lsp_code_action_kind(action.kind or "")

if kind and not action.notApplicableReason then
table.insert(code_actions, {
local code_action = {
title = action.description,
kind = kind,
data = vim.tbl_extend("force", request_range, {
action = action.name,
kind = kind,
refactor = refactor.name,
}),
})
}

code_action.command = interactive_codeactions[action.description]
and {
title = action.description,
command = c.InternalCommands.InteractiveCodeAction,
arguments = { vim.tbl_deep_extend("force", {}, code_action) },
}
or nil

table.insert(code_actions, code_action)
end
end
end
Expand All @@ -96,7 +116,7 @@ function M.handler(request, response, params, ctx)
title = fix.description,
kind = c.CodeActionKind.QuickFix,
edit = {
changes = utils.convert_tsserver_edits_to_lsp(fix.changes),
changes = proto_utils.convert_tsserver_edits_to_lsp(fix.changes),
},
})
end
Expand Down
6 changes: 4 additions & 2 deletions tests/requests_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -541,9 +541,11 @@ describe("Lsp request", function()
assert.is.same(result[1].title, "Infer function return type")
assert.is.same(result[2].title, "Remove variable statement")
elseif version and v.gt(version, { 5, 1 }) then
assert.is.same(2, #result)
print(vim.inspect(result))
assert.is.same(3, #result)
assert.is.same(result[1].title, "Move to a new file")
assert.is.same(result[2].title, "Remove variable statement")
assert.is.same(result[2].title, "Move to file")
assert.is.same(result[3].title, "Remove variable statement")
else
assert.is.same(1, #result)
assert.is.same(result[1].title, "Remove variable statement")
Expand Down

0 comments on commit 346062e

Please sign in to comment.