Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/add option to use fzf #209

Merged
merged 13 commits into from
Jan 27, 2025
12 changes: 1 addition & 11 deletions lua/easy-dotnet/ef-core/migration.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ M.remove_migration = function()
end

M.list_migrations = function()
local conf = require("telescope.config").values
local selections = require("easy-dotnet.ef-core.utils").pick_projects()
local project = selections.project
local startup_project = selections.startup_project
Expand Down Expand Up @@ -81,16 +80,7 @@ M.list_migrations = function()
}
end,
}
local picker = require("telescope.pickers").new(opts, {
prompt_title = "Migrations",
finder = require("telescope.finders").new_table({
results = migrations,
entry_maker = opts.entry_maker,
}),
sorter = require("telescope.config").values.generic_sorter({}),
previewer = conf.grep_previewer(opts),
})
picker:find()
require("easy-dotnet.picker").migration_picker(opts, migrations)
else
spinner:stop_spinner("Failed to load migrations", vim.log.levels.ERROR)
end
Expand Down
3 changes: 2 additions & 1 deletion lua/easy-dotnet/health.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ M.check = function()
vim.health.start("easy-dotnet lua dependencies")
ensure_nvim_dep_installed("plenary", "https://github.com/nvim-lua/plenary.nvim")
ensure_nvim_dep_installed("dap", { "Some functionality will be disabled", "https://github.com/mfussenegger/nvim-dap" }, false)
ensure_nvim_dep_installed("telescope", "https://github.com/nvim-telescope/telescope.nvim")
ensure_nvim_dep_installed("telescope", { "This is not needed for the plugin but is a nice addition to the experience", "https://github.com/nvim-telescope/telescope.nvim" })
ensure_nvim_dep_installed("fzf-lua", { "This is not needed for the plugin but is a nice addition to the experience", "https://github.com/ibhagwan/fzf-lua" })
ensure_nvim_dep_installed("roslyn", {
"This is not required for this plugin but is a nice addition to the .Net developer experience",
"If you are using another LSP you can safely ignore this warning",
Expand Down
68 changes: 4 additions & 64 deletions lua/easy-dotnet/nuget.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
local M = {}

local polyfills = require("easy-dotnet.polyfills")
-- local fzf = require("fzf-lua")
local sln_parse = require("easy-dotnet.parsers.sln-parse")
local pickers = require("telescope.pickers")
local picker = require("easy-dotnet.picker")
local finders = require("telescope.finders")
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local conf = require("telescope.config").values
local logger = require("easy-dotnet.logger")

local function reverse_list(list)
Expand All @@ -19,59 +13,6 @@ local function reverse_list(list)
return reversed
end

---@param search_term string | nil
local function telescope_nuget_search(search_term)
local co = coroutine.running()
local val
local opts = {}
pickers
.new(opts, {
prompt_title = "Nuget search",
default_text = search_term,
finder = finders.new_async_job({
--TODO: this part sucks I want to use JQ but it seems to be impossible to use it with telescope due to pipes and making OS independent
command_generator = function(prompt) return { "dotnet", "package", "search", prompt or "", "--format", "json" } end,
entry_maker = function(line)
--HACK: ohgod.jpeg
if line:find('"id":') == nil then return { valid = false } end
local value = line:gsub('"id": "%s*([^"]+)%s*"', "%1"):match("^%s*(.-)%s*$"):gsub(",", "")
return {
value = value,
ordinal = value,
display = value,
}
end,
cwd = vim.fn.getcwd(),
}),
sorter = conf.generic_sorter(opts),
attach_mappings = function()
actions.select_default:replace(function(prompt_bufnr)
local selection = action_state.get_selected_entry(prompt_bufnr)
actions.close(prompt_bufnr)
val = selection.value
coroutine.resume(co)
end)
return true
end,
})
:find()
coroutine.yield()
return val
end

-- ---@param cb function
-- local function fzf_nuget_search(cb)
-- fzf.fzf_live('dotnet package search <query> --format json | jq ".searchResult | .[] | .packages | .[] | .id"', {
-- fn_transform = function(line) return line:gsub('"', ""):gsub("\r", ""):gsub("\n", "") end,
-- actions = {
-- ["default"] = function(selected)
-- local package = selected[1]
-- cb(package)
-- end,
-- },
-- })
-- end

local function get_all_versions(package)
local command = string.format("dotnet package search %s --exact-match --format json | jq '.searchResult[].packages[].version'", package)
local versions = vim.fn.split(vim.fn.system(command):gsub('"', ""), "\n")
Expand All @@ -97,6 +38,7 @@ local function add_package(package, project_path)
local selected_version = picker.pick_sync(nil, versions, "Select a version", true)
logger.info("Adding package...")
local selected_project = project_path or get_project()
vim.notify(selected_project)
bosvik marked this conversation as resolved.
Show resolved Hide resolved
local command = string.format("dotnet add %s package %s --version %s", selected_project, package, selected_version.value)
local co = coroutine.running()
vim.fn.jobstart(command, {
Expand Down Expand Up @@ -124,11 +66,9 @@ local function add_package(package, project_path)
end

---@param project_path string | nil
---@param search_term string | nil
M.search_nuget = function(project_path, search_term)
-- fzf_nuget_search(on_package_selected)
local package = telescope_nuget_search(search_term)
add_package(package, project_path)
M.search_nuget = function(project_path)
local package = picker.search_nuget(add_package)
if package ~= nil then add_package(package, project_path) end
end

local function get_package_refs(project_path)
Expand Down
3 changes: 3 additions & 0 deletions lua/easy-dotnet/options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ local M = {
type = "block_scoped",
enabled = true,
},
picker = "telescope", -- "fzf" | "nil"
},
}

Expand All @@ -150,4 +151,6 @@ M.set_options = function(a)
return M.options
end

M.get_option = function(key) return M.options[key] end

return M
2 changes: 0 additions & 2 deletions lua/easy-dotnet/parsers/sln-parse.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ M.find_project_files = function()
return normalized
end

---Dotnet solution add with telescope picker
---@param slnpath string
function M.add_project_to_solution(slnpath)
local sln_projects = M.get_projects_from_sln(slnpath)
Expand Down Expand Up @@ -64,7 +63,6 @@ function M.add_project_to_solution(slnpath)
})
end

