Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#60] Add support for erlang_ls.config file #61

Merged
merged 6 commits into from
Sep 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,24 @@ Code completion is available for the following elements:
* Atom names
* Module attributes

## Customization

It is possible to customize the behaviour of the `erlang_ls` server by
adding a `erlang_ls.config` file to the root of your projects.

A sample `erlang_ls.config` file would look like the following:

otp_path: "/path/to/otp/lib/erlang"
deps_dirs:
- "lib/*"

Currently, the following customizations are possible:

| Parameter | Description |
|------------|---------------------------------------------------------------------|
| otp\_path | Path to the OTP installation |
| deps\_dirs | List of directories containing dependencies. It supports wildcards. |

## Troubleshooting

It is possible to compile and start the language server in _debug mode_:
Expand Down
14 changes: 4 additions & 10 deletions include/erlang_ls.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@
%% Language Server Protocol
%%==============================================================================

%%------------------------------------------------------------------------------
%% URI
%%------------------------------------------------------------------------------
-type uri() :: binary().
-type uri_path() :: binary().

%%------------------------------------------------------------------------------
%% Position
%%------------------------------------------------------------------------------
Expand Down Expand Up @@ -156,12 +150,12 @@
%%------------------------------------------------------------------------------
%% Text Document Identifier
%%------------------------------------------------------------------------------
-type text_document_id() :: #{ uri := uri() }.
-type text_document_id() :: #{ uri := erlang_ls_uri:uri() }.

%%------------------------------------------------------------------------------
%% Text Document Item
%%------------------------------------------------------------------------------
-type text_document_item() :: #{ uri := uri()
-type text_document_item() :: #{ uri := erlang_ls_uri:uri()
, languageId := binary()
, version := number()
, text := binary()
Expand Down Expand Up @@ -210,7 +204,7 @@
%%------------------------------------------------------------------------------
%% Initialize Request
%%------------------------------------------------------------------------------
-type workspace_folder() :: #{ uri => uri()
-type workspace_folder() :: #{ uri => erlang_ls_uri:uri()
, name => binary()
}.

Expand All @@ -225,7 +219,7 @@

-type initialize_params() :: #{ processId := number() | null
, rootPath => binary() | null
, rootUri := uri() | null
, rootUri := erlang_ls_uri:uri() | null
, initializationOptions => any()
, capabilities := client_capabilities()
, trace => off
Expand Down
1 change: 1 addition & 0 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
, {cowlib, "2.3.0"}
, {redbug, "1.2.1"}
, {lager, "3.6.8"}
, {yamerl, "0.7.0"}
]
}.

Expand Down
6 changes: 4 additions & 2 deletions rebar.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
{<<"jsx">>,{pkg,<<"jsx">>,<<"2.9.0">>},0},
{<<"lager">>,{pkg,<<"lager">>,<<"3.6.8">>},0},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.5.0">>},0},
{<<"redbug">>,{pkg,<<"redbug">>,<<"1.2.1">>},0}]}.
{<<"redbug">>,{pkg,<<"redbug">>,<<"1.2.1">>},0},
{<<"yamerl">>,{pkg,<<"yamerl">>,<<"0.7.0">>},0}]}.
[
{pkg_hash,[
{<<"cowlib">>, <<"BBD58EF537904E4F7C1DD62E6AA8BC831C8183CE4EFA9BD1150164FE15BE4CAA">>},
{<<"goldrush">>, <<"F06E5D5F1277DA5C413E84D5A2924174182FB108DABB39D5EC548B27424CD106">>},
{<<"jsx">>, <<"D2F6E5F069C00266CAD52FB15D87C428579EA4D7D73A33669E12679E203329DD">>},
{<<"lager">>, <<"897EFC7679BB82383448646C96768CDC4E747464DD18B999C7AACA485686B0DA">>},
{<<"ranch">>, <<"F04166F456790FEE2AC1AA05A02745CC75783C2BFB26D39FAF6AEFC9A3D3A58A">>},
{<<"redbug">>, <<"9153EE50E42C39CE3F6EFA65EE746F4A52896DA66862CFB59E7C0F838B7B8414">>}]}
{<<"redbug">>, <<"9153EE50E42C39CE3F6EFA65EE746F4A52896DA66862CFB59E7C0F838B7B8414">>},
{<<"yamerl">>, <<"E51DBA652DCE74C20A88294130B48051EBBBB0BE7D76F22DE064F0F3CCF0AAF5">>}]}
].
1 change: 1 addition & 0 deletions src/erlang_ls.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
, jsx
, cowlib
, lager
, yamerl
]},
{env,[]},
{modules, []},
Expand Down
47 changes: 41 additions & 6 deletions src/erlang_ls_buffer_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
-export([ start_link/0
, add_buffer/2
, get_buffer/1
, get_deps_dirs/0
, get_otp_path/0
, get_root_uri/0
, remove_buffer/1
, set_deps_dirs/1
, set_otp_path/1
, set_root_uri/1
, stop/0
]).
Expand All @@ -43,13 +47,18 @@
%%==============================================================================
%% Record Definitions
%%==============================================================================
-record(state, { buffers, root_uri }).
-record(state, { buffers
, deps_dirs = []
, root_uri
, otp_path
}).

