nvim-telescope / telescope.nvim

Find, Filter, Preview, Pick. All lua, all the time.
MIT License
16.06k stars 840 forks source link

uncolorized git diff commands #3130

Open sineptic opened 6 months ago

sineptic commented 6 months ago

Description

I use difftastic on my system as diff tool. When I call git diff in terminal output is colorized, but when I run :Telescope git_bcommits(or other command with preview) output only with 2 colors. I try to use difft --color=always, but telescope print escape symbols.

Neovim version

NVIM v0.10.0
Build type: Release
LuaJIT 2.1.1702233742

Operating system and version

OS: Arch Linux | Kernel: 6.8.5-arch1-1

Telescope version / branch / rev

telescope 0.1.7

checkhealth telescope

==============================================================================
telescope: health#telescope#check

Checking for required plugins ~
- OK plenary installed.
- OK nvim-treesitter installed.

Checking external dependencies ~
- OK rg: found ripgrep 14.1.0
- OK fd: found fd 10.1.0

===== Installed extensions ===== ~

Steps to reproduce

Expected behavior

  1. colorize diff
  2. don't print escape symbols

Actual behavior

opposite

Minimal config

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
  vim.fn.system({
    "git",
    "clone",
    "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git",
    "--branch=stable", -- latest stable release
    lazypath,
  })
end
vim.opt.rtp:prepend(lazypath)

require("lazy").setup({
    {
        'nvim-telescope/telescope.nvim',
        tag = '0.1.7',
        dependencies = {
            'nvim-lua/plenary.nvim'
        },
    },
})
etrobert commented 4 months ago

I'm also using difftastic as my diff tool and am looking into integrating it into telescope's diff preview 👀

meseck commented 4 months ago

This isn't actually a bug. Telescope's built-in pickers, such as git_bcommits and git_status uses Treesitter for syntax highlighting. In this instance, the default previewer attempts to treat the output as one of git diff without an external diff tool.

But this behavior can be fixed with a custom picker + previewer. Here is an example for a custom git_status picker:

custom_pickers.lua:

local builtin = require("telescope.builtin")
local previewers = require("telescope.previewers")
local from_entry = require("telescope.from_entry")
local utils = require("telescope.utils")

local git_command = utils.__git_command

local git_difftastic_previewer = function(opts)
  return previewers.new_termopen_previewer({
    title = "Git File Difftastic Preview",

    get_command = function(entry)
      local command = git_command({ "--no-pager", "diff" }, opts)

      if entry.status and (entry.status == "??" or entry.status == "A ") then
        local p = from_entry.path(entry, true, false)
        if p == nil or p == "" then
          return
        end
        table.insert(command, { "--no-index", "/dev/null" })
      else
        table.insert(command, { "HEAD", "--" })
      end

      return utils.flatten({
        command,
        entry.value,
      })
    end,

    scroll_fn = function(self, direction)
      if not self.state then
        return
      end

      local bufnr = self.state.termopen_bufnr
      -- 0x05 -> <C-e>; 0x19 -> <C-y>
      local input = direction > 0 and string.char(0x05) or string.char(0x19)
      local count = math.abs(direction)

      vim.api.nvim_win_call(vim.fn.bufwinid(bufnr), function()
        vim.cmd([[normal! ]] .. count .. input)
      end)
    end,
  })
end

local M = {}

M.git_status_difftastic_picker = function(opts)
  opts = opts or {}
  opts.previewer = git_difftastic_previewer(opts)

  builtin.git_status(opts)
end

return M

As with delta, see this issue: https://github.com/nvim-telescope/telescope.nvim/issues/605 There is a problem with the scrolling input (Ctrl-d + Ctrl-u). I'm not sure why, but the default scroll_fn function of previewers.new_termopen_previewer, which normally sends terminal codes to the running process, simply doesn't work. Because of this, I added a small workaround. Does anyone have any other ideas to fix this?

If you want to change, for example, difftastic's layout to inline, you can do so by adding an environment variable to the default Telescope configuration.

require("telescope").setup({
  defaults = {
    set_env = {
      DFT_DISPLAY = "inline",
    },
  ...
  }
})
etrobert commented 4 months ago

Very interesting thank you, I've been able to run it locally. Will dig deeper later 🙏

shelper commented 2 months ago

I'm also using difftastic as my diff tool and am looking into integrating it into telescope's diff preview 👀 did you find any update or implemenation for this integration? it can be manually configured as mentioned but it's lot of customization lines ...