Git Product home page Git Product logo

actions-preview.nvim's Introduction

actions-preview.nvim

actions-preview.mp4

A neovim plugin that preview code with LSP code actions applied.

The following backends are available:

Installation

Using packer.nvim:

use {
  "aznhe21/actions-preview.nvim",
  config = function()
    vim.keymap.set({ "v", "n" }, "gf", require("actions-preview").code_actions)
  end,
}

Configuration

You can customize preview using setup function if you need it.

Default configuration:

require("actions-preview").setup {
  -- options for vim.diff(): https://neovim.io/doc/user/lua.html#vim.diff()
  diff = {
    ctxlen = 3,
  },

  -- priority list of external command to highlight diff
  -- disabled by defalt, must be set by yourself
  highlight_command = {
    -- require("actions-preview.highlight").delta(),
    -- require("actions-preview.highlight").diff_so_fancy(),
    -- require("actions-preview.highlight").diff_highlight(),
  },

  -- priority list of preferred backend
  backend = { "telescope", "nui" },

  -- options related to telescope.nvim
  telescope = vim.tbl_extend(
    "force",
    -- telescope theme: https://github.com/nvim-telescope/telescope.nvim#themes
    require("telescope.themes").get_dropdown(),
    -- a table for customizing content
    {
      -- a function to make a table containing the values to be displayed.
      -- fun(action: Action): { title: string, client_name: string|nil }
      make_value = nil,

      -- a function to make a function to be used in `display` of a entry.
      -- see also `:h telescope.make_entry` and `:h telescope.pickers.entry_display`.
      -- fun(values: { index: integer, action: Action, title: string, client_name: string }[]): function
      make_make_display = nil,
    }
  ),

  -- options for nui.nvim components
  nui = {
    -- component direction. "col" or "row"
    dir = "col",
    -- keymap for selection component: https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/menu#keymap
    keymap = nil,
    -- options for nui Layout component: https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/layout
    layout = {
      position = "50%",
      size = {
        width = "60%",
        height = "90%",
      },
      min_width = 40,
      min_height = 10,
      relative = "editor",
    },
    -- options for preview area: https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/popup
    preview = {
      size = "60%",
      border = {
        style = "rounded",
        padding = { 0, 1 },
      },
    },
    -- options for selection area: https://github.com/MunifTanjim/nui.nvim/tree/main/lua/nui/menu
    select = {
      size = "40%",
      border = {
        style = "rounded",
        padding = { 0, 1 },
      },
    },
  },
}

An example of customizing diff algorithms and telescope appearance.

require("actions-preview").setup {
  diff = {
    algorithm = "patience",
    ignore_whitespace = true,
  },
  telescope = require("telescope.themes").get_dropdown { winblend = 10 },
}

highlight_command

actions-preview-delta

You can highlight diff with an external command by setting this item. This item is a priority list, which searches for available commands from the top.

NOTE for Windows users: This feature only works with PowerShell and does not operate with cmd.exe. Therefore, you need to setup your neovim to use PowerShell by following the instructions in :help shell-powershell.

local hl = require("actions-preview.highlight")
require("actions-preview").setup {
  highlight_command = {
    -- Highlight diff using delta: https://github.com/dandavison/delta
    -- The argument is optional, in which case "delta" is assumed to be
    -- specified.
    hl.delta("path/to/delta --option1 --option2"),
    -- You may need to specify "--no-gitconfig" since it is dependent on
    -- the gitconfig of the project by default.
    -- hl.delta("delta --no-gitconfig --side-by-side"),

    -- Highlight diff using diff-so-fancy: https://github.com/so-fancy/diff-so-fancy
    -- The arguments are optional, in which case ("diff-so-fancy", "less -R")
    -- is assumed to be specified. The existence of less is optional.
    hl.diff_so_fancy("path/to/diff-so-fancy --option1 --option2"),

    -- Highlight diff using diff-highlight included in git-contrib.
    -- The arguments are optional; the first argument is assumed to be
    -- "diff-highlight" and the second argument is assumed to be 
    -- `{ colordiff = "colordiff", pager = "less -R" }`. The existence of
    -- colordiff and less is optional.
    hl.diff_highlight(
      "path/to/diff-highlight",
      { colordiff = "path/to/colordiff" }
    ),

    -- And, you can use any command to highlight diff.
    -- Define the pipeline by `hl.commands`.
    hl.commands({
      { cmd = "command-to-diff-highlight" },
      -- `optional` can be used to define that the command is optional.
      { cmd = "less -R", optional = true },
    }),
    -- If you use optional `less -R` (or similar command), you can also use `hl.with_pager`.
    hl.with_pager("command-to-diff-highlight"),
    -- hl.with_pager("command-to-diff-highlight", "custom-pager"),
  },
}

