Emacs major mode for the Mojo programming language, aiming for feature parity with Modular's VS Code extension.
Derives from python-mode, so indentation, movement, and everything else
Python-shaped keeps working, with Mojo's own keywords, types, and tooling on
top.
| vscode-mojo | mojo-mode |
|---|---|
Syntax highlighting (.mojo, .🔥) |
✅ mojo-mode, both extensions |
SDK detection (mojo.sdk.path, workspace env, PATH) |
✅ mojo-sdk-path, pixi/uv/magic envs, PATH, ~/.modular |
Mojo: Refresh SDK Detection |
✅ M-x mojo-refresh-sdk |
LSP client for mojo-lsp-server |
✅ via eglot, auto-started |
mojo.lsp.includeDirs |
✅ mojo-lsp-include-dirs |
mojo.lsp.suppress.diagnostics.in.docstring |
✅ mojo-lsp-suppress-diagnostics-in-docstring |
Restart / Stop the Mojo LSP Server |
✅ mojo-lsp-restart, mojo-lsp-stop |
Run Mojo File |
✅ mojo-run-file (C-c C-c), errors clickable in compilation-mode |
Debug Mojo File in Terminal |
✅ mojo-debug-file (C-c C-d), LLDB in a comint buffer |
Attach to Process |
✅ mojo-debug-attach |
Configure Build and Run Args |
✅ mojo-set-args (C-c C-a), mojo-build-args |
Formatting, mojo.formatting.args |
✅ mojo-format-buffer (C-c C-f), mojo-format-on-save |
| Markdown code-block injection | ✅ Markdown fenced blocks and Org src blocks |
| Command palette entries | ✅ Mojo menu + keymap |
| Mojo file icon | ✅ 🔥 registered with nerd-icons (mojo-icon) |
| DAP-based debugging UI | ➖ comint LLDB instead (see below) |
| Test explorer, MLIR dump, LSP traffic recording | ❌ not implemented |
| — | ➕ mojo-repl (C-c C-z), no VS Code equivalent |
| — | ➕ imenu index for struct / trait / fn / comptime |
Emacs 29.1+ (needs eglot, defvar-keymap, replace-buffer-contents).
;; Emacs 29+ built-in
(package-vc-install '(mojo-mode :url "https://github.com/caius72/mojo-mode"))
;; straight.el
(straight-use-package '(mojo-mode :host github :repo "caius72/mojo-mode"))
;; elpaca
(elpaca (mojo-mode :host github :repo "caius72/mojo-mode"))Doom Emacs — packages.el:
(package! mojo-mode :recipe (:host github :repo "caius72/mojo-mode"))then doom sync. Nothing else is required: .mojo files pick up the mode, and
eglot starts if a mojo-lsp-server is found.
(use-package mojo-mode
:mode ("\\.mojo\\'" "\\.🔥\\'")
:custom
;; Pin an SDK instead of auto-detecting it (like mojo.sdk.path)
(mojo-sdk-path "~/.pixi/envs/mojo")
(mojo-format-on-save t)
(mojo-lsp-include-dirs '("~/src/mypkgs")))Without mojo-icon, nerd-icons would show the Python icon, since mojo-mode
derives from python-mode. The default is the 🔥 emoji; a Nerd Font glyph
avoids emoji-font sizing quirks in the modeline:
(setq mojo-icon (nerd-icons-faicon "nf-fa-fire")) ; or nil to keep Python'sEverything is auto-detected by default. The SDK is looked up in this order:
mojo-sdk-path- a workspace environment found by walking up from the current file —
.pixi/envs/default,.magic/envs/default,.venv,venv,env(disable withmojo-prefer-workspace-env) mojoonPATH~/.modular
So a per-project uv or pixi install is used automatically, without setting
anything.
| Key | Command |
|---|---|
C-c C-c |
mojo-run-file |
C-c C-b |
mojo-build-file |
C-c C-d |
mojo-debug-file |
C-c C-f |
mojo-format-buffer |
C-c C-z |
mojo-repl |
C-c C-a |
mojo-set-args |
C-c C-r |
mojo-lsp-restart |
In Doom Emacs and Spacemacs the same commands are registered under the
major-mode leader, SPC m (M-SPC m outside normal state), with which-key
labels — no configuration needed:
| Key | Command |
|---|---|
SPC m r |
run file |
SPC m b |
build file |
SPC m d / SPC m D |
debug file / attach to process |
SPC m a |
configure run args |
SPC m f |
format buffer |
SPC m z |
REPL |
SPC m l r / l s / l e |
restart server / stop server / refresh SDK |
Set mojo-setup-leader-keys to nil to opt out, or edit mojo-leader-bindings
and call M-x mojo-setup-leader-keys to change them.
mojo-debug-file runs mojo debug <file>, i.e. the LLDB command line, in a
comint buffer. A dape (DAP) integration would give breakpoints in the fringe
and an inspector; the SDK ships lldb-dap, so it is a small addition — it is
left out until someone actually wants it.
emacs -Q -batch -L . -l test/mojo-mode-tests.el -f ert-run-tests-batch-and-exitThe formatting test is skipped unless a real Mojo SDK is on PATH.
MIT.