ray-x / lsp_signature.nvim

LSP signature hint as you type
Apache License 2.0
2.01k stars 56 forks source link

provide option to hide signature help while pop up menu is open #259

Open insidewhy opened 1 year ago

insidewhy commented 1 year ago

I'm using the pop-up menu for code-completions and in many cases the lsp_signature pop-up will obscure it so I can't see any of the code-completion suggestions.

I think it would be nice to provide an option which will cause the signature help pop up to not display when there is another pop-up menu. Or maybe there's some way to ensure the code completion pop-up appears above this one? At the moment it seems like it's always below it.

If there's a simple way to configure this without adding an option to lsp_signature that would be cool too, but I think it's important enough to document that in the README, since it can be pretty frustrating to have your code completions hidden.

ray-x commented 1 year ago

is the toggle key setup can help you in this scenario?

insidewhy commented 1 year ago

is the toggle key setup can help you in this scenario?

It would help but it would be more difficult to have to keep toggling off when I know in a certain scenario I always want it to vanish automatically, plus I have to give up a precious keybinding to do this.

I tried to look for some event I can listen to in the vim/neovim API to get a callback when the PUM becomes visible, but I wasn't able to find it yet. It can be hard to google for neovim/vim APIs.

ray-x commented 1 year ago

TBH, there already checks to see if pop-menu (pmenu) in the code. https://github.com/ray-x/lsp_signature.nvim/blob/6f6252f63b0baf0f2224c4caea33819a27f3f550/lua/lsp_signature/helper.lua#L697-L704 But it not working well as there is no guarantee when pmenu will show. From what I saw, signature is normally faster so I have to guess where the pmenu will be. Last but not least, toggle key is a imap. I do not think it will affect your normal workflow. Also, you can define your own key so if signature is shown, the keybind will toggle the floating, otherwise fallback to its original function.

insidewhy commented 1 year ago

@ray-x I found a way to do it by checking for the CompleteChanged and CompleteDone events... well almost. The only problem is that the API provided by lsp_signature currently only has toggle_float_win which means I have to keep track of whether it's toggle on or off. So it would be great if I could have a disable_float_win and enable_float_win. Then I can do this:

vim.api.nvim_create_autocmd({"CompleteChanged"}, {
  callback = function()
    lsp_signature.disable_float_win()
  end
})

vim.api.nvim_create_autocmd({"CompleteDone"}, {
  callback = function()
    lsp_signature.enable_float_win()
  end
})
insidewhy commented 1 year ago

I tried this:

  local lsp_sig_enabled = true

  vim.api.nvim_create_autocmd({"CompleteChanged"}, {
    callback = function()
      if lsp_sig_enabled then
        nvim_lsp_sig.toggle_float_win()
        lsp_sig_enabled = false
      end
    end
  })

  vim.api.nvim_create_autocmd({"CompleteDone"}, {
    callback = function()
      if not lsp_sig_enabled then
        nvim_lsp_sig.toggle_float_win()
        lsp_sig_enabled = true
      end
    end
  })

but I get the following error:

Error executing vim.schedule lua callback: Vim(append):Error executing lua callback: ...im/plugged/lsp_signature
.nvim/lua/lsp_signature/init.lua:942: E565: Not allowed to change text or change window                         
stack traceback:
insidewhy commented 1 year ago

Okay there was a patch that disabled changing windows from completion events hence the previous error so I changed it to this:

  local lsp_sig_enabled = true

  vim.api.nvim_create_autocmd({"CompleteChanged"}, {
    callback = function()
      if lsp_sig_enabled then
        vim.defer_fn(function()
          nvim_lsp_sig.toggle_float_win()
        end, 0)
        lsp_sig_enabled = false
      end
    end
  })

  vim.api.nvim_create_autocmd({"CompleteDone"}, {
    callback = function()
      if not lsp_sig_enabled then
        vim.defer_fn(function()
          nvim_lsp_sig.toggle_float_win()
        end, 0)
        lsp_sig_enabled = true
      end
    end
  })

~So this calls toggle_win_float as I'd expect, however the signature window just reappears immediately. I guess it gets toggled off and then something happens which just creates a new window again.~

Actually I have no idea why this doesn't work, maybe something to do with some context issue in the completion handler.

insidewhy commented 1 year ago

After further debugging I can see it was broken because when you first open the completion menu you get CompleteChange followed by CompleteDone then CompleteChange. So I added a naive debounce like this:

  lsp_sig_enabled = true
  complete_done_debounce = false

  vim.api.nvim_create_autocmd({"CompleteChanged"}, {
    callback = function()
      complete_done_debounce = false
      vim.defer_fn(function()
        if lsp_sig_enabled then
          require("lsp_signature").toggle_float_win()
          lsp_sig_enabled = false
        end
      end, 0)
    end
  })

  vim.api.nvim_create_autocmd({"CompleteDone"}, {
    callback = function()
      complete_done_debounce = true
      vim.defer_fn(function()
        if complete_done_debounce and not lsp_sig_enabled then
          require("lsp_signature").toggle_float_win()
          lsp_sig_enabled = true
        end
        complete_done_debounce = false
      end, 10)
    end
  })

Now it works like 90% of the time, after much debugging I found that occasionally the toggle doesn't work and the lsp_signature window remains on the screen even though it's supposed to be off. I logged all my events and can see I'm enabling it and disabling it appropriately, so I'm pretty sure there's a small bug in lsp_signature when it comes to this.

insidewhy commented 1 year ago

Okay the toggle is working fine, it's just sometimes when you toggle to the disabled state, the existing signature help doesn't get cleared and remains on the screen.

ray-x commented 1 year ago

The best way to check if floating is on

    _LSP_SIG_CFG.winnr
    and _LSP_SIG_CFG.winnr > 0
    and vim.api.nvim_win_is_valid(_LSP_SIG_CFG.winnr)
xinghe98 commented 1 month ago

After further debugging I can see it was broken because when you first open the completion menu you get CompleteChange followed by CompleteDone then CompleteChange. So I added a naive debounce like this:

  lsp_sig_enabled = true
  complete_done_debounce = false

  vim.api.nvim_create_autocmd({"CompleteChanged"}, {
    callback = function()
      complete_done_debounce = false
      vim.defer_fn(function()
        if lsp_sig_enabled then
          require("lsp_signature").toggle_float_win()
          lsp_sig_enabled = false
        end
      end, 0)
    end
  })

  vim.api.nvim_create_autocmd({"CompleteDone"}, {
    callback = function()
      complete_done_debounce = true
      vim.defer_fn(function()
        if complete_done_debounce and not lsp_sig_enabled then
          require("lsp_signature").toggle_float_win()
          lsp_sig_enabled = true
        end
        complete_done_debounce = false
      end, 10)
    end
  })

Now it works like 90% of the time, after much debugging I found that occasionally the toggle doesn't work and the lsp_signature window remains on the screen even though it's supposed to be off. I logged all my events and can see I'm enabling it and disabling it appropriately, so I'm pretty sure there's a small bug in lsp_signature when it comes to this.

I have the same need, how do you solve it now?