Skip to content

Releases: stubbedev/shell-lsp

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 11 Oct 20:01

shell-lsp 0.4.1 fixes diagnostics in Neovim.

Fixes

  • Diagnostic tags are sent as an integer array. They went out as a base64
    string, so Neovim raised bad argument #1 to 'ipairs' whenever a file had
    a finding tagged deprecated or unnecessary, such as backtick command
    substitution.

Install

Release binaries for Linux, macOS and Windows (amd64, arm64) with
SHA256SUMS are attached below. Alternatively
go install github.com/stubbedev/shell-lsp@v0.4.1 or
nix profile install github:stubbedev/shell-lsp. For VS Code, install the
Shell LSP extension, or shell-lsp-0.4.1.vsix below. Editor setup:
docs/editors.md.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 18:16

shell-lsp 0.4.0 is about understanding and steering the linter from the
editor: diagnostics explain themselves on hover, you can see which shell a
file is linted as and switch it, choose how strict linting is with one
setting, and fix or ignore a check across a file or the whole workspace.

Highlights

  • Diagnostics explain themselves: hovering a finding shows its severity,
    a one-line summary, a before/after preview of its fix marked safe or for
    review, how to silence it, and links to its entry in
    docs/checks.md
    or docs/rules.md
    and the ShellCheck wiki. Diagnostic codes link to those docs in editors
    that support it.
  • See and switch the shell: VS Code's status bar shows the shell a file is
    linted as and what decided it ("from the shebang #!/usr/bin/env bash",
    "guessed from the .sh extension"). Clicking it switches the shell by
    writing a # shellcheck shell= directive, which every editor and
    shell-lsp check honour. Other editors can ask the server through the new
    shellLsp/documentDialect and shellLsp/setDialect requests; a Neovim
    statusline snippet is in
    docs/editors.md.
  • lint.profile: minimal keeps errors, warnings and the notes that
    point at real bugs; recommended (the default) is unchanged; strict
    turns on the optional checks. shell-lsp check --profile does the same.
    Explicit lint.exclude, lint.optional and directives still win.
  • Per-check actions on a diagnostic: fix every finding of that check in
    the file, ignore it in the file (merged into the header's disable=
    line), or ignore it in the workspace (added to the nearest
    .shellcheckrc, created at the folder root if needed, after
    confirmation).

Changes

  • The editor now applies the nearest .shellcheckrc (including
    ~/.shellcheckrc and $XDG_CONFIG_HOME/shellcheckrc) the way
    shell-lsp check does: its disable, enable and extended-analysis
    settings affect diagnostics, a broken file is reported by name, and edits
    to it are picked up. Its shell= and source-path= are still read only by
    the command line.
  • A new # shellcheck shell= line is inserted after the existing header
    directives instead of directly after the shebang.
  • VS Code's generic shellscript language no longer counts as naming the
    shell, so a file without a shebang is shown as a guess.

Install

Release binaries for Linux, macOS and Windows (amd64, arm64) with
SHA256SUMS are attached below. Alternatively
go install github.com/stubbedev/shell-lsp@v0.4.0 or
nix profile install github:stubbedev/shell-lsp. For VS Code, install the
Shell LSP extension, or shell-lsp-0.4.0.vsix below. Editor setup:
docs/editors.md.

Known limitations

  • .shellcheckrc files get no completion or hover, because editors do not
    send them to language servers.

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 17:36

shell-lsp 0.3.0 makes # shellcheck directives first-class in the editor,
describes every check, adds six native checks, parses more of what the
shells accept, and fixes a parser crash and two kinds of findings that
never reached files with Windows line endings or a byte order mark.

Highlights

  • Editing directives: completion inside # shellcheck comments for keys,
    every check code (typing 208 finds SC2086), optional check names, shells
    and source= paths; hover on a code shows its severity, summary, wiki or
    rules link and how many findings the directive silences here;
    source= paths are links and go-to-definition targets; directives are
    highlighted.

  • Every check described: all 473 checks carry a one-line summary, shown
    in hover and completion and listed with their severities and optional
    names in docs/checks.md.
    shell-lsp check --list-optional names the codes each optional check
    turns on.

  • New native checks
    (docs/rules.md):

    • SL2004 a trap set inside $(…) or a pipeline stage, which never
      reaches the script;
    • SL2005 an exit inside $(…) or a pipeline stage that only leaves
      the subshell while the script carries on;
    • SL2006 a mktemp file or directory nothing ever removes, with a fix
      that adds a cleanup trap;
    • SL2007 a function that pushdes without ever popding;
    • SL2008 a ${…} the shell accepts when reading the script but stops on
      with "bad substitution" when it runs it, such as ${};
    • SL2009 (optional, enable=unused-directives) disable= codes that
      silence nothing, with a safe fix that removes them.
  • More of the shells' grammar: associative-array keys such as [e/]=0
    and ${m[a.b]}, and expansions bash only rejects at run time, now parse
    instead of producing syntax errors; on a 2,579-script corpus the
    remaining parse errors are in a file bash rejects too.

  • Faster than 0.2.0 despite the new checks: about 6% less CPU and 8%
    less memory per keystroke on a 5,000-line script, 11% less CPU and 18%
    fewer system calls when diagnosing a whole workspace cold, and 8% less CPU
    for shell-lsp check.

