Installation
Timeline DSL is used as a CLI tool. This guide assumes installation via Homebrew as the primary method.
brew tap keroway/tapbrew install tdslAfter installation, verify that the CLI runs correctly.
tdsl --helpRequirements
Section titled “Requirements”- macOS or Linux (Homebrew / one-line install)
- Windows (PowerShell one-line install / manual binary installation)
- Git
For installation methods other than Homebrew (macOS / Linux one-liner, Windows PowerShell, cargo-binstall, cargo), see Homebrew and Other Installation Methods.
VS Code Extension
Section titled “VS Code Extension”Since v1.0.0, a VS Code extension providing syntax highlighting is available. It has been published on the Marketplace since v1.2.0, and snippets are available from v1.4.0 onwards.
Installation
Section titled “Installation”Search for Timeline DSL in the VS Code Extensions panel (Ctrl+Shift+X / Cmd+Shift+X) and install it. Alternatively, run the following command.
code --install-extension keroway.timeline-dslAvailable snippets
Section titled “Available snippets”| Prefix | Expands to |
| ---------- | ----------------------------------------------------------------------------------- |
| timeline | Template for a timeline block (includes title, unit, range, and calendar) |
| lane | Template for a lane definition (includes kind and order) |
| span | Template for a span event (with start and end dates) |
Snippets are active in files with the .tdsl extension.
The VS Code extension provides syntax highlighting and snippets, and when the tdsl CLI is available it also starts tdsl lsp as a built-in LSP client. Interactive features such as diagnostics, completion, hover, and goto-definition are handled by the language server (LSP) described below.
Language Server (LSP)
Section titled “Language Server (LSP)”Since v1.11.0, you can start the Timeline DSL language server (LSP) with tdsl lsp. The server communicates over standard input/output (stdio), so any editor with an LSP client (VS Code, Neovim, Helix, Emacs, etc.) can connect to it and get interactive assistance while editing .tdsl files. Since v1.19.0, the VS Code extension includes an LSP client that starts tdsl lsp automatically.
| Feature | Description | Version | | --------------- | ---------------------------------------------------------------- | -------- | | Diagnostics | Reports syntax and semantic errors in real time while editing | v1.11.0+ | | Completion | Completes DSL keywords | v1.12.0+ | | Hover | Shows hover information for lane IDs / QIDs | v1.12.0+ | | Goto Definition | Jumps from a lane reference to its lane declaration | v1.12.0+ | | References | Returns the declaration and all reference locations of a lane ID | v1.13.0+ | | Rename | Renames a lane ID across its declaration and all references | v1.13.0+ | | Code Action | Provides lint auto-fixes as quick fixes | v1.13.0+ | | Document Symbol | Returns hierarchical symbols (timeline > lane > items) | v1.13.0+ | | Formatting | Formats the whole document to the canonical style | v1.14.0+ |
The launch command takes no arguments.
tdsl lspIn each editor, register the command tdsl lsp as the language server bound to .tdsl (language ID: tdsl). Example for Neovim (core LSP from 0.10+, no plugin required):
vim.filetype.add({ extension = { tdsl = "tdsl" } })
vim.api.nvim_create_autocmd("FileType", { pattern = "tdsl", callback = function() vim.lsp.start({ name = "tdsl-lsp", cmd = { "tdsl", "lsp" }, root_dir = vim.fs.root(0, { ".git" }), }) end,})For Helix, register it in languages.toml.
[language-server.tdsl-lsp]command = "tdsl"args = ["lsp"]
[[language]]name = "tdsl"scope = "source.tdsl"file-types = ["tdsl"]language-servers = ["tdsl-lsp"]In VS Code, the Timeline DSL extension resolves the tdsl binary from PATH and starts tdsl lsp automatically. If needed, set the extension setting timelineDsl.serverPath to the absolute path of your tdsl binary. For Neovim / Helix and other editors, register the server manually as shown above.
How each feature behaves
Section titled “How each feature behaves”- Diagnostics / completion / hover / goto-definition: syntax and semantic errors show up in real time while editing, and you get DSL keyword completion, hover for lane IDs / QIDs, and jumps from a lane reference to its declaration.
- References: place the cursor on a lane declaration or reference to list all references of that lane ID (
lanedeclaration, thelanefield ofspan/event/event_range, and thelaneproperty ofmap). - Rename: renaming on a lane ID replaces the declaration and all references at once. Rename is rejected on anything other than a lane ID (keywords, string literals).
- Document Symbol: returns an outline in the hierarchy
timeline>lane> items (span/event/event_range). - Formatting: formats the whole document to the canonical style via your editor's format command (v1.14.0+). It uses the same formatting engine as the CLI
tdsl fmt. Comments are preserved liketdsl fmt, although comments inside blocks may be relocated to canonical positions.
All features run on static analysis of the source text and need no network I/O (offline).
Code actions and fixable / non-fixable lint
Section titled “Code actions and fixable / non-fixable lint”Code actions offer auto-fixes equivalent to tdsl lint --fix as quick fixes. Some lint issues are auto-fixable and some are not.
| Kind | Lint issues | Code action |
| ----------- | ----------------------------------------------- | ------------------------------------------------------- |
| fixable | start_gt_end / invalid_tags / missing_id | Offers the quick fix "fix all auto-fixable lint issues" |
| non-fixable | unknown_lane / duplicate_id / empty_label | No quick fix (fix it by hand) |
When there are no fixable issues, no quick fix is shown. Applying it reformats and replaces the entire document with the same emitter as tdsl lint --fix. Comments are preserved where possible, although comments inside blocks may be relocated to canonical positions. The output matches tdsl lint --fix.
See also Commands for an overview of tdsl lsp.