On Saturday, December 23, 2017 at 12:23:43 PM UTC+1, Ben Jackson wrote: > Hi Bram and community, > > I have prepared a brief request for comments on a proposed new Vim feature > which I am personally very keen on, but would like to gauge the appetite for > it and the thoughts of the community and maintainers at large before actually > embarking on a proper implementation. > > The feature is IDE-like display of the method signature being entered at the > same time as the insert-mode completion menu. > > The RFC is best viewed in a gist here and includes a POC and some demos in > animated-gif form: > https://gist.github.com/puremourning/3ac3be4527ee094250ae516fc26561a2 > > It's also replicated below for those that prefer plaintext :) > > I'd be super grateful for any responses, comments, flames, ideas or even > insults ;) > > Cheers, > Ben > > --- > > # TL;DR > > This RFC proposes introducing a second popup menu in insert mode to display > method argument hints, current parameter, etc. similar to a number of IDEs and > editors. The proposal is to allow scripts to control this (such as on insert > of > `(` and `)` characters) and for it to be non-interractive and not to interfere > with insert-mode completion. > > The purpose of the RFC is to guage the appetite from Bram and the community > for > such a feature, and to discuss the design/functional behaviours prior to > committing to an implementation/etc. > > # Motivation > > There are a number of Vim plugins which attempt to provide some IDE-like > features using Vim's completion system, in combination with omnifuncs and > insert-mode completion that is built-in. Examples: > > - YouCompleteMe - https://github.com/Valloric/YouCompleteMe > - neocomplete, deoplete, neocomplcache, and other friends > - eclim? > - any number of hundreds of omnifuncs > - Microsoft language server client? > - Various other "async complete" plugins > - possibly any number of other completion plugins, including implementations > specific to particular languages (e.g. using omnifunc), or using l > > In their simplest form, these provide a list of identifiers which are > semantically valid to be inserted at the current cursor position (or the > result > of the equivalent of omnifunc's 'findstart' request), using the insert-mode > completion APIs provided by Vim. > > One of the most commonly requested features for YouCompleteMe is the ability > to > display the valid arguments for function calls, as well as semantically > correct > identifiers. This feature is known as "argument hints", "parameter > completions", "signature help" or suchlike. > [Microsoft's Language Server Protocol][lsp] refers to them as "Signature > Help". > > # Illustrative example > > For example, the user types something like the following, with the cursor on > `^`: > > ```c > > typedef struct pum_T > { > int pum_item_count; > int pum_selected; > pumitem_T* items[]; > } pum; > > void pum_display_item( pum_T* pum, > char_u* message, > pumitem_T* item_list ); > > void pum_display_item( pum_T* pum, > int selected_item, > pumitem_T* item ); > > void main(void) > { > pum_T pum = init_pum(); > pum_display_item( pum, pum.^ > } > > ``` > > Current completion systems (or omni-completion, invoked with `<C-x><C-o>`) > would > typically present a popup menu with the valid options from the definition, > such as: > > - `int pum_selected` > - `int pum_item_count` > > Methods often have many more arguments than this toy example, and > the declaration is not likely visible when it is used. Instead, many IDEs and > other editors provide a second "popup" when the user types the `(`. Typically, > this is _above_ rather than below the current line and contains the list of > overloads of the fucntion and their arguments, often highlighting (one way or > another) the "current" argument being entered. > > For example, it might look like this: > > |------------------------------------------------------------------------| > | pum_display_item( pum_T* pum, **char_u *message**, pumitem_T* item ) | > | pum_display_item( pum_T* pum, **int selected_item**, pumitem_T* item ) | > |------------------------------------------------------------------------| > pum_display_item( pum, pum.^ > |---------------------------| > | pum_selected int | > | int pum_item_count int | > |---------------------------| > > # Known existing attempts in Vim > > - **The preview window.** > By using the extra data in the completion menu item structure, we can show > some static information in the preview window. The drawbacks are that the > preview window has to always be visible (taking up valuable screen real > estate), or it pops in and out of visibility, causing the current row to > shift disconcertingly on the screen. Requires `preview` in the `completeopt` > and other autocmds etc. to show/hide it. Cursor moving into and out of > the preview window triggers `BufEnter` autocoms, which causes meaningful lag > when the completion menu is visible (OK, this could be blamed mostly on the > plugins using `BufEnter` autocommand, but you get the picture). > > - **Oblitum/YouCompleteMe.** > This is an approach using the standard PUM 100% with no hacks. The drawback > is > that only the current argument is displayed, and mutually exclusively with > suggestions for the current identifier. > > - a YouCompleteMe test which also uses the command line (user experience is > not > good using the command line, as the text can be clobbered by other things, > timers, etc.) > > - **jedi-vim.** > A python omnifunc plugin uses conceal highlighting to simulate a second > menu. > The conceal apprach seems to involve actually changing the buffer contents > and > relying on special highlight groups to make the _appearance_ of a second > "menu". Ingenious, perhaps, but probably not fun to implement or maintain. > With no disrespect to the author, it seems like a hack. > > There are probably others; I just listed the ones I researched. > > # Proposal > > Vim currently supports a single popup menu, which is used for: > > - insert-mode completion > - balloons (a more recent addition, only in the terminal) > > In the GUI, balloons are implemented as a popover window via a GUI-specific > mechanism. > > The proposal is to allow 2 (mostly) independent popup menus to be displayed > insert mode: > > - the interractive completion menu, controlled without changes (via CTRL-X > mode) > - a second menu not overlapping the completion menu controlled only by > scripts. > > For the purposes of this RFC (and brevity), I will refer to the menus as: > > - the completion menu, and > - the hint menu > > respectively. > > ## Display > > Priority in terms of display is always given to the completion menu, as that > is > the one the user interracts with. The completion menu prefers to draw below > the > cursor (if there is room), above otherwise. > > The hint menu prefers (for example): > - if there is no completion menu: > - if there is room above, above the cursor line > - otherwise if there is blow, below the cursor > - otherwise not at all > - if there is a completion menu, and it wants to be below the cursor: > - if there is room above, above the cursor line > - otherwise, not at all > - if there is a completion menu, and it wants to be above the cursor: > - if there is room below, below the cursor line > - otherwise, not at all > > Both the completion menu and the hint menu are cleared when a balloon is > displayed. > > ## Content > > Discussion point: This is open for debate and I would love to hear thoughts on > it. I see there are a couple of options here: > > 1. **"Pass-through"**. The contents of the hint menu are at the discretion of > the script. Borrowing from the approach taken for balloons, the menu > supports > a list of strings, but does not perform any additional formatting (such as > spacing/splitting). > > 2. **"Call a spoon a spoon"**. The purpose of the feature is argument hints, > so > we make the API specific to that. Anything else is YAGNI. > e.g. The API is passed a list of signatures, including the active signature > and argument. Vim then handles the display and highlighting, allowing the > script interface to be relatively simple, while restricting (perhaps) the > amount of innovation. > > # Implementation > > One could argue that parameter hints are a special case of balloons. The > special > case is that they are visible at the same time as completions in insert mode. > However, I'm not totally convinced that's the right approach. In particular, > balloons are very different in the terminal and GUI, and I feel like this > feels > more similar to insert-mode completion than any existing expected use case for > balloons. > > So instead, the proposal is to actualy just add (yet) another popupmenu, whose > data is independent of the existing popopmenu and balloon data. > > The general idea would be to re-use most (if not all) of the existing > popupmenu > code, by factoring its data out and passing an instance of "a" pum to most > functions. A vimscript API controls the hint pum, and the API for completion > is > unchanged. > > Here's a (very) brief idea of how I _think_ it could be done: > > - Phase 1, refactor so that pum data isn't quite-so global > - store all pum-related state in a struct pum_T > - declare a single instance of this called `compl_pum` > - use `compl_pum` for completion and balloons exactly as it is used today > - No functional change. > > - Phase 2, add the second pum > - create a vimscript API that allows a script to display the hint pum in > insert mode > - provide experrimental support for: > - hint_pum_set( {arg} ) = set the contents of the hint menu > - arg contents TBD, but a list of strings, maybe or something else... > - hint_pum_show( column ) = enable display of the hint menu > - hint_pum_hide() = disable display of the hint menu > - hint_pum_visible() = return whether hint menu is displayed > - hint the hint pum when exiting insert mode (and probably a load of other > things i haven't thought of) > > - Phase 3, allow hint menu to highlight the current argument > - Details sketchy, as they depend on some of the previous discussion points. > - One option is to embed something, perhaps using magic string markers in > the > menu input strings, to "bold" some section. > - Another option might be to somehow use new specific highlighting groups, > or something along those lines, combined with knowledge about which > argument > is selected. > > # Comments > > I'd welcome comments on anything including: > > - The welcomeness/appetite for such functionality > - The generality of the proposal (or otherwise) > - The overall approach, related ideas/works/etc. > - Niggly bikeshedding; the more the merrirer > > Of course nothing is set in stone at this stage, but I did write a proof of > concept about 12 months ago as part of the research into the idea. > > Some demos are attached to the gist as comments. I can point to the code in > Vim and YouCompleteMe, but it is very hacky and exploratorys, so it would be > completely re-engineered before any PR/patch is sent. > > [lsp]: > https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textDocument_signatureHelp > > Demos: > 1. > https://user-images.githubusercontent.com/10584846/34235430-99105e76-e5e9-11e7-819e-9ae8e77bc9f8.gif > 2. > https://user-images.githubusercontent.com/10584846/34235624-c09472e2-e5ea-11e7-9430-0058389e0a92.gif > 3. > https://user-images.githubusercontent.com/10584846/34235626-c2d7faec-e5ea-11e7-99ea-a3122ff377a6.gif
Hello, I have updated this patch on top of commit 8.1.0360. I haven't added any tests or help docs, but you can view the updated branch here: https://github.com/bstaletic/vim/tree/current_argument_update Best regards, Boris Staletic -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
