dense-analysis / ale

Check syntax in Vim/Neovim asynchronously and fix files, with Language Server Protocol (LSP) support
BSD 2-Clause "Simplified" License
13.58k stars 1.44k forks source link

ALE doesn't start bash-language-server or texlab #2790

Closed rharish101 closed 5 years ago

rharish101 commented 5 years ago

Information

VIM version

VIM - Vi IMproved 8.1 (2018 May 18, compiled Sep  3 2019 19:23:34)
Included patches: 1-1968

Operating System: Arch Linux, with zsh as the default shell

What went wrong

I have installed bash-language-server and texlab through the Arch Linux package. However, ALE does not start them when opening a .sh file or a .tex file (as seen through ALE's command history, and evidenced by the lack of completion), even when :ALEInfo reports that it has enabled language_server as a linter for the sh filetype and texlab for the tex filetype.

Reproducing the bug

  1. Install bash-language-server and texlab
  2. Open a .sh file or .tex file
  3. ALE does not show completion

:ALEInfo

For bash:


 Current Filetype: sh
Available Linters: ['language_server', 'shell', 'shellcheck']
  Enabled Linters: ['language_server', 'shell', 'shellcheck']
 Suggested Fixers: 
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'shfmt' - Fix sh files with shfmt.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_sh_language_server_executable = 'bash-language-server'
let g:ale_sh_language_server_use_global = 0
let g:ale_sh_shell_default_shell = 'zsh'
let g:ale_sh_shellcheck_change_directory = 1
let g:ale_sh_shellcheck_dialect = 'auto'
let g:ale_sh_shellcheck_exclusions = ''
let g:ale_sh_shellcheck_executable = 'shellcheck'
let g:ale_sh_shellcheck_options = ''
 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 = 100
let g:ale_completion_enabled = 1
let g:ale_completion_max_suggestions = 50
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 = 1
let g:ale_fixers = {'go': ['gofmt'], 'cpp': ['uncrustify'], 'python': ['black', 'isort']}
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_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {'python': ['pyls']}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
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 = {'.*\.tex$': {'ale_enabled': 0}}
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 1
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_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:

(executable check - success) zsh
(finished - exit code 0) ['/bin/zsh', '-c', 'zsh -n ''/tmp/vwWguDS/1/concatenate-mp3.sh''']

<<<NO OUTPUT RETURNED>>>

(executable check - failure) shellcheck

For tex:


 Current Filetype: tex
Available Linters: ['alex', 'chktex', 'lacheck', 'proselint', 'redpen', 'texlab', 'textlint', 'vale', 'writegood']
   Linter Aliases:
'writegood' -> ['write-good']
  Enabled Linters: ['alex', 'chktex', 'lacheck', 'proselint', 'redpen', 'texlab', 'textlint', 'vale', 'writegood']
 Suggested Fixers: 
  'latexindent' - Indent code within environments, commands, after headings and within special code blocks.
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'textlint' - Fix text files with textlint --fix
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_tex_chktex_executable = 'chktex'
let g:ale_tex_chktex_options = '-I'
let g:ale_tex_lacheck_executable = 'lacheck'
let g:ale_tex_texlab_executable = 'texlab'
let g:ale_tex_texlab_options = ''
 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 = 100
let g:ale_completion_enabled = 1
let g:ale_completion_max_suggestions = 50
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 = 1
let g:ale_fixers = {'go': ['gofmt'], 'cpp': ['uncrustify'], 'python': ['black', 'isort']}
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_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {'python': ['pyls']}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '%code: %%s'
let g:ale_lsp_root = {}
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 = 1
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_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:

(executable check - failure) alex
(executable check - success) chktex
(finished - exit code 0) ['/bin/zsh', '-c', 'chktex -v0 -p stdin -q -I < ''/tmp/vmKvnpU/1/example.tex''']

<<<OUTPUT STARTS>>>
stdin:3:12:1:Command terminated with space.
stdin:27:23:1:Command terminated with space.
stdin:28:23:1:Command terminated with space.
<<<OUTPUT ENDS>>>

(executable check - success) lacheck
(finished - exit code 0) ['/bin/zsh', '-c', '''lacheck'' ''/tmp/vmKvnpU/2/example.tex''']

<<<NO OUTPUT RETURNED>>>

(executable check - failure) proselint
(executable check - failure) redpen
(executable check - failure) textlint
(executable check - failure) vale
(executable check - failure) write-good
hsanson commented 5 years ago

@rharish101 one of the requirements for language servers is that they must be provided a project root path. Unfortunately sometimes it is not easy to determine such path within ALE so some heuristics are used instead.

For bash-language-server the project root is set to the closest folder that contains a .git directory. See ale_linters#sh#language_server#GetProjectRoot(buffer) method for more details. This means that this language server will only work on git tracked projects.

For texlab is strange since the ale_linters#tex#texlab#GetProjectRoot(buffer) method always returns an empty string. This effectively disables this language server for all files. Maybe the author of texlab support may provide more information.

rharish101 commented 5 years ago

Thanks a lot for pointing this out. I now defined a new linter (through ale#linter#Define) using a custom function for finding the project root, as follows:

function! BashLangServProjRoot(buffer)
  let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
  let l:curr_dir = fnamemodify(bufname(a:buffer), ':h')
  return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : l:curr_dir
endfunction

call ale#linter#Define('sh', {
\   'name': 'bashls',
\   'lsp': 'stdio',
\   'executable': function('ale_linters#sh#language_server#GetExecutable'),
\   'command': function('ale_linters#sh#language_server#GetCommand'),
\   'project_root': function('BashLangServProjRoot'),
\})

Is this method recommended for use? I would like your advice on using this in my vimrc. If it's fine, then I'll use this for texlab too.

hsanson commented 5 years ago

That would work as a temporary fix for you so feel free to do so. The correct way would be to fix the FindRoot() methods of these linter so no configuration is required for them to work.

You can also use g:ale_lsp_root variable to override the current root.

hsanson commented 5 years ago

Duplicate #2699 Related #2501

w0rp commented 5 years ago

The project root functions are working as expected. You can specify the project root with ale_lsp_root if the default project root detection doesn't work. Someone might be able to find a way to detect more project roots for Bash scripts, but I don't know what you'd look for.