Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>X-Change Life Twee ToolsNew to Visual Studio Code? Get it now.
X-Change Life Twee Tools

X-Change Life Twee Tools

aphrodite

|
168 installs
| (0) | Free
Lightweight syntax highlighting + passage navigation for X-Change Life's X-Lowe (Harlowe-like) Twee files.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

XCL Twee X-Lowe (VS Code Extension)

VS Code extension for X-Change Life Twee (.twee) files using X-Lowe (Harlowe-style syntax).

Features

  • Syntax highlighting for XCL/X-Lowe patterns (passages, macros, variables, hooks, HTML)
  • Passage Explorer panel in the Activity Bar for quick navigation
  • Macro Handbook panel (categorized macro browser + docs)
  • Palette Gallery panel with live theme previews and one-click application
  • Media Validation — verifies (pic:), (vid:), (media:) paths exist on disk with hover status and inline diagnostics
  • Go to Definition (F12 or Ctrl/Cmd+Click) on passage references
  • Rename Passage (F2) — renames the header and all references across the workspace
  • Passage Folding — fold/unfold passage blocks from the gutter or with keyboard shortcuts
  • Autocomplete for macros and passage names
  • CodeLens showing passage targets inline
  • Hover info for macros and passage references
  • Status bar showing current passage and word count
  • 14 custom color themes optimized for Twee editing

Keyboard Shortcuts

All keybindings are active only in .twee files and can be disabled with the master toggle xcl.keybindings.enabled.

Navigation

