Skip to content

Commit

Permalink
feat: new picker treesitter (closes #1447)
Browse files Browse the repository at this point in the history
  • Loading branch information
ibhagwan committed Sep 28, 2024
1 parent 86b77a6 commit 2f4ea2f
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 1 deletion.
4 changes: 4 additions & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,10 @@ Location list (output of `:lopen`)

Location list history (output of `:lhistory`)

#### treesitter

Current buffer treesitter symbols

#### blines

Current buffer lines
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ to see detailed usage notes and a comprehensive list of all available options.**
| `loclist_stack` | location stack |
| `lines` | open buffers lines |
| `blines` | current buffer lines |
| `treesitter` | current buffer treesitter symbols |
| `tabs` | open tabs |
| `args` | argument list |

Expand Down
8 changes: 7 additions & 1 deletion doc/fzf-lua-opts.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*fzf-lua-opts.txt* For Neovim >= 0.8.0 Last change: 2024 August 07
*fzf-lua-opts.txt* For Neovim >= 0.8.0 Last change: 2024 September 26

==============================================================================
Table of Contents *fzf-lua-opts-table-of-contents*
Expand Down Expand Up @@ -989,6 +989,12 @@ Location list history (output of `:lhistory`)



treesitter *fzf-lua-opts-treesitter*

Current buffer treesitter symbols



blines *fzf-lua-opts-blines*

Current buffer lines
Expand Down
18 changes: 18 additions & 0 deletions lua/fzf-lua/defaults.lua
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,24 @@ M.defaults.blines = {
_cached_hls = { "buf_name", "buf_nr", "path_linenr" },
}

M.defaults.treesitter = {
previewer = M._default_previewer_fn,
prompt = "Treesitter> ",
file_icons = false,
color_icons = false,
fzf_opts = {
["--multi"] = true,
["--delimiter"] = "[:]",
["--with-nth"] = "2..",
["--tiebreak"] = "index",
},
line_field_index = "{2}",
_actions = function()
return M.globals.actions.buffers or M.globals.actions.files
end,
_cached_hls = { "buf_name", "buf_nr", "path_linenr", "path_colnr" },
}

M.defaults.tags = {
previewer = { _ctor = previewers.builtin.tags },
prompt = "Tags> ",
Expand Down
1 change: 1 addition & 0 deletions lua/fzf-lua/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ do
tabs = { "fzf-lua.providers.buffers", "tabs" },
lines = { "fzf-lua.providers.buffers", "lines" },
blines = { "fzf-lua.providers.buffers", "blines" },
treesitter = { "fzf-lua.providers.buffers", "treesitter" },
helptags = { "fzf-lua.providers.helptags", "helptags" },
manpages = { "fzf-lua.providers.manpages", "manpages" },
-- backward compat
Expand Down
68 changes: 68 additions & 0 deletions lua/fzf-lua/providers/buffers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,72 @@ M.tabs = function(opts)
core.fzf_exec(contents, opts)
end


M.treesitter = function(opts)
opts = config.normalize_opts(opts, "treesitter")
if not opts then return end

local __has_ts, _ = pcall(require, "nvim-treesitter")
if not __has_ts then
utils.info("Treesitter requires 'nvim-treesitter'.")
return
end

-- Default to current buffer
opts.bufnr = tonumber(opts.bufnr) or vim.api.nvim_get_current_buf()
opts._bufname = path.basename(vim.api.nvim_buf_get_name(opts.bufnr))
if not opts._bufname or #opts._bufname == 0 then
opts._bufname = utils.nvim_buf_get_name(opts.bufnr)
end

local ts_parsers = require("nvim-treesitter.parsers")
if not ts_parsers.has_parser(ts_parsers.get_buf_lang(opts.bufnr)) then
utils.info(string.format("No treesitter parser found for '%s' (bufnr=%d).",
opts._bufname, opts.bufnr))
return
end

local kind2hl = function(kind)
local map = { var = "variable.builtin" }
return "@" .. (map[kind] or kind)
end

local contents = function(cb)
coroutine.wrap(function()
local co = coroutine.running()
local ts_locals = require("nvim-treesitter.locals")
for _, definition in ipairs(ts_locals.get_definitions(opts.bufnr)) do
local nodes = ts_locals.get_local_nodes(definition)
for _, node in ipairs(nodes) do
if node.node then
vim.schedule(function()
local lnum, col, _, _ = vim.treesitter.get_node_range(node.node)
local node_text = vim.treesitter.get_node_text(node.node, opts.bufnr)
local node_kind = node.kind and utils.ansi_from_hl(kind2hl(node.kind), node.kind)
local entry = string.format("[%s]%s%s:%s:%s:\t[%s] %s",
utils.ansi_codes[opts.hls.buf_nr](tostring(opts.bufnr)),
utils.nbsp,
utils.ansi_codes[opts.hls.buf_name](opts._bufname),
utils.ansi_codes[opts.hls.path_linenr](tostring(lnum + 1)),
utils.ansi_codes[opts.hls.path_colnr](tostring(col + 1)),
node_kind or "",
node_text)
cb(entry, function(err)
coroutine.resume(co)
if err then cb(nil) end
end)
end)
coroutine.yield()
end
end
end
cb(nil)
end)()
end

opts = core.set_header(opts, opts.headers or { "cwd" })

core.fzf_exec(contents, opts)
end

return M

0 comments on commit 2f4ea2f

Please sign in to comment.