epwalsh / obsidian.nvim

Obsidian 🤝 Neovim
Apache License 2.0
3.32k stars 151 forks source link

nvim_cmp: can't cycle through suggestions #440

Open aaronmcadam opened 4 months ago

aaronmcadam commented 4 months ago

🐛 Describe the bug

I can't seem to cycle through suggestions. My keybinding will only let me choose one, and then I see a flicker.

See the attached video for more context:

https://github.com/epwalsh/obsidian.nvim/assets/37928/9d32996f-e449-409f-a13e-098167e4021f

Config

Obsidian.nvim config:

  {
    "epwalsh/obsidian.nvim",
    version = "*", -- recommended, use latest release instead of latest commit
    lazy = true,
    ft = "markdown",
    dependencies = {
      "nvim-lua/plenary.nvim",
      "hrsh7th/nvim-cmp",
      "nvim-telescope/telescope.nvim",
      "nvim-treesitter/nvim-treesitter",
    },
    opts = {
      workspaces = {
        {
          name = "Remote Second Brain",
          path = "~/Documents/Remote Second Brain/",
        },
      },
      notes_subdir = "30 Areas/31 Inbox",
      new_notes_location = "notes_subdir",
      templates = {
        subdir = "50 Resources/54 Templates",
        date_format = "%Y-%m-%d",
        time_format = "%H:%M",
      },
      daily_notes = {
        folder = "40 Journal/41 Daily Notes/2024",
        date_format = "%Y-%m-%d",
        time_format = "%H:%M",
        template = "OTPL Daily Note.md",
      },
      -- Optional, set to true to force ':ObsidianOpen' to bring the app to the foreground.
      open_app_foreground = true,
      -- Optional, by default when you use `:ObsidianFollowLink` on a link to an external
      -- URL it will be ignored but you can customize this behavior here.
      ---@param url string
      follow_url_func = function(url)
        -- Open the URL in the default web browser.
        vim.fn.jobstart({ "open", url }) -- Mac OS
        -- vim.fn.jobstart({"xdg-open", url})  -- linux
      end,
      note_id_func = function(title)
        return title
      end,
      note_frontmatter_func = function(note)
        -- Add the title of the note as an alias.
        if note.title then
          note:add_alias(note.title)
        end

        local out = { aliases = note.aliases, tags = note.tags }

        -- `note.metadata` contains any manually added fields in the frontmatter.
        -- So here we just make sure those fields are kept in the frontmatter.
        if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then
          for k, v in pairs(note.metadata) do
            out[k] = v
          end
        end

        return out
      end,
      -- Optional, customize the default name or prefix when pasting images via `:ObsidianPasteImg`.
      ---@return string
      image_name_func = function()
        -- Prefix image names with timestamp.
        return string.format("%s-", os.time())
      end,
      attachments = {
        -- The default folder to place images in via `:ObsidianPasteImg`.
        -- If this is a relative path it will be interpreted as relative to the vault root.
        -- You can always override this per image by passing a full path to the command instead of just a filename.
        -- img_folder = "50 Resources/51 Attachments",
        img_folder = "TestAttachments",
      },
    },
    keys = {
      {
        "<leader>nb",
        "<cmd>ObsidianBacklinks<cr>",
        desc = "Show backlinks for current note",
      },
      {
        "<leader>nd",
        "<cmd>ObsidianToday<cr>",
        desc = "Open new Daily Note",
      },
      {
        "<leader>nf",
        "<cmd>ObsidianFollowLink<cr>",
        desc = "Follow link",
      },
      {
        "<leader>nn",
        "<cmd>ObsidianNew<cr>",
        desc = "Create new note",
      },
      {
        "<leader>no",
        "<cmd>ObsidianOpen<cr>",
        desc = "Open note in Obsidian",
      },
      {
        "<leader>nll",
        "<cmd>ObsidianLink<cr>",
        desc = "Link selection",
      },
      {
        "<leader>nln",
        "<cmd>ObsidianLinkNew<cr>",
        desc = "Create and link new note",
      },
      {
        "<leader>nq",
        "<cmd>ObsidianQuickSwitch<cr>",
        desc = "Switch to another note",
      },
      {
        "<leader>ns",
        "<cmd>ObsidianSearch<cr>",
        desc = "Search notes",
      },
      {
        "<leader>nt",
        "<cmd>ObsidianTemplate<cr>",
        desc = "Insert template",
      },
      {
        "<leader>ny",
        "<cmd>ObsidianYesterday<cr>",
        desc = "Open yesterday's Daily Note",
      },
    },
  },

