1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-03 14:40:04 +08:00
SpaceVim/bundle/telescope.nvim/lua/telescope/previewers/utils.lua

185 lines
5.3 KiB
Lua
Raw Normal View History

2022-05-16 22:20:10 +08:00
local context_manager = require "plenary.context_manager"
local ts_utils = require "telescope.utils"
local strings = require "plenary.strings"
local conf = require("telescope.config").values
local has_ts, _ = pcall(require, "nvim-treesitter")
local _, ts_configs = pcall(require, "nvim-treesitter.configs")
local _, ts_parsers = pcall(require, "nvim-treesitter.parsers")
local Job = require "plenary.job"
local utils = {}
utils.with_preview_window = function(status, bufnr, callable)
if bufnr and vim.api.nvim_buf_call and false then
vim.api.nvim_buf_call(bufnr, callable)
else
return context_manager.with(function()
vim.cmd(string.format("noautocmd call nvim_set_current_win(%s)", status.preview_win))
coroutine.yield()
vim.cmd(string.format("noautocmd call nvim_set_current_win(%s)", status.prompt_win))
end, callable)
end
end
-- API helper functions for buffer previewer
--- Job maker for buffer previewer
utils.job_maker = function(cmd, bufnr, opts)
opts = opts or {}
opts.mode = opts.mode or "insert"
-- bufname and value are optional
-- if passed, they will be use as the cache key
-- if any of them are missing, cache will be skipped
if opts.bufname ~= opts.value or not opts.bufname or not opts.value then
local command = table.remove(cmd, 1)
local writer = (function()
if opts.writer ~= nil then
local wcommand = table.remove(opts.writer, 1)
return Job:new {
command = wcommand,
args = opts.writer,
env = opts.env,
cwd = opts.cwd,
}
end
end)()
Job
:new({
command = command,
args = cmd,
env = opts.env,
cwd = opts.cwd,
writer = writer,
on_exit = vim.schedule_wrap(function(j)
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end
if opts.mode == "append" then
vim.api.nvim_buf_set_lines(bufnr, -1, -1, false, j:result())
elseif opts.mode == "insert" then
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, j:result())
end
if opts.callback then
opts.callback(bufnr, j:result())
end
end),
})
:start()
else
if opts.callback then
opts.callback(bufnr)
end
end
end
local function has_filetype(ft)
return ft and ft ~= ""
end
--- Attach default highlighter which will choose between regex and ts
utils.highlighter = function(bufnr, ft, opts)
opts = opts or {}
opts.preview = opts.preview or {}
opts.preview.treesitter = vim.F.if_nil(
opts.preview.treesitter,
type(conf.preview) == "table" and conf.preview.treesitter
)
local ts_highlighting = opts.preview.treesitter == true
or type(opts.preview.treesitter) == "table" and vim.tbl_contains(opts.preview.treesitter, ft)
local ts_success
if ts_highlighting then
ts_success = utils.ts_highlighter(bufnr, ft)
end
if not ts_highlighting or ts_success == false then
utils.regex_highlighter(bufnr, ft)
end
end
--- Attach regex highlighter
utils.regex_highlighter = function(bufnr, ft)
if has_filetype(ft) then
vim.api.nvim_buf_set_option(bufnr, "syntax", ft)
return true
end
return false
end
local treesitter_attach = function(bufnr, ft)
local lang = ts_parsers.ft_to_lang(ft)
if not ts_configs.is_enabled("highlight", lang, bufnr) then
return false
end
local config = ts_configs.get_module "highlight"
for k, v in pairs(config.custom_captures) do
vim.treesitter.highlighter.hl_map[k] = v
end
vim.treesitter.highlighter.new(ts_parsers.get_parser(bufnr, lang))
local is_table = type(config.additional_vim_regex_highlighting) == "table"
if
config.additional_vim_regex_highlighting
and (not is_table or vim.tbl_contains(config.additional_vim_regex_highlighting, lang))
then
vim.api.nvim_buf_set_option(bufnr, "syntax", ft)
end
return true
end
-- Attach ts highlighter
utils.ts_highlighter = function(bufnr, ft)
if not has_ts then
has_ts, _ = pcall(require, "nvim-treesitter")
if has_ts then
_, ts_configs = pcall(require, "nvim-treesitter.configs")
_, ts_parsers = pcall(require, "nvim-treesitter.parsers")
end
end
if has_ts and has_filetype(ft) then
return treesitter_attach(bufnr, ft)
end
return false
end
utils.set_preview_message = function(bufnr, winid, message, fillchar)
fillchar = vim.F.if_nil(fillchar, "")
local height = vim.api.nvim_win_get_height(winid)
local width = vim.api.nvim_win_get_width(winid)
vim.api.nvim_buf_set_lines(
bufnr,
0,
-1,
false,
ts_utils.repeated_table(height, table.concat(ts_utils.repeated_table(width, fillchar), ""))
)
local anon_ns = vim.api.nvim_create_namespace ""
local padding = table.concat(ts_utils.repeated_table(#message + 4, " "), "")
local lines = {
padding,
" " .. message .. " ",
padding,
}
vim.api.nvim_buf_set_extmark(
bufnr,
anon_ns,
0,
0,
{ end_line = height, hl_group = "TelescopePreviewMessageFillchar" }
)
local col = math.floor((width - strings.strdisplaywidth(lines[2])) / 2)
for i, line in ipairs(lines) do
vim.api.nvim_buf_set_extmark(
bufnr,
anon_ns,
math.floor(height / 2) - 1 + i,
0,
{ virt_text = { { line, "TelescopePreviewMessage" } }, virt_text_pos = "overlay", virt_text_win_col = col }
)
end
end
return utils