Zed Extension for Stata

April 20, 2026 · View on GitHub

A Zed extension providing support for the Stata statistical programming language.

Features

  • Code completion
  • Diagnostics (e.g., detects syntax errors and undefined macros)
  • Syntax highlighting
  • Run Stata code from the editor (requires additional setup—see below)

⚠️ Development Status: This is an early-stage implementation. While functional, it requires substantial testing and code review. Contributions and feedback are welcome!

Related Repositories:

  • Sight - A language server and VS Code extension for Stata
  • tree-sitter-stata - A tree-sitter grammar
  • send-to-stata - A utility for sending Stata code to the Stata application This Zed extension uses the tree-sitter grammar and language server from those repositories to provide syntax highlighting and diagnostics. The send-to-stata utility sends code to Stata on Windows; macOS uses AppleScript.

Tip

The Zed extension does not include send-to-stata; run the installer below for your platform.

Installation

Install from the Zed extension marketplace by searching for "Stata".

Syntax highlighting, completions, and diagnostics will work immediately once you open a ".do" file.

Outline Configuration

Zed can populate the outline and breadcrumbs from Sight's LSP textDocument/documentSymbol response instead of the tree-sitter outline query.

Add the following to your Zed user settings:

{
  "languages": {
    "Stata": {
      "document_symbols": "on"
    }
  }
}

You can add this in either of these places:

  • User settings (~/.config/zed/settings.json on macOS/Linux, %APPDATA%\Zed\settings.json on Windows) to enable LSP-backed outline for all Stata files

  • Project settings (.zed/settings.json in a repository) to enable it only for that project

Without this setting, Zed uses the tree-sitter outline query, which is currently much narrower than Sight's document symbols.

Send to Stata (Optional)

Execute Stata code directly from Zed with keyboard shortcuts. Works with both the Stata application and terminal sessions.

Note

Why a separate install? Zed extensions can provide tasks, but custom keybindings still have to live in user config, and in practice users need their own copies of the tasks for those bindings. On Windows, the workflow also depends on the native send-to-stata.exe binary. The installer sets up the required script or executable plus the user-owned task and keybinding configuration.

See tools/send-to-stata/README.md for full documentation, configuration options, and troubleshooting.

Keyboard Shortcuts

MacWindowsAction
cmd-enterctrl-enterSend statement to Stata app
shift-cmd-entershift-ctrl-enterSend file to Stata app
opt-cmd-enteralt-ctrl-enterInclude statement (preserves locals)
opt-shift-cmd-enteralt-shift-ctrl-enterInclude file (preserves locals)
shift-entershift-enterPaste selection to terminal
opt-enteralt-enterPaste current line to terminal

macOS

Run the installer in Terminal:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/jbearak/zed-stata/main/tools/send-to-stata/install-macos.sh)"

Windows

Important

The Windows scripts require PowerShell 7+ (pwsh). Install PowerShell 7 (if not already installed):

winget install Microsoft.PowerShell

Run the installer in PowerShell:

irm https://raw.githubusercontent.com/jbearak/zed-stata/main/tools/send-to-stata/install-windows.ps1 | iex

Tip

Focus behavior: The installer prompts whether to return focus to Zed after sending code to Stata.

Jupyter REPL (Optional)

The installer creates two Jupyter kernels:

KernelWorking DirectoryUse Case
StataFile's directoryScripts with paths relative to the script location
Stata (Workspace)Workspace rootScripts with paths relative to the project root

The workspace kernel walks up from the file's directory looking for .git, .stata-project, or .project markers to find the project root. If no marker is found, it falls back to the file's directory.

Usage in Zed:

  1. Open a .do file
  2. Select stata or stata_workspace as the kernel
  3. Click the 🔄 icon in the editor toolbar to execute code or use Control+Shift+Enter keyboard shortcut

Note: stata_kernel works well for interactive exploration but can hang on long-running loops or operations taking more than several seconds. For batch scripts or iterative workflows, use Send to Stata instead. See comparison table below.

macOS

Run the installer in Terminal:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/jbearak/zed-stata/main/tools/jupyter-kernel/install-macos.sh)"

Windows

Important

The Windows scripts require PowerShell 7+ (pwsh). Install PowerShell 7 (if not already installed):

winget install Microsoft.PowerShell

Run the installer in PowerShell:

irm https://raw.githubusercontent.com/jbearak/zed-stata/main/tools/jupyter-kernel/install-windows.ps1 | iex

Important

After installing or updating the Jupyter kernels, restart Zed. Kernel discovery/connection state can be cached, and a restart is often required before the kernels can connect successfully. The installer adds the Jupyter virtual environment to your PATH so Zed can discover the kernels.

Caution

The Windows installer is intentionally opinionated to work reliably:

  • Uses Python 3.11 via the Python Launcher (py -3.11) (newer versions have caused dependency and kernelspec issues).
  • Recreates the venv if needed to ensure the venv is actually using Python 3.11.
  • Installs only minimal Jupyter components (jupyter-core, jupyter-client, and a pinned ipykernel) instead of the full jupyter meta-package to avoid pulling in notebook/jupyterlab and native build dependencies (e.g. pywinpty).
  • Writes kernelspecs deterministically into %APPDATA%\jupyter\kernels\... (including kernel.json) so Zed can discover them.

Warning

Start the kernel before opening Stata. On Windows, if Stata is already running when you launch a Jupyter kernel, the kernel will close your Stata application. This is a fundamental limitation of Stata's Windows architecture. Start the kernel first, then open Stata if needed. This issue does not affect macOS.

Choosing Between Send-to-Stata and Jupyter REPL