%%==============================================================================
%% Type Definitions
%%==============================================================================
-type state() :: #state{}.
-type buffer() :: pid().
-type path() :: file:filename().

%%%=============================================================================
%%% API
Expand All @@ -58,23 +67,39 @@
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, {}, []).

-spec add_buffer(uri(), buffer()) -> ok.
-spec add_buffer(erlang_ls_uri:uri(), buffer()) -> ok.
add_buffer(Uri, Buffer) ->
gen_server:call(?SERVER, {add_buffer, Uri, Buffer}).

-spec get_buffer(uri()) -> {ok, buffer() | undefined}.
-spec get_buffer(erlang_ls_uri:uri()) -> {ok, buffer() | undefined}.
get_buffer(Uri) ->
gen_server:call(?SERVER, {get_buffer, Uri}).

-spec get_root_uri() -> {ok, uri() | undefined}.
-spec get_deps_dirs() -> {ok, [path()]}.
get_deps_dirs() ->
gen_server:call(?SERVER, {get_deps_dirs}).

-spec get_otp_path() -> {ok, path() | undefined}.
get_otp_path() ->
gen_server:call(?SERVER, {get_otp_path}).

-spec get_root_uri() -> {ok, erlang_ls_uri:uri() | undefined}.
get_root_uri() ->
gen_server:call(?SERVER, {get_root_uri}).

-spec remove_buffer(uri()) -> ok.
-spec remove_buffer(erlang_ls_uri:uri()) -> ok.
remove_buffer(Uri) ->
gen_server:call(?SERVER, {remove_buffer, Uri}).

-spec set_root_uri(uri()) -> ok.
-spec set_deps_dirs([erlang_ls_uri:path()]) -> ok.
set_deps_dirs(DepsDirs) ->
gen_server:call(?SERVER, {set_deps_dirs, DepsDirs}).

-spec set_otp_path(erlang_ls_uri:uri()) -> ok.
set_otp_path(Uri) ->
gen_server:call(?SERVER, {set_otp_path, Uri}).

-spec set_root_uri(erlang_ls_uri:uri()) -> ok.
set_root_uri(Uri) ->
gen_server:call(?SERVER, {set_root_uri, Uri}).

