diff --git a/autoload/ale/handlers/shellcheck.vim b/autoload/ale/handlers/shellcheck.vim index 351d6d3f..701c43b2 100644 --- a/autoload/ale/handlers/shellcheck.vim +++ b/autoload/ale/handlers/shellcheck.vim @@ -1,8 +1,32 @@ " Author: w0rp " Description: This file adds support for using the shellcheck linter +" Shellcheck supports shell directives to define the shell dialect for scripts +" that do not have a shebang for some reason. +" https://github.com/koalaman/shellcheck/wiki/Directive#shell +function! ale#handlers#shellcheck#GetShellcheckDialectDirective(buffer) abort + let l:linenr = 0 + let l:pattern = '\s\{-}#\s\{-}shellcheck\s\{-}shell=\(.*\)' + let l:possible_shell = ['bash', 'dash', 'ash', 'tcsh', 'csh', 'zsh', 'ksh', 'sh'] + + while l:linenr < min([50, line('$')]) + let l:linenr += 1 + let l:match = matchlist(getline(l:linenr), l:pattern) + + if len(l:match) > 1 && index(l:possible_shell, l:match[1]) >= 0 + return l:match[1] + endif + endwhile + + return '' +endfunction + function! ale#handlers#shellcheck#GetDialectArgument(buffer) abort - let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + let l:shell_type = ale#handlers#shellcheck#GetShellcheckDialectDirective(a:buffer) + + if empty(l:shell_type) + let l:shell_type = ale#handlers#sh#GetShellType(a:buffer) + endif if !empty(l:shell_type) " Use the dash dialect for /bin/ash, etc. diff --git a/test/test_shell_detection.vader b/test/test_shell_detection.vader index 697054d0..11d801c3 100644 --- a/test/test_shell_detection.vader +++ b/test/test_shell_detection.vader @@ -127,3 +127,51 @@ Execute(The dash dialect should be used for the shell and the base function): Execute(dash should be used for shellcheck): AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a Bash shellcheck shell directive): + # shellcheck shell=bash + +Execute(bash dialect should be detected appropriately): + AssertEqual 'bash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a sh shellcheck shell directive): + #shellcheck shell=sh + +Execute(sh dialect should be detected appropriately): + AssertEqual 'sh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a tcsh shellcheck shell directive): + # shellcheck shell=tcsh + +Execute(tcsh dialect should be detected appropriately): + AssertEqual 'tcsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a zsh shellcheck shell directive): + # shellcheck shell=zsh + +Execute(zsh dialect should be detected appropriately): + AssertEqual 'zsh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a csh shellcheck shell directive): + # shellcheck shell=csh + +Execute(zsh dialect should be detected appropriately): + AssertEqual 'csh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ksh shellcheck shell directive): + # shellcheck shell=ksh + +Execute(ksh dialect should be detected appropriately): + AssertEqual 'ksh', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a dash shellcheck shell directive): + # shellcheck shell=dash + +Execute(dash dialect should be detected appropriately): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr('')) + +Given(A file with a ash shellcheck shell directive): + # shellcheck shell=ash + +Execute(dash dialect should be detected for ash that shellcheck does not support): + AssertEqual 'dash', ale#handlers#shellcheck#GetDialectArgument(bufnr(''))