elixir-lsp / elixir_sense Goto Github PK
View Code? Open in Web Editor NEWProvides context-aware information for code completion, documentation, go/jump to definition, signature info and more
License: MIT License
Provides context-aware information for code completion, documentation, go/jump to definition, signature info and more
License: MIT License
Hi there,
I am using a behaviour statement in a macro like so:
defmacro __using__(opts) do
quote location: :keep do
@behaviour unquote(__MODULE__)
...
end
end
Unfortunately, it raises this error:
Message: an exception was raised:
** (ArgumentError) argument error
:erlang.atom_to_binary({:unquote, [line: 37, column: 18], [{:__MODULE__, [line: 37, column: 26], nil}]}, :utf8)
(elixir_sense) lib/elixir_sense/core/introspection.ex:552: ElixirSense.Core.Introspection.module_to_string/1
(elixir_sense) lib/elixir_sense/providers/suggestion.ex:336: anonymous fn/2 in ElixirSense.Providers.Suggestion.find_callbacks/2
(elixir) lib/enum.ex:2994: Enum.flat_map_list/2
(elixir_sense) lib/elixir_sense/providers/suggestion.ex:335: ElixirSense.Providers.Suggestion.find_callbacks/2
Cheers
This library is currently licensed under MIT license but it contains code taken from alchemist-server project licensed under GPL v3:
lib/alchemist/helpers/complete.ex
lib/alchemist/helpers/module_info.ex
and test/alchemist/helpers/module_info_test.exs
The status of lib/alchemist/helpers/complete.ex
is even more complicated as it is in fact a derrived work basing on elixir lib/iex/lib/iex/autocomplete.ex
covered by Apache License v2 and copyrighted by Platformatec and it's not likely that alchemist-server authors had Platformatec's agreement to relicense it under GPL v3. AFAIK modifications to Apache Licensed code can be released under GPL v3, but the not modified part stays under original license.
What needs to be done:
lib/alchemist/helpers/complete.ex
and also test/alchemist/helpers/complete_test.exs
), i.e. mention that original parts are copyrighted and licensend under Apache License and include list of modifications and required notices.As agreed in #98
Many documentation changes come with every otp and elixir update. We need to change our tests to depend more on fixtures. This applies to both erlang edoc and elixir docs.
In ElixirLS typing @do
above a function definition fails to return any completions and can result in an exception:
07:36:09.440 [error] Process #PID<0.400.0> raised an exception
** (CaseClauseError) no case clause matching: [{:hi, [line: 10, column: 7], nil}, [do: {:__block__, [], [{{:., [line: 16, column: 7], [{:__aliases__, [line: 16, column: 5], [:IO]}, :puts]}, [line: 16, column: 7], ["hihihibefesffesfasasd"]}, {{:., [line: 17, column: 9], [{:__aliases__, [line: 17, column: 5], [:Enum]}, :chunk_every]}, [line: 17, column: 9], [[], 3]}]}]]
(elixir_sense 1.0.1) lib/elixir_sense/core/metadata_builder.ex:556: ElixirSense.Core.MetadataBuilder.pre/2
(elixir 1.10.3) lib/macro.ex:430: anonymous fn/4 in Macro.do_traverse_args/4
(elixir 1.10.3) lib/enum.ex:1520: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(elixir 1.10.3) lib/enum.ex:1520: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(elixir 1.10.3) lib/macro.ex:396: Macro.do_traverse/4
(elixir 1.10.3) lib/macro.ex:411: Macro.do_traverse/4
(elixir 1.10.3) lib/enum.ex:1520: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(elixir 1.10.3) lib/macro.ex:416: Macro.do_traverse/4
Are there currently any tests of completion that involve a file that fails to compile?
Hi,
after upgrading Elixir, probably from df04a2d (also reported on branch 1.11), ElixirLS fail to start (via eglot) due to a missing function/signature in ElixirSense.
I'm using Emacs+eglot+ElixirLS in a Debian system with Erlang 23 and Elixir aligned to master branch (1.12.0-dev)
Back to the code ElixirSense project test fails with the same origin:
** (FunctionClauseError) no function clause matching in ElixirSense.Core.Normalized.Code.extract_docs/1
The following arguments were given to ElixirSense.Core.Normalized.Code.extract_docs/1:
# 1
%{}
Attempted function clauses (showing 3 out of 3):
defp extract_docs(%{"en" => docs_en})
defp extract_docs(:hidden)
defp extract_docs(:none)
Trying to change ElixirSense.Core.Normalized.Code.extract_docs/1
with:
diff --git a/lib/elixir_sense/core/normalized/code.ex b/lib/elixir_sense/core/normalized/code.ex
index 8659bf5..c9eec83 100644
--- a/lib/elixir_sense/core/normalized/code.ex
+++ b/lib/elixir_sense/core/normalized/code.ex
@@ -68,7 +68,7 @@ defp map_doc_entry({{kind, name, arity}, anno, signatures, docs, metadata}) do
String.t() | false | nil
defp extract_docs(%{"en" => docs_en}), do: docs_en
defp extract_docs(:hidden), do: false
- defp extract_docs(:none), do: nil
+ defp extract_docs(_), do: nil
defp get_fun_docs(module, docs) do
docs_from_module =
ElixirLS seam to work fine but two test on ElixirSense still fail:
test retrieve function documentation from behaviour if available (ElixirSense.DocsTest)
test retrieve macro documentation from behaviour if available (ElixirSense.DocsTest)
My original intention was to offer a complete solution as a pull-request but at the moment, given even the two failed tests, I still wanted to get involved with something useful.
Enrico
Could you add ability to set default authentication token (AUTH_TOKEN) on start up ElixirSense API server?
Failing test (test/elixir_sense/core/metadata_builder_test.exs):
# Fix for
# ** (CaseClauseError) no case clause matching: {:__MODULE__, [line: 34, column: 35], nil}
# (elixir_sense) lib/elixir_sense/core/metadata_builder.ex:213: ElixirSense.Core.MetadataBuilder.pre/2
# (elixir) lib/macro.ex:290: anonymous fn/4 in Macro.do_traverse_args/4
# (elixir) lib/enum.ex:1440: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
# (elixir) lib/enum.ex:1440: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
# (elixir) lib/macro.ex:256: Macro.do_traverse/4
# (elixir) lib/macro.ex:271: Macro.do_traverse/4
# (elixir) lib/enum.ex:1440: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
# (elixir) lib/macro.ex:276: Macro.do_traverse/4
test "protocol implementation using __MODULE__" do
state =
"""
defprotocol NiceProto do
def reverse(term)
end
defmodule MyStruct do
defstruct [a: nil]
defimpl NiceProto, for: __MODULE__ do
def reverse(term), do: String.reverse(term)
end
end
"""
|> string_to_state
# protocol implementation module name does not inherit enclosing module, only protocol
assert get_line_module(state, 8) == NiceProto.MyStruct
assert get_line_protocol(state, 8) == {NiceProto, [MyStruct]}
end
I've tried to fix this but I'm not sure how (or where) to replace __MODULE__
with a module name.
IDE: VScode
OS: MacOS
The following is an error I see in Developer Tools when I restart VSCode:
[ElixirSense] 13:22:09.105 [error] Task #PID<0.159.0> started from ElixirSense.Server.TCPServer terminating** (stop) exited in: GenServer.call(ElixirSense.Server.TCPServer.ConnectionHandlerSupervisor, {:start_task, [{:nonode@nohost, #PID<0.159.0>, #PID<0.159.0>}, [#PID<0.159.0>, #PID<0.158.0>], {:erlang, :apply, [#Function<1.131136907/0 in ElixirSense.Server.TCPServer.start_connection_handler/2>, []]}], nil, nil}, :infinity)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started (elixir) lib/gen_server.ex:999: GenServer.call/3
/Users/kj/.vscode-insiders/extensions/mjmcloug.vscode-elixir-1.1.0/elixir_sense/lib/elixir_sense/server/tcp_server.ex:58: ElixirSense.Server.TCPServer.accept/2 (elixir) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3Function: &ElixirSense.Server.TCPServer.listen/3 Args: ["unix", "localhost", "0"]ok:localhost:/tmp/elixir-sense-1581272529106882000.sock (at Socket.<anonymous> (/Users/kj/.vscode-insiders/extensions/mjmcloug.vscode-elixir-1.1.0/out/src/elixirSenseServerProcess.js:35:21))
Currently the tests are run only on elixir 1.9. I did an experiment on my fork with Github Actions. I set up a matrix and with some ifs added the test suite passes on 1.9, 1.8 and 1.7. Making 1.6 work would take too much effort and I think it's time we dropped support (or maybe when 1.10 is released).
https://github.com/lukaszsamson/elixir_sense/runs/308785248
Anyway I think we should introduce testing on more than one version.
@msaraiva @axelson WDYT?
In ElixirSense.Providers.References
, Mix.Tasks.Xref.calls/0
is used to find references to functions. However, the Mix.Tasks.Xref.calls/0
function is now deprecated in favour of the new compilation tracers feature of Elixir 1.10.
Naturally, we'll want to be backwards compatible as much as possible, and may not need to change right away.
That said, the new compilation tracers approach represents some challenges. Namely:
I'd be happy to help out with this, but I first wanted to get some input from folks who know more about ElixirSense than I do.
Example:
defmodule Project.Resolvers.Accounts do
alias Project.Accounts
When using Accounts
, code completion will suggest functions from the module it's currently in instead of the defined alias.
I'm using elixir-ls on Neovim + ALE.
10:05:05.675 [error] Process #PID<0.16894.1> raised an exception
** (FunctionClauseError) no function clause matching in ElixirSense.Core.Introspection.get_metadata_entry_md/1
(elixir_sense 1.0.1) lib/elixir_sense/core/introspection.ex:271: ElixirSense.Core.Introspection.get_metadata_entry_md({:delegate_to, {Timex.Parse.DateTime.Parser, :parse!, 2}})
(elixir 1.10.2) lib/enum.ex:1400: anonymous fn/3 in Enum.map/2
(stdlib 3.12.1) maps.erl:232: :maps.fold_1/3
(elixir 1.10.2) lib/enum.ex:2127: Enum.map/2
(elixir_sense 1.0.1) lib/elixir_sense/core/introspection.ex:261: ElixirSense.Core.Introspection.get_metadata_md/1
(elixir_sense 1.0.1) lib/elixir_sense/core/introspection.ex:229: anonymous fn/6 in ElixirSense.Core.Introspection.get_func_docs_md/2
(elixir 1.10.2) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir_sense 1.0.1) lib/elixir_sense/core/introspection.ex:221: ElixirSense.Core.Introspection.get_func_docs_md/2
Code:
https://github.com/bitwalker/timex/blob/3.6.1/lib/timex.ex#L475-L483
@doc """
Same as parse/2 and parse/3, except parse! raises on error.
See parse/2 or parse/3 docs for usage examples.
"""
@spec parse!(String.t(), String.t()) :: DateTime.t() | NaiveDateTime.t() | no_return
@spec parse!(String.t(), String.t(), atom) :: DateTime.t() | NaiveDateTime.t() | no_return
defdelegate parse!(datetime_string, format_string), to: Timex.Parse.DateTime.Parser
defdelegate parse!(datetime_string, format_string, tokenizer), to: Timex.Parse.DateTime.Parser
Let's be frank. I don't know of a single active user of ElixirSense server. All relevant IDEs/editors have long migrated to language server. In the last 3 years there were only 2 issues reported and no contributions. Maintaining it adds an unnecessary burden - run.exs is not covered by tests and needs tweaking on every module addition/refactoring. Server tests are flaky and crash when other tests do IO. It makes debugging more complicated. I know it could be changed into a proper application (vide elixir-lsp apps). I know it could be extracted to a separate library. I just don't see there's a need for it any more. @msaraiva please voice your opinion.
From the downstream issue I created:
Given code like this:
some_enum |> Enum.reduce(acc, fn e, acc -> ... end)If I use the ExDoc shortcut on
reduce
I get theEnum.reduce/2
docs instead of theEnum.reduce/3
docs.
The "ExDoc" command is requesting the documentation for the reduce
function from ElixirSense.
Mix.Tasks.Xref.calls/0
is deprecated now and does not seem to work correctly. We should probably migrate to compiler tracing
I'm getting the following exception and similar fairly regularly when writing a ecto query:
Company: backend company-capf error "an exception was raised:
** (FunctionClauseError) no function clause matching in :elixir_env.trace/2
(elixir 1.10.4) src/elixir_env.erl:35: :elixir_env.trace({:alias_reference, [line: 1], User}, #Macro.Env<aliases: [], context: nil, context_modules: [], file: "nofile", function: nil, functions: [], lexical_tracker: nil, line: 0, macro_aliases: [], macros: [], module: nil, requires: [], ...>)
(elixir 1.10.4) lib/macro.ex:1384: Macro.do_expand_once/2
(elixir 1.10.4) lib/macro.ex:1369: Macro.expand_once/2
(elixir_sense 1.0.1) lib/elixir_sense/plugins/ecto/query.ex:192: ElixirSense.Plugins.Ecto.Query.infer_type/4
(elixir_sense 1.0.1) lib/elixir_sense/plugins/ecto/query.ex:226: anonymous fn/4 in ElixirSense.Plugins.Ecto.Query.extract_bindings/4
(elixir 1.10.4) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir_sense 1.0.1) lib/elixir_sense/plugins/ecto.ex:87: ElixirSense.Plugins.Ecto.suggestions/4
(elixir_sense 1.0.1) lib/elixir_sense/providers/suggestion/generic_reducer.ex:39: ElixirSense.Providers.Suggestion.GenericReducer.reduce/6" with args (candidates achi)
My project is on:
erlang 22.3.4.3
elixir 1.10.4-otp-22
It seems that the following doesn't work when in a .eex
files, ~E
or ~L
:
I get this ArgumentError
whenever I am editing a config file with the latest elixir_sense (commit e6374a2)
** (ArgumentError) expected an Elixir module, got: Elixir
(elixir) lib/module.ex:1299: Module.split/2
(elixir_sense) lib/elixir_sense/core/metadata_builder.ex:376: ElixirSense.Core.MetadataBuilder.pre/2
(elixir) lib/macro.ex:286: anonymous fn/4 in Macro.do_traverse_args/4
(elixir) lib/enum.ex:1431: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
(elixir) lib/macro.ex:252: Macro.do_traverse/4
(elixir_sense) lib/elixir_sense/core/metadata_builder.ex:23: ElixirSense.Core.MetadataBuilder.build/1
(elixir_sense) lib/elixir_sense/core/parser.ex:21: ElixirSense.Core.Parser.parse_string/4
(elixir_sense) lib/elixir_sense.ex:43: ElixirSense.docs/3
Having something like:
alias Components.{Dialog, Dialog.Footer, Button}
when trying to auto-complete:
[Error - 11:25:31 AM] Request textDocument/completion failed.
Message: an exception was raised:
** (MatchError) no match of right hand side value: ["Dialog", "Footer"]
(elixir_sense) lib/elixir_sense/core/state.ex:525: anonymous fn/2 in ElixirSense.Core.State.expand_alias/2
(elixir) lib/enum.ex:2956: Enum.find_list/3
(elixir_sense) lib/elixir_sense/core/state.ex:524: ElixirSense.Core.State.expand_alias/2
(elixir_sense) lib/elixir_sense/core/state.ex:383: ElixirSense.Core.State.add_alias/2
(elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir_sense) lib/elixir_sense/core/metadata_builder.ex:131: ElixirSense.Core.MetadataBuilder.pre_alias/4
(elixir) lib/macro.ex:290: anonymous fn/4 in Macro.do_traverse_args/4
(elixir) lib/enum.ex:1440: Enum."-map_reduce/3-lists^mapfoldl/2-0-"/3
Is it possible to expose a public API that will return the Module that corresponds to the current line in the file? (i.e. if there are three modules defined in a file, this API will return the module whose body is on the specified line).
This would be a replacement for ElixirLS calling into ElixirSense.Core.Metadata.get_env
:
Related issue: elixir-lsp/elixir-ls#234
The following test fails
test "find references of variables in arguments" do
buffer = """
defmodule MyModule do
def call(conn) do
if true do
conn
end
end
end
"""
references = ElixirSense.references(buffer, 2, 13)
assert references == [
%{range: %{end: %{column: 16, line: 2}, start: %{column: 12, line: 2}}, uri: nil},
%{range: %{end: %{column: 11, line: 4}, start: %{column: 7, line: 4}}, uri: nil},
]
# returns []
end
The reason is broken variable tracking in MetadataBuilder.State. new_func_vars_scope works differently from new_vars_scope - it does not increment the scope_id counter and thanks to that conn variable is not in the function scope. The second problem is subscope handling. When leaving a subscope in remove_vars_scope all subscope variable positions are lost.
Elixir sense error tolerant parser would be usable e.g in elixir-ls DocumentSymbolsProvider
Should ElixirSense.definition/3
be able to handle modules that are provided with Elixir, like GenServer
? See https://github.com/balduncle/playground/blob/master/test/playground_test.exs for 3 tests that are currently failing due to the paths to the source files for built in modules not existing on my computer and instead being associated with the machine Elixir was built on. Note that the Enum test comes straight from the docs on hex.
Thanks.
I think it's time to publish a new release since we already have some nice new features and a bunch of fixes/improvements. Unless any of you has something else in mind, I'm planning to to this after #20, #25 and #24 are implemented and merged.
/cc @axelson, @@lukaszsamson
Currently, the logic we have in ElixirSense.Providers.Suggestion is way too complex and hard to maintain. For instance if we want to restrict the list of suggestions based on the context, we need to write that logic for each different case we need.
I started to refactor the code so we can have a main reducer going through a list of producers. Each producer returns a set of suggestions that will be added to the final list. A producer can also inform if the reducer should continue to collect more suggestions or if the list provided is already the final list.
One problem I've found so far is handling the hint
suggestion. Currently, the hint suggestion is generated along with variables, attributes, variable fields, functions, macros and modules, all inside ElixirSense.Providers.Suggestion.Complete.complete/2
. If I want to be able to selectively show/hide individual groups of suggestions, I need to have a way to split them into groups. That's possible with the current implementation by naively using Enum.group_by/2
. The problem is that the hint item, as far as I understood, is built while retrieving all those suggestions. If I remove any of them, the hint might become invalid.
So I have a question: Is the hint suggestion actually being used by any editor? Can't we just drop it out of the list and get rid of all the complexity involved? I took a look at elixir-ls
code and I couldn't find where it's being used. It's just ignored.
@lukaszsamson in case we can't drop the hint suggestion, do you think it would be feasible to extract the related logic so we could apply it only after we have the final list? I've noticed you do something similar using the Hint.combine/2
function, however, I couldn't find a way to use it with the existing suggestions already returned by Complete.complete/2
.
I have a strange issue, I don't know if it's only for me or you also have the same problem but haven't noticed it.
elixir run.exs unix 0 dev
{:ok, socket} =
...
data = :erlang.term_to_binary(request)
:ok = :gen_tcp.send(socket, data)
{:ok, response} = :gen_tcp.recv(socket, 0)
:erlang.binary_to_term(response)
By this time I see in the output of my server that it listens to a new sock file.
I did try to to connect to the old sock but it's not available anymore
Interactive Elixir (1.9.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, socket} = :gen_tcp.connect({:local, '/var/folders/h8/xlzsrqld6rldv_l03dsn60x80000gn/T/elixir-sense-1571438027826601476.sock'}, 0, [:binary, active: false, packet: 4])
** (MatchError) no match of right hand side value: {:error, :econnrefused}
(stdlib) erl_eval.erl:453: :erl_eval.expr/5
(iex) lib/iex/evaluator.ex:257: IEx.Evaluator.handle_eval/5
(iex) lib/iex/evaluator.ex:237: IEx.Evaluator.do_eval/3
(iex) lib/iex/evaluator.ex:215: IEx.Evaluator.eval/3
(iex) lib/iex/evaluator.ex:103: IEx.Evaluator.loop/1
(iex) lib/iex/evaluator.ex:27: IEx.Evaluator.init/4
The original issue come from elixir-lsp/elixir-ls#358, start from support do/end block would be good. Love to hear your feedback.
NOTE: I have a prototype version on ElixirLS that use :elixir_tokenizer
here wingyplus/elixir-ls@2d9a94c.
In the ElixirLS debugger it would be very helpful to get the list of modules defined in a file. This would allow the user to only interpret some of the modules in their project instead of all modules of the system. Defining by filename would be a more natural interface than a list of module names.
Related ElixirLS issue: elixir-lsp/elixir-ls#615
Although after thinking about it in #615 I opted to go with a regex based on the module name I still think that this could be a useful feature for ElixirSense to have.
I've gotten at least one other report of this. And here's a particular repo where I'm seeing it:
Then add the following line:
q2 = from e in Institute.Schedule.Event,
where: e.|
(The |
represents the cursor). I'd expect to get a list of fields but instead no completion is returned.
Hi @axelson, @asummers and anyone interested.
I'm working on a new open-source project called Surface
that should become public in the next couple of days. You can see it in action here. The main goal is to provide a standard way to create and reuse components in Phoenix/LiveView with exceptional integration with editors and other tools.
Having that in mind, I created a VS Code extension to add support for syntax highlighting and I believe it would be great if the project could stay under the elixir-lsp
umbrella. The extension can be found at https://github.com/msaraiva/vscode-surface.
I also have some ideas listed at the end of the Getting Started to improve developer experience by customizing ElixirSense. @lukaszsamson let me know what you think.
Cheers.
-marlus
Potential candidates
@lukaszsamson commented in #121 (comment):
Let's do them in follow up PRs. This one is already big. I'm not sure if callbacks, overridable and protocols are good candidates. Apart from those I'd include more suggestions from complete module: elixir/erlang modules, variables, attributes, map/struct keys. Elixir modules would probably work better with some letter downcasing.
Currently the clients have to match against "No documentation available" string. See elixir-lsp/elixir-ls#279 (comment)
Consider the example code below:
defmodule Vector do
@spec magnitude(Vec2.t()) :: number()
def magnitude(%Vec2{} = v), do: :math.sqrt(:math.pow(v.x, 2) + :math.pow(v.y, 2))
@spec normalize(Vec2.t()) :: Vec2.t()
def normalize(%Vec2{} = v) do
length = magnitude(v)
%{v | x: v.x / length, y: v.y / length}
end
end
When I hover mouse on length
in function normalize
, the hover document will show length
built-in document. But since magnitude
function has type spec. I expected the hover should show it as a number or not show when hover on length
variable.
From what I can tell it is possible to find references from a call, but you can't find references from the definition of a function.
So this works:
test "working example" do
buffer = """
defmodule A do
def a_fun do
B.Callee.fun()
^
end
end
"""
references = ElixirSense.references(buffer, 3, 14)
assert references != []
end
But this does not:
test "elixir-ls references test" do
buffer = """
defmodule B.Callee do
def fun() do
^
:ok
end
end
"""
references = ElixirSense.references(buffer, 2, 7)
assert references != []
end
I'm trying to use ElixirSense.references/3
(elixir-lsp/elixir-ls#39) but need to be able to find the references for a function from it's definition (which I think makes sense from a usability standpoint as well).
Main reason: elixir-ls already requires 1.7 and lots of tests are already failing on 1.6
ElixirSense.Core.Normalized.Code
to expose EEP-48 doc formatElixirSense.Core.Normalized.Typespec
ElixirSense.Core.Normalized.Tokenizer
I'm looking into a test failure in the https://github.com/elixir-lsp/elixir-ls/ repo. I believe that I've tracked it down to a potential bug that occurs when trying to find the actual_mod_fun of a function named "fun" fails because it is detected as a built-in type, but a function named "my_fun" or pretty much any other name succeeds.
Example module that is not correctly recognized:
defmodule B.Callee do
def fun() do
^
:ok
end
end
This results in a call to ElixirSense.Core.Introspection.actual_mod_fun/4
with the args:
mod_fun: {nil, :fun}
imports: []
aliases: []
module: B
In earlier versions of ElixirSense this would return {B, :fun}
but on the current master (899db30) it returns {nil, :fun}
because that is what is returned by find_builtin_type/1
(which executes before find_function_in_current_module/2
).
The change appears to have happened in b5c56c1
Note: I think this was the actual error underlying #41
Okay, was finally able to capture detailed info about the loop/memory issue mentioned in elixir-lsp/elixir-ls#82
Here are the screenshots that I captured
We can see that there is an infinite loop of lines 700, 712, 710 (this is on commit 2dc70af):
What is happening appears to be that find_metadata_function
is currently operating on a nil
module and then it recursively calls itself. So a solution would probably involve adding a case to the Enum.find/2
call that handles a nil
module non-recursively.
While I ran into this on commit 2dc70af, the same issue appears to still exist on the master branch.
Original discussion started here: msaraiva/elixir_sense#42 (comment)
As already explained, I'll be glad to transfer the ownership. We just need to synchronize the steps to minimize the troubles we might have. Does this sound feasible?
.elixir_ls
directory, then restart your editor
When I hover over a function implementation of a callback, it shows me term
typespec instead of the defined callback typespec. ie.
defmodule MyBehaviour do
@callback print(name :: binary()) :: :ok
end
defmodule MyPrinter do
@behaviour MyBehaviour
@impl true
def print(name), do: :ok
end
Hovering to MyPrinter.print
displays MyPrinter.print(term)
and it should be MyPrinter.print(binary) :: :ok
How can I see the correct function typespec?
Not sure if detecting that state
is a %State{}
struct is reasonable for a code snippet like:
%State{formatted: formatted} = state = socket.assigns.state
state = %{state | form[^]}
The [^]
represents the cursor and it should be able to be autocompleted to formatted
.
I noticed that ElixirLS does not use ElixirSense.references/3
. That means it will not benefit from the latest changes that provide accurate information on function calls references, including the column range and a bunch of other improvements. Those changes are absolutely necessary for the refactoring feature.
@balduncle, maybe this was the problem you were facing?
@JakeBecker be aware that the current ElixirLS implementation is not compatible with the latest version of ElixirSense. There's at least one breaking change regarding ElixirLS.LanguageServer.Providers.References
calling functions from the ElixirSense.Core.Introspection
module. Usually, in order to avoid more incompatibilities, clients should try as much as possible to only call functions from the public ElixirSense
module API, which is the official API.
As far as I could see, the only thing that was implemented in the ElixirLS version that was not implemented in ElixirSense, is the support for references in umbrella projects here.
So, I believe we should, in ElxirSense:
ElixirSense
module are part of the public API.In ElixirLS:
ElixirSense.references/3
instead of own implementation@axelson and @lukaszsamson I'm not sure if elixir-lsp/elixir-ls
is in sync with the upstream
version but I believe it would present the same problem.
Hi @lukaszsamson!
I can see the last commit is breaking the build so I wonder if there's more work to be merged soon to fix that. Otherwise, I think the commit should be reverted so we can keep the master stable to accept other changes. I don't have much context regarding the last changes but in case you need any help, please let me know. I have some stuff I want to commit but I prefer to wait for the master to be stable before pushing them.
Cheers.
I'm working on a plugin to improve Ecto
support for editors. The first two features are:
field
or add
. Example:from
:@lukaszsamson in the example above, how hard would be to identify the variable u
as an instance of %User{}
?
This will enable elixir-ls elixir-lsp/elixir-ls#126
The following test is failing
test "no completion inside docstring" do
buffer = """
defmodule MyModule do
@moduledoc \"\"\"
This is a module asd.
\"\"\"
end
"""
assert [] == ElixirSense.suggestions(buffer, 3, 24)
end
Suggestions are not aware that this is heredoc and are providing results for asd.
subject.
It seems that recursive macro expansion works differently now.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.