From 95c021fdb8e279ae3e9ab0ae1af8624d5572fad3 Mon Sep 17 00:00:00 2001 From: Daniel Koudouna Date: Mon, 24 Jun 2019 08:47:15 +0100 Subject: [PATCH] Explicitly request file watchers from client (#35) * Add explicit file watcher request It is recommended that servers register for the capability to watch files. Notably, in emacs, clients such as lsp-mode will act conservatively and not send file change notifications without the added message. Added a generic capability registration request and specify file watchers after initialization. * Mix format * Add workspace capabilities, conditionally send file watcher message --- .../lib/language_server/json_rpc.ex | 12 ++++++++++ .../lib/language_server/server.ex | 24 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/apps/language_server/lib/language_server/json_rpc.ex b/apps/language_server/lib/language_server/json_rpc.ex index 24ff60903..11d9361f8 100644 --- a/apps/language_server/lib/language_server/json_rpc.ex +++ b/apps/language_server/lib/language_server/json_rpc.ex @@ -77,6 +77,18 @@ defmodule ElixirLS.LanguageServer.JsonRpc do notify("window/logMessage", %{type: message_type_code(type), message: to_string(message)}) end + def register_capability_request(server \\ __MODULE__, method, options) do + send_request(server, "client/registerCapability", %{ + "registrations" => [ + %{ + "id" => :crypto.hash(:sha, method) |> Base.encode16(), + "method" => method, + "registerOptions" => options + } + ] + }) + end + def show_message_request(server \\ __MODULE__, type, message, actions) do send_request(server, "window/showMessageRequest", %{ "type" => message_type_code(type), diff --git a/apps/language_server/lib/language_server/server.ex b/apps/language_server/lib/language_server/server.ex index f00599a94..122b2e6b1 100644 --- a/apps/language_server/lib/language_server/server.ex +++ b/apps/language_server/lib/language_server/server.ex @@ -153,6 +153,17 @@ defmodule ElixirLS.LanguageServer.Server do super(msg, state) end + def handle_info(:send_file_watchers, state) do + JsonRpc.register_capability_request("workspace/didChangeWatchedFiles", %{ + "watchers" => [ + %{"globPattern" => "**/*.ex"}, + %{"globPattern" => "**/*.exs"} + ] + }) + + {:noreply, state} + end + def handle_info(:default_config, state) do state = case state do @@ -322,6 +333,16 @@ defmodule ElixirLS.LanguageServer.Server do # If we don't receive workspace/didChangeConfiguration for 5 seconds, use default settings Process.send_after(self(), :default_config, 5000) + # Explicitly request file watchers from the client if supported + supports_dynamic = get_in(client_capabilities, [ + "textDocument", + "codeAction", + "dynamicRegistration" + ]) + if supports_dynamic do + Process.send_after(self(), :send_file_watchers, 100) + end + {:ok, %{"capabilities" => server_capabilities()}, state} end @@ -445,7 +466,8 @@ defmodule ElixirLS.LanguageServer.Server do "documentSymbolProvider" => true, "documentOnTypeFormattingProvider" => %{"firstTriggerCharacter" => "\n"}, "codeLensProvider" => %{"resolveProvider" => false}, - "executeCommandProvider" => %{"commands" => ["spec"]} + "executeCommandProvider" => %{"commands" => ["spec"]}, + "workspace" => %{ "workspaceFolders" => %{"supported" => true, "changeNotifications" => true}} } end