Fixes

  • v=$(( x y )) and similar one-character typos inside arithmetic made
    the parser panic, losing every diagnostic for the document and crashing
    shell-lsp check (fixed upstream-ready as fork patch 0017).
  • Scripts saved with Windows line endings, which bash fails on with
    $'\r': command not found, now get SC1017, and a UTF-8 byte order mark
    that breaks the shebang gets SC1082, in the editor and from the command
    line; both were lost when the text was normalised before linting.
  • A document with classic Mac line endings no longer falls out of sync when
    an edit joins a lone carriage return and a line feed.
  • Typo hints after a syntax error on a very long line no longer scan the
    whole line: 1.7 s became 18 ms on a 1.7 MB line.
  • SC3012 names >= and <= as written in a [ ] test.
  • On Windows, stopping a Bats run, or the server exiting, now ends every
    process the suite started instead of only bash, by running each suite in
    a job object.

Install

Release binaries for Linux, macOS and Windows (amd64, arm64) with
SHA256SUMS are attached below. Alternatively
go install github.com/stubbedev/shell-lsp@v0.3.0 or
nix profile install github:stubbedev/shell-lsp. For VS Code, install the
Shell LSP extension, or shell-lsp-0.3.0.vsix below. Editor setup:
docs/editors.md.

Known limitations

  • .shellcheckrc files get no completion or hover, because editors do not
    send them to language servers.

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 14:12

shell-lsp 0.2.0 adds a command line that drops in where shellcheck and
shfmt ran, Windows support, many more quick fixes, richer completion and
hover, and a round of robustness work: the server now stays within bounded
memory and time on any input, including hostile ones.

