Skip to content

Commit

Permalink
user background job for hover provider to avoid blocking request queu…
Browse files Browse the repository at this point in the history
…e on large documents
  • Loading branch information
TheGeorge committed Sep 27, 2021
1 parent 6d591a4 commit 2522d52
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 9 deletions.
70 changes: 63 additions & 7 deletions apps/els_lsp/src/els_hover_provider.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,24 @@

-behaviour(els_provider).

-export([ handle_request/2
-export([ handle_info/2
, handle_request/2
, is_enabled/0
, init/0
, cancel_request/2
]).

-include("els_lsp.hrl").
-include_lib("kernel/include/logger.hrl").

-define(SERVER, ?MODULE).

%%==============================================================================
%% Types
%%==============================================================================
-type state() :: any().
-type state() :: #{in_progress => [progress_entry()]}.
-type progress_entry() :: {uri(), job()}.
-type job() :: pid().

%%==============================================================================
%% els_provider functions
Expand All @@ -23,24 +31,72 @@
is_enabled() ->
true.

-spec init() -> state().
init() ->
#{ in_progress => []}.

-spec handle_request(any(), state()) -> {any(), state()}.
handle_request({hover, Params}, State) ->
#{in_progress := InProgress} = State,
#{ <<"position">> := #{ <<"line">> := Line
, <<"character">> := Character
}
, <<"textDocument">> := #{<<"uri">> := Uri}
} = Params,
?LOG_DEBUG("Starting hover job ""[uri=~p, line=~p, character=~p]"
, [Uri, Line, Character]
),
Job = run_hover_job(Uri, Line, Character),
{Job, State#{in_progress => [{Uri, Job}|InProgress]}}.


-spec handle_info(any(), state()) -> state().
handle_info({result, HoverResp, Job}, State) ->
?LOG_DEBUG("Received hover result [job=~p]", [Job]),
#{ in_progress := InProgress } = State,
els_server:send_response(Job, HoverResp),
State#{ in_progress => lists:keydelete(Job, 2, InProgress) }.

-spec cancel_request(job(), state()) -> state().
cancel_request(Job, State) ->
?LOG_DEBUG("Cancelling hover [job=~p]", [Job]),
els_background_job:stop(Job),
#{ in_progress := InProgress } = State,
State#{ in_progress => lists:keydelete(Job, 2, InProgress) }.


%%==============================================================================
%% Internal Functions
%%==============================================================================

-spec run_hover_job(uri(), line(), column()) -> pid().
run_hover_job(Uri, Line, Character) ->
{ok, Doc} = els_utils:lookup_document(Uri),
POIs = els_dt_document:get_element_at_pos(Doc, Line + 1, Character + 1),
{get_docs(Uri, POIs), State}.
Config = #{ task => fun get_docs/2
, entries => [{Uri, POIs}]
, title => <<"Hover">>
, on_complete =>
fun(HoverResp) ->
?SERVER ! {result, HoverResp, self()},
ok
end
},
{ok, Pid} = els_background_job:new(Config),
Pid.

-spec get_docs({uri(), [poi()]}, undefined) -> map() | null.
get_docs({Uri, POIs}, _) ->
do_get_docs(Uri, POIs).


-spec get_docs(uri(), [poi()]) -> map() | null.
get_docs(_Uri, []) ->
-spec do_get_docs(uri(), [poi()]) -> map() | null.
do_get_docs(_Uri, []) ->
null;
get_docs(Uri, [POI|Rest]) ->
do_get_docs(Uri, [POI|Rest]) ->
case els_docs:docs(Uri, POI) of
[] ->
get_docs(Uri, Rest);
do_get_docs(Uri, Rest);
Entries ->
#{contents => els_markup_content:new(Entries)}
end.
4 changes: 2 additions & 2 deletions apps/els_lsp/src/els_methods.erl
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ textdocument_documentsymbol(Params, State) ->
-spec textdocument_hover(params(), state()) -> result().
textdocument_hover(Params, State) ->
Provider = els_hover_provider,
Response = els_provider:handle_request(Provider, {hover, Params}),
{response, Response, State}.
Job = els_provider:handle_request(Provider, {hover, Params}),
{noresponse, {Provider, Job}, State}.

%%==============================================================================
%% textDocument/completion
Expand Down

0 comments on commit 2522d52

Please sign in to comment.