ScenarioRecommendedWhy
Quick data explorationJupyter REPLInline results, fast iteration
Testing individual commandsJupyter REPLInteractive feedback
Loops with many iterationsSend to StataAvoids kernel hang issues
Operations > several secondsSend to StataAvoids potential instability
Graph-heavy workflowsSend to StataGraphs can trigger kernel hangs
Production batch jobsSend to StataReliable unattended execution

Tip

The installer creates ~/.stata_kernel.conf (or %USERPROFILE%\.stata_kernel.conf on Windows) with auto-detected settings. Edit this file to customize graph format, cache directory, and other options.

What the Install Scripts Do

Why Install Scripts Are Required

The extension provides basic tasks that show installation instructions, but full Send-to-Stata and Jupyter REPL functionality requires running the installers because:

  • Temp file management: Stata executes code from .do files, so the script creates temp files and manages cleanup
  • Statement detection: Multi-line statements with /// continuations require parsing logic
  • Stata variant detection: The script auto-detects which Stata variant (MP, SE, IC) is installed
  • Keybindings: Zed extensions cannot register keybindings; they must be added to user config files
  • Platform-specific binaries: Windows requires a native executable for clipboard/SendKeys automation

Send-to-Stata Installer

The send-to-stata installer configures keyboard shortcuts to send code from Zed to Stata.

What It Does NOT Do:

  • Does not modify Stata installation
  • Does not require admin/sudo privileges
  • Does not install system-wide packages

Files Created (macOS)

FilePurpose
~/.local/bin/send-to-stata.shMain script that communicates with Stata via AppleScript
~/.config/zed/tasks.jsonUpdated with Stata task definitions
~/.config/zed/keymap.jsonUpdated with keyboard shortcuts

Files Created (Windows)

FilePurpose
%APPDATA%\Zed\stata\send-to-stata.exeNative executable for Stata automation
%APPDATA%\Zed\tasks.jsonUpdated with Stata task definitions
%APPDATA%\Zed\keymap.jsonUpdated with keyboard shortcuts

Jupyter Kernel Installer

The Jupyter kernel installer sets up stata_kernel for use with Zed's REPL.

Files Created (macOS)

FilePurpose
~/.local/share/jupyter/kernels/stata/Standard kernel specification
~/.local/share/jupyter/kernels/stata_workspace/Workspace kernel specification
~/.stata_kernel.confKernel configuration (Stata path, graph format, etc.)

Files Created (Windows)

FilePurpose
%APPDATA%\jupyter\kernels\stata\Standard kernel specification
%APPDATA%\jupyter\kernels\stata_workspace\Workspace kernel specification
%LOCALAPPDATA%\stata_kernel\venv\Isolated Python virtual environment
%USERPROFILE%\.stata_kernel.confKernel configuration

Manual Keybindings Setup

If you prefer to configure keybindings manually instead of running the installer, add the following to your Zed keymap file.

macOS

Add to ~/.config/zed/keymap.json:

[
  {
    "context": "Editor && extension == do",
    "bindings": {
      "cmd-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Do Statement"}]]],
      "shift-cmd-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Do File"}]]],
      "alt-cmd-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Include Statement"}]]],
      "alt-shift-cmd-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Include File"}]]],
      "shift-enter": ["workspace::SendKeystrokes", "cmd-c ctrl-` cmd-v enter"],
      "alt-enter": ["workspace::SendKeystrokes", "cmd-left shift-cmd-right cmd-c ctrl-` cmd-v enter"],
      "ctrl-shift-w": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: CD to Workspace"}]]],
      "ctrl-shift-f": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: CD to File Directory"}]]]
    }
  }
]

Windows

Add to %APPDATA%\Zed\keymap.json:

[
  {
    "context": "Editor && extension == do",
    "bindings": {
      "ctrl-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Do Statement"}]]],
      "shift-ctrl-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Do File"}]]],
      "alt-ctrl-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Include Statement"}]]],
      "alt-shift-ctrl-enter": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: Include File"}]]],
      "shift-enter": ["workspace::SendKeystrokes", "ctrl-c ctrl-` ctrl-v enter"],
      "alt-enter": ["workspace::SendKeystrokes", "home shift-end ctrl-c ctrl-` ctrl-v enter"],
      "ctrl-shift-w": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: CD to Workspace"}]]],
      "ctrl-shift-f": ["action::Sequence", ["workspace::Save", ["task::Spawn", {"task_name": "Stata: CD to File Directory"}]]]
    }
  }
]

Note

Manual keybindings require the send-to-stata script/executable to be installed. The keybindings trigger tasks that call the script. Run the installer to install the script, or see tools/send-to-stata/README.md for manual script installation.

Building from Source

See DEVELOPMENT.md for detailed development setup, directory structure, and workflows.

Send-to-Stata

Install from a local clone:

git clone https://github.com/jbearak/zed-stata
cd zed-stata

# macOS
./tools/send-to-stata/install-macos.sh

# Windows (PowerShell 7+)
pwsh -File .\tools\send-to-stata\install-windows.ps1

Jupyter Kernel

Install stata_kernel from a local clone:

git clone https://github.com/jbearak/zed-stata
cd zed-stata

# macOS
./tools/jupyter-kernel/install-macos.sh

# Windows (PowerShell 7+)
pwsh -File .\tools\jupyter-kernel\install-windows.ps1
  • Sight LSP - A language server protocol implementation for the Stata statistical programming language
  • tree-sitter-stata - Tree-sitter grammar for Stata

License

Copyright © 2026 Jonathan Marc Bearak

GPLv3 - This project is open source software. You can use, modify, and distribute it with attribution, but any derivative works must also be open source under GPLv3.