|
| 1 | +--- Set directory for curent buffer. By LSPs firstly, if non available, use fallback function |
| 2 | +--- @param fallback {fn: function, hint: string} Fallback function info returns root directory as string |
| 3 | +local function find_root(fallback) |
| 4 | + local ft = vim.api.nvim_get_option_value('filetype', { buf = 0 }) |
| 5 | + local clients = vim.lsp.get_clients({ bufnr = 0 }) |
| 6 | + |
| 7 | + local dirs = vim |
| 8 | + .iter(clients) |
| 9 | + :filter(function(client) |
| 10 | + local filetypes = client.config.filetypes |
| 11 | + if filetypes and vim.tbl_contains(filetypes, ft) then |
| 12 | + return true |
| 13 | + end |
| 14 | + |
| 15 | + return false |
| 16 | + end) |
| 17 | + :map(function(client) |
| 18 | + return { root = client.config.root_dir, client = client.name } |
| 19 | + end) |
| 20 | + :totable() |
| 21 | + |
| 22 | + if type(fallback) == 'table' then |
| 23 | + local dir = fallback.fn() |
| 24 | + if dir ~= nil and dir ~= '' then |
| 25 | + table.insert(dirs, { root = dir, client = fallback.hint }) |
| 26 | + end |
| 27 | + end |
| 28 | + |
| 29 | + if #dirs == 0 then |
| 30 | + vim.notify('no rule to cd') |
| 31 | + return |
| 32 | + end |
| 33 | + |
| 34 | + local verbose_status = vim.trim(vim.fn.execute('verbose pwd')) |
| 35 | + |
| 36 | + vim.ui.select(dirs, { |
| 37 | + prompt = 'SELECT ROOT. ' .. verbose_status, |
| 38 | + format_item = function(info) |
| 39 | + return string.format('%s [%s]', info.root, info.client) |
| 40 | + end, |
| 41 | + }, function(choice) |
| 42 | + if choice ~= nil then |
| 43 | + if vim.fn.getcwd() ~= choice.root then |
| 44 | + vim.notify('setting root to ' .. choice.root, vim.log.levels.INFO, {}) |
| 45 | + vim.fn.chdir(choice.root) |
| 46 | + else |
| 47 | + vim.notify('root already in ' .. choice.root, vim.log.levels.INFO, {}) |
| 48 | + end |
| 49 | + end |
| 50 | + end) |
| 51 | +end |
| 52 | + |
| 53 | +return { |
| 54 | + find_root = find_root, |
| 55 | +} |
0 commit comments