FAQ

How to make it look like README (above)?

Here is a config to reproduce the README.

require("actions-preview").setup {
  telescope = {
    sorting_strategy = "ascending",
    layout_strategy = "vertical",
    layout_config = {
      width = 0.8,
      height = 0.9,
      prompt_position = "top",
      preview_cutoff = 20,
      preview_height = function(_, _, max_lines)
        return max_lines - 15
      end,
    },
  },
}

Why do I get Preview is not available for this action instead of a diff?

TL;DR: Because of implementation limitations in some language servers. It is not possible to compute and display diffs in these language servers.

Unfortunately, some language servers realize Code Actions by means of Command, which can perform any operation, instead of TextEdit, which notifies text changes. In these language servers, we cannot get the result of text changes by a Code Action, and as a result, we cannot compute and display diffs.

Acknowledgements

LICENSE

This project itself is distributed under GPLv3. However, this project includes the neovim code, which is distributed under the Apache License 2.0.

actions-preview.nvim's People

Contributors

aznhe21 avatar daver32 avatar krakn-dev avatar uga-rosa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

actions-preview.nvim's Issues

What is needed to see a diff?

I get action descriptions where I'd expect to see a diff:

╭──────────────────────────── Code Action Preview ─────────────────────────────╮
│Command: Inline method/variable/parameter (pylsp_rope.refactor.inline)        │

This is the case for both telescope and nui backends.
Am I missing some configuration step?

Support selecting edits

Is it possible to deselect and select the diffs? Like this list from VS Code to select and deselect which hunks should be applied.

image

Support to Code Lens

Many plugins are great showing the action but something that they are missing is the capability to do the same in CodeLens, would be great if this plugin do that

Missing the default config for the telescope

After the latest update, there are some changes when selecting operation with the telescope plugin, but the telescope item in the default config is nil value as below pic. That will throw an error after updating the Plugin

image

Unable to get highlight_command to work on Windows

Hi, thank you for making this extension! I'm struggling to get highlight_command to work with delta or diff_so_fancy. Here's my config:

  "aznhe21/actions-preview.nvim",
  config = function()
    local hl = require "actions-preview.highlight"
    require("actions-preview").setup {
      highlight_command = {
        hl.delta(),
        hl.diff_so_fancy(),
      },
      telescope = {
        sorting_strategy = "ascending",
        layout_strategy = "vertical",
        layout_config = {
          width = 0.8,
          height = 0.9,
          prompt_position = "top",
          preview_cutoff = 20,
          preview_height = function(_, _, max_lines)
            return max_lines - 15
          end,
        },
      },
    }
  end,

I installed delta and diff_so_fancy via scoop and I can run them in the command line. When I try to run code_actions() this is what I see:
Screenshot 2024-02-06 164532

Default configuration works fine though so it's not a big deal. Thanks again!

Support to Delta

Would be amazing to change the output from diff to delta, if there's any way, let me know,
An example:
Captura de Tela 2023-12-21 às 16 10 16

Error on unsupported LSPs

Hey, just tried your plugin and I got this with Omnisharp (which does not support preview) :

Error executing vim.schedule lua callback: ...t/vimplugin-lsp-zero.nvim/lua/actions-preview/action.lua:
200: bad argument #1 to 'pairs' (table expected, got nil)
stack traceback:
        [C]: in function 'pairs'
        ...t/vimplugin-lsp-zero.nvim/lua/actions-preview/action.lua:200: in function 'diff_workspace_ed
it'
        ...t/vimplugin-lsp-zero.nvim/lua/actions-preview/action.lua:276: in function 'callback'
        ...t/vimplugin-lsp-zero.nvim/lua/actions-preview/action.lua:250: in function 'resolve'
        ...t/vimplugin-lsp-zero.nvim/lua/actions-preview/action.lua:272: in function 'preview'
        ...-lsp-zero.nvim/lua/actions-preview/backend/telescope.lua:23: in function 'define_preview'
        ...scope.nvim/lua/telescope/previewers/buffer_previewer.lua:388: in function 'preview'
        ...mPackages/start/telescope.nvim/lua/telescope/pickers.lua:1075: in function 'refresh_previewe
