feat: plugin code, updates

This commit is contained in:
2025-09-07 23:36:04 +03:00
parent 773f82e610
commit 4188c9221f
15 changed files with 354 additions and 11 deletions

View File

@@ -32,15 +32,15 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Initialize CodeQL
uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
uses: github/codeql-action/init@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
with:
languages: ${{ matrix.language }}
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
uses: github/codeql-action/autobuild@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
uses: github/codeql-action/analyze@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
with:
category: '/language:${{matrix.language}}'

View File

@@ -27,4 +27,4 @@ jobs:
steps:
- name: Run PR Lint
# https://github.com/ivuorinen/actions
uses: ivuorinen/actions/pr-lint@8e88bf4cdb14c38c929ad2a89687d6eb635a3967 # 25.8.25
uses: ivuorinen/actions/pr-lint@71b97baa7c71a55b48413309b86843b1b125e149 # 25.8.31

View File

@@ -23,4 +23,4 @@ jobs:
issues: write
pull-requests: write
steps:
- uses: ivuorinen/actions/stale@8e88bf4cdb14c38c929ad2a89687d6eb635a3967 # 25.8.25
- uses: ivuorinen/actions/stale@71b97baa7c71a55b48413309b86843b1b125e149 # 25.8.31

View File

@@ -38,4 +38,4 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: ⤵️ Sync Latest Labels Definitions
uses: ivuorinen/actions/sync-labels@8e88bf4cdb14c38c929ad2a89687d6eb635a3967 # 25.8.25
uses: ivuorinen/actions/sync-labels@71b97baa7c71a55b48413309b86843b1b125e149 # 25.8.31

View File

@@ -3,7 +3,6 @@ repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: requirements-txt-fixer
- id: detect-private-key
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
@@ -42,13 +41,13 @@ repos:
rev: v0.11.0
hooks:
- id: shellcheck
args: ['--severity=warning']
args: ["--severity=warning"]
- repo: https://github.com/rhysd/actionlint
rev: v1.7.7
hooks:
- id: actionlint
args: ['-shellcheck=']
args: ["-shellcheck="]
- repo: https://github.com/renovatebot/pre-commit-hooks
rev: 41.82.10
@@ -56,8 +55,8 @@ repos:
- id: renovate-config-validator
- repo: https://github.com/bridgecrewio/checkov.git
rev: '3.2.467'
rev: "3.2.467"
hooks:
- id: checkov
args:
- '--quiet'
- "--quiet"

View File

62
README.md Normal file
View File

@@ -0,0 +1,62 @@
# Zed ShellSpec Extension
Language support for ShellSpec BDD testing framework in Zed editor.
## Features
- Syntax highlighting for ShellSpec DSL keywords
- Smart indentation for nested test blocks
- Code outline navigation
- Bracket matching and auto-completion
- Test execution integration
## Installation
1. Install via Zed's extension gallery (when published)
2. Or manually: clone to `~/.config/zed/extensions/shellspec/`
## File Types
Automatically detects files with:
- `*_spec.sh`
- `*.spec.sh`
## Usage
### Test Execution
Use Zed's task system to run tests:
```json
{
"tasks": {
"shellspec-test": {
"label": "Run ShellSpec Test",
"command": "shellspec",
"args": ["$ZED_RELATIVE_FILE"],
"cwd": "$ZED_WORKTREE_ROOT"
},
"shellspec-all": {
"label": "Run All Tests",
"command": "shellspec",
"cwd": "$ZED_WORKTREE_ROOT"
}
}
}
```
### Language Server
Uses bash-language-server for shell script features. Install with:
```bash
npm install -g bash-language-server
```
## Contributing
Issues and PRs welcome at https://github.com/ivuorinen/zed-shellspec
## License
MIT

15
extension.toml Normal file
View File