Highlights

  • shell-lsp check and shell-lsp fmt: check takes ShellCheck's
    options, .shellcheckrc files, output formats (tty, gcc, json, json1,
    checkstyle, diff, quiet, plus SARIF for code scanning) and exit codes, and
    fmt takes shfmt's flags, so both drop into CI and pre-commit hooks and
    report exactly what the editor shows. The repository ships pre-commit
    hooks (docs/cli.md).
  • Windows (#31):
    amd64 and arm64 .exe binaries, drive-letter and UNC URIs,
    case-insensitive paths, PATHEXT executable lookup, Bats through Git Bash
    or MSYS2, and a windows-latest CI job. The VS Code extension downloads
    the Windows binary too.
  • Quick fixes: 55 check codes now carry fixes, up from 15. Every fix says
    what it does and is marked either safe (keeps the script's behaviour) or
    for review. Fix-all, shellLsp.fixAll and check -f diff apply only the
    safe ones through one pipeline. New actions: add a shebang, remove
    redundant quotes, $[ ] and expr to $(( )), and disable directives for
    SL codes. Edits that touch another file ask for confirmation.
  • Completion and hover: test operators, set -o/shopt/setopt
    options, emulate modes, signals and trap conditions, parameter-expansion
    operators and zsh flags and glob qualifiers, array keys, printf
    conversions, case values taken from getopts or earlier comparisons,
    and the flags of builtins, all documented per shell. Idiom snippets at the
    start of a statement, and completions that replace the rest of a word.
  • New native checks: SL1005 for downloaded code run unchecked
    (curl … | sh, sh -c "$(curl …)", source <(curl …)), SL2002 for @
    transformations the shell does not know, SL2003 for declarations that
    assign an invalid name
    (docs/rules.md).
  • Closer to ShellCheck where ShellCheck is right: three parser bugs that
    cascaded into missed findings are fixed (unknown ${x@op} operators, a #
    after a word inside $(…), invalid declaration names), set, shopt and
    setopt are read as option changes, values inherited from the
    environment stay untrusted, and command -v $x is checked like type $x.

Robustness and security

  • Scripts that source /dev/zero, /dev/stdin, a FIFO or a device no longer
    make the server read without bound or hang; sourced files, .editorconfig
    and Bats files are read only when they are regular files, up to a size
    limit, and manual pages decompress to at most 16 MiB.
  • Memory leaks fixed in the snapshot, semantic token, diagnostics, workspace,
    editorconfig and manual-page caches, in pending client requests and in
    JSON-RPC buffers. A soak test proves the server returns to its baseline.
  • Syntax nested more than 1000 levels deep is rejected instead of
    exhausting the stack, deep nesting lints in linear time and memory, and
    several quadratic paths are gone (a case with 10,000 branches, fix-all
    over tens of thousands of findings, thousands of here-documents).
  • Brace sequences at the int64 limits terminate, and the forked parser's
    arithmetic no longer narrows integers (CodeQL clean). Thirteen new fuzz
    targets cover the parser, linter, edits, URIs and command-line parsing.

Install

Release binaries for Linux, macOS and Windows (amd64, arm64) with
SHA256SUMS are attached below. Alternatively
go install github.com/stubbedev/shell-lsp@v0.2.0 or
nix profile install github:stubbedev/shell-lsp. For VS Code, install the
Shell LSP extension, or shell-lsp-0.2.0.vsix below. Editor setup:
docs/editors.md.

Known limitations

  • On Windows, stopping a running Bats suite ends bash but may leave its
    child processes running.
  • A document using lone carriage returns (classic Mac line endings) can fall
    out of sync after an edit that inserts a line feed right after one.

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 12:04

The first release of shell-lsp: a language server for bash, zsh, POSIX sh,
dash, ksh and busybox sh in a single static binary with no runtime
dependencies. The linter, the formatter, the manual-page reader and the
.editorconfig reader are all built in.

Highlights

  • zsh is linted by zsh's rules: no bash word-splitting or globbing
    warnings where zsh does neither, zsh's own parameters and hook arrays are
    known, glob qualifiers, parameter flags and subscript flags are
    understood, and #compdef/#autoload files are detected as zsh.
  • Full zsh and ksh93 parsing: zsh syntax, from short and brace loops,
    repeat, foreach and { } always { } to anonymous functions with
    arguments, glob qualifiers and math functions, and ksh93's compound
    variables, types, namespace, .sh.math functions and seek redirections
    parse into a full syntax tree instead of syntax errors, through a patched
    fork of mvdan.cc/sh whose patches are kept ready for upstream
    (#23).
  • Native linter that reuses ShellCheck's check codes and directives, lints
    zsh, follows sourced files, and adds its own SL checks: untrusted input
    pasted into code run by eval, sh -c or source, opt-in arithmetic
    injection, functions a script never calls, and syntax and regex errors in
    embedded awk, sed and jq programs (docs/rules.md).
  • Completion and hover for builtins, keywords, functions, variables and
    paths, plus the options and (nested) subcommands of installed commands, read
    natively from their manual pages, also behind sudo, env, xargs and
    similar wrappers.
  • Sourced files act as imports: their functions and globals complete,
    hover, navigate and are followed by the linter; open buffers win over disk.
  • Navigation: definition, references, rename, call hierarchy, document
    and workspace symbols, highlights, links, selection ranges, folding.
  • Editing aids: semantic tokens (including inside awk, sed and jq
    programs), inlay hints, signature help, code lenses.
  • Formatting with the printer shfmt is built on, honouring
    .editorconfig the way shfmt does.
  • Quick fixes and refactorings: extract variable or function, inline
    variable, backticks to $(…), [ ] to [[ ]], if/elif to case, toggle
    function, add strict mode, move a function into a sourced file, and a
    fix-all source action.
  • Bats: tests in the outline, "Run file" and "Run test" lenses that run the
    project's bats and turn failures into diagnostics that follow their test.
  • Fast: whole-file lint of 10k lines in tens of milliseconds, parallel
    workspace indexing, single-flight caching per document version.

Install

Release binaries for Linux and macOS (amd64, arm64) with SHA256SUMS are
attached below. Alternatively go install github.com/stubbedev/shell-lsp@v0.1.0
or nix profile install github:stubbedev/shell-lsp. For VS Code, install
the Shell LSP extension, shell-lsp-0.1.0.vsix below, which can also
download the server for you. Editor setup:
docs/editors.md.

Known limitations

  • Windows is not supported yet (#31).