Code Monkey home page Code Monkey logo

dressing.nvim's Introduction

Dressing.nvim

With the release of Neovim 0.6 we were given the start of extensible core UI hooks (vim.ui.select and vim.ui.input). They exist to allow plugin authors to override them with improvements upon the default behavior, so that's exactly what we're going to do.

It is a goal to match and not extend the core Neovim API. All options that core respects will be respected, and we will not accept any custom parameters or options in the functions. Customization will be done entirely using a separate configuration method.

Requirements

Neovim 0.5+

On versions prior to 0.6, this plugin will act as a polyfill for vim.ui

Screenshots

vim.input replacement (handling a LSP rename)

Screenshot from 2021-12-09 17-36-16

vim.select (telescope)

Screenshot from 2021-12-02 19-46-01

vim.select (fzf)

Screenshot from 2021-12-02 19-46-54

vim.select (nui)

Screenshot from 2021-12-02 19-47-56

vim.select (built-in)

Screenshot from 2021-12-04 17-14-32

Installation

dressing.nvim supports all the usual plugin managers

Packer
require('packer').startup(function()
    use {'stevearc/dressing.nvim'}
end)
Paq
require "paq" {
    {'stevearc/dressing.nvim'};
}
vim-plug
Plug 'stevearc/dressing.nvim'
dein
call dein#add('stevearc/dressing.nvim')
Pathogen
git clone --depth=1 https://github.com/stevearc/dressing.nvim.git ~/.vim/bundle/
Neovim native package
git clone --depth=1 https://github.com/stevearc/dressing.nvim.git \
  "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/pack/dressing.nvim/start/dressing.nvim

Configuration

If you're fine with the defaults, you're good to go after installation. If you want to tweak, call this function:

require('dressing').setup({
  input = {
    -- Set to false to disable the vim.ui.input implementation
    enabled = true,

    -- Default prompt string
    default_prompt = "Input:",

    -- Can be 'left', 'right', or 'center'
    prompt_align = "left",

    -- When true, <Esc> will close the modal
    insert_only = true,

    -- These are passed to nvim_open_win
    anchor = "SW",
    border = "rounded",
    -- 'editor' and 'win' will default to being centered
    relative = "cursor",

    -- These can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
    prefer_width = 40,
    width = nil,
    -- min_width and max_width can be a list of mixed types.
    -- min_width = {20, 0.2} means "the greater of 20 columns or 20% of total"
    max_width = { 140, 0.9 },
    min_width = { 20, 0.2 },

    -- Window transparency (0-100)
    winblend = 10,
    -- Change default highlight groups (see :help winhl)
    winhighlight = "",

    override = function(conf)
      -- This is the config that will be passed to nvim_open_win.
      -- Change values here to customize the layout
      return conf
    end,

    -- see :help dressing_get_config
    get_config = nil,
  },
  select = {
    -- Set to false to disable the vim.ui.select implementation
    enabled = true,

    -- Priority list of preferred vim.select implementations
    backend = { "telescope", "fzf_lua", "fzf", "builtin", "nui" },

    -- Options for telescope selector
    -- These are passed into the telescope picker directly. Can be used like:
    -- telescope = require('telescope.themes').get_ivy({...})
    telescope = nil,

    -- Options for fzf selector
    fzf = {
      window = {
        width = 0.5,
        height = 0.4,
      },
    },

    -- Options for fzf_lua selector
    fzf_lua = {
      winopts = {
        width = 0.5,
        height = 0.4,
      },
    },

    -- Options for nui Menu
    nui = {
      position = "50%",
      size = nil,
      relative = "editor",
      border = {
        style = "rounded",
      },
      max_width = 80,
      max_height = 40,
    },

    -- Options for built-in selector
    builtin = {
      -- These are passed to nvim_open_win
      anchor = "NW",
      border = "rounded",
      -- 'editor' and 'win' will default to being centered
      relative = "editor",

      -- Window transparency (0-100)
      winblend = 10,
      -- Change default highlight groups (see :help winhl)
      winhighlight = "",

      -- These can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
      -- the min_ and max_ options can be a list of mixed types.
      -- max_width = {140, 0.8} means "the lesser of 140 columns or 80% of total"
      width = nil,
      max_width = { 140, 0.8 },
      min_width = { 40, 0.2 },
      height = nil,
      max_height = 0.9,
      min_height = { 10, 0.2 },

      override = function(conf)
        -- This is the config that will be passed to nvim_open_win.
        -- Change values here to customize the layout
        return conf
      end,
    },

    -- Used to override format_item. See :help dressing-format
    format_item_override = {},

    -- see :help dressing_get_config
    get_config = nil,
  },
})

Advanced configuration

For each of the input and select configs, there is an option get_config. This can be a function that accepts the opts parameter that is passed in to vim.select or vim.input. It must return either nil (to no-op) or config values to use in place of the global config values for that module.

For example, if you want to use a specific configuration for code actions:

require('dressing').setup({
  select = {
    get_config = function(opts)
      if opts.kind == 'codeaction' then
        return {
          backend = 'nui',
          nui = {
            relative = 'cursor',
            max_width = 40,
          }
        }
      end
    end
  }
})

Notes for plugin authors

TL;DR: you can customize the telescope vim.ui.select implementation by passing telescope into opts.

The vim.ui hooks are a great boon for us because we can now assume that users will have a reasonable UI available for simple input operations. We no longer have to build separate implementations for each of fzf, telescope, ctrlp, etc. The tradeoff is that vim.ui.select is less customizable than any of these options, so if you wanted to have a preview window (like telescope supports), it is no longer an option.

My solution to this is extending the opts that are passed to vim.ui.select. You can add a telescope field that will be passed directly into the picker, allowing you to customize any part of the UI. If a user has both dressing and telescope installed, they will get your custom picker UI. If either of those are not true, the selection UI will gracefully degrade to whatever the user has configured for vim.ui.select.

An example of usage:

vim.ui.select({'apple', 'banana', 'mango'}, {
  prompt = "Title",
  telescope = require("telescope.themes").get_cursor(),
}, function(selected) end)

For now this is available only for the telescope backend, but feel free to request additions.

Alternative and related projects

  • telescope-ui-select - provides a vim.ui.select implementation for telescope
  • nvim-fzy - fzf alternative that also provides a vim.ui.select implementation (#13)
  • guihua.lua - multipurpose GUI library that provides vim.ui.select and vim.ui.input implementations
  • nvim-notify - doing pretty much the same thing but for vim.notify
  • nui.nvim - provides common UI components for plugin authors

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.