credo only provides style warnings, but no syntax errors. Syntax errors can be generated through running mix compile.
A quick side note on the credo linter - mix tasks only work if you call them from the project root. As a result, this linter only works if you open vim from the project root.
Is there some way to detect the location of the project root? If that can be done, then ALE could always run the command from that directory.
Do you have an example of what a syntax error looks like, and some of the normal errors? Some Vader tests could be added to cover that, and that could be fixed.
Is there some way to detect the location of the project root? If that can be done, then ALE could always run the command from that directory.
Yeah, traverse up the structure until you find the file mix.exs.
Do you have an example of what a syntax error looks like, and some of the normal errors? Some Vader tests could be added to cover that, and that could be fixed.
Sure. Error messages give you paths relative to the root project directory.
== Compilation error on file {relative_path_to_file.ex(s)} ==
** ({error_type}) {relative_path_to_file.ex(s)}:{line_no}: {msg}
{stack_trace}
The other "normal errors" I've seen are in the form of warnings:
warning: {message}
{relative_path_to_file.ex(s)}:{line_no}
There's also a chance that deps produce warnings (I think you would ignore these though):
warning: {message}
{absolute_path_to_deps_file.ex(s)}:{line_no}
I'll take a look later. Could you provide some example output for errors and warnings? I'm after some real output I can add to the Vader test suite. That's the best way to fix issues like this and check for regressions.
Some example output (in code blocks) for errors:
Example error: missing an end statement
mix: missing terminator: end (for "do" starting at line 1)
Example error: unused variable
mix: variable users is unused
Example error: typing Repo.inset instead of Repo.insert (using phoenix/ecto)
mix: function Rumbl.Repo.inset/1 is undefined or private
edit - Rumbl is the app name in this last case.
Thanks for the example output. :+1: If someone wants to give this a go, go for it. I realised this is actually not a bug in the current linter, but a request for another one.
Changing to the project root for running the linter shouldn't be hard. There is a utility function which will help with this.
let l:project_dir = fnamemodify(ale#util#FindNearestFile(a:buffer, 'mix.exs'), ':h')
return 'cd ' . fnameescape(l:project_dir) . ' && mix compile ...'
I'm not sure about the other details. Implementing #333 might be required for this, maybe not.
To add to the discussion, compiling is not recommended as it won't work with exs files I think. elixirc is also not recommended since it can execute arbitrary code.
The official recommendation was/is to make a custom script that does something among the lines of File.read |> Code.string_to_quoted.
elixir -e 'r = System.argv |> List.first |> File.read! |> Code.string_to_quoted; if elem(r, 0) == :error do IO.inspect(elem(r,1)); end' -- filename.ex
https://github.com/flycheck/flycheck/issues/630
I'm prepared to give this a go (and add support for dogma as well), but I'm still in the process of switching over to ale.
The above also means we won't need to compile the _entire_ project to check a single file.
Sure, give it a go. I don't know much of anything about the language myself.
Any progress on this?
I haven't done anything. I don't know how elixir works myself.
@klingberg I suggest you use the dogma linter I added, it does syntax checking plus more
Ok, cool! Can you give me some pointers how to configure my settings, doesn't seem to work out of the box?
Nevermind, it is working! It was just the mix file that didn't lint.
@archSeer can dogma be used when not using mix? I am interested in a linter for one-off modules which are not handled by mix. Maybe adding an additional linter as described in your https://github.com/w0rp/ale/issues/340#issuecomment-287562515 would be beneficial for such cases.
@evnu I'm not sure I follow, just install dogma globally as per installation notes, and it should work for any application
@archSeer I installed dogma globally. Then, I edit an elixir file with a simple error (e.g. the file contains only receive do), but I do not create a mix project. When I run dogma myself, an error is reported:
$ dogma
Inspecting 1 file.
X
1 files, 1 error!
== bla.exs ==
1: SyntaxError: missing terminator: end (for "do" starting at line 1)
But within vim, the error is not mentioned. With g:ale_history_log_output=1 I found in :ALEInfo:
(finished - exit code 1) ['/bin/zsh', '-c', 'mix dogma ''/tmp/el/bla.exs'' --format=flycheck']
So the call to mix dogma seems to fail, if the file is not part of a mix project. I don't know if there is a good work-around.
@evnu Did you make any progress on puzzling this one out?
I ended up installing dogma globally and was hoping it would just work with ale but ran into the same issue as you and found this issue via googling. Everything looks to be set up correctly. Dogma in PATH after compilation but not receiving errors from vim (Ale is working fine with rubocop and other linters, but I really need it for elixir... =] ).
@wakatara I stopped using dogma in favour of credo. Additionally, I started to implement a simple ale linter which uses elixirc (https://github.com/evnu/ale/commit/0514843491455c099155cdf7517a7afd51a179ea to https://github.com/evnu/ale/commit/9b4f9557dc06807094e84d4a805be61ec65c7e1c). That linter is a little rough around the edges, as it does not take dependencies into account, but it does the job for me right now. If there is general interest in that linter, I will prettify the commits and issue a pull request for ale.
@evnu What? Just when I got credo linting working on my lonesome?... =]
I value your experience, so will install the standalone on credo and kill off dogma for now before my next elixir project (I also think the "marketing" of credo of being more like rubocop did make me feel it might be slightly better, but was just happy to get linting, period. =]
I think the more options the better though tbh I'm not in a position to judge the merits of the various linters. Since mistyping is my biggest issue when coding things I'm really just looking for something that is going to catch my issues before I have to puzzle out why phoenix keeps throwing an exception. =]
If you feel it's a better linter though, I'd be quite interested in it.
is there a particular reason you prefer that over credo and, by extension, dogma?
@wakatara I could not make credo or dogma check syntax reliably, thus I went down the elixirc road instead. I would not say that this is a better linter, I was just missing syntax checks.
@evnu is there any way we could merge your elixirc checker into the main Ale repository? it would be really useful to me.
/
@colbydehart I am currently quite busy, but I just rebased my WIP onto ale's current master (c1da786). Check out https://github.com/evnu/ale/tree/add-elixirc-linter if you want to give it a spin. To try it, add my repo as a remote, fetch and checkout the branch. When trying, please keep in mind that I did not yet implement handling warnings. If anyone wants to use that branch to come up with a proper pull request, feel free to take the existing WIP.
@evnu awesome! i will check it out. Thanks for sharing.
@evnu Throw up a pull request if you want, and I will look at it when I get the time. I'm currently working through a backlog of emails right now.
I checked out @evnu's code and altered it to use mix instead of elixirc. Made a PR here https://github.com/w0rp/ale/pull/1618
Is there a short example on how to configure the mix linter to show syntax errors since #1618 was merged? I can't get anything working here locally - I just have to notice when mix format doesn't actually run and try and find my error or run mix compile in another terminal.
It's worth mentioning here that I just disabled the mix linter by default. See :help g:ale_linters. It can consume way too much CPU power for some people.
@deybhayden were you able to figure out this situation of getting some sort of linting feedback (mix, elixir-ls, dialyxir, credo, etc)? with ALE + (neo)vim? a super bummer not getting any sort of feedback until like you said, you realize mix_format isn't fixing your code on save because of some error.
My plan was to add credo to my project and see if that integration worked - since mix wasn't working for me. Just haven't got a chance to do it yet since credo is a lot more opinionated & configurable (requiring more time to set it up properly) vs hey you've got a syntax error (why I tried out the mix one first).
@megalithic I got elixir-ls to work (introduced in #1956). You just need to download and build a release of elixir-ls in another directory, then specify the ls release directory in your vim files like so:
" Assuming repo is checked out at ~/.elixir-ls, and just specified release as the output directory of the release build process
let g:ale_elixir_elixir_ls_release = $HOME.'/.elixir-ls/release'
I think this ^^^ should be more stable than using the mix linter for anyone looking at this now.
tbh, i would recommend just removing the mix linter since it has been causing so many problems.
It breaks new phoenix projects i know. I would advise ppl to use the elixir-ls linter for syntax errors in the docs.
The mix linter has already been disabled by default. I offer the same advice to people. Some people may want to use the mix linter, so I'll leave it there for now.
@deybhayden does elixir-ls provide linting info for you? The completion works fine with elixir-ls, but I don't get any syntax error reporting.
Most helpful comment
@wakatara I stopped using
dogmain favour ofcredo. Additionally, I started to implement a simple ale linter which useselixirc(https://github.com/evnu/ale/commit/0514843491455c099155cdf7517a7afd51a179ea to https://github.com/evnu/ale/commit/9b4f9557dc06807094e84d4a805be61ec65c7e1c). That linter is a little rough around the edges, as it does not take dependencies into account, but it does the job for me right now. If there is general interest in that linter, I will prettify the commits and issue a pull request for ale.