feat: filetype_hook & improved docs; fix preview partial override (#1273)

This commit is contained in:
fdschmidt93
2021-09-27 15:24:35 +02:00
committed by GitHub
parent 87471bc3ff
commit a6c7498bdc
5 changed files with 173 additions and 66 deletions

View File

@@ -315,14 +315,52 @@ telescope.setup({opts}) *telescope.setup()*
complete within `timeout` milliseconds. complete within `timeout` milliseconds.
Set to false to not timeout preview. Set to false to not timeout preview.
Default: 250 Default: 250
- hook(s): Function(s) that takes `(filepath, bufnr, opts)` - hook(s): Function(s) that takes `(filepath, bufnr, opts)`, where opts
to be run if the buffer previewer was not shown due to exposes winid and ft (filetype).
the respective test. Available hooks (in order of priority):
Available hooks are: {mime, filesize, timeout}_hook, e.g. {filetype, mime, filesize, timeout}_hook
preview = { Important: the filetype_hook must return true or false
mime_hook = function(filepath, bufnr, opts) ... end to indicate whether to continue (true) previewing or not (false),
} respectively.
See `telescope/previewers/*.lua` for relevant examples. Two examples:
local putils = require("telescope.previewers.utils")
... -- preview is called in telescope.setup { ... }
preview = {
-- 1) Do not show previewer for certain files
filetype_hook = function(filepath, bufnr, opts)
-- you could analogously check opts.ft for filetypes
local excluded = vim.tbl_filter(function(ending)
return filepath:match(ending)
end, {
".*%.csv",
".*%.toml",
})
if not vim.tbl_isempty(excluded) then
putils.set_preview_message(
bufnr,
opts.winid,
string.format("I don't like %s files!",
excluded[1]:sub(5, -1))
)
return false
end
return true
end,
-- 2) Truncate lines to preview window for too large files
filesize_hook = function(filepath, bufnr, opts)
local path = require("plenary.path"):new(filepath)
-- opts exposes winid
local height = vim.api.nvim_win_get_height(opts.winid)
local lines = vim.split(path:head(height), "[\r]?\n")
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
end,
}
The configuration recipes for relevant examples.
Note: if plenary does not recognize your filetype yet --
1) Please consider contributing to:
$PLENARY_REPO/data/plenary/filetypes/builtin.lua
2) Register your filetype locally as per link
https://github.com/nvim-lua/plenary.nvim#plenaryfiletype
Default: nil Default: nil
- treesitter: Determines whether the previewer performs treesitter - treesitter: Determines whether the previewer performs treesitter
highlighting, which falls back to regex-based highlighting. highlighting, which falls back to regex-based highlighting.
@@ -331,6 +369,8 @@ telescope.setup({opts}) *telescope.setup()*
`table`: table of filetypes for which to attach treesitter `table`: table of filetypes for which to attach treesitter
highlighting highlighting
Default: true Default: true
- msg_bg_fillchar: Character to fill background of unpreviewable buffers with
Default: ""
*telescope.defaults.vimgrep_arguments* *telescope.defaults.vimgrep_arguments*

View File

@@ -402,6 +402,7 @@ append(
filesize_limit = 25, filesize_limit = 25,
timeout = 250, timeout = 250,
treesitter = true, treesitter = true,
msg_bg_fillchar = "",
}, },
[[ [[
This field handles the global configuration for previewers. This field handles the global configuration for previewers.
@@ -426,14 +427,52 @@ append(
complete within `timeout` milliseconds. complete within `timeout` milliseconds.
Set to false to not timeout preview. Set to false to not timeout preview.
Default: 250 Default: 250
- hook(s): Function(s) that takes `(filepath, bufnr, opts)` - hook(s): Function(s) that takes `(filepath, bufnr, opts)`, where opts
to be run if the buffer previewer was not shown due to exposes winid and ft (filetype).
the respective test. Available hooks (in order of priority):
Available hooks are: {mime, filesize, timeout}_hook, e.g. {filetype, mime, filesize, timeout}_hook
preview = { Important: the filetype_hook must return true or false
mime_hook = function(filepath, bufnr, opts) ... end to indicate whether to continue (true) previewing or not (false),
} respectively.
See `telescope/previewers/*.lua` for relevant examples. Two examples:
local putils = require("telescope.previewers.utils")
... -- preview is called in telescope.setup { ... }
preview = {
-- 1) Do not show previewer for certain files
filetype_hook = function(filepath, bufnr, opts)
-- you could analogously check opts.ft for filetypes
local excluded = vim.tbl_filter(function(ending)
return filepath:match(ending)
end, {
".*%.csv",
".*%.toml",
})
if not vim.tbl_isempty(excluded) then
putils.set_preview_message(
bufnr,
opts.winid,
string.format("I don't like %s files!",
excluded[1]:sub(5, -1))
)
return false
end
return true
end,
-- 2) Truncate lines to preview window for too large files
filesize_hook = function(filepath, bufnr, opts)
local path = require("plenary.path"):new(filepath)
-- opts exposes winid
local height = vim.api.nvim_win_get_height(opts.winid)
local lines = vim.split(path:head(height), "[\r]?\n")
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)
end,
}
The configuration recipes for relevant examples.
Note: if plenary does not recognize your filetype yet --
1) Please consider contributing to:
$PLENARY_REPO/data/plenary/filetypes/builtin.lua
2) Register your filetype locally as per link
https://github.com/nvim-lua/plenary.nvim#plenaryfiletype
Default: nil Default: nil
- treesitter: Determines whether the previewer performs treesitter - treesitter: Determines whether the previewer performs treesitter
highlighting, which falls back to regex-based highlighting. highlighting, which falls back to regex-based highlighting.
@@ -442,6 +481,8 @@ append(
`table`: table of filetypes for which to attach treesitter `table`: table of filetypes for which to attach treesitter
highlighting highlighting
Default: true Default: true
- msg_bg_fillchar: Character to fill background of unpreviewable buffers with
Default: ""
]] ]]
) )
@@ -697,7 +738,7 @@ function config.set_defaults(user_defaults, tele_defaults)
vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {})) vim.tbl_deep_extend("keep", if_nil(config.values[name], {}), if_nil(default_val, {}))
) )
end end
if name == "history" or name == "cache_picker" then if name == "history" or name == "cache_picker" or name == "preview" then
if user_defaults[name] == false or config.values[name] == false then if user_defaults[name] == false or config.values[name] == false then
return false return false
end end

