From 433779916223596dce3ea64f4b77300c3aa2bfdc Mon Sep 17 00:00:00 2001 From: Sten Laane <21343173+StenAL@users.noreply.github.com> Date: Wed, 31 Dec 2025 08:59:16 +0200 Subject: [PATCH] feat(bash): add indents query It's pretty basic at the moment but already makes working with bash scripts way easier. --- SUPPORTED_LANGUAGES.md | 2 +- runtime/queries/bash/indents.scm | 32 ++++++++++++++++++++++++++ tests/indent/bash/test.sh | 39 ++++++++++++++++++++++++++++++++ tests/indent/bash_spec.lua | 33 +++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 runtime/queries/bash/indents.scm create mode 100644 tests/indent/bash/test.sh create mode 100644 tests/indent/bash_spec.lua diff --git a/SUPPORTED_LANGUAGES.md b/SUPPORTED_LANGUAGES.md index 03e8b5d4..d1e0e790 100644 --- a/SUPPORTED_LANGUAGES.md +++ b/SUPPORTED_LANGUAGES.md @@ -20,7 +20,7 @@ Language | Tier | Queries | Maintainer [astro](https://github.com/virchau13/tree-sitter-astro) | unstable | `HFIJL` | @virchau13 [authzed](https://github.com/mleonidas/tree-sitter-authzed) | unstable | `H  J ` | @mattpolzin [awk](https://github.com/Beaglefoot/tree-sitter-awk) | unstable | `H  J ` | -[bash](https://github.com/tree-sitter/tree-sitter-bash) | unstable | `HF JL` | @TravonteD +[bash](https://github.com/tree-sitter/tree-sitter-bash) | unstable | `HFIJL` | @TravonteD [bass](https://github.com/vito/tree-sitter-bass) | unstable | `HFIJL` | @amaanq [beancount](https://github.com/polarmutex/tree-sitter-beancount) | unmaintained | `HF J ` | @polarmutex [bibtex](https://github.com/latex-lsp/tree-sitter-bibtex) | unstable | `HFIJ ` | @theHamsta, @clason diff --git a/runtime/queries/bash/indents.scm b/runtime/queries/bash/indents.scm new file mode 100644 index 00000000..c0a4bed4 --- /dev/null +++ b/runtime/queries/bash/indents.scm @@ -0,0 +1,32 @@ +[ + (if_statement) + (for_statement) + (while_statement) + (case_statement) + (function_definition) + (compound_statement) + (subshell) + (command_substitution) + (do_group) + (case_item) +] @indent.begin + +[ + "fi" + "done" + "esac" + "}" + ")" + "then" + "do" + (elif_clause) + (else_clause) +] @indent.branch + +[ + "fi" + "done" + "esac" + "}" + ")" +] @indent.end diff --git a/tests/indent/bash/test.sh b/tests/indent/bash/test.sh new file mode 100644 index 00000000..7e708a93 --- /dev/null +++ b/tests/indent/bash/test.sh @@ -0,0 +1,39 @@ +for i in 1 2 3; do + if [[ true ]]; then + echo "asd" + elif [ true ]; then + echo "dsa" + else + echo "" + fi + echo $i +done + +while true; do + break +done + +case $foo in + a) echo a ;; + b) echo b ;; +esac + +function x() { + echo x +} + +y() { + echo y +} + +{ + echo z +} + +( + echo subshell +) + +A=$( + echo command substitution +) diff --git a/tests/indent/bash_spec.lua b/tests/indent/bash_spec.lua new file mode 100644 index 00000000..fa551c37 --- /dev/null +++ b/tests/indent/bash_spec.lua @@ -0,0 +1,33 @@ +local Runner = require('tests.indent.common').Runner +local XFAIL = require('tests.indent.common').XFAIL + +local run = Runner:new(it, 'tests/indent/bash', { + tabstop = 4, + shiftwidth = 4, + softtabstop = 0, + expandtab = true, +}) + +describe('indent Bash:', function() + describe('whole file:', function() + run:whole_file('.', { + expected_failures = {}, + }) + end) + + describe('new line:', function() + run:new_line('test.sh', { on_line = 1, text = 'echo test', indent = 4 }) -- in "for" + run:new_line('test.sh', { on_line = 2, text = 'echo test', indent = 8 }) -- in "if" + run:new_line('test.sh', { on_line = 4, text = 'echo test', indent = 8 }) -- in "elif" + run:new_line('test.sh', { on_line = 6, text = 'echo test', indent = 8 }) -- in "else" + run:new_line('test.sh', { on_line = 8, text = 'echo test', indent = 4 }) -- after "fi" + run:new_line('test.sh', { on_line = 12, text = 'echo test', indent = 4 }) -- in "while" + run:new_line('test.sh', { on_line = 18, text = 'c) echo test ;;', indent = 4 }) -- in "case" + run:new_line('test.sh', { on_line = 21, text = 'echo test', indent = 4 }) -- in "function" + run:new_line('test.sh', { on_line = 25, text = 'echo test', indent = 4 }) -- in "f() { ... }" + run:new_line('test.sh', { on_line = 29, text = 'echo test', indent = 4 }) -- in "{ ... }" + run:new_line('test.sh', { on_line = 33, text = 'echo test', indent = 4 }) -- in subshell + run:new_line('test.sh', { on_line = 37, text = 'echo test', indent = 4 }) -- in command substitution + run:new_line('test.sh', { on_line = 39, text = 'echo test', indent = 0 }) + end) +end)