Esc

    Rexa runs language servers for diagnostics, hover information and code navigation. Each server is off until you turn it on, except JSON, which is on by default.

    Turn a server on

    The first time you open a file whose language has a server, Rexa offers Enable. You can also turn servers on in Settings → Language servers, or in settings.json:

    settings.json
    {
      "lsp": { "enabled_servers": ["rust-analyzer", "typescript-language-server"] }
    }

    Enabling a server applies to every project.

    Built-in servers

    Name Languages Command
    rust-analyzer Rust rust-analyzer
    typescript-language-server TypeScript, JavaScript typescript-language-server --stdio
    pyright Python pyright-langserver --stdio
    gopls Go gopls
    clangd C, C++ clangd
    zls Zig zls
    lua-language-server Lua lua-language-server
    vscode-json-language-server JSON, JSONC vscode-json-language-server --stdio

    Rexa looks for each command on your PATH, including the PATH your login shell sets. The JSON and TypeScript servers need no install: when the command is missing, Rexa runs a pinned copy and caches it in ~/Library/Caches/deno.

    Features

    Feature How
    Diagnostics Underlines and gutter dots. Counts in the status bar.
    Hover Rest the pointer for 300 ms, or K in Vim normal mode.
    Go to definition F12 or ⌘-click
    Go to declaration ⌃ F12
    Go to type definition ⌘ F12 or ⌘ ⇧-click
    Go to implementation ⇧ F12

    The jumps also work from git diffs and the right-click menu.

    Problems

    Action Shortcut
    Problems tab ⌘ ⇧ M
    Problems palette ⌃ ⇧ M
    Next / previous problem F8 / ⇧ F8

    The Problems tab lists errors and warnings for the worktree, grouped by file, with filters for each. Click the counts in the status bar for the same list as a popup.

    Server status

    Each running server has a status bar item with its name and progress, such as Rust: Indexing (42%). A trailing … means starting, yellow means not installed, and red means it failed.

    Click the item for its details and a menu: Restart, Stop or Start, Show Logs, the server’s own commands (such as Reload Workspace for Rust), the toolchain picker, and Restart All Language Servers.

    Toolchains

    Rexa picks a toolchain per server root: the TypeScript version, Python interpreter, Node version, Rust toolchain or Go toolchain. It prefers the one closest to the project, never a machine-wide install.

    • TypeScript uses the project’s node_modules/typescript. Without one, Rexa uses a bundled TypeScript 7, or TypeScript 5.9 for projects that declare TypeScript 6 or older.
    • Python uses the project’s .venv.
    • Node follows .nvmrc, .node-version or volta.node. Write a version number; aliases such as lts/* are not resolved.

    Change it from the server’s status item (TypeScript Version…, Python Interpreter…), or pin it per project in .rexa/config.json. New terminals and agents in the worktree get the same Python and Node first on PATH.

    Add or replace a server

    lsp.servers adds a server, or replaces a built-in one with the same name:

    settings.json
    {
      "lsp": {
        "enabled_servers": ["ruby-lsp"],
        "servers": {
          "ruby-lsp": {
            "label": "Ruby",
            "languages": ["ruby"],
            "command": "ruby-lsp",
            "args": [],
            "root_markers": ["Gemfile"]
          }
        }
      }
    }

    Each server also accepts env, initialization_options and settings. Zed extensions can provide servers too; see Themes and extensions.

    From the command line

    rexa lsp reports and controls servers in the running app:

    Terminal
    rexa lsp                          # status of every server
    rexa lsp diagnostics src/main.rs  # diagnostics for a file
    rexa lsp restart rust-analyzer    # restart one server
    rexa lsp toolchain python .venv   # pick a toolchain

    Each server’s log is in ~/Library/Logs/rexa/lsp/.