View File

@@ -1,7 +1,6 @@
local from_entry = require "telescope.from_entry" local from_entry = require "telescope.from_entry"
local Path = require "plenary.path" local Path = require "plenary.path"
local utils = require "telescope.utils" local utils = require "telescope.utils"
local strings = require "plenary.strings"
local putils = require "telescope.previewers.utils" local putils = require "telescope.previewers.utils"
local Previewer = require "telescope.previewers.previewer" local Previewer = require "telescope.previewers.previewer"
local conf = require("telescope.config").values local conf = require("telescope.config").values
@@ -56,39 +55,6 @@ local function defaulter(f, default_opts)
} }
end end
local function set_timeout_message(bufnr, winid, message)
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,
utils.repeated_table(height, table.concat(utils.repeated_table(width, ""), ""))
)
for linenr = 0, height do
vim.api.nvim_buf_add_highlight(bufnr, -1, "TelescopePreviewMessage", linenr, 0, -1)
end
local anon_ns = vim.api.nvim_create_namespace ""
local padding = table.concat(utils.repeated_table(#message + 4, " "), "")
local lines = {
padding,
" " .. message .. " ",
padding,
}
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
-- modified vim.split to incorporate a timer -- modified vim.split to incorporate a timer
local function split(s, sep, plain, opts) local function split(s, sep, plain, opts)
opts = opts or {} opts = opts or {}
@@ -190,14 +156,20 @@ previewers.file_maker = function(filepath, bufnr, opts)
opts.preview = opts.preview or {} opts.preview = opts.preview or {}
opts.preview.timeout = vim.F.if_nil(opts.preview.timeout, 250) -- in ms opts.preview.timeout = vim.F.if_nil(opts.preview.timeout, 250) -- in ms
opts.preview.filesize_limit = vim.F.if_nil(opts.preview.filesize_limit, 25) -- in mb opts.preview.filesize_limit = vim.F.if_nil(opts.preview.filesize_limit, 25) -- in mb
opts.preview.msg_bg_fillchar = vim.F.if_nil(opts.preview.msg_bg_fillchar, "") -- in mb
if opts.use_ft_detect == nil then if opts.use_ft_detect == nil then
opts.use_ft_detect = true opts.use_ft_detect = true
end end
local ft = opts.use_ft_detect and pfiletype.detect(filepath) opts.ft = opts.use_ft_detect and pfiletype.detect(filepath)
if opts.bufname ~= filepath then if opts.bufname ~= filepath then
if not vim.in_fast_event() then if not vim.in_fast_event() then
filepath = vim.fn.expand(filepath) filepath = vim.fn.expand(filepath)
end end
if type(opts.preview.filetype_hook) == "function" then
if not opts.preview.filetype_hook(filepath, bufnr, opts) then
return
end
end
vim.loop.fs_stat(filepath, function(_, stat) vim.loop.fs_stat(filepath, function(_, stat)
if not stat then if not stat then
return return
@@ -215,17 +187,20 @@ previewers.file_maker = function(filepath, bufnr, opts)
end), end),
}) })
else else
if opts.preview.check_mime_type == true and has_file and ft == "" then if opts.preview.check_mime_type == true and has_file and opts.ft == "" then
-- avoid SIGABRT in buffer previewer happening with utils.get_os_command_output -- avoid SIGABRT in buffer previewer happening with utils.get_os_command_output
local output = capture(string.format([[file --mime-type -b "%s"]], filepath)) local output = capture(string.format([[file --mime-type -b "%s"]], filepath))
local mime_type = vim.split(output, "/")[1] local mime_type = vim.split(output, "/")[1]
if mime_type ~= "text" and mime_type ~= "inode" then if mime_type ~= "text" and mime_type ~= "inode" then
if type(opts.preview.mime_hook) == "function" then if type(opts.preview.mime_hook) == "function" then
opts.preview.mime_hook(filepath, bufnr, opts) vim.schedule_wrap(opts.preview.mime_hook)(filepath, bufnr, opts)
else else
vim.schedule(function() vim.schedule_wrap(putils.set_preview_message)(
set_timeout_message(bufnr, opts.winid, "Binary cannot be previewed") bufnr,
end) opts.winid,
"Binary cannot be previewed",
opts.preview.msg_bg_fillchar
)
end end
return return
end end
@@ -235,11 +210,14 @@ previewers.file_maker = function(filepath, bufnr, opts)
local mb_filesize = math.floor(stat.size / bytes_to_megabytes) local mb_filesize = math.floor(stat.size / bytes_to_megabytes)
if mb_filesize > opts.preview.filesize_limit then if mb_filesize > opts.preview.filesize_limit then
if type(opts.preview.filesize_hook) == "function" then if type(opts.preview.filesize_hook) == "function" then
opts.preview.filesize_hook(filepath, bufnr, opts) vim.schedule_wrap(opts.preview.filesize_hook)(filepath, bufnr, opts)
else else
vim.schedule(function() vim.schedule_wrap(putils.set_preview_message)(
set_timeout_message(bufnr, opts.winid, "File exceeds preview size limit") bufnr,
end) opts.winid,
"File exceeds preview size limit",
opts.preview.msg_bg_fillchar
)
end end
return return
end end
@@ -261,12 +239,17 @@ previewers.file_maker = function(filepath, bufnr, opts)
if opts.callback then if opts.callback then
opts.callback(bufnr) opts.callback(bufnr)
end end
putils.highlighter(bufnr, ft, opts) putils.highlighter(bufnr, opts.ft, opts)
else else
if type(opts.preview.timeout_hook) == "function" then if type(opts.preview.timeout_hook) == "function" then
opts.preview.timeout_hook(filepath, bufnr, opts) vim.schedule_wrap(opts.preview.timeout_hook)(filepath, bufnr, opts)
else else
set_timeout_message(bufnr, opts.winid, "Previewer timed out") vim.schedule_wrap(putils.set_preview_message)(
bufnr,
opts.winid,
"Previewer timed out",
opts.preview.msg_bg_fillchar
)
end end
return return
end end

