mirror of
https://github.com/ivuorinen/shellspec-zed.git
synced 2026-01-26 03:04:11 +00:00
feat: plugin code, updates
This commit is contained in:
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
@@ -32,15 +32,15 @@ jobs:
|
|||||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
uses: github/codeql-action/init@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
queries: security-and-quality
|
queries: security-and-quality
|
||||||
|
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
uses: github/codeql-action/autobuild@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
uses: github/codeql-action/analyze@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.30.1
|
||||||
with:
|
with:
|
||||||
category: '/language:${{matrix.language}}'
|
category: '/language:${{matrix.language}}'
|
||||||
|
|||||||
2
.github/workflows/pr-lint.yml
vendored
2
.github/workflows/pr-lint.yml
vendored
@@ -27,4 +27,4 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Run PR Lint
|
- name: Run PR Lint
|
||||||
# https://github.com/ivuorinen/actions
|
# https://github.com/ivuorinen/actions
|
||||||
uses: ivuorinen/actions/pr-lint@8e88bf4cdb14c38c929ad2a89687d6eb635a3967 # 25.8.25
|
uses: ivuorinen/actions/pr-lint@71b97baa7c71a55b48413309b86843b1b125e149 # 25.8.31
|
||||||
|
|||||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -23,4 +23,4 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
steps:
|
steps:
|
||||||
- uses: ivuorinen/actions/stale@8e88bf4cdb14c38c929ad2a89687d6eb635a3967 # 25.8.25
|
- uses: ivuorinen/actions/stale@71b97baa7c71a55b48413309b86843b1b125e149 # 25.8.31
|
||||||
|
|||||||
2
.github/workflows/sync-labels.yml
vendored
2
.github/workflows/sync-labels.yml
vendored
@@ -38,4 +38,4 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: ⤵️ Sync Latest Labels Definitions
|
- name: ⤵️ Sync Latest Labels Definitions
|
||||||
uses: ivuorinen/actions/sync-labels@8e88bf4cdb14c38c929ad2a89687d6eb635a3967 # 25.8.25
|
uses: ivuorinen/actions/sync-labels@71b97baa7c71a55b48413309b86843b1b125e149 # 25.8.31
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ repos:
|
|||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v6.0.0
|
rev: v6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: requirements-txt-fixer
|
|
||||||
- id: detect-private-key
|
- id: detect-private-key
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
args: [--markdown-linebreak-ext=md]
|
args: [--markdown-linebreak-ext=md]
|
||||||
@@ -42,13 +41,13 @@ repos:
|
|||||||
rev: v0.11.0
|
rev: v0.11.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: shellcheck
|
- id: shellcheck
|
||||||
args: ['--severity=warning']
|
args: ["--severity=warning"]
|
||||||
|
|
||||||
- repo: https://github.com/rhysd/actionlint
|
- repo: https://github.com/rhysd/actionlint
|
||||||
rev: v1.7.7
|
rev: v1.7.7
|
||||||
hooks:
|
hooks:
|
||||||
- id: actionlint
|
- id: actionlint
|
||||||
args: ['-shellcheck=']
|
args: ["-shellcheck="]
|
||||||
|
|
||||||
- repo: https://github.com/renovatebot/pre-commit-hooks
|
- repo: https://github.com/renovatebot/pre-commit-hooks
|
||||||
rev: 41.82.10
|
rev: 41.82.10
|
||||||
@@ -56,8 +55,8 @@ repos:
|
|||||||
- id: renovate-config-validator
|
- id: renovate-config-validator
|
||||||
|
|
||||||
- repo: https://github.com/bridgecrewio/checkov.git
|
- repo: https://github.com/bridgecrewio/checkov.git
|
||||||
rev: '3.2.467'
|
rev: "3.2.467"
|
||||||
hooks:
|
hooks:
|
||||||
- id: checkov
|
- id: checkov
|
||||||
args:
|
args:
|
||||||
- '--quiet'
|
- "--quiet"
|
||||||
|
|||||||
62
README.md
Normal file
62
README.md
Normal 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
15
extension.toml
Normal 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"]
|
||||||
25
languages/shellspec/brackets.scm
Normal file
25
languages/shellspec/brackets.scm
Normal 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
|
||||||
29
languages/shellspec/config.toml
Normal file
29
languages/shellspec/config.toml
Normal 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 = "'" }
|
||||||
73
languages/shellspec/highlights.scm
Normal file
73
languages/shellspec/highlights.scm
Normal 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+")
|
||||||
38
languages/shellspec/indents.scm
Normal file
38
languages/shellspec/indents.scm
Normal 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
|
||||||
40
languages/shellspec/injections.scm
Normal file
40
languages/shellspec/injections.scm
Normal 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)
|
||||||
33
languages/shellspec/outline.scm
Normal file
33
languages/shellspec/outline.scm
Normal 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
|
||||||
29
languages/shellspec/runnables.scm
Normal file
29
languages/shellspec/runnables.scm
Normal 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
|
||||||
Reference in New Issue
Block a user