Expand All @@ -95,12 +120,22 @@ handle_call({add_buffer, Uri, Buffer}, _From, State) ->
handle_call({get_buffer, Uri}, _From, State) ->
Buffer = proplists:get_value(Uri, State#state.buffers),
{reply, {ok, Buffer}, State};
handle_call({get_deps_dirs}, _From, State) ->
DepsDirs = State#state.deps_dirs,
{reply, {ok, DepsDirs}, State};
handle_call({get_otp_path}, _From, State) ->
OtpPath = State#state.otp_path,
{reply, {ok, OtpPath}, State};
handle_call({get_root_uri}, _From, State) ->
RootUri = State#state.root_uri,
{reply, {ok, RootUri}, State};
handle_call({remove_buffer, Uri}, _From, State) ->
Buffers = proplists:delete(Uri, State#state.buffers),
{reply, ok, State#state{buffers = Buffers}};
handle_call({set_deps_dirs, DepsDirs}, _From, State) ->
{reply, ok, State#state{deps_dirs = DepsDirs}};
handle_call({set_otp_path, Path}, _From, State) ->
{reply, ok, State#state{otp_path = Path}};
handle_call({set_root_uri, Uri}, _From, State) ->
{reply, ok, State#state{root_uri = Uri}}.

Expand Down
32 changes: 18 additions & 14 deletions src/erlang_ls_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
-export([ did_open/4
, did_save/1
, did_close/1
, initialize/1
, initialize/2
, start_link/2
, stop/0
]).
Expand Down Expand Up @@ -51,28 +51,29 @@
%%==============================================================================
%% Type Definitions
%%==============================================================================
-type state() :: #state{}.
-type hostname() :: tuple().
-type port_no() :: pos_integer().
-type state() :: #state{}.
-type hostname() :: tuple().
-type port_no() :: pos_integer().
-type init_options() :: [].

%%==============================================================================
%% API
%%==============================================================================
-spec did_open(uri(), binary(), number(), binary()) -> ok.
-spec did_open(erlang_ls_uri:uri(), binary(), number(), binary()) -> ok.
did_open(Uri, LanguageId, Version, Text) ->
gen_server:call(?SERVER, {did_open, Uri, LanguageId, Version, Text}).

-spec did_save(uri()) -> ok.
-spec did_save(erlang_ls_uri:uri()) -> ok.
did_save(Uri) ->
gen_server:call(?SERVER, {did_save, Uri}).

-spec did_close(uri()) -> ok.
-spec did_close(erlang_ls_uri:uri()) -> ok.
did_close(Uri) ->
gen_server:call(?SERVER, {did_close, Uri}).

-spec initialize(uri()) -> ok.
initialize(RootUri) ->
gen_server:call(?SERVER, {initialize, RootUri}).
-spec initialize(erlang_ls_uri:uri(), init_options()) -> ok.
initialize(RootUri, InitOptions) ->
gen_server:call(?SERVER, {initialize, RootUri, InitOptions}).

-spec start_link(hostname(), port_no()) -> {ok, pid()}.
start_link(Host, Port) ->
Expand Down Expand Up @@ -117,11 +118,14 @@ handle_call({did_close, Uri}, _From, State) ->
Content = erlang_ls_protocol:notification(Method, Params),
ok = gen_tcp:send(State#state.socket, Content),
{reply, ok, State};
handle_call({initialize, RootUri}, From, #state{ request_id = RequestId
, socket = Socket
} = State) ->
handle_call({initialize, RootUri, InitOptions}, From, State) ->
#state{ request_id = RequestId
, socket = Socket
} = State,
Method = <<"initialize">>,
Params = #{ <<"rootUri">> => RootUri },
Params = #{ <<"rootUri">> => RootUri
, <<"initializationOptions">> => InitOptions
},
Content = erlang_ls_protocol:request(RequestId, Method, Params),
gen_tcp:send(Socket, Content),
{noreply, State#state{ request_id = RequestId + 1
Expand Down
32 changes: 21 additions & 11 deletions src/erlang_ls_code_navigation.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@
%%==============================================================================

%% API
-export([ goto_definition/2
, goto_definition/3
]).

-export([ otp_path/0
]).
-export([ goto_definition/2 ]).

%%==============================================================================
%% Includes
Expand All @@ -27,7 +22,7 @@
-spec goto_definition(binary(), erlang_ls_poi:poi()) ->
{ok, binary(), erlang_ls_poi:range()} | {error, any()}.
goto_definition(Filename, POI) ->
goto_definition(Filename, POI, full_path()).
goto_definition(Filename, POI, include_path()).

%% TODO: Abstract pattern
-spec goto_definition(binary(), erlang_ls_poi:poi(), [string()]) ->
Expand Down Expand Up @@ -125,7 +120,7 @@ definition({type_application, {Type, _}}) ->

-spec otp_path() -> [string()].
otp_path() ->
Root = code:root_dir(),
{ok, Root} = erlang_ls_buffer_server:get_otp_path(),
Sources = filename:join([Root, "lib", "*", "src"]),
Includes = filename:join([Root, "lib", "*", "include"]),
lists:append([ filelib:wildcard(Sources)
Expand All @@ -140,9 +135,24 @@ app_path() ->
, filename:join([RootPath, "include"])
].

-spec full_path() -> [string()].
full_path() ->
lists:append( [ app_path(), otp_path() ]).
-spec deps_path() -> [string()].
deps_path() ->
{ok, RootUri} = erlang_ls_buffer_server:get_root_uri(),
RootPath = binary_to_list(erlang_ls_uri:path(RootUri)),
{ok, Dirs} = erlang_ls_buffer_server:get_deps_dirs(),
lists:foldl(fun(Dir, Acc) ->
Sources = filename:join([RootPath, Dir, "src"]),
Includes = filename:join([RootPath, Dir, "include"]),
lists:append([ filelib:wildcard(Sources)
, filelib:wildcard(Includes)
, Acc
])
end
, [], Dirs).

-spec include_path() -> [string()].
include_path() ->
lists:append( [ app_path(), otp_path(), deps_path() ]).

%% Look for a definition recursively in a file and its includes.
-spec search(binary(), [string()], any()) ->
Expand Down
2 changes: 1 addition & 1 deletion src/erlang_ls_compiler_diagnostics.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
%%==============================================================================
%% Callback Functions
%%==============================================================================
-spec diagnostics(uri()) -> [diagnostic()].
-spec diagnostics(erlang_ls_uri:uri()) -> [diagnostic()].
diagnostics(Uri) ->
Path = erlang_ls_uri:path(Uri),
case compile:file(binary_to_list(Path), ?COMPILER_OPTS) of
Expand Down
2 changes: 1 addition & 1 deletion src/erlang_ls_diagnostics.erl
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
%%==============================================================================
%% Callback Functions Definitions
%%==============================================================================
-callback diagnostics(uri()) -> [diagnostic()].
-callback diagnostics(erlang_ls_uri:uri()) -> [diagnostic()].
2 changes: 1 addition & 1 deletion src/erlang_ls_dialyzer_diagnostics.erl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
%%==============================================================================
%% Callback Functions
%%==============================================================================
-spec diagnostics(uri()) -> [diagnostic()].
-spec diagnostics(erlang_ls_uri:uri()) -> [diagnostic()].
diagnostics(Uri) ->
Path = erlang_ls_uri:path(Uri),
WS = try dialyzer:run([{files, [binary_to_list(Path)]}, {from, src_code}])
Expand Down
Loading