0
0
Prechádzať zdrojové kódy

feat(telescope-shroud): implement custom `telescope-shroud` plugin for `grep` filter management

Joe 1 rok pred
rodič
commit
de7f51cc56

+ 1 - 0
.config/nvim/custom/proj-conf/lua/proj-conf/init.lua

@@ -31,6 +31,7 @@ local status = {
 for _, i in pairs({
     require("proj-conf.lsp"),
     require("proj-conf.save-formatter"),
+    require("proj-conf.telescope-shroud"),
     require("proj-conf.projects.deno_typescript_monorepo"),
     require("proj-conf.projects.ruff_pyright")
 }) do

+ 10 - 0
.config/nvim/custom/proj-conf/lua/proj-conf/telescope-shroud.lua

@@ -0,0 +1,10 @@
+local shroud = require("telescope-shroud")
+
+return {
+    default = {},
+    shroud_tests = function()
+        shroud.set_default({
+            "!**/tests/**", "!tests/*"
+        })
+    end
+}

+ 191 - 0
.config/nvim/custom/telescope-shroud/lua/telescope-shroud/init.lua

@@ -0,0 +1,191 @@
+local builtin = require("telescope.builtin")
+local actions = require("telescope.actions")
+local conf = require("telescope.config").values
+local finders = require("telescope.finders")
+local pickers = require("telescope.pickers")
+local themes = require("telescope.themes")
+local action_state = require("telescope.actions.state")
+
+local all_filters = {}
+local selected_filters = {}
+
+local get_selected = function()
+    local result = {}
+    for k, v in pairs(selected_filters) do
+        if v then
+            table.insert(result, k)
+        end
+    end
+    return result
+end
+
+local get_filters = function()
+    local async = require 'plenary.async'
+    local sender, receiver = async.control.channel.mpsc()
+    local results = {}
+    async.run(function()
+        local result = vim.fn.system(
+            "fd -t f | rev | cut -d/ -f1 -s | rev | cut -d. -f2- -s | tr '[:upper:]' '[:lower:]' | sort | uniq | xargs -I{} -n 1 printf '*.{}\n!*.{}\n'")
+        sender.send(result)
+    end)
+    async.run(function()
+        local result = vim.fn.system(
+            "fd -t d | xargs -n 1 -I{} printf '{}*\n!{}*\n'")
+        sender.send(result)
+    end)
+    async.run(function()
+        local result = vim.fn.system(
+            "fd -t d | rev | cut -d/ -f2 -s | rev | sort | uniq | xargs -n 1 -I{} printf '**/{}/*\n!**/{}/*\n'")
+        sender.send(result)
+    end)
+    for _ = 1, 3 do
+        local value = receiver.recv()
+        if value ~= nil and value ~= "" and value ~= " " then
+            results = vim.list_extend(results,
+                vim.split(value, "\n"))
+        end
+    end
+    return results
+end
+
+local populate = function()
+    all_filters = get_filters()
+    return all_filters
+end
+
+local title_from_filters = function(filters)
+    if vim.tbl_count(filters) == 0 then
+        return ""
+    end
+    if vim.tbl_count(filters) > 3 then
+        return " (3+ Filters)"
+    end
+    return " (" .. table.concat(filters, ", ") .. ")"
+end
+
+local open_default = function()
+    local filters = get_selected()
+    builtin.live_grep({
+        prompt_title = "Grep" ..
+            title_from_filters(filters),
+        glob_pattern = filters
+    })
+end
+
+local open_narrow = function()
+    local results
+    if all_filters[1] ~= nil then
+        results = all_filters
+    else
+        results = populate()
+    end
+    local default_option = "**/*"
+    if results[1] ~= default_option then
+        table.insert(results, 1, default_option)
+    end
+    pickers.new(themes.get_dropdown({}),
+        {
+            prompt_title = "Grep Filters",
+            finder = finders.new_table({
+                results = results
+            }),
+            sorter = conf.generic_sorter(),
+            attach_mappings = function(prompt_bufnr, _)
+                actions.toggle_selection:replace(function() end)
+                actions.select_default:replace(function()
+                    actions.close(prompt_bufnr)
+                    local selection = action_state
+                        .get_selected_entry()
+                    builtin.live_grep({
+                        prompt_title = "Grep" ..
+                            title_from_filters(selection),
+                        glob_pattern = selection
+                    })
+                end)
+                return true
+            end,
+        }):find()
+end
+
+
+local create_selected_filter_picker = function()
+    local unique_filters = {}
+    for _, v in pairs(get_selected()) do
+        unique_filters[v] = true
+    end
+    if all_filters[1] == nil then
+        all_filters = populate()
+    end
+    for _, v in pairs(all_filters) do
+        unique_filters[v] = true
+    end
+    local results = {}
+
+    -- Lazy implementation to put selected filters at the top
+    for k, _ in pairs(unique_filters) do
+        if selected_filters[k] then
+            table.insert(results, k)
+        end
+    end
+    for k, _ in pairs(unique_filters) do
+        if selected_filters[k] ~= true and k ~= "" then
+            table.insert(results, k)
+        end
+    end
+
+    local startup_complete = false
+    local picker = pickers.new(themes.get_dropdown({}), {
+        prompt_title = "Default Grep Filters",
+        finder = finders.new_table({
+            results = results
+        }),
+        sorter = conf.generic_sorter(),
+        on_complete = { function(picker)
+            if startup_complete == false then
+                local i = 1
+                for entry in picker.manager:iter() do
+                    if selected_filters[entry[1]] then
+                        picker:add_selection(picker:get_row(i))
+                    end
+                    i = i + 1
+                end
+
+                startup_complete = true
+            end
+        end },
+        attach_mappings = function(prompt_bufnr, _)
+            actions.toggle_selection:enhance({
+                post = function()
+                    selected_filters = {}
+                    for k, v in pairs(action_state.get_current_picker(prompt_bufnr)._multi._entries) do
+                        if v then
+                            selected_filters[k[1]] = true
+                        end
+                    end
+                end
+            })
+            actions.select_default:replace(actions.toggle_selection)
+            return true
+        end
+    })
+    return picker
+end
+
+local set_default = function(items)
+    if items ~= nil then
+        selected_filters = {}
+        for _, v in pairs(items) do
+            selected_filters[v] = true
+        end
+        return
+    end
+    create_selected_filter_picker():find()
+end
+
+return {
+    populate = populate,
+    set_default = set_default,
+    open_narrow = open_narrow,
+    open_default = open_default,
+    get_selected = get_selected,
+}

+ 6 - 2
.config/nvim/lua/plugins/proj-conf.lua

@@ -1,9 +1,13 @@
 return {
     dir = "../custom/proj-conf",
     name = "proj-conf",
-    dependencies = { "neovim/nvim-lspconfig", "hrsh7th/nvim-cmp",
+    dependencies = {
+        "nvim-telescope/telescope.nvim",
+        "neovim/nvim-lspconfig",
+        "hrsh7th/nvim-cmp",
         "command-palette",
-        "nvim-telescope/telescope.nvim" },
+        "telescope-shroud"
+    },
     enabled = true,
     lazy = false,
     config = function(_, _) require("proj-conf").setup() end

+ 26 - 50
.config/nvim/lua/plugins/telescope.lua

@@ -9,12 +9,6 @@ return {
         },
         config = function(_, _)
             local builtin = require("telescope.builtin")
-            local actions = require("telescope.actions")
-            local conf = require("telescope.config").values
-            local finders = require("telescope.finders")
-            local pickers = require("telescope.pickers")
-            local themes = require("telescope.themes")
-            local action_state = require("telescope.actions.state")
             require("telescope").setup({
                 extensions = {
                     ["ui-select"] = { require("telescope.themes").get_dropdown() }
@@ -55,50 +49,6 @@ return {
             vim.keymap.set("n", "sS", builtin.pickers)
             vim.keymap.set("n", "sa", builtin.find_files)
             vim.keymap.set("n", "sg", builtin.git_files)
-            vim.keymap.set("n", "si", builtin.live_grep)
-            vim.keymap.set("n", "sI", function()
-                local async = require 'plenary.async'
-                local sender, receiver = async.control.channel.mpsc()
-                local results = {}
-                async.run(function()
-                    local result = vim.fn.system(
-                        "fd -t f | rev | cut -d/ -f1 -s | cut -d. -f1 -s | rev | tr '[:upper:]' '[:lower:]' | sort | uniq | xargs -I{} -n 1 printf '*.{}\n!*.{}\n'")
-                    sender.send(result)
-                end)
-                async.run(function()
-                    local result = vim.fn.system(
-                        "fd -t d | xargs -n 1 -I{} printf '{}*\n!{}*\n'")
-                    sender.send(result)
-                end)
-                async.run(function()
-                    local result = vim.fn.system(
-                        "fd -t d | rev | cut -d/ -f2 -s | rev | sort | uniq | xargs -n 1 -I{} printf '**/{}/*\n!**/{}/*\n'")
-                    sender.send(result)
-                end)
-                for _ = 1, 3 do
-                    local value = receiver.recv()
-                    if value ~= nil then
-                        results = vim.list_extend(results,
-                            vim.split(value, "\n"))
-                    end
-                end
-                pickers.new(themes.get_dropdown({}),
-                    {
-                        finder = finders.new_table({
-                            results = results
-                        }),
-                        sorter = conf.generic_sorter(),
-                        attach_mappings = function(prompt_bufnr, _)
-                            actions.select_default:replace(function()
-                                actions.close(prompt_bufnr)
-                                local selection = action_state
-                                    .get_selected_entry()
-                                builtin.live_grep({ glob_pattern = selection })
-                            end)
-                            return true
-                        end,
-                    }):find()
-            end)
             vim.keymap.set("n", "sb", builtin.buffers)
             vim.keymap.set("n", "sj", builtin.jumplist)
             vim.keymap.set("n", "sw", builtin.grep_string)
@@ -129,5 +79,31 @@ return {
         })
         require("telescope").load_extension("file_browser")
     end
+}, {
+    dir = "../custom/telescope-shroud",
+    name = "telescope-shroud",
+    dependencies = { "nvim-telescope/telescope.nvim",
+        "command-palette",
+        "nvim-lua/plenary.nvim" },
+    enabled = true,
+    config = function(_, _)
+        local shroud = require("telescope-shroud")
+        local palette = require("command-palette")
+        palette.add({
+            {
+                "Telescope Shroud", "Telescope `grep` filter management", { {
+                "Populate", "Reload the list of filter options", shroud.populate
+            }, {
+                "Clear default", "Reset the default filters", function()
+                shroud.set_default({})
+            end
+            }, {
+                "Set default", "Set the default filters", shroud.set_default }, {
+                "Open default", "Set the default filters", shroud.open_default }, {
+                "Open narrow", "Set the default filters", shroud.open_narrow } } }
+        })
+        vim.keymap.set("n", "si", shroud.open_default)
+        vim.keymap.set("n", "sI", shroud.open_narrow)
+    end
 }
 }