Skip to content

resolve completion item documentation on completion-menu selection #2052

Closed
@the-mikedavis

Description

@the-mikedavis

The LSP docs on completion request have a nice blurb about this:

If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request (completionItem/resolve). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the textDocument/completion request doesn’t fill in the documentation property for returned completion items since it is expensive to compute.

The Erlang language server only sends documentation for completion items on completionItem/resolve (I assume because it's non-trivial to lookup documentation).

Upon a Menu's PromptEvent::Update event, we should resolve_completion_item (implemented in #1315) if there is not existing documentation and then merge in the response to the currently selected item. I believe the request can be done in this block:

PromptEvent::Update => {
// always present here
let item = item.unwrap();
let transaction = item_to_transaction(
doc,
item,
offset_encoding,
start_offset,
trigger_offset,
);
// initialize a savepoint
doc.savepoint();
doc.apply(&transaction, view.id);
editor.last_completion = Some(CompleteAction {
trigger_offset,
changes: completion_changes(&transaction, trigger_offset),
});
}

We currently trigger the resolve on the PromptEvent::Validate event in order to resolve additional text edit actions. If I hit enter (triggers validate) on a completion item in the menu, the Erlang LS already sends:

2022-04-08T23:19:19.351 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"completionItem/resolve","params":{"data":{"arity":2,"function":"get","module":"maps"},"insertText":"get","insertTextFormat":1,"kind":3,"label":"get/2"},"id":9}
2022-04-08T23:19:19.359 helix_lsp::transport [INFO] <- {"id":9,"jsonrpc":"2.0","result":{"documentation":{"kind":"markdown","value":"```erlang\nget(Key, Map) -> Value\nwhen Key :: term(), Map :: map(), Value :: term().\n```\n\n---\n*Since:* OTP 17\\.0\n\nReturns value `Value` associated with `Key` if `Map` contains `Key`\\.\n\nThe call fails with a `{badmap,Map}` exception if `Map` is not a map, or with a `{badkey,Key}` exception if no value is associated with `Key`\\.\n\n*Example:*\n\n```erlang\n> Key = 1337,\n  Map = #{42 => value_two,1337 => \"value one\",\"a\" => 1},\n  maps:get(Key,Map).\n\"value one\"\n```\n"},"data":{"arity":2,"function":"get","module":"maps"},"insertText":"get","insertTextFormat":1,"kind":3,"label":"get/2"}}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-helix-termArea: Helix term improvementsC-enhancementCategory: Improvements

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions