Other Editors
Bad Juju is "just" an LSP server, which means any editor with a sufficiently capable LSP client can drive it. The first-party Helix configuration is documented here as the canonical example; the same principles apply to other LSP-capable editors.
Helix
Helix has no plugin system, so the integration is a small
languages.toml snippet plus a few CLI one-liners.
Requirements
- Helix 25.01+
jjandbadjujuon yourPATH
Setup
- Install the server. See Getting Started.
- Merge the language config. Copy
clients/helix/languages.tomlfrom the repo into either:~/.config/helix/languages.toml(user-wide), or.helix/languages.tomlat the root of your project (per-project).
Opening buffers
Helix doesn't auto-open files returned by code actions, so the entry point is the shell:
hx "$(badjuju status)"
hx "$(badjuju log)"
hx "$(badjuju diff)" # change diff for @
hx "$(badjuju diff --revision abc123)" # diff a specific revision
You can open multiple diffs at once:
hx "$(badjuju diff --revision abc)" "$(badjuju diff --revision def)"
Navigation
Once a .jujutsu buffer is open, Helix uses Space a for code
actions. With the cursor on a commit row you'll get:
| Action | Description |
|---|---|
Edit commit <rev> | Move @ to this commit |
Abandon commit <rev> | Delete this commit |
Describe commit <rev> | Edit commit message |
Show diff for <rev> | Open the change diff |
New child of <rev> | jj new <rev> |
Bookmark <rev>… | Bookmark management menu |
| Squash from this revision | Mark this commit as squash source |
| Rebase --source from this revision | Mark source for jj rebase -s |
| Rebase --revisions from this revision | Mark source for jj rebase -r |
| Rebase --branch from this revision | Mark source for jj rebase -b |
After marking a squash source, Squash into this revision and Cancel pending operation appear on every commit row.
After marking a rebase source, three destination actions appear:
| Action | Description |
|---|---|
| Rebase onto this revision | jj rebase … -d <dest> |
| Insert after this revision | jj rebase … --insert-after <dest> |
| Insert before this revision | jj rebase … --insert-before <dest> |
| Cancel pending operation | Clear the pending rebase source |
See Manipulating Commits for the full walkthrough.
For file rows in the status buffer:
| Action | Description |
|---|---|
Squash <file> | Move file from @ into parent |
Unsquash <file> | Pull file from parent back into @ |
Log <file> | Open the log file buffer for this path |
The Log <file> action opens
.jj/badjuju/file/<path>.jujutsu on demand. Helix doesn't auto-open
files returned by code actions, so open it manually after invoking
the action.
For squash-window rows:
| Action | Description |
|---|---|
| Move hunk to SELECTED / REMAINING | Toggle the hunk under the cursor |
Move file <name> to SELECTED / REMAINING | Toggle a whole file |
| Move all hunks to SELECTED / REMAINING | Select / deselect everything |
Log shortcuts
In log.jujutsu, lines beginning with JJ: are revset shortcuts.
Place the cursor on one and choose Apply revset: <label> from
Space a to re-run the log with that revset.
Other clients bind
Enter/RETto a context-aware dispatch — on shortcut lines it applies the revset, elsewhere it falls through to go-to-definition. Helix has no keybinding layer in Bad Juju, so useSpace afor both.
Auto-reload
When a jj operation runs outside Helix, the server pushes the
refreshed buffer content via workspace/applyEdit. Helix's handler
marks the buffer modified after the edit even though the on-disk
file already matches; :write is then a no-op. You can ignore the
modified indicator until your next real edit.
Known limitations
Helix doesn't auto-open files returned by code actions. If
Show diff for <rev> or Squash into this revision report a
new file path, open it manually:
:open .jj/badjuju/diff-change-<id>.jujutsu
:open .jj/badjuju/squash/<from>-<to>.jujutsu
Any other LSP-capable editor
If your editor:
- Speaks the Language Server Protocol,
- Can launch a stdio LSP server with a custom command, and
- Can invoke code actions (
textDocument/codeAction),
…then it can drive Bad Juju. You'll need to wire up:
- A filetype for
*.jujutsufiles. - An LSP server config that launches
badjuju lspand detects the workspace via a.jj/marker. - (Optional) Keybindings or commands that send
workspace/executeCommandfor thebadjuju.*operations listed in the Status buffer reference and elsewhere.
Reading the VS Code extension
source,
the Helix languages.toml
snippet,
or the Kakoune client (which uses kak-lsp and exposes
full command dispatch and keymaps) will give you a working template. If
you build an integration for a new editor, please open an
issue — we'd love to
include it.