nvim-cmp config:

  return {
    completion = {
      completeopt = "menu,menuone,noinsert,noselect",
    },
    snippet = {
      expand = function(args)
        require("luasnip").lsp_expand(args.body)
      end,
    },

    -- These mappings are based on the latest kickstart.nvim changes.
    -- @see https://github.com/nvim-lua/kickstart.nvim/pull/635

    -- For an understanding of why these mappings were
    -- chosen, you will need to read `:help ins-completion`
    mapping = cmp.mapping.preset.insert({
      -- Select the [n]ext item
      ["<C-n>"] = cmp.mapping.select_next_item(),

      -- Select the [p]revious item
      ["<C-p>"] = cmp.mapping.select_prev_item(),

      -- Accept ([y]es) the completion.
      --  This will auto-import if your LSP supports it.
      --  This will expand snippets if the LSP sent a snippet.
      ["<C-y>"] = cmp.mapping.confirm({ select = true }),

      -- Manually trigger a completion from nvim-cmp.
      --  Generally you don't need this, because nvim-cmp will display
      --  completions whenever it has completion options available.
      ["<C-Space>"] = cmp.mapping.complete(),

      -- Think of <c-l> as moving to the right of your snippet expansion.
      --  So if you have a snippet that's like:
      --  function $name($args)
      --    $body
      --  end
      --
      -- <c-l> will move you to the right of each of the expansion locations.
      -- <c-h> is similar, except moving you backwards.
      ["<C-l>"] = cmp.mapping(function()
        if luasnip.expand_or_locally_jumpable() then
          luasnip.expand_or_jump()
        end
      end, { "i", "s" }),
      ["<C-h>"] = cmp.mapping(function()
        if luasnip.locally_jumpable(-1) then
          luasnip.jump(-1)
        end
      end, { "i", "s" }),

      ["<C-e>"] = cmp.mapping.abort(),
      ["<C-u>"] = cmp.mapping.scroll_docs(-4),
      ["<C-d>"] = cmp.mapping.scroll_docs(4),
    }),
    formatting = {
      format = function(_, item)
        local icons = require("azvim.core.helpers").icons.kinds

        if icons[item.kind] then
          item.kind = icons[item.kind] .. item.kind
        end

        return item
      end,
    },
    sources = cmp.config.sources({
      { name = "nvim_lsp", priority = 1000 },
      { name = "luasnip", priority = 800 },
      { name = "git", priority = 600 },
      { name = "copilot", priority = 600 },
      { name = "buffer", priority = 400 },
      { name = "path", priority = 250 },
    }),
  }

Environment

❯ nvim --version

NVIM v0.10.0-dev-2255+g4c9119461-Homebrew
Build type: Release
LuaJIT 2.1.1703358377
Run "nvim -V1 -v" for more info

dotfiles on  main [!]
❯ nvim --headless -c 'lua require("obsidian").info()' -c q

Plugins:
  [obsidian.nvim (v3.5.3)] Commit SHA: 9ede6c86b1f47afe00442a6e84fa1f5b00153742
  [plenary.nvim] Commit SHA: 4f71c0c4a196ceb656c824a70792f3df3ce6bb6d
  [nvim-cmp] Commit SHA: 04e0ca376d6abdbfc8b52180f8ea236cbfddf782
  [telescope.nvim] Commit SHA: 2e1e382df42467029b493c143c2e727028140214
Tools:
  [rg] ripgrep 14.0.3
Environment:
  [OS] Darwin⏎                                                                                                                              
epwalsh commented 4 months ago

@aaronmcadam from what I can tell it looks like you cycle through with "down arrow" just not with <CTRL-n>?

aaronmcadam commented 4 months ago

@aaronmcadam from what I can tell it looks like you cycle through with "down arrow" just not with <CTRL-n>?

Correct, but that's awkward as I never use the arrow keys for cycling suggestions 😄

epwalsh commented 4 months ago

Just trying to understand the issue. Does this happen with other sources? If so, does it still happen with other sources if you add completion = { nvim_cmp = false } to your obsidian.nvim config?

aaronmcadam commented 4 months ago

The flickering doesn't happen with other sources in other files (for example a tsx file):

https://github.com/epwalsh/obsidian.nvim/assets/37928/a494f9b1-4129-46ce-9e72-010d175f7c81

aaronmcadam commented 4 months ago

The Text source works ok from a markdown file: CleanShot 2024-02-26 at 21 41 34@2x

aaronmcadam commented 4 months ago

So it appears to be only "Reference" sources that don't seem to allow cycling for me.

aaronmcadam commented 4 months ago

I changed the binding for select_next_item to <Tab> just in case of a conflict somewhere, and I saw the same issue.

epwalsh commented 4 months ago

I can't reproduce this, but I can give you some things to try. Go into your clone of obsidian.nvim and try editing the cmp entries here: https://github.com/epwalsh/obsidian.nvim/blob/4c3601063fb89ca83d2c00ab0fb081bb6e433f8e/lua/cmp_obsidian.lua#L73-L76

In particular see what happens if you remove the documentation field or change the kind field.

aaronmcadam commented 4 months ago

In particular see what happens if you remove the documentation field or change the kind field

I've removed the documentation field and changed the kind, but I see the same issue.

epwalsh commented 4 months ago

Hey @hrsh7th, do you have any idea what might cause this?

SappyJoy commented 1 month ago

I had the same issue with cycling, but without flickering. And also I can't confirm any suggestion.

Surprisingly, when I changed

['<C-y>'] = cmp.mapping.confirm { select = true },

to

['<CR>'] = cmp.mapping.confirm { select = true },

in nvim-cmp config, confirmation began to work. But I still couldn't cycle with <C-n> and <C-p>.

Finally, in @epwalsh dotfiles I found this line

['<C-y>'] = cmp.mapping.confirm { select = false, behavior = cmp.ConfirmBehavior.Insert },

This line fixes confirmation and cycling issue too.

aaronmcadam commented 1 month ago

I had the same issue with cycling, but without flickering. And also I can't confirm any suggestion.

Surprisingly, when I changed

['<C-y>'] = cmp.mapping.confirm { select = true },

to

['<CR>'] = cmp.mapping.confirm { select = true },

in nvim-cmp config, confirmation began to work. But I still couldn't cycle with <C-n> and <C-p>.

Finally, in @epwalsh dotfiles I found this line

['<C-y>'] = cmp.mapping.confirm { select = false, behavior = cmp.ConfirmBehavior.Insert },

This line fixes confirmation and cycling issue too.

Overriding the confirm behaviour didn't work for me.