nix-community / nixvim

Configure Neovim with Nix! [maintainer=@GaetanLepage, @traxys, @mattsturgeon, @khaneliman]
https://nix-community.github.io/nixvim
MIT License
1.69k stars 261 forks source link

[BUG] cmp cmdline doesn't show cmdline completions when cmdline is configured #1533

Closed PowerUser64 closed 5 months ago

PowerUser64 commented 5 months ago
Field Description
Plugin cmp
Nixpkgs f1010e0469db743d14519a1efd37e23f8513d714
Home Manager n/a

Description

When cmp cmdline is configured through nix code, it does not show the cmdline completion menu. However, when it is configured through equivilant lua code (via extraConfigLua), it works. In the MRE below, I have provided nix code and lua code that are supposed to produce the same output as each other. Yet, when neovim loads it, cmdline completions only show up when the lua code version is enabled. I have included the lua code generated by each of these for the purpose of comparison.

To test the MRE, first overwrite the default.nix of the nixvim template flake with it, then build the flake. Try running it and try typing something into the cmdline (:). The completion menu should not pop up. Then, exit and uncomment the code block that sets extraConfigLua at the bottom. Build and repeat the cmdline test. Now, the completion menu should open. You can see the difference in the generated code if you edit the output of nixvim's builder in result/bin/nvim and find the init.lua that is opened near the end of the bottom line. That lua code is the code at the bottom of this issue.

Minimal, Reproducible Example (MRE)

{
  plugins = {
    cmp-buffer.enable = true;
    cmp-cmdline.enable = true;

    cmp = {
      enable = true;
      settings = {
        autoEnableSources = true;
        sources = [
          {
            name = "buffer";
            option.get_bufnrs.__raw = "vim.api.nvim_list_bufs";
          }
        ];
        mapping = {
          "<c-n>" = "cmp.mapping.select_next_item()";
          "<c-p>" = "cmp.mapping.select_prev_item()";
          "<Up>" = "cmp.mapping.select_next_item()";
          "<Down>" = "cmp.mapping.select_prev_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>" =
            # lua
            ''
              function(fallback)
                if cmp.visible() then
                  cmp.select_next_item()
                end
              end
            '';
          "<s-tab>" =
            # lua
            ''
              function(fallback)
                if cmp.visible() then
                  cmp.select_prev_item()
                end
              end
            '';
        };
        cmdline = let
          search_config = { mapping = { __raw = "cmp.mapping.preset.cmdline()"; }; sources = [ { name = "buffer"; } ]; };
          in {
          "/" = search_config;
          "?" = search_config;
          ":" = { mapping = { __raw = "cmp.mapping.preset.cmdline()"; };
            sources = [
              {
                name = "cmdline";
                option.ignore_cmds = [ "man" "!" ];
              }
            ];
          };
        };
      };
    };
  };

  ## Uncomment this block and cmdline completion will work

  #extraConfigLua =
  #  # lua
  #  ''
  #    local cmp = require'cmp'
  #
  #    local search_config = {
  #       mapping = cmp.mapping.preset.cmdline(),
  #       sources = {
  #          { name = 'buffer' },
  #       }
  #    }
  #    -- Use buffer source for `/` and `?`
  #    cmp.setup.cmdline('/', search_config)
  #    cmp.setup.cmdline('?', search_config)
  #    -- `:` cmdline setup.
  #    cmp.setup.cmdline(':', {
  #       mapping = cmp.mapping.preset.cmdline(),
  #       sources = cmp.config.sources({
  #          { name = 'cmdline' },
  #       })
  #    })
  #  '';

  # Colorscheme, to help with readability
  colorschemes.cyberdream.enable = true;
}

lua code written by me, in extraConfigLua above (works):

-- ...

local cmp = require("cmp")

local search_config = {
    mapping = cmp.mapping.preset.cmdline(),
    sources = {
        { name = "buffer" },
    },
}
-- Use buffer source for `/` and `?`
cmp.setup.cmdline("/", search_config)
cmp.setup.cmdline("?", search_config)
-- `:` cmdline setup.
cmp.setup.cmdline(":", {
    mapping = cmp.mapping.preset.cmdline(),
    sources = cmp.config.sources({
        { name = "cmdline" },
    }),
})

Generated lua code by nixvim (broken):

cmp.setup({
    -- ...
    ["cmdline"] = {
        ["/"] = { ["mapping"] = cmp.mapping.preset.cmdline(), ["sources"] = { { ["name"] = "buffer" } } },
        [":"] = {
            ["mapping"] = cmp.mapping.preset.cmdline(),
            ["sources"] = { { ["name"] = "cmdline", ["option"] = { ["ignore_cmds"] = { "man", "!" } } } },
        },
        ["?"] = { ["mapping"] = cmp.mapping.preset.cmdline(), ["sources"] = { { ["name"] = "buffer" } } },
    },
    -- ...
})
4lxs commented 5 months ago

you need to put the cmdline config in plugins.cmp.cmdline as documented here. you have it in plugins.cmp.settings.cmdline. the following will work

{
  plugins = {
    cmp-buffer.enable = true;
    cmp-cmdline.enable = true;

    cmp = {
      enable = true;
      settings = {
        autoEnableSources = true;
        sources = [
          {
            name = "buffer";
            option.get_bufnrs.__raw = "vim.api.nvim_list_bufs";
          }
        ];
        mapping = {
          "<c-n>" = "cmp.mapping.select_next_item()";
          "<c-p>" = "cmp.mapping.select_prev_item()";
          "<Up>" = "cmp.mapping.select_next_item()";
          "<Down>" = "cmp.mapping.select_prev_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>" =
            # lua
            ''
              function(fallback)
                if cmp.visible() then
                  cmp.select_next_item()
                end
              end
            '';
          "<s-tab>" =
            # lua
            ''
              function(fallback)
                if mp.visible() then
                  cmp.select_prev_item()
                end
              end
            '';
        };
      };

      # note that cmdline is outside of the settings key
      cmdline = let
        search_config = {
          mapping = {__raw = "cmp.mapping.preset.cmdline()";};
          sources = [{name = "buffer";}];
        };
      in {
        "/" = search_config;
        "?" = search_config;
        ":" = {
          mapping = {__raw = "cmp.mapping.preset.cmdline()";};
          sources = [
            {name = "cmdline";}
          ];
        };
      };
    };
  };

  ## Uncomment this block and cmdline completion will work

  # extraConfigLua =
  #   # lua
  #   ''
  #     local cmp = require'cmp'
  #
  #     local search_config = {
  #        mapping = cmp.mapping.preset.cmdline(),
  #        sources = {
  #           { name = 'buffer' },
  #        }
  #     }
  #     -- Use buffer source for `/` and `?`
  #     cmp.setup.cmdline('/', search_config)
  #     cmp.setup.cmdline('?', search_config)
  #     -- `:` cmdline setup.
  #     cmp.setup.cmdline(':', {
  #        mapping = cmp.mapping.preset.cmdline(),
  #        sources = cmp.config.sources({
  #           { name = 'cmdline' },
  #        })
  #     })
  #   '';

  # Colorscheme, to help with readability
  colorschemes.cyberdream.enable = true;
}
PowerUser64 commented 5 months ago

Ah! Thank you for catching this! Everything works now.