URDF for Zed
URDF language support for Zed with:
- Syntax highlighting
- Outline / structure view
- Auto indentation
- Context-aware completions for common URDF tags, attributes, and values
This extension targets .urdf files and builds on top of the XML Tree-sitter grammar plus an external URDF language server.
Features
- Recognizes
.urdffiles as theURDFlanguage - Reuses the XML Tree-sitter grammar for parsing
- Provides syntax highlighting through Tree-sitter queries
- Provides outline support for URDF/XML elements
- Shows
namecontext in outline entries forrobot,link, andjoint - Provides completions for common URDF tags such as:
robotlinkjointvisualcollisioninertialgeometryoriginparentchildaxislimitmaterialmesh
- Provides completions for common URDF attributes and values
- Supports both block-style and self-closing completions for tags like
linkandmaterial
Installation
For normal users:
- Install the extension in Zed
- Open a
.urdffile - The extension will look for a language server binary whose version exactly matches the extension version
- If that exact-version binary is not already cached, the extension downloads the matching GitHub Release asset for the same version
This extension intentionally uses a strict version lock between the extension and the language server.
That means:
- extension version
0.1.0only accepts language server release tagv0.1.0 - extension version
0.1.1only accepts language server release tagv0.1.1 - the extension does not use the latest release automatically
- the extension does not silently fall back to a different installed server version
Version Lock Policy
The repository follows these rules:
Cargo.tomlversionextension.tomlversionurdf-language-server/Cargo.tomlversion- Git tag name without the leading
v
must all be identical.
Examples:
- extension version:
0.1.0 - language server crate version:
0.1.0 - Git tag:
v0.1.0
At runtime, the extension downloads only the release with tag v0.1.0 when the extension version is 0.1.0.
Release Assets
Expected release asset names:
urdf-language-server-vX.Y.Z-x86_64-unknown-linux-musl.tar.gzurdf-language-server-vX.Y.Z-x86_64-apple-darwin.tar.gzurdf-language-server-vX.Y.Z-aarch64-apple-darwin.tar.gzurdf-language-server-vX.Y.Z-x86_64-pc-windows-msvc.zip
Each archive must contain the executable at the archive root:
urdf-language-serverurdf-language-server.exeon Windows
Development
Prerequisites
Install Rust with rustup.
Install as a Dev Extension in Zed
- Open Zed
- Open the command palette
- Run
zed: install dev extension - Select this repository folder
After changing the extension, open the Extensions page and click Rebuild for the dev extension.
Local Testing Without GitHub Release
You do not need to publish a GitHub Release every time you modify the language server during development.
With the strict version-locked setup used by this extension, the runtime behavior is:
- The extension first checks whether a language server binary for the exact same version already exists in the local versioned cache directory
- Only if that exact-version binary is missing does it try to download the matching GitHub Release asset for the same version tag
That means local development can use a manually built binary, as long as:
- the extension version and language server version are the same
- the binary is placed at the expected versioned cache path
Keep versions in sync
Before local testing, make sure these versions are identical:
Cargo.tomlextension.tomlurdf-language-server/Cargo.toml
For example, if the version is 0.1.0, then all three files should use 0.1.0.
Build the language server locally
From the repository root:
cargo build --manifest-path ./urdf-language-server/Cargo.toml --releasePut the binary into the expected local cache directory
Create the versioned cache directory expected by the extension:
Linux:
~/.local/share/zed/extensions/work/.zed-urdf/<version>/macOS:
~/Library/Application Support/zed/extensions/work/.zed-urdf/<version>/Windows:
%LOCALAPPDATA%\Zed\extensions\work\.zed-urdf\<version>\Then copy the locally built binary into that directory.
Linux
If you build for the default host target:
ZED_EXT_DIR="$HOME/.local/share/zed/extensions/work/urdf/.zed-urdf/0.1.0"
mkdir -p "$ZED_EXT_DIR"
cp urdf-language-server/target/release/urdf-language-server "$ZED_EXT_DIR/urdf-language-server"
chmod +x "$ZED_EXT_DIR/urdf-language-server"If you explicitly build a target triple, your output path may instead look like this:
ZED_EXT_DIR="$HOME/.local/share/zed/extensions/work/urdf/.zed-urdf/0.1.0"
mkdir -p "$ZED_EXT_DIR"
cp urdf-language-server/target/x86_64-unknown-linux-gnu/release/urdf-language-server "$ZED_EXT_DIR/urdf-language-server"
chmod +x "$ZED_EXT_DIR/urdf-language-server"macOS
ZED_EXT_DIR="$HOME/Library/Application Support/zed/extensions/work/urdf/.zed-urdf/0.1.0"
mkdir -p "$ZED_EXT_DIR"
cp urdf-language-server/target/release/urdf-language-server "$ZED_EXT_DIR/urdf-language-server"
chmod +x "$ZED_EXT_DIR/urdf-language-server"Windows (PowerShell)
$ZedExtDir = "$env:LOCALAPPDATA\Zed\extensions\work\.zed-urdf\0.1.0"
New-Item -ItemType Directory -Force -Path $ZedExtDir | Out-Null
Copy-Item "urdf-language-server\target\release\urdf-language-server.exe" "$ZedExtDir\urdf-language-server.exe"Replace 0.1.0 with your actual current extension version.
Recommended local test workflow after changing the language server
When you modify urdf-language-server/src/main.rs:
- Keep all versions unchanged if you are just testing local behavior
- Run the local release build
- Copy the new binary into
.zed-urdf/<version>/ - Rebuild the dev extension in Zed
- Reopen a
.urdffile and verify completions
Testing a version bump locally
If you want to test a new version locally, such as moving from 0.1.0 to 0.1.1:
Update these files to
0.1.1:Cargo.tomlextension.tomlurdf-language-server/Cargo.toml
Build the language server again
Copy the binary into
.zed-urdf/0.1.1/Rebuild the dev extension in Zed
The extension will then use only the 0.1.1 binary and will not reuse the old 0.1.0 cache.
When is GitHub Release actually needed?
A GitHub Release is only needed when you want to test the real published download path:
- remove the local cached binary for the current version
- keep the same version
- create the matching Git tag such as
v0.1.0 - publish the release assets
- let the extension download that exact-version asset automatically
Publishing Notes
This repository keeps the language server source code, but the published Zed extension does not ship the server binary inside the extension package.
Instead:
- GitHub Actions builds versioned language server binaries
- those binaries are uploaded as GitHub Release assets
- the extension downloads only the asset whose tag exactly matches the extension version
Troubleshooting
If the extension does not seem to work:
- open
Zed.logusingzed: open log - or launch Zed from the command line with:
zed --foregroundThis usually shows more detailed extension and language server logs during development.
You may also want to check:
- whether the three version fields are exactly the same
- whether the local binary exists under
.zed-urdf/<version>/ - whether the binary name is correct for your platform
- whether the binary is executable on Unix-like systems
Project Structure
.
├── .github/
│ └── workflows/
│ ├── check-version-sync.yml
│ └── release-language-server.yml
├── README.md
├── extension.toml
├── Cargo.toml
├── src/
│ └── lib.rs
├── languages/
│ └── urdf/
│ ├── config.toml
│ ├── highlights.scm
│ ├── indents.scm
│ └── outline.scm
└── urdf-language-server/
├── Cargo.toml
└── src/
└── main.rsExample
<?xml version="1.0"?>
<robot name="demo_robot">
<link name="base_link" />
<link name="arm_link">
<visual>
<geometry>
<box size="1 1 1" />
</geometry>
</visual>
</link>
<joint name="base_to_arm" type="revolute">
<parent link="base_link" />
<child link="arm_link" />
<origin xyz="0 0 0.1" rpy="0 0 0" />
<axis xyz="0 0 1" />
<limit lower="-1.57" upper="1.57" effort="100" velocity="1.0" />
</joint>
</robot>Notes
- This extension currently uses the XML grammar for parsing URDF documents
- Completions are provided by the external custom URDF language server
- The completion engine is designed specifically for common URDF authoring workflows, rather than full XML Schema/XSD validation
Acknowledgements
This project builds on and draws inspiration from:
Many thanks to the maintainers and contributors of those projects.
License
This project is licensed under the Apache License 2.0.