hrsh7th / nvim-cmp

A completion plugin for neovim coded in Lua.
MIT License
7.53k stars 377 forks source link

Simple markdown support #1699

Open FormalSnake opened 10 months ago

FormalSnake commented 10 months ago

FAQ

Announcement

Minimal reproducible full config

not relevant but

local cmp = require "cmp"

require("luasnip.loaders.from_vscode").lazy_load()

local formatting_style = {
    -- default fields order i.e completion word + item.kind + item.kind icons
    fields = { "abbr", "kind", "menu" },
    format = require('tailwindcss-colorizer-cmp').formatter,
}

local function border(hl_name)
    return {
        { "╭", hl_name },
        { "─", hl_name },
        { "╮", hl_name },
        { "│", hl_name },
        { "╯", hl_name },
        { "─", hl_name },
        { "╰", hl_name },
        { "│", hl_name },
    }
end

local icons = {
    Text = "󰉿",
    Variable = "󰜢",
    Snippet = "",
    Function = "󰊕",
    Keyword = "󰌋",
    Field = "",
    Property = "",
    Enum = "",
}
local options = {
    completion = {
        completeopt = "menu,menuone",
    },

    window = {
        completion = {
            side_padding = 0,
            winhighlight = "Normal:CmpPmenu,CursorLine:PmenuSel,Search:PmenuSel",
            scrollbar = true,
            border = border "CmpDocBorder",
        },
        documentation = {
            border = border "CmpDocBorder",
            winhighlight = "Normal:CmpDoc",
        },
    },
    snippet = {
        expand = function(args)
            require("luasnip").lsp_expand(args.body)
        end,
    },

    -- formatting = formatting_style,
    formatting = {
        format = function(_, vim_item)
            vim_item.kind = icons[vim_item.kind] .. " " .. vim_item.kind or vim_item.kind
            return vim_item
        end,
    },
    mapping = {
        ["<C-p>"] = cmp.mapping.select_prev_item(),
        ["<C-n>"] = cmp.mapping.select_next_item(),
        ["<C-d>"] = cmp.mapping.scroll_docs(-4),
        ["<C-f>"] = cmp.mapping.scroll_docs(4),
        ["<C-Space>"] = cmp.mapping.complete(),
        ["<C-e>"] = cmp.mapping.close(),
        ["<CR>"] = cmp.mapping.confirm {
            behavior = cmp.ConfirmBehavior.Insert,
            select = true,
        },
        ["<Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_next_item()
            elseif require("luasnip").expand_or_jumpable() then
                vim.fn.feedkeys(
                    vim.api.nvim_replace_termcodes("<Plug>luasnip-expand-or-jump", true, true, true),
                    "")
            else
                fallback()
            end
        end, {
            "i",
            "s",
        }),
        ["<S-Tab>"] = cmp.mapping(function(fallback)
            if cmp.visible() then
                cmp.select_prev_item()
            elseif require("luasnip").jumpable(-1) then
                vim.fn.feedkeys(
                    vim.api.nvim_replace_termcodes("<Plug>luasnip-jump-prev", true, true, true), "")
            else
                fallback()
            end
        end, {
            "i",
            "s",
        }),
    },

    sources = {
        { name = "nvim_lsp" },
        { name = "luasnip" },
        { name = "buffer" },
        { name = "nvim_lua" },
        { name = "path" },
    },
    {
        { name = 'buffer' },
    },
}
require("cmp").setup(options)

Description

Markdown is not displayed correctly image

Steps to reproduce

just use the plugin

Expected behavior

instead of seeing the markdown it should be formatted

Actual behavior

it is not

Additional context

No response

FormalSnake commented 10 months ago

i know this is not a bug but its the only issue template

MariaSolOs commented 10 months ago

@FormalSnake this will be possible once https://github.com/neovim/neovim/pull/25073 goes in.

FormalSnake commented 10 months ago

Nice! What a coincidence lol

nsoufian commented 10 months ago

The https://github.com/neovim/neovim/pull/25073 is merged into master, can we expect that nvim-cmp docs will be the same as neovim core hover soon?

@MariaSolOs Thank you for https://github.com/neovim/neovim/pull/25073

FormalSnake commented 9 months ago

This is great!

MariaSolOs commented 9 months ago

Alright here's the thing: I had initially envisioned https://github.com/neovim/neovim/pull/25073 to include the public API for the new LSP markdown methods, but because that will involve a larger refactor tracked by https://github.com/neovim/neovim/issues/25272, this will happen in the future. In the meantime, here's a workaround I have in my dotfiles that's inspired by what Noice does.

DISCLAIMER: You shouldn't patch plugins like this or use private (prefixed by _) methods in Neovim. This will very likely cause your configuration to break and you won't be able to blame anyone about it except for yourself, so use at your own risk.

Still here? Okay here's the code.

--- HACK: Override `vim.lsp.util.stylize_markdown` to use Treesitter.
---@param bufnr integer
---@param contents string[]
---@param opts table
---@return string[]
---@diagnostic disable-next-line: duplicate-set-field
vim.lsp.util.stylize_markdown = function(bufnr, contents, opts)
    contents = vim.lsp.util._normalize_markdown(contents, {
        width = vim.lsp.util._make_floating_popup_size(contents, opts),
    })
    vim.bo[bufnr].filetype = 'markdown'
    vim.treesitter.start(bufnr)
    vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, contents)

    return contents
end

I have extra enhancements in my (publicly available) configuration, but I'll leave that as an exercise for the reader to figure out/find.

FormalSnake commented 9 months ago

I tried it and it looks great, but how do I scroll in the docs without mouse 😅

hedyhli commented 8 months ago

Mappings in the minimal config from your issue description has bindings to scroll docs:

        ["<C-d>"] = cmp.mapping.scroll_docs(-4),
        ["<C-f>"] = cmp.mapping.scroll_docs(4),
carschandler commented 4 months ago

This is particularly important for documentations that make frequent use of &nbsp; since that can make docs pretty tough to read when they don't get rendered.