@@ -0,0 +1,15 @@
id = "shellspec"
name = "ShellSpec BDD Testing"
version = "0.1.0"
schema_version = 1
authors = ["Ismo Vuorinen <ismo@vuorinen.net>"]
description = "Language support for ShellSpec BDD testing framework"
repository = "https://github.com/ivuorinen/shellspec-zed"
[grammars.shellspec]
repository = "https://github.com/tree-sitter/tree-sitter-bash"
rev = "main"
[language_servers.bash-language-server]
name = "Bash Language Server"
languages = ["ShellSpec"]

View File

@@ -0,0 +1,25 @@
; Quote pairs
("'" @open "'" @close)
("\"" @open "\"" @close)
; Command substitution
("$(" @open ")" @close)
("${" @open "}" @close)
; Parentheses
("(" @open ")" @close)
; Square brackets
("[" @open "]" @close)
; Curly braces
("{" @open "}" @close)
; ShellSpec block structure (if using End keyword)
(simple_command
(command_name) @_cmd
(#match? @_cmd "^(Describe|Context|It|Specify|Example)$")) @open
(simple_command
(command_name) @_end
(#eq? @_end "End")) @close

View File

@@ -0,0 +1,29 @@
name = "ShellSpec"
grammar = "bash"
path_suffixes = ["_spec.sh", ".spec.sh"]
line_comments = ["# "]
tab_size = 2
hard_tabs = false
first_line_pattern = "^#!/.*shellspec"
[[brackets]]
start = "'"
end = "'"
close = true
newline = false
not_in = ["string", "comment"]
[[brackets]]
start = "\""
end = "\""
close = true
newline = false
not_in = ["string", "comment"]
[[brackets]]
start = "$("
end = ")"
close = true
newline = true
block_comment = { start = ": '", end = "'" }

View File

@@ -0,0 +1,73 @@
; BDD Structure Keywords
["Describe" "Context" "ExampleGroup"] @keyword.function
["It" "Specify" "Example"] @keyword.function
["Todo"] @keyword.function
; Prefixed block keywords
["xDescribe" "xContext" "xExampleGroup" "xIt" "xSpecify" "xExample"] @keyword.function.inactive
["fDescribe" "fContext" "fExampleGroup" "fIt" "fSpecify" "fExample"] @keyword.function.focus
; Control flow
["Pending" "Skip"] @keyword.control
["When" "The" "Assert"] @keyword.control
["End"] @keyword.control
; Hook keywords
["BeforeEach" "AfterEach" "BeforeAll" "AfterAll"] @keyword.function
["BeforeCall" "AfterCall" "BeforeRun" "AfterRun"] @keyword.function
["Before" "After"] @keyword.function
; Helper keywords
["Include" "Set" "Data" "Parameters" "Dump"] @keyword
["Path" "File" "Dir"] @keyword
; Evaluation keywords
["call" "run" "command" "script" "source"] @function.method
; Assertion keywords
["should" "not"] @keyword.operator
["output" "stdout" "error" "stderr" "status" "variable" "path"] @variable.builtin
; Matchers
["equal" "eq" "be" "exist" "valid" "satisfy"] @function.method
["match" "start_with" "end_with" "include" "contain"] @function.method
; Modifiers
["line" "word" "length" "contents" "result"] @variable.parameter
["first" "second" "third" "of"] @variable.parameter
; Language chains
["a" "an" "as" "the"] @keyword.operator
; Skip conditional
(word) @keyword.control
(#match? @keyword.control "^Skip\\s+if$")
; Test descriptions and strings
(string) @string
(raw_string) @string
; Comments
(comment) @comment
; Numbers
(number) @number
; Variables
(variable_name) @variable
(variable_assignment) @variable
; Function definitions
(function_definition
name: (word) @function)
; Command names
(command_name) @function
; Data block markers
(word) @punctuation.special
(#eq? @punctuation.special "#|")
; Tags (key:value pairs)
(word) @label
(#match? @label "\\w+:\\w+")

View File

@@ -0,0 +1,38 @@
; Indent content inside BDD blocks
(simple_command
(command_name) @_name
(#match? @_name "^(Describe|Context|ExampleGroup|It|Specify|Example)$")) @indent
; Indent prefixed blocks
(simple_command
(command_name) @_name
(#match? @_name "^[xf](Describe|Context|ExampleGroup|It|Specify|Example)$")) @indent
; Indent hook content
(simple_command
(command_name) @_name
(#match? @_name "^(BeforeEach|AfterEach|BeforeAll|AfterAll|BeforeCall|AfterCall|BeforeRun|AfterRun)$")) @indent
; Indent Data blocks
(simple_command
(command_name) @_name
(#match? @_name "^(Data|Parameters)$")) @indent
; Indent function definitions
(function_definition) @indent
; Indent compound statements
(compound_statement) @indent
; Indent conditional statements
(if_statement) @indent
(for_statement) @indent
(while_statement) @indent
; Indent pipeline continuations
(pipeline) @indent
; Dedent End keyword
(simple_command
(command_name) @_name
(#eq? @_name "End")) @dedent

View File

@@ -0,0 +1,40 @@
; Inject shell highlighting in function definitions
(function_definition
body: (compound_statement) @injection.content
(#set! injection.language "bash"))
; Inject shell in command substitutions
(command_substitution
"$(" @injection.punctuation.bracket
(_) @injection.content
(#set! injection.language "bash")
")" @injection.punctuation.bracket)
; Inject shell in When blocks with call/run
(simple_command
(command_name) @_when
(#eq? @_when "When")
(word) @_action
(#match? @_action "^(call|run)$")
(word)+ @injection.content
(#set! injection.language "bash"))
; Inject shell in arithmetic expressions
(arithmetic_expansion
"$((" @injection.punctuation.bracket
(_) @injection.content
(#set! injection.language "bash")
"))" @injection.punctuation.bracket)
; Inject shell in process substitution
(process_substitution
"<(" @injection.punctuation.bracket
(_) @injection.content
(#set! injection.language "bash")
")" @injection.punctuation.bracket)
(process_substitution
">(" @injection.punctuation.bracket
(_) @injection.content
(#set! injection.language "bash")
")" @injection.punctuation.bracket)

View File

@@ -0,0 +1,33 @@
; Test suites
(simple_command
(command_name) @_name
(#match? @_name "^(Describe|Context|ExampleGroup)$")
(word) @name) @item
; Individual tests
(simple_command
(command_name) @_name
(#match? @_name "^(It|Specify|Example)$")
(word) @name) @item
; Focused tests
(simple_command
(command_name) @_name
(#match? @_name "^f(Describe|Context|It|Specify|Example)$")
(word) @name) @item
; Skipped tests
(simple_command
(command_name) @_name
(#match? @_name "^x(Describe|Context|It|Specify|Example)$")
(word) @name) @item
; Hooks
(simple_command
(command_name) @_name
(#match? @_name "^(BeforeEach|AfterEach|BeforeAll|AfterAll)$")
(word) @name) @item
; Function definitions
(function_definition
name: (word) @name) @item

View File

@@ -0,0 +1,29 @@
; Individual test execution
(simple_command
(command_name) @_name
(#match? @_name "^(It|Specify|Example)$")
(word) @run) @shellspec-test
; Test suite execution
(simple_command
(command_name) @_name
(#match? @_name "^(Describe|Context|ExampleGroup)$")
(word) @run) @shellspec-suite
; Focused test execution
(simple_command
(command_name) @_name
(#match? @_name "^f(It|Specify|Example)$")
(word) @run) @shellspec-focused-test
; Focused suite execution
(simple_command
(command_name) @_name
(#match? @_name "^f(Describe|Context|ExampleGroup)$")
(word) @run) @shellspec-focused-suite
; Pending test markers
(simple_command
(command_name) @_name
(#match? @_name "^(Pending|Todo)$")
(word) @run) @shellspec-pending