r'
        ...mPackages/start/telescope.nvim/lua/telescope/pickers.lua:1028: in function 'set_selection'
        ...mPackages/start/telescope.nvim/lua/telescope/pickers.lua:1360: in function '_do_selection'
        ...mPackages/start/telescope.nvim/lua/telescope/pickers.lua:1322: in function ''
        vim/_editor.lua: in function <vim/_editor.lua:0>

vim.lsp.util.parse_snippet is deprecated

Thanks for the amazing plugin! I've been using it for a long time.

Just for your information, it seems that vim.lsp.util.parse_snippet is deprecated in nightly Neovim, and your plugin now shows the following message:

vim.lsp.util.parse_snippet is deprecated :help deprecated
This feature will be removed in Nvim version 0.11

Which is quite annoying, but nothing that prevents the plugin from working.

See neovim/neovim#25733 for the actual deprecation. I see that in nvim-cmp (hrsh7th/nvim-cmp#1734) they simply removed the deprecated code; but I'm not sure if this plugin requires it for something... as such I will leave the decision of what to do, up to you :-)

Window size

The window size that pops up for me is on the smaller side and cuts off the diff. I had to make some adjustments to make everything fit.

using lazy nvim:

return {
  "aznhe21/actions-preview.nvim",
  config = function()
    require("actions-preview").setup {
      diff = {
        ctxlen = 3,
      },
      -- priority list of preferred backend
      backend = { "telescope" },
      -- options for telescope.nvim: https://github.com/nvim-telescope/telescope.nvim#themes
      telescope = require("telescope.themes").get_dropdown({
        layout_strategy = "center",
        layout_config = {
          height = function(_, _, max_lines)
            return math.min(max_lines, 30)
          end
        }
      }),
    }

    vim.keymap.set({ "v", "n" }, "gf", require("actions-preview").code_actions)
  end,
}

How can I get mine to look like the preview in the README?

Code deduplication of `vim.lsp.util.apply_text_edits`

Hi @aznhe21 and ty for this plugin!

I was recently acquainted with it as part of a feature request for my plugin ibhagwan/fzf-lua#944.

As part of the implementation I reused your diff generation code (with proper credit in the commit/comments) ibhagwan/fzf-lua@b3b05f9.

While doing so I noticed you created your own version of vim.lsp.util.apply_text_edits that applies the edits to lines input (instead of the original buffer argument):

local function apply_text_edits(text_edits, lines, offset_encoding)

I personally try to avoid duping vim code whenever possible and rely on the runtime in case the logic is changed in the future (bug fixes, etc). In my implementation I opted for reusing the runtime code by creating a temp buffer (with the original lines in its contents) and thus I am able to call vim.lsp.util.apply_text_edits directly:

So instead of:

local function diff_text_edits(text_edits, bufnr, offset_encoding)
local eol = get_eol(bufnr)
local lines = get_lines(bufnr)
local old_text = table.concat(lines, eol)
apply_text_edits(text_edits, lines, offset_encoding)
return vim.diff(old_text .. "\n", table.concat(lines, eol) .. "\n", config.diff)
end

I use:

local function diff_text_edits(text_edits, bufnr, offset_encoding, diff_opts)
  local eol = get_eol(bufnr)
  local orig_lines = get_lines(bufnr)
  local tmpbuf = vim.api.nvim_create_buf(false, true)
  vim.api.nvim_buf_set_lines(tmpbuf, 0, -1, false, orig_lines)
  vim.lsp.util.apply_text_edits(text_edits, tmpbuf, offset_encoding)
  local new_lines = get_lines(tmpbuf)
  vim.api.nvim_buf_delete(tmpbuf, { force = true })
  local diff = vim.diff(
    table.concat(orig_lines, eol) .. eol,
    table.concat(new_lines, eol) .. eol,
    diff_opts)
  return utils.strsplit(vim.trim(diff), eol)
end

Thought you might be interested should you decide to take a similar approach one day.

Hopefully this helps and thanks again!

Not displaying all code actions.

I started using this plugin with nvim-lightbulb. Figure out that sometimes lightbulb appears, but actions-preview showing "No Actions".

