From 8546fdf610584c367f0f1e105aedec370d71bf54 Mon Sep 17 00:00:00 2001 From: Senghan Bright Date: Wed, 2 Dec 2020 00:27:54 +0100 Subject: [PATCH] new builtin - autocommands (#302) * feat: new builtin - Autocommands finder * fix: remove decorators to avoid confusion. * make preview split same hl-group as border * use highlight instead of marker character for preview selection hl --- lua/telescope/builtin/init.lua | 1 + lua/telescope/builtin/internal.lua | 90 ++++++++++++++++++++++++++++++ lua/telescope/make_entry.lua | 38 +++++++++++++ lua/telescope/previewers.lua | 45 +++++++++++++++ 4 files changed, 174 insertions(+) diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua index 4ac3a8c..078a3e6 100644 --- a/lua/telescope/builtin/init.lua +++ b/lua/telescope/builtin/init.lua @@ -58,6 +58,7 @@ builtin.registers = require('telescope.builtin.internal').registers builtin.keymaps = require('telescope.builtin.internal').keymaps builtin.filetypes = require('telescope.builtin.internal').filetypes builtin.highlights = require('telescope.builtin.internal').highlights +builtin.autocommands = require('telescope.builtin.internal').autocommands builtin.lsp_references = require('telescope.builtin.lsp').references builtin.lsp_document_symbols = require('telescope.builtin.lsp').document_symbols diff --git a/lua/telescope/builtin/internal.lua b/lua/telescope/builtin/internal.lua index c50e04b..73db64d 100644 --- a/lua/telescope/builtin/internal.lua +++ b/lua/telescope/builtin/internal.lua @@ -569,6 +569,96 @@ internal.highlights = function(opts) }):find() end +internal.autocommands = function(opts) + local autocmd_table = {} + + local pattern = {} + pattern.BUFFER = "" + pattern.EVENT = "[%a]+" + pattern.GROUP = "[%a%d_:]+" + pattern.INDENT = "^%s%s%s%s" -- match indentation of 4 spaces + + local event, group, ft_pat, cmd, source_file, source_lnum + local current_event, current_group, current_ft + + local cmd_output = vim.fn.execute("verb autocmd *", "silent") + for line in cmd_output:gmatch("[^\r\n]+") do + -- capture group and event + group, event = line:match("^(" .. pattern.GROUP .. ")%s+(" .. pattern.EVENT .. ")") + -- ..or just an event + if event == nil then + event = line:match("^(" .. pattern.EVENT .. ")") + end + + if event then + group = group or "" + if event ~= current_event or group ~= current_group then + current_event = event + current_group = group + end + goto line_parsed + end + + -- non event/group lines + ft_pat = line:match(pattern.INDENT .. "(%S+)") + if ft_pat then + if ft_pat:match("^%d+") then + ft_pat = "" + end + current_ft = ft_pat + + -- is there a command on the same line? + cmd = line:match(pattern.INDENT .. "%S+%s+(.+)") + + goto line_parsed + end + + if current_ft and cmd == nil then + -- trim leading spaces + cmd = line:gsub("^%s+", "") + goto line_parsed + end + + if current_ft and cmd then + source_file, source_lnum = line:match("Last set from (.*) line (.*)") + if source_file then + local autocmd = {} + autocmd.event = current_event + autocmd.group = current_group + autocmd.ft_pattern = current_ft + autocmd.command = cmd + autocmd.source_file = source_file + autocmd.source_lnum = source_lnum + table.insert(autocmd_table, autocmd) + + cmd = nil + end + end + + ::line_parsed:: + end + + -- print(vim.inspect(autocmd_table)) + + pickers.new(opts,{ + prompt_title = 'autocommands', + finder = finders.new_table { + results = autocmd_table, + entry_maker = make_entry.gen_from_autocommands(opts), + }, + previewer = previewers.autocommands.new(opts), + sorter = conf.generic_sorter(opts), + attach_mappings = function(prompt_bufnr) + actions._goto_file_selection:replace(function(_, cmd) + local selection = actions.get_selected_entry() + actions.close(prompt_bufnr) + vim.cmd(cmd .. ' ' .. selection.value) + end) + + return true + end + }):find() +end local function apply_checks(mod) for k, v in pairs(mod) do diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua index 2a4ae5c..e1389d4 100644 --- a/lua/telescope/make_entry.lua +++ b/lua/telescope/make_entry.lua @@ -682,4 +682,42 @@ function make_entry.gen_from_ctags(opts) end end +function make_entry.gen_from_autocommands(_) + local displayer = entry_display.create { + separator = "ā–", + items = { + { width = 14 }, + { width = 18 }, + { width = 16 }, + { remaining = true }, + }, + } + + local make_display = function(entry) + return displayer { + entry.event, + entry.group, + entry.ft_pattern, + entry.command + } + end + + -- TODO: dump current filtered items to buffer + return function(entry) + return { + event = entry.event, + group = entry.group, + ft_pattern = entry.ft_pattern, + command = entry.command, + value = string.format("+%d %s", entry.source_lnum, entry.source_file), + source_file = entry.source_file, + source_lnum = entry.source_lnum, + -- + valid = true, + ordinal = entry.event .. " " .. entry.group .. " " .. entry.ft_pattern .. " " .. entry.command, + display = make_display, + } + end +end + return make_entry diff --git a/lua/telescope/previewers.lua b/lua/telescope/previewers.lua index 81664ec..9c63836 100644 --- a/lua/telescope/previewers.lua +++ b/lua/telescope/previewers.lua @@ -770,6 +770,51 @@ previewers.man = defaulter(function(_) } end) +previewers.autocommands = defaulter(function(_) +return previewers.new_buffer_previewer { + setup = function() + return {} + end, + + teardown = function(self) + if self.state and self.state.hl_id then + pcall(vim.fn.matchdelete, self.state.hl_id, self.state.hl_win) + self.state.hl_id = nil + end + end, + + preview_fn = function(self, entry, status) + local results = vim.tbl_filter( + function (x) return x.group == entry.group end, + status.picker.finder.results + ) + local display = {} + table.insert(display, string.format(" augroup: %s - [ %d entries ]", entry.group, #results)) + -- TODO: calculate banner width/string in setup() + -- TODO: get column characters to be the same HL group as border + table.insert(display, string.rep("─", vim.fn.getwininfo(status.preview_win)[1].width)) + + local selected_row + for idx, item in ipairs(results) do + if item == entry then + selected_row = idx + end + table.insert(display, + string.format(" %-14sā–%-08s %s", item.event, item.ft_pattern, item.command) + ) + end + + with_preview_window(status, nil, function() + -- TODO: set filetype in setup() + vim.api.nvim_buf_set_option(status.preview_bufnr, "filetype", "vim") + vim.api.nvim_buf_set_lines(status.preview_bufnr, 0, -1, false, display) + vim.api.nvim_buf_add_highlight(status.preview_bufnr, 0, "TelescopeBorder", 1, 0, -1) + vim.api.nvim_buf_add_highlight(status.preview_bufnr, 0, "TelescopeSelection", selected_row + 1, 0, -1) + end) + end, +} +end, {}) + previewers.display_content = defaulter(function(_) return previewers.new_buffer_previewer { preview_fn = function(self, entry, status)