VIM version
NVIM v0.3.1-1-g489d32f2b
Build type: RelWithDebInfo
Operating System: Ubuntu 18.04
When saving a rust file that has an error, ale shows no lint/error message. When looking at the ALEInfo output, it appears that calls to cargo build/cargo check fail.
I've tried solving the issue by ale_linters/rust/cargo.vim and changing the quoting, shell command, etc. Without any success. I've also tried changing the ale settings for rust, but they all still seem to fail at this step. Admittedly though I'm not very familiar with neovim api/vimscript.
I've also reproduced this issue on my other laptop. Same operating system, but with fresh install of neovim, ale, rust and configuration files.
I'm happy to submit a PR if there's a fix somewhere that can be made.
Thanks
Example failing code
fn main() {
let a = 10;
let b: String = a;
println!("Hello, world!");
}
Current Filetype: rust
Available Linters: ['cargo', 'rls', 'rustc']
Enabled Linters: ['cargo']
Suggested Fixers:
'remove_trailing_lines' - Remove all blank lines at the end of a file.
'rustfmt' - Fix Rust files with Rustfmt.
'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
Linter Variables:
let g:ale_rust_cargo_avoid_whole_workspace = 1
let g:ale_rust_cargo_check_all_targets = 0
let g:ale_rust_cargo_check_examples = 0
let g:ale_rust_cargo_check_tests = 0
let g:ale_rust_cargo_default_feature_behavior = 'default'
let g:ale_rust_cargo_include_features = ''
let g:ale_rust_cargo_use_check = 1
Global Variables:
let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'javascript': ['eslint']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_lint_on_insert_leave = 0
let g:ale_linter_aliases = {}
let g:ale_linters = {'javascript': ['eslint']}
let g:ale_linters_explicit = 0
let g:ale_list_window_size = 10
let g:ale_list_vertical = 0
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'Error'
let g:ale_echo_msg_format = '%code: %%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'Warning'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'javascript': ['eslint']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 200
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'always'
let g:ale_lint_on_insert_leave = 0
let g:ale_linter_aliases = {}
let g:ale_linters = {'javascript': ['eslint']}
let g:ale_linters_explicit = 0
let g:ale_list_window_size = 10
let g:ale_list_vertical = 0
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 0
let g:ale_sign_error = '>>'
let g:ale_sign_info = '--'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = '>>'
let g:ale_sign_style_warning = '--'
let g:ale_sign_warning = '--'
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
Command History:
(executable check - success) cargo
(finished - exit code 0) ['/usr/bin/zsh', '-c', 'cargo --version']
(finished - exit code 1) ['/usr/bin/zsh', '-c', 'cd ''/home/holden/code/tmp/foo'' && cargo build --frozen --message-format=json -q']
<<<OUTPUT STARTS>>>
nvim: Unknown option argument: "--frozen"
More info with "nvim -h"
<<<OUTPUT ENDS>>>
After some more random investigation I don't think is an Ale issue. I looked into how neovim runs commands. I modified a script found here https://neovim.io/doc/user/job_control.html. When I run the below script with nvim -u foo.vim it opens up a blank neovim window. Like you'd get if you just ran nvim. If you comment out the zsh portion and uncomment the bash version, it prints the expected output. Oddly enough I couldnt mimic this behavior running any other command, regardless of location, standard out redirection, etc.
I was able to bypass this issue in ale by forcing ale to use bash in autoload/ale/job.vim (just returning a hardcoded string) (Probably a better way to do this).
If this all sounds correct, I'll close the issue and move it to the relevant discussion.
Cheers
foo.vim
function! s:OnEvent(job_id, data, event) dict
if a:event == 'stdout'
let str = self.shell.' stdout: '.join(a:data)
elseif a:event == 'stderr'
let str = self.shell.' stderr: '.join(a:data)
else
let str = self.shell.' exited'
endif
call append(line('$'), str)
endfunction
let s:callbacks = {
\ 'on_stdout': function('s:OnEvent'),
\ 'on_stderr': function('s:OnEvent'),
\ 'on_exit': function('s:OnEvent')
\ }
let job2 = jobstart(['zsh', '-c', 'cargo build'], extend({'shell': 'shell 2'}, s:callbacks))
"let job2 = jobstart(['bash', '-c', 'cargo build'], extend({'shell': 'shell 2'}, s:callbacks))
It would be useful to have an override option for the short term. A PR could be set up for managing that, if you'd like to open one. As a temporary fix, if you don't often use the shell, you could set shell=/bin/bash or otherwise until it works.
Does this issue also happen with a clean zsh setup? no zshrc, profile, env, etc. ?
Running the command with -df for a cleanish set up, shows no difference. I'll investigate a truly clean set up when I get the chance later tonight/tomorrow.
I'll look into making a PR for adding an option to set the shell ale uses. In the meantime I have just edited the function in ale that looks for the shell to use and had it hard coded to return bash.
Only enough cargo is the only command that I've found with this discrepancy. Even other commands inside that directory run fine. It's seemingly bizarre.
Thanks for the reply!
I can't think of an explanation for this. Perhaps we should just make the shell that ALE uses configurable, and then you can set it to use bash instead. ALE could still fall back on $shell if the option isn't set. A second option would be needed for the shell flag to use, (-c, etc.) which could only be used if the shell option is set.
$ nvim --version
NVIM v0.3.1-1-g489d32f2b
And I'm using ale 1d4f98553852499e0f8ebd951db6ada2b1d973e3, this is the same configuration on both of my machines
On both my machines, ale runs the write-good linter on markdown files just fine:
(executable check - success) write-good
(finished - exit code 5) ['/usr/bin/zsh', '-c', '''write-good'' ''/tmp/nvimMri3oD/14/CHANGELOG.md''']
<<<OUTPUT STARTS>>>
In /tmp/nvimMri3oD/14/CHANGELOG.md
=============
ges to this project will be documented in this file.
^^^^^^^^^^^^^
"be documented" may be passive voice on line 3 at column 41
And I can reproduce @stegmanh 's results on my fresh ArchLinux desktop:
(finished - exit code 1) ['/usr/bin/zsh', '-c', 'cd ''/path/to/my/rust/project'' && cargo build --frozen --message-format=json -q']
<<<OUTPUT STARTS>>>
nvim: Unknown option argument: "--frozen"
More info with "nvim -h"
<<<OUTPUT ENDS>>>
But, on my Pixelbook with Debian, I get:
(finished - exit code 101) ['/usr/bin/zsh', '-c', 'cd ''/path/to/my/rust/project'' && cargo check --frozen --message-format=json -q']
<<<OUTPUT STARTS>>>
{"//":"the proper JSON output from a successful cargo run indicating some errors in my code"}
<<<OUTPUT ENDS>>>
I'm not sure why neovim on the Pixelbook is merrily using /usr/bin/zsh to execute things, but neovim on ArchLinux is having the same "nvim: Unknown option argument" issues...
Update: it hopefully doesn't matter, but I'm using zsh 5.3.1 (x86_64-debian-linux-gnu) on my Pixelbook, and zsh 5.6.2 (x86_64-pc-linux-gnu) on ArchLinux
Hey @jokeyrhyme
I haven't done much rust coding recently so I haven't investigated much further. I think it's a neovim or zsh issue though. Since I was able to reproduce outside of Ale.
I'm running zsh 5.4.2 (x86_64-ubuntu-linux-gnu) seeing the same issue on my XPS w/ Ubuntu 18.01. Ill check the zsh version on my other install.
If it helps at all, inside of your neovim autoload/ale folder there's job.vim file that you can edit to bypass the issue. If you edit around line 188 where it says return split(&shell) + split(&shellcmdflag) + [l:command] and change it to return ['/bin/bash'] + split(&shellcmdflag) + [l:command] it fixes the issue by using bash instead.
I have the code in a branch to support this as an option, just haven't had the chance to clean it up enough to make a PR.
Is it possible to change it to /bin/sh instead? I am pretty sure that it exists on almost every system, and don't think we use too many nonstandard features.
Don't see why not. Just tested on my machine and it works fine with /bin/sh
The PR would allow you to set it to anything you wanted
If /bin/sh does work on every Unix system, then I'm good with that solution.
Is it possible / advantageous to use /usr/bin/env sh for this? The shellcheck folks tend to trust the cross-UNIX location of "env" more than the location of "sh": https://github.com/koalaman/shellcheck/wiki/SC2239
My opinion on the matter is that we should check for /bin/sh but provide a custom option in case someone has a weird setup.
https://github.com/vim/vim/blob/master/configure uses #! /bin/sh so Vim assumes that /bin/sh exists, perhaps so should we.
I read up on it, just to be sure.
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html
Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh, and should be determined by interrogation of the PATH returned by getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell built-in.
Essentially, we can't assume /bin/sh exists. I thought that was the case. We may be able to search for the valid location of it, though.