What I found:

  • vim.lsp.buf.code_action() - also return 'No actions'
  • require('nvim-lightbulb').debug({}) - returns:
[Code Actions]
i   No code action support: copilot
i With code action support: lua_ls

lua_ls
1. Disable diagnostics in the workspace (undefined-global). quickfix
2. Disable diagnostics on this line (undefined-global). quickfix
3. Disable diagnostics in this file (undefined-global). quickfix
  • nvim-code-action-menu - can show those actions with no problem.

The question is why builtin function don't show all actions while external plugin can?
Just guessing but, this plugin using vim.lsp.buf.code_action() to fetch actions right?

Thanks for help.

Don't override default telescope theme

Currently when using the telescope backend the theme is overriden unless specified. However, I use a global theme on my telescope install which is thus ignored.

local opts = vim.deepcopy(config) or require("telescope.themes").get_dropdown()

A simple fix would be to simply just put in {} if no config exists, which is also the current work around:

require("actions-preview").setup {
  telescope = {}
}

This way users can still specify what they want, but if they have global defaults they don't get removed.

Code Action Preview Not Working

The code action preview just show the string same as code actions. See the screenshot:
issue

I use lazy.nvim to install plugin.
My config:

   {
      "aznhe21/actions-preview.nvim",
      config = function()
         vim.keymap.set(
            { "v", "n" },
            "<Leader>ca",
            require("actions-preview").code_actions
         )
      end,
   },

Support refactor/rename

Have you thought about also supporting refactor/rename? It supports the same mechanism as code actions and it would be really nice to also have it!

Adding custom code actions

Can I somehow create my own "code action"? (not based on lsp, just an entry that will show up under certain circumstances in the list of available actions)

I guess I should use one of make_value / make_make_display fields, but am not sure how

Opening a preview of ALL code actions for current buffer

Hey, thanks for the plugin, works like a charm !

However, before switching to the builtin LSP, I used CoC with a bunch of plugins (mostly TypeScript oriented stuff) and I had a handy shortcut that would either:

  • Show code actions for what was under the cursor if there was any
  • Show code actions for the whole document if nothing under cursor had actions available

There would be actions that save a lot of time like "Delete all unused imports" in TS, instead of having to go through a list of all of them and deleting them one by one.

Currently, when trying to open actions-preview on a random part of the document with no quickfix simply yields "No code action available".

I tried going Visual mode and selecting the whole document then opening the actions menu, but sadly it didn't have the expected results, most likely because the LSP is trying to find something to do with that whole bunch of text instead of proposing a list of all individual quickfixes. 🤔

So, would there be a way to display all actions including the ones that are not specific to a specific symbol under cursor ?

Is it still possible to disable the diff previewer?

Hi, thanks for the plugin.

I'm currently using the get_cursor theme from telescope. Sometimes the diff window becomes too bulky and overlaps with options from the actions menu:

image

Hence I would like to disable the diff preview sometimes. A month ago this could be achieved by the following configuration, by passing false to previewer option:

require('actions-preview').setup { telescope = require('telescope.themes').get_cursor { previewer = false } }
Screenshot 2024-02-23 at 9 30 30 pm

Which unfortunately does not work anymore since e4aa224. With the same configuration, the code actions menu pops up still, but selecting an option gives the following error:

Error executing lua callback: ...s-preview.nvim/lua/actions-preview/backend/telescope.lua:100: attempt to index field 'state' (a nil value)
stack traceback:
	...s-preview.nvim/lua/actions-preview/backend/telescope.lua:100: in function '_teardown_func'
	...zy/telescope.nvim/lua/telescope/previewers/previewer.lua:78: in function 'teardown'
	...share/nvim/lazy/telescope.nvim/lua/telescope/pickers.lua:1486: in function 'on_close_prompt'
	...share/nvim/lazy/telescope.nvim/lua/telescope/pickers.lua:531: in function <...share/nvim/lazy/telescope.nvim/lua/telescope/pickers.lua:530>

A similar error would also arise when trying to quit/close the popup.

Here's an animation showing the chaos:

Screen.Recording.2024-02-23.at.9.37.25.pm.mov

Having these said I guess that's definitely not how things work now. Is it still possible to disable the diff previewer? If yes, then what would be the correct way to setup so?

Thanks again for your efforts and devotion in the plugin. If you need more information please let me know.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.