feat!(previewer): replace plenary.filetype with vim.filetype.match (#2529)

This commit is contained in:
Simon Hauser
2023-06-09 11:24:52 +02:00
committed by GitHub
parent 42267407ae
commit 66b03e7740
6 changed files with 144 additions and 91 deletions

View File

@@ -540,8 +540,8 @@ append(
Fields:
- check_mime_type: Use `file` if available to try to infer whether the
file to preview is a binary if plenary's
filetype detection fails.
file to preview is a binary if filetype
detection fails.
Windows users get `file` from:
https://github.com/julian-r/file-windows
Set to false to attempt to preview any mime type.
@@ -594,11 +594,10 @@ append(
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
Note: we use vim.filetype filetype detection,
so if you have troubles with files not
highlighting correctly, please read
|vim.filetype|
Default: nil
- treesitter: Determines whether the previewer performs treesitter
highlighting, which falls back to regex-based highlighting.

View File

@@ -5,7 +5,6 @@ local putils = require "telescope.previewers.utils"
local Previewer = require "telescope.previewers.previewer"
local conf = require("telescope.config").values
local pfiletype = require "plenary.filetype"
local pscan = require "plenary.scandir"
local buf_delete = utils.buf_delete
@@ -201,7 +200,6 @@ previewers.file_maker = function(filepath, bufnr, opts)
if opts.use_ft_detect == nil then
opts.use_ft_detect = true
end
opts.ft = opts.use_ft_detect and pfiletype.detect(filepath)
if opts.bufname ~= filepath then
if not vim.in_fast_event() then
filepath = vim.fn.expand(filepath)
@@ -218,76 +216,74 @@ previewers.file_maker = function(filepath, bufnr, opts)
if stat.type == "directory" then
handle_directory_preview(filepath, bufnr, opts)
else
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
local output = capture(string.format([[file --mime-type -b "%s"]], filepath))
local mime_type = vim.split(output, "/")
if mime_type[1] ~= "text" and mime_type[1] ~= "inode" and mime_type[2] ~= "json" then
if type(opts.preview.mime_hook) == "function" then
vim.schedule_wrap(opts.preview.mime_hook)(filepath, bufnr, opts)
else
vim.schedule_wrap(putils.set_preview_message)(
bufnr,
opts.winid,
"Binary cannot be previewed",
opts.preview.msg_bg_fillchar
)
end
return
end
if mime_type[2] == "json" then
opts.ft = "json"
end
end
if opts.preview.filesize_limit then
local mb_filesize = math.floor(stat.size / bytes_to_megabytes)
if mb_filesize > opts.preview.filesize_limit then
if type(opts.preview.filesize_hook) == "function" then
vim.schedule_wrap(opts.preview.filesize_hook)(filepath, bufnr, opts)
else
vim.schedule_wrap(putils.set_preview_message)(
bufnr,
opts.winid,
"File exceeds preview size limit",
opts.preview.msg_bg_fillchar
)
end
return
end
end
opts.start_time = vim.loop.hrtime()
Path:new(filepath):_read_async(vim.schedule_wrap(function(data)
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end
local processed_data = split(data, "[\r]?\n", _, opts)
if processed_data then
local ok = pcall(vim.api.nvim_buf_set_lines, bufnr, 0, -1, false, processed_data)
if not ok then
vim.schedule(function()
opts.ft = opts.use_ft_detect and putils.filetype_detect(filepath)
if opts.preview.check_mime_type == true and has_file and (opts.ft == nil or opts.ft == "") then
-- avoid SIGABRT in buffer previewer happening with utils.get_os_command_output
local output = capture(string.format([[file --mime-type -b "%s"]], filepath))
local mime_type = vim.split(output, "/")
if mime_type[1] ~= "text" and mime_type[1] ~= "inode" and mime_type[2] ~= "json" then
if type(opts.preview.mime_hook) == "function" then
opts.preview.mime_hook(filepath, bufnr, opts)
else
putils.set_preview_message(
bufnr,
opts.winid,
"Binary cannot be previewed",
opts.preview.msg_bg_fillchar
)
end
return
end
if opts.callback then
opts.callback(bufnr)
if mime_type[2] == "json" then
opts.ft = "json"
end
putils.highlighter(bufnr, opts.ft, opts)
else
if type(opts.preview.timeout_hook) == "function" then
vim.schedule_wrap(opts.preview.timeout_hook)(filepath, bufnr, opts)
else
vim.schedule_wrap(putils.set_preview_message)(
bufnr,
opts.winid,
"Previewer timed out",
opts.preview.msg_bg_fillchar
)
end
return
end
end))
if opts.preview.filesize_limit then
local mb_filesize = math.floor(stat.size / bytes_to_megabytes)
if mb_filesize > opts.preview.filesize_limit then
if type(opts.preview.filesize_hook) == "function" then
opts.preview.filesize_hook(filepath, bufnr, opts)
else
putils.set_preview_message(
bufnr,
opts.winid,
"File exceeds preview size limit",
opts.preview.msg_bg_fillchar
)
end
return
end
end
opts.start_time = vim.loop.hrtime()
Path:new(filepath):_read_async(vim.schedule_wrap(function(data)
if not vim.api.nvim_buf_is_valid(bufnr) then
return
end
local processed_data = split(data, "[\r]?\n", _, opts)
if processed_data then
local ok = pcall(vim.api.nvim_buf_set_lines, bufnr, 0, -1, false, processed_data)
if not ok then
return
end
if opts.callback then
opts.callback(bufnr)
end
putils.highlighter(bufnr, opts.ft, opts)
else
if type(opts.preview.timeout_hook) == "function" then
opts.preview.timeout_hook(filepath, bufnr, opts)
else
putils.set_preview_message(bufnr, opts.winid, "Previewer timed out", opts.preview.msg_bg_fillchar)
end
return
end
end))
end)
end
end)
else
@@ -431,7 +427,7 @@ previewers.new_buffer_previewer = function(opts)
data = {
title = entry.preview_title,
bufname = self.state.bufname,
filetype = pfiletype.detect(self.state.bufname or ""),
filetype = putils.filetype_detect(self.state.bufname or ""),
},
})
end)
@@ -851,7 +847,7 @@ previewers.git_commit_diff_as_was = defaulter(function(opts)
local cmd = { "git", "--no-pager", "show" }
local cf = opts.current_file and Path:new(opts.current_file):make_relative(opts.cwd)
local value = cf and (entry.value .. ":" .. cf) or entry.value
local ft = cf and pfiletype.detect(value) or "diff"
local ft = cf and putils.filetype_detect(value) or "diff"
table.insert(cmd, value)
putils.job_maker(cmd, self.state.bufnr, {

View File

@@ -4,9 +4,55 @@ local strings = require "plenary.strings"
local conf = require("telescope.config").values
local Job = require "plenary.job"
local Path = require "plenary.path"
local utils = {}
local detect_from_shebang = function(p)
local s = p:readbyterange(0, 256)
if not s then
local lines = vim.split(s, "\n")
return vim.filetype.match { contents = lines }
end
end
local parse_modeline = function(tail)
if tail:find "vim:" then
return tail:match ".*:ft=([^: ]*):.*$" or ""
end
end
local detect_from_modeline = function(p)
local s = p:readbyterange(-256, 256)
if s then
local lines = vim.split(s, "\n")
local idx = lines[#lines] ~= "" and #lines or #lines - 1
if idx >= 1 then
return parse_modeline(lines[idx])
end
end
end
utils.filetype_detect = function(filepath)
local match = vim.filetype.match { filename = filepath }
if match and match ~= "" then
return match
end
local p = Path:new(filepath)
if p and p:exists() then
match = detect_from_shebang(p)
if match and match ~= "" then
return match
end
match = detect_from_modeline(p)
if match and match ~= "" then
return match
end
end
end
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)