~cjoly/telescope-repo.nvim

df17ace59bcb73c8b03db45ab398ba5bdaae5cb0 — Clément Joly 1 year, 9 months ago 5d5cfce
feat: add a setting to switch to the project directory

Switch to an opened project directory, in each window and for the
corresponding file.

Fixes #8
M README.md => README.md +3 -0
@@ 121,6 121,9 @@ You can change the default argument given to subcommands (like [`list`](#list) o
          "value",
        },
      },
      settings = {
        auto_lcd = true,
      }
    },
  },
}

M lua/telescope/_extensions/repo.lua => lua/telescope/_extensions/repo.lua +6 -4
@@ 1,12 1,14 @@
local main = require("telescope._extensions.repo.main")
local r_config = require("telescope._extensions.repo.config")
local health = require("telescope._extensions.repo.health")

local fallback_error = { "Falling back to `:Telescope repo list`, but this behavior may change in the future" }

return require("telescope").register_extension({
    health = health.check,
    setup = r_config.setup,
    health = function()
        require("telescope._extensions.repo.health").check()
    end,
    setup = function(opts)
        require("telescope._extensions.repo.config").setup(opts)
    end,
    exports = {
        list = main.list,
        cached_list = main.cached_list,

A lua/telescope/_extensions/repo/autocmd_lcd.lua => lua/telescope/_extensions/repo/autocmd_lcd.lua +50 -0
@@ 0,0 1,50 @@
local Path = require("plenary.path")

local M = {}

M.active = false

-- List of absolute paths to projects opened with the extension
local project_paths = {}

-- Add a project path so that the autocmd will lcd to it if a file in that path is opened
function M.add_project(path)
    local abs_path = Path:new(path)
    abs_path = abs_path:absolute()
    project_paths[abs_path] = true
end

-- Find the best suited project path. Can be passed a file
local function find_project(path_or_file)
    local buf_path = Path:new(path_or_file)
    local abs_buf_path = buf_path:absolute()
    while not (project_paths[abs_buf_path] or abs_buf_path == "/") do
        buf_path = buf_path:parent()
        abs_buf_path = buf_path:absolute()
    end
    if abs_buf_path ~= "/" then
        return abs_buf_path
    end
    return nil
end

-- Define autocmd to change the folder of the current file (with lcd).
function M.setup()
    M.active = true
    -- Ensure we create only one autocmd, even if the function is called multiple times
    local autocmd_group = vim.api.nvim_create_augroup("telescope_repo_lcd", { clear = true })

    vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, {
        callback = function()
            local path_or_file = vim.fn.expand("%")
            local project_path = find_project(path_or_file)
            if project_paths then
                vim.cmd("lcd " .. project_path)
            end
        end,
        group = autocmd_group,
        desc = "lcd to the deepest project directory",
    })
end

return M

M lua/telescope/_extensions/repo/config.lua => lua/telescope/_extensions/repo/config.lua +5 -2
@@ 2,8 2,11 @@ local M = {}

M.values = {}

M.setup = function(opts)
    M.values = opts
function M.setup(opts)
    M.values = opts or {}
    if M.values.settings and M.values.settings.auto_lcd then
        require("telescope._extensions.repo.autocmd_lcd").setup()
    end
end

return M

M lua/telescope/_extensions/repo/main.lua => lua/telescope/_extensions/repo/main.lua +9 -2
@@ 14,6 14,7 @@ local t_utils = require("telescope.utils")
local Path = require("plenary.path")

-- Other modules in this plugin
local autocmd_lcd = require("telescope._extensions.repo.autocmd_lcd")
local utils = require("telescope._extensions.repo.utils")
local list = require("telescope._extensions.repo.list")
local cached_list = require("telescope._extensions.repo.cached_list")


@@ 132,10 133,12 @@ end

local function call_picker(list_opts, command, prompt_title_supplement, user_opts)
    if list_opts == nil then
        error("Incorrect call to call_picker, list_opts should be specified to pass relevant options to the first picker")
        error([[
        Incorrect call to call_picker, list_opts should be specified to pass relevant options to the first picker]])
    end
    if user_opts == nil then
        error("Incorrect call to call_picker, user_opts should be specified to pass relevant options to the second picker")
        error([[
        Incorrect call to call_picker, user_opts should be specified to pass relevant options to the second picker]])
    end

    local prompt_title = "Git repositories"


@@ 169,6 172,10 @@ local function call_picker(list_opts, command, prompt_title_supplement, user_opt
                actions_set.select:replace(function(_, type)
                    local entry = actions_state.get_selected_entry()
                    local dir = from_entry.path(entry)
                    if autocmd_lcd.active and type ~= "" then
                        autocmd_lcd.add_project(dir)
                    end

                    if type == "default" then
                        actions._close(prompt_bufnr, false)
                        vim.schedule(function()