nvim-cmp icon indicating copy to clipboard operation
nvim-cmp copied to clipboard

Change cmdline settings for specific file type

Open jrwrigh opened this issue 3 years ago • 2 comments

I use https://github.com/rbong/vim-flog/ quite a bit and it will sort it's cmdline completions to suite what the user is doing. For example, it will put the commit hash of the commit under the cursor as the first completion option (which is often what I want). The cmp sorting messes with this quite a bit and I don't like it too much. So I'd like to do one of two things:

  1. Disable the sorting that cmp does (assuming that would allow for the vim-flog sorting to come through) while retaining the cmp interface
  2. Disable cmp completely for vim-flog files (it uses the floggraph filetype)

Unfortunately, I can't figure out how to do either of these.

For 1, I've tried

-- Set configuration for specific filetype.
cmp.setup.filetype('floggraph', {
  enabled = true,
  sources = {},
  sorting = {
    comparators = {
      cmp.config.compare.order,
    },
  },
})

But it appears to have no effect.

For 2, I've tried:

-- Set configuration for specific filetype.
cmp.setup.filetype('floggraph', {
  enabled = true,
})

but it also has no effect.

This kind of makes sense as I want to change the cmdline settings when I'm in a specific filetype rather than changing the cmp behavior in the file itself. However, I'm not sure how to go about cmdline settings when inside a buffer of a specific filetype. Any ideas?

jrwrigh avatar Jul 25 '22 15:07 jrwrigh

So I've gotten something like this:

function FlogGraph_cmdline()
  cmp = require('cmp')

  cmp.setup.cmdline(':', {
    mapping = cmdline_mappings,
    sorting = {
      comparators = {
        cmp.config.compare.order,
      },
    },
    sources = cmp.config.sources({
      { name = 'cmdline' },
      { name = 'path' }
    }),
    completion = {
      autocomplete = true
    }
  })
end

local cmp_augroup = vim.api.nvim_create_augroup("Custom cmp.nvim", { clear = true })
vim.api.nvim_create_autocmd(
  "FileType",
  { callback = FlogGraph_cmdline, group = cmp_augroup, pattern = "floggraph" }
)

Which does exactly what I want when I open a floggraph filetype. However, it also changes the cmdline settings for every other file as well. Is there a way to limit the cmdline settings to a specific buffer?

jrwrigh avatar Jul 25 '22 16:07 jrwrigh

A bit ugly/verbose, but here's the solution I have now that works well:

local function FlogGraph_cmdline()
  cmp.setup.cmdline(':', {
    mapping = cmdline_mappings,
    sorting = {
      comparators = {
        cmp.config.compare.order,
      },
    },
    sources = cmp.config.sources({
      { name = 'cmdline' },
      { name = 'path' }
    }),
    completion = {
      autocomplete = true
    }
  })
end

local function Normal_cmdline()
  cmp.setup.cmdline(':', {
    mapping = cmdline_mappings,
    sources = cmp.config.sources({
      { name = 'cmdline' },
      { name = 'path' },
      { name = 'cmdline_history' },
    }, {
      { name = 'cmdline' }
    }),
    completion = {
      autocomplete = false
    }
  })
end

local function FlogGraph_autocmd()
  FlogGraph_cmdline()
  local cmdline_group = vim.api.nvim_create_augroup("cmdline_group", { clear = true })
  vim.api.nvim_create_autocmd(
    "BufEnter",
    { callback = FlogGraph_cmdline, group = cmdline_group, pattern = "<buffer>" }
  )
  vim.api.nvim_create_autocmd(
    "BufLeave",
    { callback = Normal_cmdline, group = cmdline_group, pattern = "<buffer>" }
  )
end

local cmp_augroup = vim.api.nvim_create_augroup("Custom cmp.nvim", { clear = true })
vim.api.nvim_create_autocmd(
  "FileType",
  { callback = FlogGraph_autocmd, group = cmp_augroup, pattern = "floggraph" }
)

Walking through the code, I have a command to apply and remove the cmdline settings (FlogGraph_cmdline and Normal_cmdline). I have a autocmd trigger for the floggraph filetype. This calls FlogGraph_autocmd, which creates buffer-local autocommands (see :h autocmd-buflocal) to set and unset the cmdline settings.

Edit:

Here's a cleaner implementation:

local orig_cmdline_config = require('cmp.config').cmdline[':']

local function FlogGraph_cmdline()
  cmp.setup.cmdline(':', {
    mapping = cmdline_mappings,
    sorting = {
      comparators = {
        cmp.config.compare.order,
      },
    },
    sources = cmp.config.sources({
      { name = 'cmdline' },
      { name = 'path' }
    }),
  })
end

local function Normal_cmdline()
  cmp.setup.cmdline(':', orig_cmdline_config)
end

local function FlogGraph_autocmd()
  FlogGraph_cmdline()
  local Flog_cmdline_group = vim.api.nvim_create_augroup("Flog_cmdline_group", { clear = true })
  vim.api.nvim_create_autocmd(
    "BufEnter",
    { callback = FlogGraph_cmdline, group = Flog_cmdline_group, pattern = "<buffer>" }
  )
  vim.api.nvim_create_autocmd(
    "BufLeave",
    { callback = Normal_cmdline, group = Flog_cmdline_group, pattern = "<buffer>" }
  )
end

local cmp_augroup = vim.api.nvim_create_augroup("Custom cmp.nvim", { clear = true })
vim.api.nvim_create_autocmd(
  "FileType",
  { callback = FlogGraph_autocmd, group = cmp_augroup, pattern = "floggraph" }
)

This doesn't require setting the "Normal" cmdline config with a copy/paste. Instead I store the "normal" cmdline config on setup and then just reuse it.

jrwrigh avatar Jul 25 '22 16:07 jrwrigh