---Dotnet solution remove with telescope picker
---@param slnpath string
function M.remove_project_from_solution(slnpath)
local projects = M.get_projects_from_sln(slnpath)
Expand Down
143 changes: 143 additions & 0 deletions lua/easy-dotnet/picker/_base.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
local M = {}

M.nuget_search = function()
local Job = require("plenary.job")
local co = coroutine.running()
local val
local function search_nuget(prompt)
local results = {}
Job:new({
command = "dotnet",
args = { "package", "search", prompt or "", "--format", "json" },
cwd = vim.fn.getcwd(),
on_stdout = function(_, line)
if line:find('"id":') then
local value = line:gsub('"id": "%s*([^"]+)%s*"', "%1"):match("^%s*(.-)%s*$"):gsub(",", "")
table.insert(results, { display = value, value = value })
end
end,
on_exit = function()
vim.schedule(function()
local items = {}
for _, result in ipairs(results) do
table.insert(items, result.display)
end
vim.ui.select(items, { prompt = "Nuget search" }, function(choice)
if choice then
for _, result in ipairs(results) do
if result.display == choice then
val = result.value
coroutine.resume(co)
return
end
end
else
coroutine.resume(co)
end
end)
end)
end,
}):start()
end

local function prompt_for_search()
vim.ui.input({ prompt = "Enter search query: " }, function(input)
if input then
search_nuget(input)
else
coroutine.resume(co)
end
end)
end
prompt_for_search()
coroutine.yield()
return val
end

M.migration_pick = function(opts, migration)
vim.ui.select(migration, {
prompt = "Migrations",
format_item = function(item) return opts.entry_maker(item).display end,
}, function(choice)
if choice then opts.on_select(choice) end
end)
end

M.preview_picker = function(bufnr, options, on_select_cb, title, previewer)
if #options == 0 then error("No options provided, minimum 1 is required") end

-- Auto pick if only one option present
if #options == 1 then
on_select_cb(options[1])
return
end

local entries = {}
for _, option in ipairs(options) do
table.insert(entries, option.display)
end

vim.ui.select(entries, { prompt = title }, function(selected)
if selected then
for _, option in ipairs(options) do
if option.display == selected then
on_select_cb(option)
break
end
end
end
end)
end

M.picker = function(bufnr, options, on_select_cb, title, autopick)
if autopick == nil then autopick = true end
if #options == 0 then error("No options provided, minimum 1 is required") end
M.migration_pick = function(opts, migration)
vim.ui.select(migration, {
prompt = "Migrations",
format_item = function(item) return opts.entry_maker(item).display end,
}, function(choice)
if choice then opts.on_select(choice) end
end)
end

-- Auto pick if only one option present
if #options == 1 and autopick == true then
on_select_cb(options[1])
return
end

local items = {}
for _, option in ipairs(options) do
table.insert(items, option.display)
end

vim.ui.select(items, { prompt = title }, function(choice)
if choice then
for _, option in ipairs(options) do
if option.display == choice then
on_select_cb(option)
break
end
end
end
end)
end

---@generic T
---@param bufnr number | nil
---@param options table<T>
---@param title string | nil
---@return T
M.pick_sync = function(bufnr, options, title, autopick)
local co = coroutine.running()
local selected = nil
M.picker(bufnr, options, function(i)
selected = i
if coroutine.status(co) ~= "running" then coroutine.resume(co) end
end, title or "", autopick)
if not selected then coroutine.yield() end
return selected
end

return M
Loading
Loading