From e08a5b13312495fe6534b0c9b89cc0ffe06b7079 Mon Sep 17 00:00:00 2001 From: Simon Hauser Date: Fri, 15 Jan 2021 09:27:46 +0100 Subject: [PATCH] feat: show git log for remote branches (#428) --- lua/telescope/builtin/git.lua | 16 ++-- lua/telescope/builtin/internal.lua | 9 +- lua/telescope/pickers/_test.lua | 2 +- lua/telescope/previewers/buffer_previewer.lua | 94 +++++++++---------- lua/telescope/previewers/term_previewer.lua | 4 +- lua/telescope/utils.lua | 11 ++- 6 files changed, 65 insertions(+), 71 deletions(-) diff --git a/lua/telescope/builtin/git.lua b/lua/telescope/builtin/git.lua index c2d31c6..c30625e 100644 --- a/lua/telescope/builtin/git.lua +++ b/lua/telescope/builtin/git.lua @@ -28,8 +28,7 @@ git.files = function(opts) end git.commits = function(opts) - local cmd = 'git log --pretty=oneline --abbrev-commit' - local results = vim.split(utils.get_os_command_output(cmd), '\n') + local results = utils.get_os_command_output({ 'git', 'log', '--pretty=oneline', '--abbrev-commit' }) pickers.new(opts, { prompt_title = 'Git Commits', @@ -47,8 +46,9 @@ git.commits = function(opts) end git.bcommits = function(opts) - local cmd = 'git log --pretty=oneline --abbrev-commit ' .. vim.fn.expand('%') - local results = vim.split(utils.get_os_command_output(cmd), '\n') + local results = utils.get_os_command_output({ + 'git', 'log', '--pretty=oneline', '--abbrev-commit', vim.fn.expand('%') + }) pickers.new(opts, { prompt_title = 'Git BCommits', @@ -68,7 +68,7 @@ end git.branches = function(opts) -- Does this command in lua (hopefully): -- 'git branch --all | grep -v HEAD | sed "s/.* //;s#remotes/[^/]*/##" | sort -u' - local output = vim.split(utils.get_os_command_output('git branch --all'), '\n') + local output = utils.get_os_command_output({ 'git', 'branch', '--all' }) local tmp_results = {} for _, v in ipairs(output) do @@ -106,9 +106,9 @@ git.branches = function(opts) end git.status = function(opts) - local output = utils.get_os_command_output('git status -s') + local output = utils.get_os_command_output{ 'git', 'status', '-s' } - if output == '' then + if table.getn(output) == 0 then print('No changes found') return end @@ -116,7 +116,7 @@ git.status = function(opts) pickers.new(opts, { prompt_title = 'Git Status', finder = finders.new_table { - results = vim.split(output, '\n'), + results = output, entry_maker = make_entry.gen_from_git_status(opts) }, previewer = previewers.git_file_diff.new(opts), diff --git a/lua/telescope/builtin/internal.lua b/lua/telescope/builtin/internal.lua index bc23b69..434ae78 100644 --- a/lua/telescope/builtin/internal.lua +++ b/lua/telescope/builtin/internal.lua @@ -403,17 +403,12 @@ internal.help_tags = function(opts) end internal.man_pages = function(opts) - local pages = utils.get_os_command_output(opts.man_cmd or "apropos --sections=1 ''") - - local lines = {} - for s in pages:gmatch("[^\r\n]+") do - table.insert(lines, s) - end + local pages = utils.get_os_command_output(opts.man_cmd or { 'apropos', '--sections=1', '' }) pickers.new(opts, { prompt_title = 'Man', finder = finders.new_table { - results = lines, + results = pages, entry_maker = opts.entry_maker or make_entry.gen_from_apropos(opts), }, previewer = previewers.man.new(opts), diff --git a/lua/telescope/pickers/_test.lua b/lua/telescope/pickers/_test.lua index 1ab5a97..eeb9823 100644 --- a/lua/telescope/pickers/_test.lua +++ b/lua/telescope/pickers/_test.lua @@ -155,7 +155,7 @@ local get_results_from_file = function(file) }, } - j:sync(1000) + j:sync(10000) local results = j:stderr_result() local result_table = {} diff --git a/lua/telescope/previewers/buffer_previewer.lua b/lua/telescope/previewers/buffer_previewer.lua index 82ea040..1f267e6 100644 --- a/lua/telescope/previewers/buffer_previewer.lua +++ b/lua/telescope/previewers/buffer_previewer.lua @@ -24,11 +24,10 @@ previewers.file_maker = function(filepath, bufnr, opts) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.split(data, '[\r]?\n')) if opts.callback then opts.callback(bufnr) end - if not opts.state or bufnr == opts.state.bufnr then putils.highlighter(bufnr, ft) end + putils.highlighter(bufnr, ft) end)) else if opts.callback then opts.callback(bufnr) end - if not opts.state or bufnr == opts.state.bufnr then putils.highlighter(bufnr, ft) end end end @@ -159,8 +158,7 @@ previewers.cat = defaulter(function(_) local p = from_entry.path(entry, true) if p == nil or p == '' then return end conf.buffer_previewer_maker(p, self.state.bufnr, { - bufname = self.state.bufname, - state = self.state, + bufname = self.state.bufname }) end } @@ -195,11 +193,11 @@ previewers.vimgrep = defaulter(function(_) conf.buffer_previewer_maker(p, self.state.bufnr, { bufname = self.state.bufname, - state = self.state, callback = 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}) + vim.api.nvim_buf_call(bufnr, function() vim.cmd"norm! zz" end) end self.state.last_set_bufnr = bufnr @@ -369,63 +367,61 @@ previewers.man = defaulter(function(_) end) previewers.git_branch_log = defaulter(function(_) + local highlight_buffer = function(bufnr, content) + for i = 1, #content do + local line = content[i] + local _, hstart = line:find('[%*%s|]*') + if hstart then + local hend = hstart + 7 + if hend < #line then + vim.api.nvim_buf_add_highlight(bufnr, ns_previewer, "TelescopeResultsIdentifier", i - 1, hstart - 1, hend) + end + end + local _, cstart = line:find('- %(') + if cstart then + local cend = string.find(line, '%) ') + vim.api.nvim_buf_add_highlight(bufnr, ns_previewer, "TelescopeResultsConstant", i - 1, cstart - 1, cend) + end + local dstart, _ = line:find(' %(%d') + if dstart then + vim.api.nvim_buf_add_highlight(bufnr, ns_previewer, "TelescopeResultsSpecialComment", i - 1, dstart, #line) + end + end + end + + local remotes = utils.get_os_command_output{ 'git', 'remote' } 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) + local current_remote = 1 + + local gen_cmd = function(v) + return { 'git', '-P', 'log', '--graph', '--pretty=format:%h -%d %s (%cr)', + '--abbrev-commit', '--date=relative', v } + end + + local handle_results + handle_results = 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 + if current_remote <= table.getn(remotes) then + local value = 'remotes/' .. remotes[current_remote] .. '/' .. entry.value + current_remote = current_remote + 1 + putils.job_maker(gen_cmd(value), bufnr, { callback = handle_results }) + else + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "No log found for branch: " .. entry.value }) end + elseif content and table.getn(content) > 1 then + highlight_buffer(bufnr, content) end end - local cmd = { 'git', '-P', 'log', '--graph', '--pretty=format:%h -%d %s (%cr)', - '--abbrev-commit', '--date=relative', entry.value - } - putils.job_maker(cmd, self.state.bufnr, { + putils.job_maker(gen_cmd(entry.value), self.state.bufnr, { value = entry.value, bufname = self.state.bufname, - callback = highlight_buffer + callback = handle_results }) end } diff --git a/lua/telescope/previewers/term_previewer.lua b/lua/telescope/previewers/term_previewer.lua index 28e19e1..94bd5e0 100644 --- a/lua/telescope/previewers/term_previewer.lua +++ b/lua/telescope/previewers/term_previewer.lua @@ -77,8 +77,8 @@ local cat_maker = function(filename, _, start, _) end if 1 == vim.fn.executable('file') then - local output = utils.get_os_command_output('file --mime-type -b ' .. filename) - local mime_type = vim.split(output, '/')[1] + local output = utils.get_os_command_output{ 'file', '--mime-type', '-b', filename } + local mime_type = vim.split(output[1], '/')[1] if mime_type ~= "text" then return { "echo", "Binary file found. These files cannot be displayed!" } end diff --git a/lua/telescope/utils.lua b/lua/telescope/utils.lua index e1ef7f3..913c9a2 100644 --- a/lua/telescope/utils.lua +++ b/lua/telescope/utils.lua @@ -1,4 +1,5 @@ local pathlib = require('telescope.path') +local Job = require('plenary.job') local utils = {} @@ -193,10 +194,12 @@ function utils.display_termcodes(str) end function utils.get_os_command_output(cmd) - local handle = assert(io.popen(cmd, 'r')) - local output = assert(handle:read('*a')) - assert(handle:close()) - return output + if type(cmd) ~= "table" then + print('Telescope: [get_os_command_output]: cmd has to be a table') + return {} + end + local command = table.remove(cmd, 1) + return Job:new({ command = command, args = cmd }):sync() end return utils