View File

@@ -1,4 +1,7 @@
local context_manager = require "plenary.context_manager" 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 has_ts, _ = pcall(require, "nvim-treesitter")
local _, ts_configs = pcall(require, "nvim-treesitter.configs") local _, ts_configs = pcall(require, "nvim-treesitter.configs")
@@ -66,7 +69,10 @@ end
utils.highlighter = function(bufnr, ft, opts) utils.highlighter = function(bufnr, ft, opts)
opts = opts or {} opts = opts or {}
opts.preview = opts.preview or {} opts.preview = opts.preview or {}
opts.preview.treesitter = vim.F.if_nil(opts.preview.treesitter, true) 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 local ts_highlighting = opts.preview.treesitter == true
or type(opts.preview.treesitter) == "table" and vim.tbl_contains(opts.preview.treesitter, ft) or type(opts.preview.treesitter) == "table" and vim.tbl_contains(opts.preview.treesitter, ft)
@@ -127,4 +133,41 @@ utils.ts_highlighter = function(bufnr, ft)
return false return false
end 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 return utils

View File

@@ -53,8 +53,8 @@ highlight default link TelescopePreviewSize String
highlight default link TelescopePreviewUser Constant highlight default link TelescopePreviewUser Constant
highlight default link TelescopePreviewGroup Constant highlight default link TelescopePreviewGroup Constant
highlight default link TelescopePreviewDate Directory highlight default link TelescopePreviewDate Directory
highlight default link TelescopePreviewMessage TelescopePreviewNormal highlight default link TelescopePreviewMessage TelescopePreviewNormal
highlight default link TelescopePreviewFillchar TelescopePreviewNormal
" Used for Picker specific Results highlighting " Used for Picker specific Results highlighting
highlight default link TelescopeResultsClass Function highlight default link TelescopeResultsClass Function