We’re using erlang.mk. I’ve just moved from using Erlang LS to ELP, in Visual Studio Code.
My editor is now a sea of yellow squiggles, because it can’t find my dependencies. For example, it doesn’t recognise cowboy_req:set_resp_headers/2 and so on.
Does anyone have a working example of ELP’s .elp.toml file for use with erlang.mk projects? I found one in the RabbitMQ repo, and hacked on it, thus:
[build_info]
deps = "deps/*"
But after doing this, ELP still warns about (e.g.) cowboy, plus it’s forgotten about built-in OTP functions, such as string:uppercase/1.
Hi @rlipscombe
The full documentation for the build_info field is available here:
An extensive example is the one from OTP itself:
## %CopyrightBegin%
##
## SPDX-License-Identifier: Apache-2.0
##
## Copyright Ericsson AB 2025. All Rights Reserved.
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
## %CopyrightEnd%
This file has been truncated. show original
If you could share a (maybe minimized) version of the repo and/or the erlang.mk config, I can help you get started. What did the erlang_ls.config file looked for the repo?
This is what I use for a poorly structured umbrella project:
[build_info]
apps = [
"apps/*",
{"name" = "a_bad_app_that_we_have_on_the_root_folder", "dir" = ".", "src_dirs" = ["src"], "include_dirs" = ["apps/*/src", "apps/*/include"]}
]
deps = [
"deps/*"
]
I use kerl to manage Erlang and OTP24, in particular, for this project.
ELP finds OTP functions and deps with no issue in VSCode. There are other things I’m missing, mostly because I’m on OTP24 (like eqwalizer support, I believe)… but the rest works… mostly fine (with a lot of warnings, but no blocking problems).
1 Like
And since I’m pretty sure @robertoaloi will ask me about the warnings… This is one example that repeats a lot :
Panic context:
>
request: textDocument/codeLens CodeLensParams {
text_document: TextDocumentIdentifier {
uri: Url {
scheme: "file",
cannot_be_a_base: false,
username: "",
password: None,
host: None,
port: None,
path: "/path/to/my_module.erl",
query: None,
fragment: None,
},
},
work_done_progress_params: WorkDoneProgressParams {
work_done_token: None,
},
partial_result_params: PartialResultParams {
partial_result_token: None,
},
}
read '<unnamed>' panicked at /Users/runner/work/erlang-language-platform/erlang-language-platform/crates/erlang_service/src/lib.rs:366:14:
failed sending request to parse server: "SendError(..)"
stack backtrace:
0: __rustc::rust_begin_unwind
1: core::panicking::panic_fmt
2: core::result::unwrap_failed
3: <elp_ide_db::RootDatabase as elp_ide_db::erl_ast::AstLoader>::load_ast
4: salsa::derived::slot::Slot<Q,MP>::read_upgrade
5: <DB as elp_ide_db::erl_ast::ErlAstDatabase>::module_ast::__shim
6: <elp_ide_db::RootDatabase as elp_ide_db::common_test::CommonTestLoader>::check
7: salsa::derived::slot::Slot<Q,MP>::read_upgrade
8: <DB as elp_ide_db::common_test::CommonTestDatabase>::ct_info::__shim
9: elp::handlers::handle_code_lens
10: <F as threadpool::FnBox>::call_box
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 10:28:22] Request textDocument/codeLens failed.
Message: internal error
Code: -32603
@elbrujohalcon do you have a small repro for this one? It would help me fixing it.
Sorry, but no. It’s a huge repo, with tons of particular customizations and zero chance of sharing anything from it. It’s super private.
This seems to work:
[build_info]
apps = [{name = "my_app", dir = "."}]
deps = "deps/*"
Kinda odd that you need to specify the app, even though this isn’t an umbrella. Maybe ELP needs the name for something?
It doesn’t like hackney, though – because of the way that hackney:post/{1,2,3,4}, etc. are defined with a macro, I’m guessing.
2 Likes
@rlipscombe We could probably default to the current directory if no apps are specified.
Regarding hackney, I am not super familiar with the project but yes. hackney.erl defines methods via macros and that confuses the language server. The logic to extract function definitions and other useful elements is mostly in:
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is dual-licensed under either the MIT license found in the
* LICENSE-MIT file in the root directory of this source tree or the Apache
* License, Version 2.0 found in the LICENSE-APACHE file in the root directory
* of this source tree. You may select, at your option, one of the
* above-listed licenses.
*/
//! A lookup map for definitions in a module/file.
//!
//! DefMap represents definitions of various constructs in a file -
//! functions, records, types, in a way that is easy to lookup.
//! It represents the state as Erlang compiler sees it - after include resolution.
//!
//! They are constructed recursively and separately for all headers and modules -
//! this makes sure that we need to do a minimal amount of re-computation on changes.
use std::mem;
This file has been truncated. show original
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is dual-licensed under either the MIT license found in the
* LICENSE-MIT file in the root directory of this source tree or the Apache
* License, Version 2.0 found in the LICENSE-APACHE file in the root directory
* of this source tree. You may select, at your option, one of the
* above-listed licenses.
*/
use elp_syntax::AstNode;
use elp_syntax::AstPtr;
use elp_syntax::SmolStr;
use elp_syntax::SyntaxNode;
use elp_syntax::ast;
use elp_syntax::ast::DeprecatedFunArity;
use elp_syntax::ast::Desc;
use elp_syntax::unescape;
use fxhash::FxHashMap;
use la_arena::Idx;
This file has been truncated. show original
Feel free to have a look.