package.json- this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension.syntaxes/vcl.tmLanguage.json- this is the Text mate grammar file that is used for tokenization.language-configuration.json- this is the language configuration, defining the tokens that are used for comments and brackets.client/- this is the Language Server Protocol client that connects to the local LSP server.server/- this is the Language Server Protocol server that provides completions, hover, diagnostics, and other IDE features.
brew install npm
npm i node@lts
To develop this extension on your machine, clone this repository and install its dependencies:
gh repo clone fastly/vscode-fastly-vcl
cd vscode-fastly-vcl
npm i
This will automatically download the falco binaries via the postinstall script. The binaries are placed in falco-js/bin/ and are not committed to git.
- Open this folder in VS Code.
- Run
Cmd+Shift+Bto start compiling the client in watch mode. - Press
Cmd+Shift+Dto switch to the Run and Debug View in the sidebar. - Select
Fastly VCL Clientfrom the drop down. - Press ▷ to run the launch config with the debugger attached (
F5). - In the Extension Development Host instance of VSCode, open a document in
Fastly VCLlanguage mode. - Save the file with a
.vclextension. - Use it as a scratchpad to try out all the features!
To run the grammar tests:
npm run test:colorizationThe test cases are stored as markdown files under test/colorize-fixtures. Grammar test results are stored under test/colorize-results, which are automatically generated from the fixtures.
To run the semantic tokens tests:
npm run test:semantic-tokensThe test renders client/testFixture/semanticTokens.vcl with XML tags showing token types and compares against test/semantic-tokens-results/semanticTokens.vcl.xml. To update the expected output after changes:
npx tsx server/src/test/renderSemanticTokens.ts client/testFixture/semanticTokens.vcl > test/semantic-tokens-results/semanticTokens.vcl.xmlTo run the LSP tests:
npm run test:e2eTo run the LSP tests with code coverage:
npm run test:e2e:coverageCoverage reports are generated in coverage/ (text, lcov, and HTML formats).
The LSP server uses JSON metadata files in server/src/metadata/ for completions, hover, and other features. To regenerate these from upstream source definitions:
./scripts/generate-metadata.sh <path-to-source-json-dir>This requires jq to be installed. The jq filters are in jq-filters/.
The falco binaries are downloaded from GitHub releases. To update to a new version:
- Edit
FALCO_VERSIONinscripts/download-falco.sh - Delete
falco-js/bin/and runnpm install(or run the script directly)
To check for lint errors:
npm run lintTo check code formatting:
npm run format:checkTo auto-fix formatting:
npm run formatRun the following command to compile the VSCode extension as a .vsix file.
npm run package
Then, either run code --install-extension vscode-fastly-vcl-{VERSION}.vsix or follow the steps below to install the extension:
- Press
Cmd+Shift+Xto go to the VS Code extension tab. - Click the ellipsis (above "Search Extensions in Marketplace") and pick
Install from VSIX...from the dropdown. - Install the
.vsixfile you created.
CI runs automatically on all pull requests via GitHub Actions with Dagger, a containerized CI/CD engine. The pipeline runs:
- Linting (
npm run lint) - Formatting checks (
npm run format:check) - Colorization tests (
npm run test:colorization) - Semantic tokens tests (
npm run test:semantic-tokens) - LSP e2e tests (
npm run test:e2e) - Package building (
npm run package)
Dagger lets you run the exact same CI pipeline locally that runs in GitHub Actions. Install the Dagger CLI:
brew install dagger/tap/daggerRun the full CI pipeline:
npm run dagger:ci
# or directly: dagger call ci --source=.Run individual steps:
npm run dagger:lint # Run linting
npm run dagger:test # Run tests
dagger call format-check --source=.
dagger call package --source=.List all available Dagger functions:
dagger functionsThe Dagger module is defined in .dagger/src/index.ts.
Please open a pull request with your changes.
To publish a new version to the VS Code Marketplace:
-
Prerequisites
- You must be a member of the
fastlypublisher on the VS Code Marketplace
- You must be a member of the
-
Prepare the release
- Update
versioninpackage.json - npm install
- Run
vsce ls --tree vscode-fastly-vcl-2.0.8.vsix, check if all files are needed in the extension, otherwise add them to .vscodeignore - Move items from "Unreleased" to a new version section in
CHANGELOG.md - Commit these changes:
git commit -am "chore: prepare release v2.0.X"
- Update
-
Run all checks
npm run lint npm run format:check npm test -
Publish Using the UI:
- Visit https://marketplace.visualstudio.com/vscode
- Select "Publish extensions"
- Log in as your personal account and authenticate.
- Select the three dots near the extension and select Update
- Upload the new .vsix
-
Tag the release
git tag vX.Y.Z git push origin main --tags
-
Upload a new GitHub release Visit https://github.com/fastly/vscode-fastly-vcl/releases and upload the .vsix file with a changelog.
This uses a JSON TextMate language grammar: syntaxes/vcl.tmLanguage.json, a structured collection of regular expressions, to tokenize the text into scopes such as:
keyword.control.vclvariable.other.vclstring.quoted.double.vclcomment.line.number-sign.vcl
For example, the extension scopes Fastly code macros as control keywords using a regular expression in JSON:
{
"name": "keyword.control.vcl",
"match": "^\\s*#FASTLY\\s+(deliver|error|fetch|hash|hit|log|miss|pass|recv)\\s*$"
}Visual Studio Code themes such as GitHub Dark Default or the default Light+ map scopes to colours and styles.
The GitHub Dark default theme maps the keyword scope to red using a JavaScript object:
{
scope: "keyword",
settings: {
foreground: lightDark(scale.red[5], scale.red[3])
}
}The Fastly VCL Language Server Protocol (LSP) server (in server/) works for .vcl files. The server is still in an early state. The following list tracks the protocol features that are supported:
-
textDocument/codeAction -
textDocument/completion(incl.completion/resolve) -
textDocument/definition -
textDocument/didChange (incremental) -
textDocument/didClose -
textDocument/didOpen -
textDocument/didSave -
textDocument/documentHighlight -
textDocument/documentSymbol -
textDocument/executeCommand -
textDocument/formatting -
textDocument/hover -
textDocument/inlayHint -
textDocument/prepareCallHierarchy -
callHierarchy/incomingCalls -
callHierarchy/outgoingCalls -
textDocument/prepareRename -
textDocument/rangeFormatting -
textDocument/references -
textDocument/rename -
textDocument/selectionRange -
textDocument/signatureHelp -
workspace/symbol -
workspace/didChangeConfiguration -
workspace/executeCommand
