Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 4 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,31 +130,15 @@ opening a certain file type, see the [Neovim LSP documentation](https://neovim.i

## Configuration

The language server needs to know your library mapping to perform full analysis of the code. For this it uses a
configuration file in the [TOML](https://github.com/toml-lang/toml) format named `vhdl_ls.toml`.

`vhdl_ls` will load configuration files in the following order of priority (first to last):

1. A file named `.vhdl_ls.toml` in the user home folder.
2. A file name from the `VHDL_LS_CONFIG` environment variable.
3. A file named `vhdl_ls.toml` in the workspace root.

Settings in a later files overwrites those from previously loaded files.

Define the VHDL revision to use for parsing and analysis with the `standard` key.
The expected value is the year associated the VHDL standard.
Supported standards are 1993, 2008 and 2019 where both the long version ("2008") and the short version ("08") can be
used.
If nothing is specified, 2008 is used.
The language server needs to know your library mapping to perform full analysis of the code. For this it uses a configuration file in the [TOML](https://github.com/toml-lang/toml) format named `vhdl_ls.toml`.

> [!NOTE]
> Defining the standard feature is a relatively new feature (since april 2024).
> Anything but the 2008 standard will not change much at the moment.
> Read the full documentation in [the wiki](https://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration)

**Example vhdl_ls.toml**
### Example vhdl_ls.toml / Quickstart

```toml
# What standard to use. This is optional and defaults to VHDL2008.
# What standard to use. This is optional and defaults to VHDL 2008.
standard = "2008"
# File names are either absolute or relative to the parent folder of the vhdl_ls.toml file
[libraries]
Expand Down Expand Up @@ -187,18 +171,6 @@ unused = 'error' # Upgrade the 'unused' diagnostic to the 'error' severity
unnecessary_work_library = false # Disable linting for the 'library work;' statement
```

Using the `lint` table, you can configure the severity of diagnostics or turn of diagnostics altogether.

> [!WARNING]
> You can overwrite every diagnostic error code including syntax or analysis errors using the lint table.
> However, the intended use-case is for lints only.
> Overwriting syntax or analysis errors (e.g., error codes `mismatched_kinds` or `syntax`) can cause unwanted side
> effects

Paths in the `vhdl_ls.toml` can contain glob patterns (i.e., `.../*/`).
On Unix machines, they can contain environment variables using the `$NAME` or `${NAME}` syntax.
On Windows machines, use the `%NAME%` syntax to substitute environment variables.

## Ignoring errors

You can use the comment-pair `-- vhdl_ls off` and `-- vhdl_ls on` to conditionally disable and re-enable parsing of
Expand Down
33 changes: 33 additions & 0 deletions schemas/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Schemas tests

This folder contains Schema tests for `vhdl_ls.schema.json`.

## Running the tests locally:

> [!NOTE]
> Usage of [uv](https://docs.astral.sh/uv/) is recommended. The minimum Python version is 3.11

### Using `uv`

`uv run schemas/validate_tests.py`

### Using regular Python

1. Install the Python dependency for schema validation:

```
python3 -m pip install jsonschema
```

2. Run the validator script from the repository root:

```
python3 schemas/validate_tests.py
```


## Return codes:

- `0`: all tests behaved as expected
- `1`: There was at least one failure
- `2`: The `vhdl_ls.schema.json` file was not found
3 changes: 3 additions & 0 deletions schemas/tests/invalid/additional_property_in_library.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[libraries.mylib]
files = ["a.vhd"]
unexpected = 123
2 changes: 2 additions & 0 deletions schemas/tests/invalid/library_named_work.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[libraries.work]
files = ["top.vhd"]
5 changes: 5 additions & 0 deletions schemas/tests/invalid/lint_wrong_type.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[libraries.ieee2008]
files = ["std_logic.vhd"]

[lint]
rule-number = 123
2 changes: 2 additions & 0 deletions schemas/tests/invalid/missing_libraries.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
preferred_case = "upper"
standard = "2019"
14 changes: 14 additions & 0 deletions schemas/tests/valid/full_valid.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
preferred_case = "lower"
standard = "2008"

[libraries.ieee2008]
files = ["std_logic.vhd", "types.vhd"]
exclude = ["legacy/*"]
is_third_party = false

[libraries.my_lib]
files = ["core.vhd", "utils.vhd"]

[lint]
some-rule = false
another-rule = "warning"
3 changes: 3 additions & 0 deletions schemas/tests/valid/minimal_valid.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[libraries.ieee2008]
files = ["std_logic.vhd"]

73 changes: 73 additions & 0 deletions schemas/validate_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "jsonschema",
# ]
# ///
"""
Validate JSON tests under `schemas/tests` against `schemas/vhdl_ls.schema.json`.

Usage:
uv run schemas/validate_tests.py or
python3 schemas/validate_tests.py
"""
import json
from pathlib import Path
import sys

import jsonschema
from jsonschema import Draft4Validator
import tomllib


ROOT = Path(__file__).parent
SCHEMA_PATH = ROOT / "vhdl_ls.schema.json"
TESTS_DIR = ROOT / "tests"


def load_toml(path):
with open(path, "rb") as file:
return tomllib.load(file)


def load_json(path):
with open(path, "rb") as file:
return json.load(file)


def main():
if not SCHEMA_PATH.exists():
print(f"Schema not found at {SCHEMA_PATH}")
return 2

schema = load_json(SCHEMA_PATH)
validator = Draft4Validator(schema)

failures = 0
total = 0

for sub in ("valid", "invalid"):
folder = TESTS_DIR / sub
for path in sorted(folder.iterdir()):
total += 1
data = load_toml(path)
errors = list(validator.iter_errors(data))
should_be_valid = (sub == "valid")

if should_be_valid and errors:
print(f"FAIL (expected valid): {path}")
for e in errors[:5]:
print(" -", e.message)
failures += 1
elif (not should_be_valid) and (not errors):
print(f"FAIL (expected invalid): {path} -- no validation errors found")
failures += 1
else:
print(f"OK: {path}")

print(f"\nChecked {total} files: {total - failures} OK, {failures} FAILED")
return 1 if failures else 0


if __name__ == "__main__":
sys.exit(main())
80 changes: 80 additions & 0 deletions schemas/vhdl_ls.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"$schema": "http://json-schema.org/draft-04/schema",
"id": "https://github.com/VHDL-LS/rust_hdl",
"title": "vhdl_ls language server configuration",
"description": "Configuration schema for vhdl_ls, the VHDL language server. Defines libraries, linting rules, and code formatting preferences.",
"type": "object",
"properties": {
"preferred_case": {
"description": "The preferred letter case for code completions and suggestions (e.g., lower, upper_snake, pascal)\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#preferred_case",
"type": "string",
"enum": [
"lower",
"snake",
"upper",
"upper_snake",
"pascal",
"upper_camel"
]
},
"standard": {
"description": "The VHDL standard version for analysis and linting. Supports short (e.g., '08') and full (e.g., '2008') notation\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#standard",
"type": "string",
"enum": ["1993", "93", "2008", "08", "2019", "19"]
},
"libraries": {
"type": "object",
"description": "Defines VHDL libraries in the project. Each library name (except 'work') maps to an object specifying source files\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#libraries",
"patternProperties": {
"^(?!work$).+$": {
"type": "object",
"description": "A VHDL library definition. Library names must not be 'work' (reserved by VHDL spec).",
"properties": {
"files": {
"type": "array",
"description": "Array of source file paths or glob patterns belonging to this library. Either absolute or relative to vhdl_ls.toml\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#files",
"items": {
"type": "string",
"description": "A file path or glob pattern (e.g., 'src/**/*.vhd', 'lib/ieee.vhd')."
}
},
"exclude": {
"type": "array",
"description": "Array of source file paths or glob patterns to exclude from this library\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#exclude",
"items": {
"type": "string",
"description": "A file path or glob pattern to exclude (e.g., 'legacy/*', 'src/*_old.vhd')."
}
},
"is_third_party": {
"type": "boolean",
"description": "Whether this library is third-party. May affect diagnostic reporting. Defaults to false\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#is_third_party",
"default": false
}
},
"additionalProperties": false,
"required": ["files"]
}
},
"additionalProperties": false
},
"lint": {
"type": "object",
"description": "Configures linting rules. Each key is a rule name, and the value controls its behavior (true/false to enable/disable, or a string for specific severity)\nhttps://github.com/VHDL-LS/rust_hdl/wiki/VHDL%E2%80%90LS-Configuration#lint",
"patternProperties": {
"^.+$": {
"anyOf": [
{ "type": "boolean" },
{
"type": "string",
"enum": ["hint", "info", "warning", "error"]
}
],
"description": "Lint rule configuration. Can be a boolean (enable/disable) or a string (e.g., 'warning', 'error')."
}
},
"additionalProperties": false
}
},
"required": ["libraries"]
}