You can download TextMate from here.
Use GitHub Issues for bug reports and feature requests.
- macOS 14.0 (Sonoma) or later
- Xcode (full install, not just Command Line Tools —
ibtoolandactoolare required). Make sure the active developer directory points to Xcode:sudo xcode-select -s /Applications/Xcode.app/Contents/Developer - ninja — build system similar to
make - cmake ≥ 3.21 — meta build system
All dependencies can be installed using Homebrew:
brew install ninja cmakegit clone --recursive https://github.com/tectiv3/textmate.git
cd textmate
make runIf you already cloned without --recursive, fetch the submodules separately:
git submodule update --init --recursivemake debug # Incremental debug build (ASan enabled)
make release # Incremental release build (LTO, no ASan)
make run # Build debug and launch
make clean # Remove all build dirs| Dependency | Status | Replacement |
|---|---|---|
| Old rave build system (62 files) | Removed | CMake + Ninja |
| multimarkdown + bin/gen_html | Removed | Pre-converted HTML |
| Cap'n Proto | Replaced | NSKeyedArchiver |
| google-sparsehash | Replaced | std::unordered_map |
| ragel | Replaced | Hand-written parser |
| boost (variant + crc) | Replaced | std::variant + zlib crc32 |
Press Cmd+Shift+P to open the command palette — a unified fuzzy-search interface for navigating TextMate. Type a prefix to switch modes:
| Prefix | Mode | What it does |
|---|---|---|
| (none) | Recent Projects | Open a recent project |
> |
Commands | Run any menu action or bundle command |
@ |
Symbols | Jump to a symbol in the current document |
# |
Bundle Editor | Open a grammar, snippet, or command in the bundle editor |
: |
Go to Line | Jump to a line number |
/ |
Find in Project | Open Find in Project with a pre-filled query |
~ |
Settings | Toggle editor settings (soft wrap, invisibles, etc.) |
Results are ranked by fuzzy match score. Frequently used items are boosted over time.
TextMate has built-in Language Server Protocol support for diagnostics and completions. Configure it per-project in .tm_properties:
# .tm_properties
[ *.php ]
lspCommand = "intelephense --stdio"
lspInitOptions = '{"licenceKey":"YOUR-KEY-HERE","clearCache":true}'
# .tm_properties
[ *.go ]
lspCommand = gopls
# .tm_properties
[ *.{c,cc,cpp,h,hpp,m,mm} ]
lspCommand = clangd
# .tm_properties
[ *.py ]
lspCommand = "pyright-langserver --stdio"
Alternative Python server with plugin ecosystem (ruff, mypy, black):
# .tm_properties
[ *.py ]
lspCommand = pylsp
To disable specific plugins (e.g. mypy if it can't find your project's dependencies):
# .tm_properties
[ *.py ]
lspCommand = pylsp
lspInitOptions = '{"pylsp": {"plugins": {"pylsp_mypy": {"enabled": false}}}}'
If you need pylsp to resolve project-specific packages, install it inside your project's virtualenv instead of using the global one.
Volar 2.0+ uses Hybrid Mode with typescript-language-server for script support:
# .tm_properties
[ *.{vue,ts,tsx,js,jsx} ]
lspCommand = "$TM_PROJECT_DIRECTORY/node_modules/.bin/typescript-language-server --stdio"
lspInitOptions = '{ "plugins": [{ "name": "@vue/typescript-plugin", "location": "./node_modules/@vue/language-server", "languages": ["vue"] }] }'
# .tm_properties
[ *.rs ]
lspCommand = rust-analyzer
# .tm_properties
[ *.lua ]
lspCommand = lua-language-server
# .tm_properties
[ *.{sh,bash,zsh} ]
lspCommand = "bash-language-server start"
# .tm_properties
[ *.rb ]
lspCommand = ruby-lsp
Requires Xcode. Project must have a Package.swift or compile_commands.json.
# .tm_properties
[ *.swift ]
lspCommand = "xcrun sourcekit-lsp"
| Property | Description |
|---|---|
lspCommand |
Command to launch the language server (required) |
lspEnabled |
Set to false to disable LSP for matching files (default: true) |
lspRootPath |
Override workspace root detection |
lspInitOptions |
JSON object passed as initializationOptions to the server |
lspFormatOnSave |
Set to true to format via LSP before saving (default: false) |
formatCommand |
Shell command for an external formatter (stdin/stdout, overrides LSP formatting) |
formatOnSave |
Set to true to format before saving — uses formatCommand if set, else LSP (default: false) |
Press Opt+Tab to trigger LSP completions. Diagnostics (errors, warnings) appear automatically in the gutter.
Open the LSP log panel via View → LSP Log (or click the LSP status indicator in the bottom bar). Shows all JSON-RPC traffic, server stderr, errors, and lifecycle events. Use the filter field to narrow by server name or message content.
TextMate supports GitHub Copilot inline completions (ghost text). Requires a GitHub Copilot subscription.
Install copilot-language-server (the modern native binary):
npm install -g @github/copilot-language-serverOr via nix:
environment.systemPackages = [ pkgs.copilot-language-server ];TextMate auto-detects the binary from $PATH. To override, set copilotCommand in .tm_properties:
copilotCommand = /path/to/copilot-language-server
| Property | Description |
|---|---|
copilotCommand |
Path to copilot-language-server binary (overrides auto-detect) |
copilotEnabled |
Set to false to disable Copilot for matching files (default: true) |
Copilot suggestions appear automatically as ghost text while typing. Press Tab to accept, Esc to dismiss. Sign in via TextMate → Copilot → Sign In on first use.
Set copilotEnabled = false in .tm_properties. Like all TextMate settings, it can be scoped globally, per-project, or per-file-type:
# ~/.tm_properties — disable everywhere
copilotEnabled = false
# project .tm_properties — disable for one file type
[ *.md ]
copilotEnabled = false
Format the current document via Text → Format Code. Enable format-on-save per file type.
You can use any external formatter that reads stdin and writes formatted output to stdout. When formatCommand is set, it takes priority over LSP formatting for that file type. Standard TextMate variables (TM_FILEPATH, TM_TAB_SIZE, TM_SOFT_TABS, etc.) are available to the command. The working directory is set to the project root so tools find their config files.
Note: Quote the command if it contains arguments.
# .tm_properties
# JavaScript/TypeScript with Prettier
[ *.{js,jsx,ts,tsx} ]
formatCommand = "prettier --parser=typescript"
formatOnSave = true
# PHP with Prettier
[ *.php ]
formatCommand = "prettier --parser=php"
formatOnSave = true
# Python with Black
[ *.py ]
formatCommand = "black -q -"
formatOnSave = true
# Rust with rustfmt
[ *.rs ]
formatCommand = rustfmt
formatOnSave = true
# Go with gofmt
[ *.go ]
formatCommand = gofmt
formatOnSave = true
# C/C++/ObjC with clang-format
[ *.{c,cc,cpp,h,hpp,m,mm} ]
formatCommand = clang-format
formatOnSave = true
For file types without a formatCommand, formatting falls back to the language server (if it supports textDocument/formatting):
# .tm_properties
[ *.php ]
formatOnSave = true
The legacy lspFormatOnSave key still works for backward compatibility.
The source for TextMate is released under the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
TextMate is a trademark of Allan Odgaard.













