local utils = require("cd-project.utils") local success, _ = pcall(require, "telescope.pickers") if not success then utils.log_error("telescope not installed") return end local pickers = require("telescope.pickers") local finders = require("telescope.finders") local conf = require("telescope.config").values local actions = require("telescope.actions") local action_state = require("telescope.actions.state") local repo = require("cd-project.project-repo") local api = require("cd-project.api") ---@param callback fun(project: CdProject.Project): nil ---@param opts? table local function project_picker(callback, opts) opts = opts or {} -- TODO: a format function local projects = repo.get_projects() local maxLength = 0 for _, project in ipairs(projects) do if #project.name > maxLength then maxLength = #project.name end end pickers .new(opts, { attach_mappings = function(prompt_bufnr) actions.select_default:replace(function() actions.close(prompt_bufnr) ---@type CdProject.Project local selected_project = action_state.get_selected_entry().value callback(selected_project) end) return true end, prompt_title = "[CdProject]", finder = finders.new_table({ results = projects, ---@param project CdProject.Project entry_maker = function(project) return { value = project, display = utils.format_entry(project, maxLength), ordinal = project.path, } end, }), sorter = conf.generic_sorter(opts), }) :find() end ---@param opts? table local cd_project = function(opts) opts = opts or {} local projects = repo.get_projects() local maxLength = 0 for _, project in ipairs(projects) do if #project.name > maxLength then maxLength = #project.name end end pickers .new(opts, { attach_mappings = function(prompt_bufnr) actions.select_default:replace(function() actions.close(prompt_bufnr) ---@type CdProject.Project local selected_project = action_state.get_selected_entry().value api.cd_project(selected_project.path) end) return true end, prompt_title = "cd to project", finder = finders.new_table({ results = projects, ---@param project CdProject.Project entry_maker = function(project) return { value = project, display = utils.format_entry(project, maxLength), ordinal = project.path, } end, }), sorter = conf.generic_sorter(opts), }) :find() end ---@param opts? table local cd_project_in_tab = function(opts) opts = opts or {} local projects = repo.get_projects() local maxLength = 0 for _, project in ipairs(projects) do if #project.name > maxLength then maxLength = #project.name end end pickers .new(opts, { attach_mappings = function(prompt_bufnr) actions.select_default:replace(function() actions.close(prompt_bufnr) ---@type CdProject.Project local selected_project = action_state.get_selected_entry().value api.cd_project_in_tab(selected_project.path) end) return true end, prompt_title = "tcd to project", finder = finders.new_table({ results = projects, ---@param project CdProject.Project entry_maker = function(project) return { value = project, display = utils.format_entry(project, maxLength), ordinal = project.path, } end, }), sorter = conf.generic_sorter(opts), }) :find() end local search_and_add = function(opts) opts = opts or {} local find_command = utils.check_for_find_cmd() if not find_command then utils.log_error("You need to install fd or find.") return end vim.fn.jobstart(find_command, { stdout_buffered = true, on_stdout = function(_, data) pickers .new(opts, { attach_mappings = function(prompt_bufnr) actions.select_default:replace(function() actions.close(prompt_bufnr) local selected_dir = action_state.get_selected_entry().value vim.ui.input({ prompt = "Add a project name: " }, function(name) if not name or name == "" then vim.notify('No name given, using "' .. utils.get_tail_of_path(selected_dir) .. '" instead') local project = api.build_project_obj(selected_dir) if not project then return end return api.add_project(project) end local project = api.build_project_obj(selected_dir, name) if not project then return end return api.add_project(project) end) end) return true end, prompt_title = "Select dir to add", finder = finders.new_table({ results = data, }), sorter = conf.file_sorter(opts), }) :find() end, }) end return { cd_project = cd_project, cd_project_in_tab = cd_project_in_tab, search_and_add = search_and_add, project_picker = project_picker, }