Skip to content

Commit

Permalink
Register capabilities dynamically, complete support for didChangedWat…
Browse files Browse the repository at this point in the history
…chedFiles (#1332)

* Register capability for didChangeWatchedFiles

If the client supports it, be notified about OS changes about watched files.

* Register capabilities dynamically, complete support for didChangedWatchedFiles

By being able to register capabilities dynamically, Erlang LS can
instruct the client to send `didChangeWatchedFiles`
requests whenever a file or directory is modified outside of the
client itself. Through this mechanism it is possible to prevent text
synchronization issues and crashes during events such as a rebase or a checkout.

* Update apps/els_lsp/src/els_general_provider.erl

Co-authored-by: Michał Muskała <[email protected]>
  • Loading branch information
robertoaloi and michalmuskala authored Jun 14, 2022
1 parent 2c539fd commit 637022b
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions apps/els_lsp/src/els_general_provider.erl
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ handle_request({initialized, _Params}) ->
<<"erlang_ls">>,
filename:basename(RootUri)
),
register_capabilities(),
els_distribution_server:start_distribution(NodeName),
?LOG_INFO("Started distribution for: [~p]", [NodeName]),
els_indexing:maybe_start(),
Expand Down Expand Up @@ -176,3 +177,39 @@ server_capabilities() ->
version => els_utils:to_binary(Version)
}
}.

-spec register_capabilities() -> ok.
register_capabilities() ->
Methods = [<<"didChangeWatchedFiles">>],
ClientCapabilities = els_config:get(capabilities),
Registrations = [
dynamic_registration_options(Method)
|| Method <- Methods, is_dynamic_registration_enabled(Method, ClientCapabilities)
],
case Registrations of
[] ->
?LOG_INFO("Skipping dynamic capabilities registration");
_ ->
Params = #{registrations => Registrations},
els_server:send_request(<<"client/registerCapability">>, Params)
end.

-spec is_dynamic_registration_enabled(binary(), map()) -> boolean().
is_dynamic_registration_enabled(Method, ClientCapabilities) ->
maps:get(
<<"dynamicRegistration">>,
maps:get(Method, maps:get(<<"workspace">>, ClientCapabilities, #{}), #{}),
false
).

-spec dynamic_registration_options(binary()) -> map().
dynamic_registration_options(<<"didChangeWatchedFiles">>) ->
RootPath = els_uri:path(els_config:get(root_uri)),
GlobPattern = filename:join([RootPath, "**", "*.{e,h}rl"]),
#{
id => <<"workspace/didChangeWatchedFiles">>,
method => <<"workspace/didChangeWatchedFiles">>,
registerOptions => #{
watchers => [#{globPattern => GlobPattern}]
}
}.

0 comments on commit 637022b

Please sign in to comment.