summaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
authorfdschmidt93 <39233597+fdschmidt93@users.noreply.github.com>2021-03-03 22:33:03 +0100
committerGitHub <noreply@github.com>2021-03-03 22:33:03 +0100
commitdb7615578b43586ef6526c56ba397f86b13fbed9 (patch)
tree0b1644a0269b96f96370962b77babe8486403058 /lua
parent390e5fa9f50a2946e2c1d080f114313d984bc4e1 (diff)
feat: lsp diagnostics and prefiltering by entry attribute (#543)
prefiltering for lsp_document_symbols and lsp_workspace_symbols. example: type `:var:` to show all vars
Diffstat (limited to 'lua')
-rw-r--r--lua/telescope/builtin/init.lua1
-rw-r--r--lua/telescope/builtin/lsp.lua32
-rw-r--r--lua/telescope/config.lua1
-rw-r--r--lua/telescope/make_entry.lua78
-rw-r--r--lua/telescope/sorters.lua50
-rw-r--r--lua/telescope/utils.lua35
6 files changed, 194 insertions, 3 deletions
diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua
index 2d76c79..940d3a3 100644
--- a/lua/telescope/builtin/init.lua
+++ b/lua/telescope/builtin/init.lua
@@ -64,6 +64,7 @@ builtin.spell_suggest = require('telescope.builtin.internal').spell_suggest
builtin.lsp_references = require('telescope.builtin.lsp').references
builtin.lsp_document_symbols = require('telescope.builtin.lsp').document_symbols
builtin.lsp_code_actions = require('telescope.builtin.lsp').code_actions
+builtin.lsp_diagnostics = require('telescope.builtin.lsp').diagnostics
builtin.lsp_range_code_actions = require('telescope.builtin.lsp').range_code_actions
builtin.lsp_workspace_symbols = require('telescope.builtin.lsp').workspace_symbols
diff --git a/lua/telescope/builtin/lsp.lua b/lua/telescope/builtin/lsp.lua
index 49bc698..8324cf1 100644
--- a/lua/telescope/builtin/lsp.lua
+++ b/lua/telescope/builtin/lsp.lua
@@ -64,7 +64,10 @@ lsp.document_symbols = function(opts)
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts)
},
previewer = conf.qflist_previewer(opts),
- sorter = conf.generic_sorter(opts),
+ sorter = conf.prefilter_sorter{
+ tag = "symbol_type",
+ sorter = conf.generic_sorter(opts)
+ }
}):find()
end
@@ -180,7 +183,32 @@ lsp.workspace_symbols = function(opts)
entry_maker = opts.entry_maker or make_entry.gen_from_lsp_symbols(opts)
},
previewer = conf.qflist_previewer(opts),
- sorter = conf.generic_sorter(opts),
+ sorter = conf.prefilter_sorter{
+ tag = "symbol_type",
+ sorter = conf.generic_sorter(opts)
+ }
+ }):find()
+end
+
+lsp.diagnostics = function(opts)
+ local locations = utils.diagnostics_to_tbl(opts)
+
+ if vim.tbl_isempty(locations) then
+ print('No diagnostics found')
+ return
+ end
+
+ pickers.new(opts, {
+ prompt_title = 'LSP Diagnostics',
+ finder = finders.new_table {
+ results = locations,
+ entry_maker = opts.entry_maker or make_entry.gen_from_lsp_diagnostics(opts)
+ },
+ previewer = conf.qflist_previewer(opts),
+ sorter = conf.prefilter_sorter{
+ tag = "type",
+ sorter = conf.generic_sorter(opts)
+ }
}):find()
end
diff --git a/lua/telescope/config.lua b/lua/telescope/config.lua
index 5e025e3..17c1e91 100644
--- a/lua/telescope/config.lua
+++ b/lua/telescope/config.lua
@@ -161,6 +161,7 @@ function config.set_defaults(defaults)
set("default_mappings", nil)
set("generic_sorter", sorters.get_generic_fuzzy_sorter)
+ set("prefilter_sorter", sorters.prefilter)
set("file_sorter", sorters.get_fuzzy_file)
set("file_ignore_patterns", nil)
diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua
index 8c793d7..2b27328 100644
--- a/lua/telescope/make_entry.lua
+++ b/lua/telescope/make_entry.lua
@@ -27,6 +27,13 @@ local lsp_type_highlight = {
["Variable"] = "TelescopeResultsVariable",
}
+local lsp_type_diagnostic = {
+ [1] = "Error",
+ [2] = "Warning",
+ [3] = "Information",
+ [4] = "Hint"
+}
+
local make_entry = {}
do
@@ -847,6 +854,77 @@ function make_entry.gen_from_ctags(opts)
end
end
+function make_entry.gen_from_lsp_diagnostics(opts)
+ opts = opts or {}
+ opts.tail_path = utils.get_default(opts.tail_path, true)
+
+ local signs = {}
+ for _, v in pairs(lsp_type_diagnostic) do
+ signs[v] = vim.trim(vim.fn.sign_getdefined("LspDiagnosticsSign" .. v)[1].text)
+ end
+ -- expose line width for longer msg if opts.hide_filename
+ local line_width = utils.get_default(opts.line_width, 48)
+ local displayer = entry_display.create {
+ separator = "▏",
+ items = {
+ { width = 11 },
+ { width = line_width },
+ { remaining = true }
+ }
+ }
+
+ local make_display = function(entry)
+ local filename
+ if not opts.hide_filename then
+ filename = entry.filename
+ if opts.tail_path then
+ filename = utils.path_tail(filename)
+ elseif opts.shorten_path then
+ filename = utils.path_shorten(filename)
+ end
+ end
+
+ -- add styling of entries
+ local pos = string.format("%3d:%2d", entry.lnum, entry.col)
+ local line_info = {
+ string.format("%s %s", signs[entry.type], pos),
+ string.format("LspDiagnosticsDefault%s", entry.type)
+ }
+ -- remove line break to avoid display issues
+ local text = string.format("%-" .. line_width .."s", entry.text:gsub(".* | ", ""):gsub("[\n]", ""))
+
+ return displayer {
+ line_info,
+ text,
+ filename,
+ }
+ end
+
+ return function(entry)
+ local filename = entry.filename or vim.api.nvim_buf_get_name(entry.bufnr)
+
+ return {
+ valid = true,
+
+ value = entry,
+ ordinal = (
+ not opts.ignore_filename and filename
+ or ''
+ ) .. ' ' .. entry.text,
+ display = make_display,
+ bufnr = entry.bufnr,
+ filename = filename,
+ type = entry.type,
+ lnum = entry.lnum,
+ col = entry.col,
+ text = entry.text,
+ start = entry.start,
+ finish = entry.finish,
+ }
+ end
+end
+
+
function make_entry.gen_from_autocommands(_)
local displayer = entry_display.create {
separator = "▏",
diff --git a/lua/telescope/sorters.lua b/lua/telescope/sorters.lua
index a85a75b..6ae404d 100644
--- a/lua/telescope/sorters.lua
+++ b/lua/telescope/sorters.lua
@@ -39,6 +39,7 @@ function Sorter:new(opts)
return setmetatable({
state = {},
+ filter_function = opts.filter_function,
scoring_function = opts.scoring_function,
highlighter = opts.highlighter,
discard = opts.discard,
@@ -84,7 +85,13 @@ function Sorter:score(prompt, entry)
return FILTERED
end
- local score = self:scoring_function(prompt or "", ordinal, entry)
+ local filter_score
+ if self.filter_function ~= nil then
+ filter_score, prompt = self:filter_function(prompt, entry)
+ end
+
+ local score = (filter_score == FILTERED and FILTERED or
+ self:scoring_function(prompt or "", ordinal, entry))
if score == FILTERED then
self:_mark_discarded(prompt, ordinal)
@@ -467,4 +474,45 @@ sorters.get_substr_matcher = function()
}
end
+local substr_matcher = function(_, prompt, line, _)
+ local display = line:lower()
+ local search_terms = util.max_split(prompt, "%s")
+ local matched = 0
+ local total_search_terms = 0
+ for _, word in pairs(search_terms) do
+ total_search_terms = total_search_terms + 1
+ if display:find(word, 1, true) then
+ matched = matched + 1
+ end
+ end
+
+ return matched == total_search_terms and 0 or FILTERED
+end
+
+local filter_function = function(opts)
+ local scoring_function = vim.F.if_nil(opts.filter_function, substr_matcher)
+ local tag = vim.F.if_nil(opts.tag, "ordinal")
+ local delimiter = vim.F.if_nil(opts.delimiter, ":")
+
+ return function(_, prompt, entry)
+ local filter = "^(" .. delimiter .. "(%S+)" .. "[" .. delimiter .. "%s]" .. ")"
+ local matched = prompt:match(filter)
+
+ if matched == nil then
+ return 0, prompt
+ end
+ -- clear prompt of tag
+ prompt = prompt:sub(#matched + 1, -1)
+ local query = vim.trim(matched:gsub(delimiter, ""))
+ return scoring_function(_, query, entry[tag], _), prompt
+ end
+end
+
+sorters.prefilter = function(opts)
+ local sorter = opts.sorter
+ sorter.filter_function = filter_function(opts)
+ sorter._was_discarded = function() return false end
+ return sorter
+end
+
return sorters
diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua
index 928b502..cd58c13 100644
--- a/lua/telescope/utils.lua
+++ b/lua/telescope/utils.lua
@@ -82,6 +82,41 @@ utils.quickfix_items_to_entries = function(locations)
return results
end
+utils.diagnostics_to_tbl = function(opts)
+ opts = opts or {}
+
+ local bufnr = vim.api.nvim_get_current_buf()
+ local filename = vim.api.nvim_buf_get_name(bufnr)
+ local buffer_diags = vim.lsp.diagnostic.get(bufnr, opts.client_id)
+
+ local items = {}
+ local lsp_type_diagnostic = {[1] = "Error", [2] = "Warning", [3] = "Information", [4] = "Hint"}
+ local insert_diag = function(diag)
+ local start = diag.range['start']
+ local finish = diag.range['end']
+ local row = start.line
+ local col = start.character
+
+ local line = (vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false) or {""})[1]
+
+ table.insert(items, {
+ bufnr = bufnr,
+ filename = filename,
+ lnum = row + 1,
+ col = col + 1,
+ start = start,
+ finish = finish,
+ text = vim.trim(line .. " | " .. diag.message),
+ type = lsp_type_diagnostic[diag.severity] or lsp_type_diagnostic[1]
+ })
+ end
+
+ for _, diag in ipairs(buffer_diags) do insert_diag(diag) end
+
+ table.sort(items, function(a, b) return a.lnum < b.lnum end)
+ return items
+end
+
-- TODO: Figure out how to do this... could include in plenary :)
-- NOTE: Don't use this yet. It will segfault sometimes.
--