From 1d40ab5ccda6be3680fd809d34d93366b11c4ef8 Mon Sep 17 00:00:00 2001 From: Simon Hauser Date: Tue, 29 Dec 2020 21:05:59 +0100 Subject: [PATCH] feat: All buffer previewers are now async and more config options (#354) Configure preview window with: autocmd User TelescopePreviewerLoaded setlocal wrap autocmd User TelescopePreviewerLoaded setlocal number file_maker example: Use regex highlighting for certain filetype like `*min.js` because they slow down things with treesitter highlighter. Just a snippet for tests. We will do an extension :) local previewers = require('telescope.previewers') local putils = require('telescope.previewers.utils') local pfiletype = require('plenary.filetype') local _bad = { '.*%.min%.js' } local bad_files = function(filepath) for _, v in ipairs(_bad) do if filepath:match(v) then return true end end return false end local new_maker = function(filepath, bufnr, bufname, use_ft_detect, callback) if use_ft_detect == nil then use_ft_detect = true end if bad_files(filepath) then previewers.buffer_previewer_maker(filepath, bufnr, bufname, false, callback) local ft = pfiletype.detect(filepath) putils.regex_highlighter(bufnr, ft) else previewers.buffer_previewer_maker(filepath, bufnr, bufname, use_ft_detect, callback) end end require('telescope').setup { defaults = { buffer_previewer_maker = new_maker, } } --- README.md | 42 ++- lua/telescope/config.lua | 1 + lua/telescope/make_entry.lua | 2 +- lua/telescope/previewers/buffer_previewer.lua | 281 ++++++++++++------ lua/telescope/previewers/init.lua | 29 +- lua/telescope/previewers/term_previewer.lua | 35 +-- lua/telescope/previewers/utils.lua | 52 ++++ plugin/telescope.vim | 2 + 8 files changed, 296 insertions(+), 148 deletions(-) diff --git a/README.md b/README.md index 3c3d1c9..a605c68 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,21 @@ Gaze deeply into unknown regions using the power of the moon. ## What Is Telescope? `telescope.nvim` is a highly extendable fuzzy finder over lists. Built on the latest -awesome features from `neovim` core. Telescope is centered around -modularity, allowing for easy customization. +awesome features from `neovim` core. Telescope is centered around +modularity, allowing for easy customization. Community driven built-in [pickers](#pickers), [sorters](#sorters) and [previewers](#previewers). ### Built-in Support: -- [Vim](#vim-pickers) -- [Files](#file-pickers) +- [Vim](#vim-pickers) +- [Files](#file-pickers) - [Git](#git-pickers) - [LSP](#lsp-pickers) - [Treesitter](#treesitter-pickers) ![by @glepnir](https://user-images.githubusercontent.com/41671631/100819597-6f737900-3487-11eb-8621-37ec1ffabe4b.gif) - + @@ -162,6 +162,9 @@ require('telescope').setup{ file_previewer = require'telescope.previewers'.cat.new, -- For buffer previewer use `require'telescope.previewers'.vim_buffer_cat.new` grep_previewer = require'telescope.previewers'.vimgrep.new, -- For buffer previewer use `require'telescope.previewers'.vim_buffer_vimgrep.new` qflist_previewer = require'telescope.previewers'.qflist.new, -- For buffer previewer use `require'telescope.previewers'.vim_buffer_qflist.new` + + -- Developer configurations: Not meant for general override + buffer_previewer_maker = require'telescope.previewers'.buffer_previewer_maker } } ``` @@ -203,6 +206,12 @@ EOF | `grep_previewer` | What telescope previewer to use for grep and similar | [Previewers](#previewers) | | `qflist_previewer` | What telescope previewer to use for qflist | [Previewers](#previewers) | + +### Options for extension developers +| Keys | Description | Options | +|------------------------|-------------------------------------------------------|----------------------------| +| `buffer_previewer_maker` | How a file gets loaded and which highlighter will be used. Extensions will change it | function | + ### Options affecting Sorting | Keys | Description | Options | @@ -356,7 +365,7 @@ require('telescope.builtin').fd({ -- or new custom picker's attach_mappings fiel Built-in functions. Ready to be bound to any key you like. :smile: -```vim +```vim :lua require'telescope.builtin'.planets{} :nnoremap pp :lua require'telescope.builtin'.planets{} @@ -441,17 +450,24 @@ Built-in functions. Ready to be bound to any key you like. :smile: | `previewers.cat.new` | Default previewer for files. Uses `cat`/`bat` | | `previewers.vimgrep.new` | Default previewer for grep and similar. Uses `cat`/`bat` | | `previewers.qflist.new` | Default previewer for qflist. Uses `cat`/`bat` | -| `previewers.vim_buffer_cat.new` | Experimental previewer for files. Uses vim buffers | -| `previewers.vim_buffer_vimgrep.new` | Experimental previewer for grep and similar. Uses vim buffers | -| `previewers.vim_buffer_qflist.new` | Experimental previewer for qflist. Uses vim buffers | +| `previewers.vim_buffer_cat.new` | Experimental previewer for files. Uses vim buffers | +| `previewers.vim_buffer_vimgrep.new`| Experimental previewer for grep and similar. Uses vim buffers | +| `previewers.vim_buffer_qflist.new` | Experimental previewer for qflist. Uses vim buffers | | .................................. | Your next awesome previewer here :D | By default, telescope.nvim uses `cat`/`bat` for preview. However after telescope's new experimental previewers are stable this will change. The new experimental previewers use tree-sitter and vim buffers, provide much -better performance and are ready for daily usage (`vim_buffer_cat` more than the others), but there might be -cases where it can't detect a Filetype correctly, thus leading to wrong highlights. -Also `vimgrep` and `qflist` might be slower due to synchronous file loading. +better performance and are ready for daily usage, but there might be cases where it can't detect a Filetype +correctly, thus leading to wrong highlights. This is because we can't determine the filetype in the traditional way +(we don't do `bufload`. We read the file async with `vim.loop.fs_` and attach only a highlighter), because we can't +execute autocommands, otherwise the speed of the previewer would slow down considerably. +If you want to configure more filetypes take a look at +[plenary wiki](https://github.com/nvim-lua/plenary.nvim#plenaryfiletype). +If you want to configure the `vim_buffer_` previewer, e.g. you want the line to wrap do this: +```vim +autocmd User TelescopePreviewerLoaded setlocal wrap +``` ## Sorters @@ -511,7 +527,7 @@ enhancements by using compiled C and interfacing directly with Lua. - [telescope-packer.nvim](https://github.com/nvim-telescope/telescope-packer.nvim) - A Telescope extension that provides extra functionality for Packer.nvim - [telescope-github.nvim](https://github.com/nvim-telescope/telescope-github.nvim) - Integration with github cli - [telescope-vimspector.nvim](https://github.com/nvim-telescope/telescope-vimspector.nvim) - Integration for [vimspector](https://github.com/puremourning/vimspector) -- [telescope-fzf-writer.nvim](https://github.com/nvim-telescope/telescope-fzf-writer.nvim) - Incorporating some fzf concepts with plenary jobs and telescope +- [telescope-fzf-writer.nvim](https://github.com/nvim-telescope/telescope-fzf-writer.nvim) - Incorporating some fzf concepts with plenary jobs and telescope - [telescope-symbols.nvim](https://github.com/nvim-telescope/telescope-symbols.nvim) - Picking symbols and insert them at point. Extensions can be refenced by doing the following: diff --git a/lua/telescope/config.lua b/lua/telescope/config.lua index de01fbd..eb527eb 100644 --- a/lua/telescope/config.lua +++ b/lua/telescope/config.lua @@ -96,6 +96,7 @@ function config.set_defaults(defaults) set("file_previewer", function(...) return require('telescope.previewers').cat.new(...) end) set("grep_previewer", function(...) return require('telescope.previewers').vimgrep.new(...) end) set("qflist_previewer", function(...) return require('telescope.previewers').qflist.new(...) end) + set("buffer_previewer_maker", function(...) return require('telescope.previewers').buffer_previewer_maker(...) end) end function config.clear_defaults() diff --git a/lua/telescope/make_entry.lua b/lua/telescope/make_entry.lua index dba6762..c1a4f66 100644 --- a/lua/telescope/make_entry.lua +++ b/lua/telescope/make_entry.lua @@ -270,7 +270,7 @@ function make_entry.gen_from_git_commits() local make_display = function(entry) return displayer { - {entry.value, "TelescopeResultsNumber"}, + {entry.value, "TelescopeResultsIdentifier"}, entry.msg } end diff --git a/lua/telescope/previewers/buffer_previewer.lua b/lua/telescope/previewers/buffer_previewer.lua index 2e34945..39f3ad0 100644 --- a/lua/telescope/previewers/buffer_previewer.lua +++ b/lua/telescope/previewers/buffer_previewer.lua @@ -1,60 +1,34 @@ -local debounce = require('telescope.debounce') local from_entry = require('telescope.from_entry') local path = require('telescope.path') local utils = require('telescope.utils') local putils = require('telescope.previewers.utils') local Previewer = require('telescope.previewers.previewer') +local conf = require('telescope.config').values local pfiletype = require('plenary.filetype') -local has_ts, _ = pcall(require, 'nvim-treesitter') -local _, ts_highlight = pcall(require, 'nvim-treesitter.highlight') -local _, ts_parsers = pcall(require, 'nvim-treesitter.parsers') - local buf_delete = utils.buf_delete - local defaulter = utils.make_default_callable local previewers = {} -local previewer_ns = vim.api.nvim_create_namespace('telescope.previewers') +local ns_previewer = vim.api.nvim_create_namespace('telescope.previewers') -local file_maker_async = function(filepath, bufnr, bufname, callback) - local ft = pfiletype.detect(filepath) +previewers.file_maker = function(filepath, bufnr, bufname, use_ft_detect, callback) + if use_ft_detect == nil then use_ft_detect = true end + local ft = use_ft_detect and pfiletype.detect(filepath) if bufname ~= filepath then path.read_file_async(filepath, vim.schedule_wrap(function(data) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.split(data, "\n")) - if callback then callback() end + if callback then callback(bufnr) end end)) else - if callback then callback() end + if callback then callback(bufnr) end end - if ft ~= '' then - if has_ts and ts_parsers.has_parser(ft) then - ts_highlight.attach(bufnr, ft) - else - vim.cmd(':ownsyntax ' .. ft) - end - end -end - -local file_maker_sync = function(filepath, bufnr, bufname) - local ft = pfiletype.detect(filepath) - if bufname ~= filepath then - local data = path.read_file(filepath) - vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.split(data, "\n")) - end - - if ft ~= '' then - if has_ts and ts_parsers.has_parser(ft) then - ts_highlight.attach(bufnr, ft) - else - vim.cmd(':ownsyntax ' .. ft) - end - end + putils.highlighter(bufnr, ft) end previewers.new_buffer_previewer = function(opts) @@ -69,6 +43,8 @@ previewers.new_buffer_previewer = function(opts) local old_bufs = {} local bufname_table = {} + local global_state = require'telescope.state' + local function get_bufnr(self) if not self.state then return nil end return self.state.bufnr @@ -100,11 +76,21 @@ previewers.new_buffer_previewer = function(opts) opt_teardown(self) end + local last_nr + if opts.keep_last_buf then + last_nr = global_state.get_global_key('last_preview_bufnr') + -- Push in another buffer so the last one will not be cleaned up + local bufnr = vim.api.nvim_create_buf(false, true) + vim.api.nvim_win_set_buf(self.state.winid, bufnr) + end + set_bufnr(self, nil) set_bufname(self, nil) for _, bufnr in ipairs(old_bufs) do - buf_delete(bufnr) + if bufnr ~= last_nr then + buf_delete(bufnr) + end end end @@ -134,8 +120,14 @@ previewers.new_buffer_previewer = function(opts) self.state.bufname = nil end + if opts.keep_last_buf then global_state.set_global_key("last_preview_bufnr", self.state.bufnr) end + opts.define_preview(self, entry, status) + putils.with_preview_window(status, nil, function() + vim.cmd'do User TelescopePreviewerLoaded' + end) + if opts.get_buffer_by_name then set_bufname(self, opts.get_buffer_by_name(self, entry)) end @@ -180,7 +172,7 @@ previewers.cat = defaulter(function(_) putils.with_preview_window(status, nil, function() local p = from_entry.path(entry, true) if p == nil or p == '' then return end - file_maker_async(p, self.state.bufnr, self.state.bufname) + conf.buffer_previewer_maker(p, self.state.bufnr, self.state.bufname) end) end } @@ -196,7 +188,7 @@ previewers.vimgrep = defaulter(function(_) teardown = function(self) if self.state and self.state.last_set_bufnr and vim.api.nvim_buf_is_valid(self.state.last_set_bufnr) then - vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, previewer_ns, 0, -1) + vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, ns_previewer, 0, -1) end end, @@ -210,17 +202,18 @@ previewers.vimgrep = defaulter(function(_) local p = from_entry.path(entry, true) if p == nil or p == '' then return end - file_maker_sync(p, self.state.bufnr, self.state.bufname) - - if lnum ~= 0 then - if self.state.last_set_bufnr then - pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, previewer_ns, 0, -1) - end - pcall(vim.api.nvim_buf_add_highlight, self.state.bufnr, previewer_ns, "TelescopePreviewLine", lnum - 1, 0, -1) - pcall(vim.api.nvim_win_set_cursor, status.preview_win, {lnum, 0}) + if self.state.last_set_bufnr then + pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, ns_previewer, 0, -1) end - self.state.last_set_bufnr = self.state.bufnr + conf.buffer_previewer_maker(p, self.state.bufnr, self.state.bufname, true, function(bufnr) + if lnum ~= 0 then + pcall(vim.api.nvim_buf_add_highlight, bufnr, ns_previewer, "TelescopePreviewLine", lnum - 1, 0, -1) + pcall(vim.api.nvim_win_set_cursor, self.state.winid, {lnum, 0}) + end + + self.state.last_set_bufnr = bufnr + end) end) end } @@ -248,13 +241,17 @@ previewers.ctags = defaulter(function(_) scode = string.gsub(scode, [[\/]], [[/]]) scode = string.gsub(scode, '[*]', [[\*]]) - file_maker_sync(entry.filename, self.state.bufnr, self.state.bufname) + conf.buffer_previewer_maker(entry.filename, self.state.bufnr, self.state.bufname, true, function(bufnr) + vim.api.nvim_buf_call(bufnr, function() + pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid) + vim.cmd "norm! gg" + vim.fn.search(scode, "W") + vim.cmd "norm! zz" - pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid) - vim.cmd "norm! gg" - vim.fn.search(scode) + self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', scode) + end) + end) - self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', scode) end) end } @@ -287,13 +284,18 @@ previewers.builtin = defaulter(function(_) text = entry.text:gsub('_', '.', 1) end - file_maker_sync(entry.filename, self.state.bufnr, self.state.bufname) + conf.buffer_previewer_maker(entry.filename, self.state.bufnr, self.state.bufname, true, function(bufnr) + vim.api.nvim_buf_call(bufnr, function() + pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid) + vim.cmd "norm! gg" + vim.fn.search(text, "W") + vim.cmd "norm! zz" + + self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', text) + end) + end) - pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid) - vim.cmd "norm! gg" - vim.fn.search(text) - self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', text) end) end } @@ -322,14 +324,18 @@ previewers.help = defaulter(function(_) query = query:sub(2) query = [[\V]] .. query - file_maker_sync(entry.filename, self.state.bufnr, self.state.bufname) - vim.cmd(':ownsyntax help') + conf.buffer_previewer_maker(entry.filename, self.state.bufnr, self.state.bufname, false, function(bufnr) + vim.api.nvim_buf_call(bufnr, function() + vim.cmd(':ownsyntax help') - pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid) - vim.cmd "norm! gg" - vim.fn.search(query, "W") + pcall(vim.fn.matchdelete, self.state.hl_id, self.state.winid) + vim.cmd "norm! gg" + vim.fn.search(query, "W") + vim.cmd "norm! zz" - self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', query) + self.state.hl_id = vim.fn.matchadd('TelescopePreviewMatch', query) + end) + end) end) end } @@ -337,36 +343,131 @@ end, {}) previewers.man = defaulter(function(_) return previewers.new_buffer_previewer { - define_preview = debounce.throttle_leading(function(self, entry, status) + get_buffer_by_name = function(_, entry) + return entry.value + end, + + define_preview = function(self, entry, status) putils.with_preview_window(status, nil, function() - local cmd = entry.value - local man_value = vim.fn['man#goto_tag'](cmd, '', '') - if #man_value == 0 then - print("No value for:", cmd) - return - end - - local filename = man_value[1].filename - if vim.api.nvim_buf_get_name(0) == filename then - return - end - - vim.api.nvim_command('view ' .. filename) - - vim.api.nvim_buf_set_option(self.state.bufnr, 'buftype', 'nofile') - vim.api.nvim_buf_set_option(self.state.bufnr, 'bufhidden', 'hide') - vim.api.nvim_buf_set_option(self.state.bufnr, 'swapfile', false) - vim.api.nvim_buf_set_option(self.state.bufnr, 'buflisted', false) - end) - end, 5) + local win_width = vim.api.nvim_win_get_width(self.state.winid) + putils.job_maker({'man', '-P', 'cat', entry.value}, + { ["MANWIDTH"] = win_width }, + entry.value, + self.state.bufnr, + self.state.bufname + ) + putils.regex_highlighter(_, 'man') + end) + end } end) +previewers.git_branch_log = defaulter(function(_) + return previewers.new_buffer_previewer { + get_buffer_by_name = function(_, entry) + return entry.value + end, + + define_preview = function(self, entry, status) + local highlight_buffer = function(bufnr, content) + if content and table.getn(content) == 0 then + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "No log found for branch: " .. entry.value }) + elseif content and table.getn(content) > 1 then + for i = 1, #content do + local line = content[i] + local _, hash_start = line:find('[%*%s|]*') + if hash_start then + local hash_end = hash_start + 7 + if hash_end < #line then + vim.api.nvim_buf_add_highlight(bufnr, + ns_previewer, + "TelescopeResultsIdentifier", + i - 1, + hash_start - 1, + hash_end + ) + end + end + local _, cur_start = line:find('- %(') + if cur_start then + local cur_end = string.find(line, '%) ') + vim.api.nvim_buf_add_highlight(bufnr, + ns_previewer, + "TelescopeResultsConstant", + i - 1, + cur_start - 1, + cur_end + ) + end + local date_start, _ = line:find(' %(%d') + if date_start then + vim.api.nvim_buf_add_highlight(bufnr, + ns_previewer, + "TelescopeResultsSpecialComment", + i - 1, + date_start, + #line + ) + end + end + end + end + + putils.with_preview_window(status, nil, function() + local cmd = { 'git', '-P', 'log', '--graph', '--pretty=format:%h -%d %s (%cr)', + '--abbrev-commit', '--date=relative', entry.value + } + putils.job_maker(cmd, nil, entry.value, self.state.bufnr, self.state.bufname, highlight_buffer) + end) + end + } +end, {}) + +previewers.git_commit_diff = defaulter(function(_) + return previewers.new_buffer_previewer { + get_buffer_by_name = function(_, entry) + return entry.value + end, + + define_preview = function(self, entry, status) + putils.with_preview_window(status, nil, function() + putils.job_maker({ 'git', '-P', 'diff', entry.value .. '^!' }, + nil, + entry.value, + self.state.bufnr, + self.state.bufname + ) + putils.regex_highlighter(_, 'diff') + end) + end + } +end, {}) + +previewers.git_file_diff = defaulter(function(_) + return previewers.new_buffer_previewer { + get_buffer_by_name = function(_, entry) + return entry.value + end, + + define_preview = function(self, entry, status) + putils.with_preview_window(status, nil, function() + putils.job_maker({ 'git', '-P', 'diff', entry.value }, + nil, + entry.value, + self.state.bufnr, + self.state.bufname + ) + putils.regex_highlighter(_, 'diff') + end) + end + } +end, {}) + previewers.autocommands = defaulter(function(_) return previewers.new_buffer_previewer { teardown = function(self) if self.state and self.state.last_set_bufnr and vim.api.nvim_buf_is_valid(self.state.last_set_bufnr) then - pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, previewer_ns, 0, -1) + pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, ns_previewer, 0, -1) end end, @@ -380,7 +481,7 @@ previewers.autocommands = defaulter(function(_) end, status.picker.finder.results) if self.state.last_set_bufnr then - pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, previewer_ns, 0, -1) + pcall(vim.api.nvim_buf_clear_namespace, self.state.last_set_bufnr, ns_previewer, 0, -1) end local selected_row = 0 @@ -412,7 +513,7 @@ previewers.autocommands = defaulter(function(_) end end - vim.api.nvim_buf_add_highlight(self.state.bufnr, previewer_ns, "TelescopePreviewLine", selected_row + 1, 0, -1) + vim.api.nvim_buf_add_highlight(self.state.bufnr, ns_previewer, "TelescopePreviewLine", selected_row + 1, 0, -1) vim.api.nvim_win_set_cursor(status.preview_win, {selected_row + 1, 0}) self.state.last_set_bufnr = self.state.bufnr @@ -424,11 +525,11 @@ previewers.highlights = defaulter(function(_) return previewers.new_buffer_previewer { teardown = function(self) if self.state and self.state.last_set_bufnr and vim.api.nvim_buf_is_valid(self.state.last_set_bufnr) then - vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, previewer_ns, 0, -1) + vim.api.nvim_buf_clear_namespace(self.state.last_set_bufnr, ns_previewer, 0, -1) end end, - get_buffer_by_name = function(_, entry) + get_buffer_by_name = function() return "highlights" end, @@ -457,13 +558,13 @@ previewers.highlights = defaulter(function(_) end end - pcall(vim.api.nvim_buf_clear_namespace, self.state.bufnr, previewer_ns, 0, -1) + pcall(vim.api.nvim_buf_clear_namespace, self.state.bufnr, ns_previewer, 0, -1) vim.cmd "norm! gg" vim.fn.search(entry.value .. ' ') local lnum = vim.fn.line('.') -- That one is actually a match but its better to use it like that then matchadd vim.api.nvim_buf_add_highlight(self.state.bufnr, - previewer_ns, + ns_previewer, "TelescopePreviewMatch", lnum - 1, 0, diff --git a/lua/telescope/previewers/init.lua b/lua/telescope/previewers/init.lua index 8074c65..b0f49c0 100644 --- a/lua/telescope/previewers/init.lua +++ b/lua/telescope/previewers/init.lua @@ -9,24 +9,25 @@ previewers.new = function(...) end previewers.new_termopen_previewer = term_previewer.new_termopen_previewer -previewers.git_commit_diff = term_previewer.git_commit_diff -previewers.git_branch_log = term_previewer.git_branch_log -previewers.git_file_diff = term_previewer.git_file_diff previewers.cat = term_previewer.cat previewers.vimgrep = term_previewer.vimgrep previewers.qflist = term_previewer.qflist -previewers.new_buffer_previewer = buffer_previewer.new_buffer_previewer -previewers.vim_buffer_cat = buffer_previewer.cat -previewers.vim_buffer_vimgrep = buffer_previewer.vimgrep -previewers.vim_buffer_qflist = buffer_previewer.qflist -previewers.ctags = buffer_previewer.ctags -previewers.builtin = buffer_previewer.builtin -previewers.help = buffer_previewer.help -previewers.man = buffer_previewer.man -previewers.autocommands = buffer_previewer.autocommands -previewers.highlights = buffer_previewer.highlights -previewers.display_content = buffer_previewer.display_content +previewers.new_buffer_previewer = buffer_previewer.new_buffer_previewer +previewers.buffer_previewer_maker = buffer_previewer.file_maker +previewers.vim_buffer_cat = buffer_previewer.cat +previewers.vim_buffer_vimgrep = buffer_previewer.vimgrep +previewers.vim_buffer_qflist = buffer_previewer.qflist +previewers.git_branch_log = buffer_previewer.git_branch_log +previewers.git_commit_diff = buffer_previewer.git_commit_diff +previewers.git_file_diff = buffer_previewer.git_file_diff +previewers.ctags = buffer_previewer.ctags +previewers.builtin = buffer_previewer.builtin +previewers.help = buffer_previewer.help +previewers.man = buffer_previewer.man +previewers.autocommands = buffer_previewer.autocommands +previewers.highlights = buffer_previewer.highlights +previewers.display_content = buffer_previewer.display_content previewers.Previewer = Previewer diff --git a/lua/telescope/previewers/term_previewer.lua b/lua/telescope/previewers/term_previewer.lua index 37f32ec..132cba0 100644 --- a/lua/telescope/previewers/term_previewer.lua +++ b/lua/telescope/previewers/term_previewer.lua @@ -187,15 +187,18 @@ previewers.new_termopen_previewer = function(opts) return opts.get_command(entry, st) else local env = {} + local cmd = opts.get_command(entry, st) + if not cmd then return end for k, v in pairs(termopen_env) do table.insert(env, k .. '=' .. v) end - return table.concat(env, ' ') .. ' ' .. table.concat(opts.get_command(entry, st), ' ') + return table.concat(env, ' ') .. ' ' .. table.concat(cmd, ' ') end end putils.with_preview_window(status, bufnr, function() - set_term_id(self, vim.fn.termopen(get_cmd(status), term_opts)) + local cmd = get_cmd(status) + if cmd then set_term_id(self, vim.fn.termopen(cmd, term_opts)) end end) vim.api.nvim_buf_set_name(bufnr, tostring(bufnr)) @@ -228,34 +231,6 @@ previewers.new_termopen_previewer = function(opts) return Previewer:new(opts) end -previewers.git_commit_diff = defaulter(function(_) - return previewers.new_termopen_previewer { - get_command = function(entry) - local sha = entry.value - return { 'git', '-p', 'diff', sha .. '^!' } - end - } -end, {}) - -previewers.git_branch_log = defaulter(function(_) - return previewers.new_termopen_previewer { - get_command = function(entry) - return { 'git', '-p', 'log', '--graph', - "--pretty=format:" .. add_quotes .. "%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset" - .. add_quotes, - '--abbrev-commit', '--date=relative', entry.value } - end - } -end, {}) - -previewers.git_file_diff = defaulter(function(_) - return previewers.new_termopen_previewer { - get_command = function(entry) - return { 'git', '-p', 'diff', entry.value } - end - } -end, {}) - previewers.cat = defaulter(function(opts) local maker = get_maker(opts) diff --git a/lua/telescope/previewers/utils.lua b/lua/telescope/previewers/utils.lua index ee70f42..d584577 100644 --- a/lua/telescope/previewers/utils.lua +++ b/lua/telescope/previewers/utils.lua @@ -1,5 +1,11 @@ local context_manager = require('plenary.context_manager') +local has_ts, _ = pcall(require, 'nvim-treesitter') +local _, ts_highlight = pcall(require, 'nvim-treesitter.highlight') +local _, ts_parsers = pcall(require, 'nvim-treesitter.parsers') + +local Job = require('plenary.job') + local utils = {} utils.with_preview_window = function(status, bufnr, callable) @@ -14,4 +20,50 @@ utils.with_preview_window = function(status, bufnr, callable) end end +-- API helper functions for buffer previewer +--- Job maker for buffer previewer +utils.job_maker = function(cmd, env, value, bufnr, bufname, callback) + if bufname ~= value then + local command = table.remove(cmd, 1) + Job:new({ + command = command, + args = cmd, + env = env, + on_exit = vim.schedule_wrap(function(j) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, j:result()) + if callback then callback(bufnr, j:result()) end + end) + }):start() + else + if callback then callback(bufnr) end + end +end + +--- Attach default highlighter which will choose between regex and ts +utils.highlighter = function(bufnr, ft) + if ft and ft ~= '' then + if has_ts and ts_parsers.has_parser(ft) then + ts_highlight.attach(bufnr, ft) + else + vim.cmd(':ownsyntax ' .. ft) + end + end +end + +--- Attach regex highlighter +utils.regex_highlighter = function(_, ft) + if ft and ft ~= '' then + vim.cmd(':ownsyntax ' .. ft) + end +end + +-- Attach ts highlighter +utils.ts_highlighter = function(bufnr, ft) + if ft and ft ~= '' then + if has_ts and ts_parsers.has_parser(ft) then + ts_highlight.attach(bufnr, ft) + end + end +end + return utils diff --git a/plugin/telescope.vim b/plugin/telescope.vim index 27450e9..268f01c 100644 --- a/plugin/telescope.vim +++ b/plugin/telescope.vim @@ -35,8 +35,10 @@ highlight default link TelescopeResultsStruct Struct highlight default link TelescopeResultsVariable SpecialChar highlight default link TelescopeResultsLineNr LineNr +highlight default link TelescopeResultsIdentifier Identifier highlight default link TelescopeResultsNumber Number highlight default link TelescopeResultsComment Comment +highlight default link TelescopeResultsSpecialComment SpecialComment " This is like "" in your terminal. " To use it, do `cmap (TelescopeFuzzyCommandSearch)