Action Mac Windows / Linux Command
Passage Picker (fuzzy search) Cmd+G Ctrl+G xcl.openPassagePicker
Jump to Next Passage Ctrl+] Alt+Down xcl.nextPassage
Jump to Previous Passage Ctrl+[ Alt+Up xcl.previousPassage
Go to Current Passage Header Cmd+Shift+H Ctrl+Shift+H xcl.goToPassageHeader

Folding

Action Mac Windows / Linux Command
Fold All Passages Cmd+Alt+[ Ctrl+Alt+[ xcl.foldAllPassages
Unfold All Passages Cmd+Alt+] Ctrl+Alt+] xcl.unfoldAllPassages

Editing

Action Mac Windows / Linux Command
Rename Passage (header or reference) F2 F2 VS Code native rename

Validation

Action Mac Windows / Linux Command
Validate Media (current file) Cmd+Shift+M Ctrl+Shift+M xcl.validateMedia

Disabling Keybindings

Set the master toggle to disable all XCL keybindings at once (requires reload):

{
  "xcl.keybindings.enabled": false
}

Individual features like folding and rename can also be toggled independently — see Settings.


Passage Folding

Each passage block (from :: header to the line before the next ::) can be folded. This transforms navigating long twee files — fold all, then unfold just the passage you need.

  • Gutter arrows: Click the fold arrow next to any :: header
  • Fold All / Unfold All: Cmd+Alt+[ / Cmd+Alt+] (Mac) or Ctrl+Alt+[ / Ctrl+Alt+] (Win)
  • Toggle: Disable with xcl.passageFolding.enabled: false

Works with VS Code's built-in fold commands (Ctrl+Shift+[ to fold current, Ctrl+Shift+] to unfold current).


Rename Passage (F2)

Press F2 on a :: Passage Name header or on a passage reference string inside a macro to rename it across the entire workspace.

  • Renames the passage header definition
  • Updates all references in (display:), (goto:), (cs:), (simple_option:), and all other configured passage reference macros
  • Works across all indexed .twee files
  • Toggle: Disable with xcl.passageRename.enabled: false

Passage Navigation

Passage Picker (Cmd+G / Ctrl+G)

Fuzzy-search all passages by name and jump instantly. The single highest-ROI keybind for navigating large twee projects.

Next / Previous Passage (Ctrl+] / Ctrl+[ on Mac, Alt+Down / Alt+Up on Win)

Jump between :: headers with a single keystroke. No more scrolling through 3000-line files to find the next passage.

Go to Passage Header (Cmd+Shift+H / Ctrl+Shift+H)

When your cursor is deep in passage body text, one keypress snaps you back to that passage's :: header line.


Media Validation

The extension validates media file references in (pic:), (vid:), and (media:) macros against your project's dist/output directories.

How It Works

  • Inline diagnostics: Missing media files get a yellow squiggly underline with a warning message
  • Hover status: Hover over any media path to see ✅ (found) or ❌ (not found) with the resolved path and search directories
  • Validate button: Click the $(file-media) icon in the Passages sidebar toolbar, or press Cmd+Shift+M / Ctrl+Shift+M
  • Smart path resolution: The macro auto-prepends img/ to paths, so (pic:"ch01/elara.jpg") checks for img/ch01/elara.jpg in your configured directories

What Gets Validated

(pic:"ch01/elara.jpg")              ✅ Validated → checks dist/img/ch01/elara.jpg
(vid:"img/ch01/concerned.mp4")      ✅ Validated → strips extra img/, checks dist/img/ch01/concerned.mp4
(pic:"ch01/elara.jpg","right","!")   ✅ Validated → first arg only
(media:"npc/face.png")              ✅ Validated

What Gets Skipped

Paths with variables or concatenation are automatically ignored — no false positives:

(pic:$portrait)                     ⏭ Skipped — variable reference
(pic:"prefix" + $var)               ⏭ Skipped — concatenation
(pic:$image_path)                   ⏭ Skipped — variable
(set:$portrait to "img/x.png")      ⏭ Skipped — not a media macro

Configuring Media Directories

By default, the extension searches for media files in <workspace>/dist. You can configure multiple directories:

{
  "xcl.mediaDirectories": [
    "dist",
    "build/output",
    "../shared-assets"
  ]
}

The extension watches these directories for changes and updates diagnostics automatically.

Toggling Media Validation

Disable/enable in settings:

{
  "xcl.mediaValidation.enabled": false
}

Word Count

The status bar shows a live word count for the current .twee file: ✏ 12,345 words

The count strips passage headers (:: Name), HTML comments, and macro calls for a more representative prose word count. Updates automatically as you edit.


Color Themes

The extension includes 14 carefully crafted color themes optimized for XCL Twee syntax highlighting.

Dark Themes

Theme Description
XCL Blessing Warm golden tones on deep purple-black
XCL Northwest Passage Cool blues and teals with forest undertones
XCL Cerise Vibrant pinks and magentas on dark cherry
XCL Ocean Deep sea blues with aqua accents
XCL Dark Balanced neutral dark theme
XCL Summer City Warm sunset oranges and corals
XCL Valentine Romantic reds and soft pinks
XCL Royal Regal purples with gold highlights
XCL Dream Soft pastels on midnight blue
Goblin's Pet 1970s Umbral Earthy browns and amber on dark crimson
Goblin's Pet Goblin Market Mysterious greens and golds

Light Themes

Theme Description
XCL DMG-01 Retro Game Boy–inspired monochrome green
XCL Parchment Warm sepia tones like aged paper
Goblin's Pet Reliquary White Clean ivory with antique accents

Applying Themes

  1. Via Palette Gallery: Click the XCL icon in the Activity Bar → Palettes panel → Click Apply on any theme
  2. Via Command Palette: Ctrl+Shift+P → "Preferences: Color Theme" → Select an XCL theme
  3. Via Settings: File → Preferences → Color Theme

Sidebar Views

Click the XCL icon in the Activity Bar to access all panels.

Passages

Shows passages in the currently active .twee file. Click a passage to jump to it. Drag and drop to reorder.

Toolbar actions:

  • Validate Media — Check all (pic:), (vid:), (media:) references in the current file
  • Configure Search Paths — Add or remove folders from the index
  • Refresh — Rebuild the passage index
  • Sort A→Z — Sort passages alphabetically

Macro Handbook

A categorized, searchable macro browser built from bundled JSON documentation.

Organization:

  • XCL Macros — X-Change Life / X-Lowe custom macros
  • Harlowe Macros — Core Harlowe macros
  • TGP Macros — The Goblin's Pet macros

Within each group, macros are organized by Category (Navigation, Variables, Output, etc.) and sorted by macro count. Click any macro to open its rendered documentation.

Palettes

A visual gallery of all bundled color themes with:

  • Live color swatches extracted from each theme's JSON
  • One-click Apply button to instantly set your VS Code theme
  • Open JSON button to inspect/edit the theme file
  • Search filter to quickly find themes by name

Macro Docs Files

By default, the extension loads all bundled macro documentation:

File Contents
macros/xcl-macros.harlowe.json Core Harlowe macros
macros/xcl-macros.xlowe.json X-Change Life / X-Lowe macros
macros/xcl-macros.stats.json Stats, Sidebar, Tertiary, Meter macros
macros/xcl-macros.tgp.json The Goblin's Pet macros

Override behavior:

  • Set xcl.macroDocsFile to a single JSON file path to load only that file
  • Workspace-relative paths are supported

Navigation

These macros support Go to Definition on their first string argument:

(display:"passage")
(goto:"passage")
(link-goto:"passage")
(click-goto:"passage")
(cs:"passage")
(simple_option:"passage", ...)
($simple_option:"passage", ...)

Configure the list in settings: xcl.passageReferenceMacros


Commands

Command Description
XCL: Passage Picker Quick-pick menu to jump to any passage
XCL: Open Passage Open a passage by name
XCL: Jump to Next Passage Move cursor to the next :: header
XCL: Jump to Previous Passage Move cursor to the previous :: header
XCL: Go to Current Passage Header Snap cursor back to the owning :: header
XCL: Fold All Passages Fold every passage block in the current file
XCL: Unfold All Passages Unfold every passage block in the current file
XCL: Reindex Workspace Passages Rebuild the passage index
XCL: Validate Media on Page Check all media references in the current file
XCL: Rebuild Media Index Rebuild the media file cache for all configured directories
XCL: Reload Macro Docs Reload macro documentation JSON
XCL: Open Macro Docs File Open the last-loaded macro docs JSON
XCL: Open Palette Gallery Focus the Palette Gallery panel
Sort Passages A→Z Sort passages alphabetically in the current file
Refresh Refresh the Passage Explorer (toolbar button)
Configure Search Paths Add or remove folders from the index (toolbar button)

Settings

Setting Default Description
xcl.keybindings.enabled true Master toggle for all XCL keybindings. Disable to prevent key conflicts. Requires reload.
xcl.passageFolding.enabled true Enable passage folding (fold each block from :: to the next)
xcl.passageRename.enabled true Enable Rename Passage (F2) across the workspace
xcl.indexGlobs ["**/*.twee"] File patterns to index (prefix with ! to exclude)
xcl.passageReferenceMacros ["display", "goto", "link-goto", "click-goto", "cs", "simple_option", "$simple_option"] Macros whose first string argument is treated as a passage reference
xcl.macroDocsFile "" Custom macro docs JSON path (loads ONLY this file if set)
xcl.statusBar.enabled true Show passage in status bar
xcl.codeLens.enabled true Show CodeLens for passages
xcl.documentLinks.enabled true Show visible hyperlinks on passage references
xcl.showPassageNotFoundWarnings true Show warnings when a referenced passage is not found
xcl.passageView.groupByFile true Group passages by file in the Passage Explorer view
xcl.mediaValidation.enabled true Enable media validation (diagnostics + hover) for (pic:), (vid:), (media:) macros
xcl.mediaDirectories [] Directories to search for media files (workspace-relative). Defaults to dist if empty

Installation

From VSIX

npm install
npm run compile
npm run package
code --install-extension ./xcl-twee-xlowe-1.0.8.vsix

Development Mode

Open the folder in VS Code and press F5 to launch the Extension Development Host.


Project Structure

xcl-twee-xlowe/
├── src/
│   └── extension.ts              # Main extension logic
│       ├── PassageIndex                  # Workspace-wide passage indexing
│       ├── MediaIndex                    # Media file existence cache
│       ├── MediaDiagnosticManager        # Missing media diagnostics
│       ├── MediaHoverProvider            # Media path hover (✅/❌)
│       ├── PassageTreeDataProvider       # Passage Explorer sidebar
│       ├── PassageDragAndDropController  # Drag-and-drop passage reordering
│       ├── PassageFoldingRangeProvider   # Passage folding (:: to ::)
│       ├── PassageRenameProvider         # F2 rename (header + all refs)
│       ├── MacroHandbookDataProvider     # Macro Handbook sidebar
│       ├── PaletteGalleryViewProvider    # Palette Gallery webview
│       ├── MacroRegistry                 # Macro documentation loader
│       ├── MacroDocMarkdownProvider      # Virtual markdown docs
│       ├── PassageDefinitionProvider     # Go to Definition
│       ├── PassageLinkProvider           # Document links
│       ├── PassageSymbolProvider         # Document symbols
│       ├── MacroHoverProvider            # Macro hover info
│       ├── MacroCompletionProvider       # Macro autocomplete
│       ├── PassageNameCompletionProvider # Passage name autocomplete
│       ├── PassageCodeLensProvider       # CodeLens for passages
│       └── PassageReferenceHoverProvider # Passage reference hover
│
├── syntaxes/
│   └── xcl-twee.tmLanguage.json  # TextMate grammar for syntax highlighting
│
├── themes/                       # Color themes (14 total)
│   ├── xcl-blessing-color-theme.json
│   ├── xcl-northwest-passage-color-theme.json
│   ├── xcl-cerise-color-theme.json
│   ├── xcl-ocean-color-theme.json
│   ├── xcl-dark-color-theme.json
│   ├── xcl-summer-city-color-theme.json
│   ├── xcl-valentine-color-theme.json
│   ├── xcl-royal-color-theme.json
│   ├── xcl-dream-color-theme.json
│   ├── xcl-dmg-01-color-theme.json
│   ├── xcl-parchment-color-theme.json
│   ├── goblins-pet-1970s-umbral-color-theme.json
│   ├── goblins-pet-goblin-market-color-theme.json
│   └── goblins-pet-reliquary-white-color-theme.json
│
├── macros/                       # Macro documentation JSON
│   ├── xcl-macros.harlowe.json
│   ├── xcl-macros.xlowe.json
│   ├── xcl-macros.stats.json
│   └── xcl-macros.tgp.json
│
├── language-configuration.json   # Brackets, comments, folding
├── package.json                  # Extension manifest
├── tsconfig.json                 # TypeScript configuration
├── icon.svg                      # Activity bar icon
├── icon.png                      # Marketplace icon
└── README.md                     # This file

Syntax Highlighting

The TextMate grammar (xcl-twee.tmLanguage.json) provides highlighting for:

Element Scope
Passage headers (:: Name) entity.name.section.passage.xcl-twee
Passage tags ([tag]) entity.other.attribute-name.passage.tag.xcl-twee
Navigation macros support.function.macro.navigation.xcl-twee
Audio macros support.function.macro.audio.xcl-twee
UI macros support.function.macro.ui.xcl-twee
Custom macros ($name:) support.function.macro.custom.xcl-twee
Generic macros entity.name.function.macro.xcl-twee
Variables ($var, _var) variable.other.xcl-twee
Hooks ([...], |name>[...]) meta.hook.xcl-twee
Link markup ([[...]]) meta.link.twee.xcl-twee
Strings string.quoted.*.xcl-twee
Numbers constant.numeric.xcl-twee
Booleans constant.language.boolean.xcl-twee
Operators keyword.operator.xcl-twee
HTML tags entity.name.tag.*.html
Comments comment.block.html

Language Configuration

The extension configures VS Code with:

  • Block comments: <!-- -->
  • Bracket pairs: {}, (), []
  • Auto-closing pairs: All brackets, quotes, and HTML comments
  • Folding markers: <!-- #region --> / <!-- #endregion -->

Repository

  • Source: https://gitgud.io/xchange-life/xcl-twee-xlowe
  • Issues: https://gitgud.io/xchange-life/xcl-twee-xlowe/issues

License

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft