wilder.nvim icon indicating copy to clipboard operation
wilder.nvim copied to clipboard

Candidates for second and subsequent user command arguments are not shown

Open Gelio opened this issue 3 years ago • 11 comments

Hey :wave:

I have been using this plugin for quite some time and found out there may be something wrong with the way the plugin handles candidates for user command arguments.

When trying to get completions at the end of the following command from https://github.com/sindrets/diffview.nvim:

:DiffviewOpen sway --imp

wilder.nvim does not show any candidates for the second argument (--imp).

It does show the candidates when I am typing the first argument (i.e. does suggest sway when the cmdline is :DiffviewOpen sw).

Investigation notes

Here are some debug logs from my investigation from some of the values used in wilder.nvim for the ctx and the arg:

sway --im
['s', 'w', 'a', 'y', ' ', '-', '-', 'i', 'm']
{'cmd': 'DiffviewOpen', 'expand': 'nothing', 'cmdline': 'DiffviewOpen sway --imp', 'pos': 13, 'force': 0}
{'cmd': 'DiffviewOpen', 'expand': 'nothing', 'cmdline': 'DiffviewOpen sway --imp', 'arg': 'sway --imp', 'pos': 13, 'force': 0}
{'cmd': 'DiffviewOpen', 'expand': 'nothing', 'cmdline': 'DiffviewOpen sway --imp', 'arg': 'sway --imp', 'pos': 13, 'force': 0}

The suggestions returned from the DiffviewOpen user command at that point are:

{ "--imply-local" }

It looks like wilder.nvim assumes that the argument is sway --imp and not just --imp. Thus, later, when it tries to match the completion candidates (--imply-local) against the arg, it does not find the match, because sway --imp does not match --imply-local. If it only used the last argument (--imp), it would correctly find the match between --imp and --imply-local.

I suspect the problem is somewhere in https://github.com/gelguy/wilder.nvim/blob/679f348dc90d80ff9ba0e7c470c40a4d038dcecf/autoload/wilder/cmdline/main.vim#L36

The function is quite complex and I didn't end up finding the problem, unfortunately.

Native wildmenu behavior

To check whether this is a wrong assumption of wilder.nvim or a problem in diffview.nvim completion candidates, I checked how the native wildmenu behaves. It correctly offers completions for the second argument:

image

After pressing Tab for :DiffviewOpen sway --imp, the argument is correctly completed to :DiffviewOpen sway --imply-local. Completing subsequent arguments works in the native wildmenu as well:

image

Other problematic plugins

The problem can be reproduced with other plugins that have completions for more than one user command argument. For example, with :Telescope live_grep | (| is the cursor position), there are no completions shown by wilder.nvim, but there are many completions shown in the native wildmenu.

Gelio avatar Oct 02 '22 17:10 Gelio

Thanks for the detailed info and the screenshots!

I've narrowed this down to command DiffviewOpen setting a Lua function for the complete option. I don't see a way to call that Lua function since its stringified into <Lua function NUM>, but I have a workaround in mind.

gelguy avatar Oct 03 '22 13:10 gelguy

I'm dubious whether this is the problem with the complete option of user commands. I thought the issue is in the code parsing the current cmdline and incorrectly assuming there is just one argument for user commands. That is what I gathered after seeing 'cmdline': 'DiffviewOpen sway --imp', 'arg': 'sway --imp', 'pos': 13 in the ctx in wilder#cmdline#main#do, if I recall correctly.

I'm curious, what am I missing?

Gelio avatar Oct 03 '22 14:10 Gelio

wilder gets the candidates from the command completion manually: https://github.com/gelguy/wilder.nvim/blob/777b163e394ba658ef288292efb533b25610ef9d/autoload/wilder/cmdline.vim#L681-L682

It doesn't handle Lua functions sincce complete=lua was (relatively) newly added. Furthermore, Lua functions are stringified to <Lua function>, and so cannot be de-referenced into the actual function.

The ctx doesn't contain the completions as no completions are returned.

The fallback will be to call getcompletion(cmdline, 'cmdline') and get the completions from there.

gelguy avatar Oct 03 '22 15:10 gelguy

Interesting, thanks for sharing these details. Why did it work for the first argument, though?

I get correct completions for the first argument of DiffviewOpen and I guess these completions are also returned from a Lua function:

image

You're saying that getting the completions for the first argument works fine when using a Lua function for complete, but breaks for 2nd and subsequent arguments?

I'm asking out of my curiosity, so I can better understand the Vim <-> Lua user command completions interop

Gelio avatar Oct 03 '22 16:10 Gelio

Hmm, looks like I'm wrong - wilder is already using the getcompletion(..., 'cmdline') fallback, but is setting the wrong argument for the fuzzy filter. (wilder basically doesn't handle complete=<lua function> correctly.)

You can confirm this by setting fuzzy_filter: {ctx, xs -> xs} in the options to wilder#cmdline_pipeline() (or fuzzy_filter = function(ctx, xs) return xs end for Lua).

gelguy avatar Oct 04 '22 00:10 gelguy

Yup, I confirm I can see the correct completion candidates in the xs list in the fuzzy filter.

function FuzzyFilter(ctx, xs, c)
  echomsg "ctx" a:ctx
  echomsg "xs" a:xs
  return a:xs
endfunction
      \       'fuzzy_filter': function("FuzzyFilter"),

Yields

ctx {'session_id': 3, 'handler_id': 90, 'input': 'DiffviewOpen abc --', 'run_id': 20}
xs ['--untracked-files', '--cached', '--staged', '--imply-local', '--selected-file']

The candidates are there.

At first glance, it seems to me the input/cmdline parsing logic that determines the arg to be completed seems incorrect, as I pointed out at the beginning of the Investigation notes ('cmdline': 'DiffviewOpen sway --imp', 'arg': 'sway --imp' instead of 'arg': '--imp').

Gelio avatar Oct 04 '22 07:10 Gelio

@gelguy Is there any way I can help out more here? Should I try to adjust the cmdline parsing logic so it only takes one argument into account instead of everything but the command name?

Gelio avatar Oct 07 '22 07:10 Gelio

Thanks for offering!

If you're ok with waiting, I'll have a fix done over the weekend.

gelguy avatar Oct 07 '22 10:10 gelguy

That sounds great! Take your time, there's no rush, and it's just an inconvenience, not a showstopper.

Gelio avatar Oct 07 '22 11:10 Gelio

I'm sorry to bring it up, but this bug keeps annoying me. Could I help fix it?

Gelio avatar Nov 17 '22 06:11 Gelio

I found a possible fix and raised #166

Gelio avatar Nov 18 '22 11:11 Gelio