An Emacs interface to OpenCode, providing convenient ways to interact with OpenCode’s AI-powered coding assistant directly from within Emacs.
opencode.el integrates the OpenCode AI coding assistant into your Emacs workflow. It provides a terminal-based interface that allows you to:
- Start and manage OpenCode sessions from within Emacs
- Send commands to OpenCode without leaving your editor
- Use either
shell-modeorvtermas the terminal backend - Access common OpenCode operations through convenient Emacs commands
- Leverage a comprehensive transient menu for easy command discovery
- 🚀 Seamless Integration: Launch and control OpenCode directly from Emacs
- 🖥️ Flexible Terminal Backends: Choose between
shell-modeorvtermfor the terminal - 📂 Project-Aware: Automatically detects project roots using
project.el - 🎯 Command Shortcuts: Pre-built commands for common operations (git, file operations, etc.)
- 🎨 Transient Menu: Discoverable command interface powered by
transient.el - ⚙️ Highly Customizable: Extensive customization options for behavior and appearance
- 🔄 Session Management: Easy restart, toggle, and quit functionality
- Emacs 28.1 or higher
transientpackage (version 0.9.3 or higher)- OpenCode CLI tool installed and available in PATH
- Optional:
vtermpackage (if using vterm terminal backend)
(straight-use-package
'(opencode :type git :host gitlab :repo "rogs/opencode.el"))- Clone this repository:
git clone https://gitlab.com/rogs/opencode.el.git ~/.emacs.d/lisp/opencode.el - Add to your Emacs configuration:
(add-to-list 'load-path "~/.emacs.d/lisp/opencode.el") (require 'opencode)
(use-package opencode
:ensure t
:bind (("C-c a o" . opencode-menu)
("C-c a t" . opencode-toggle))
:custom
(opencode-terminal-type 'vterm)
(opencode-split-direction 'vertical))Add to your packages.el:
(package! opencode
:recipe (:host gitlab :repo "rogs/opencode.el"))Then in your config.el:
(after! opencode
(setq opencode-terminal-type 'vterm
opencode-split-direction 'vertical)
(map! :leader
(:prefix ("a" . "ai")
:desc "OpenCode menu" "o" #'opencode-menu)))Or, if you prefer to use local path during development:
;; In packages.el
(package! opencode
:recipe (:local-repo "~/code/personal/opencode.el"))This will bind SPC a o to open the OpenCode menu, from which you can access all other commands.
To use this package, you must disable OpenCode’s built-in theme by adding the following to your opencode.json configuration file:
{
"theme": "system"
}This prevents conflicts with Emacs’ own theming system.
All customization options are available through M-x customize-group RET opencode RET.
| Variable | Type | Default | Description |
|---|---|---|---|
opencode-executable-path | string | "opencode" | Path to the OpenCode executable |
opencode-terminal-type | symbol | 'vterm | Terminal backend ('shell or 'vterm) |
opencode-split-direction | symbol | 'vertical | Window split direction ('vertical or 'horizontal) |
opencode-default-directory | directory | nil | Default directory for sessions (nil = auto-detect) |
opencode-output-buffer-name | string | "*opencode-output*" | Name of the output buffer |
opencode-shell-buffer-name | string | "*opencode-shell*" | Name of the shell buffer |
opencode-vterm-buffer-name | string | "*opencode-vterm*" | Name of the vterm buffer |
opencode-confirm-kill | boolean | t | Ask for confirmation before killing OpenCode instances |
(use-package opencode
:ensure t
:bind (("C-c a o" . opencode-menu)
("C-c a t" . opencode-toggle)
("C-c a s" . opencode-send-command))
:custom
;; Use vterm for better terminal emulation
(opencode-terminal-type 'vterm)
;; Split horizontally instead of vertically
(opencode-split-direction 'horizontal)
;; Don't confirm when killing OpenCode
(opencode-confirm-kill nil)
;; Use a specific directory for all OpenCode sessions
(opencode-default-directory "~/projects")
:config
;; Enable the minor mode globally
(opencode-mode 1))- Start OpenCode:
M-x opencode-openorC-c a o o(from menu) - Send commands: Use the various command functions or the transient menu
- Toggle visibility:
M-x opencode-toggleto show/hide the OpenCode buffer - Quit:
M-x opencode-quitto terminate the session
opencode-open- Start OpenCode in a dedicated buffer
opencode-quit- Quit OpenCode and close its buffer
opencode-restart- Restart the OpenCode process
opencode-toggle- Toggle OpenCode buffer visibility
opencode-read-file- Read a file via OpenCode (prompts for file path)
opencode-list-directory- List directory contents (prompts for directory)
opencode-grep- Search for pattern in files (prompts for pattern and optional include filter)
opencode-git-status- Show git status
opencode-git-diff- Show git diff
opencode-git-add- Add files to staging area (prompts for files)
opencode-git-commit- Commit changes (prompts for commit message)
opencode-send-bash-command- Send arbitrary bash command (prompts for command)
opencode-send-command- Send arbitrary OpenCode command (prompts for command)
opencode-todo- Show OpenCode todo list
opencode-help- Show OpenCode help
opencode-menu- Open the transient command menu
Press M-x opencode-menu to open an interactive menu with all available commands organized by category:
OpenCode ┌─────────┬─────────────────┬────────┬─────────┐ │ Control │ Files │ Git │ Other │ ├─────────┼─────────────────┼────────┼─────────┤ │ o Open │ f Read file │ s Status│ T Todo │ │ q Quit │ l List directory│ d Diff │ h Help │ │ r Restart│ g Grep │ a Add │ b Bash │ │ t Toggle│ │ c Commit│ C Command│ └─────────┴─────────────────┴────────┴─────────┘
opencode.el supports two terminal backends:
- Built into Emacs
- No additional dependencies
- May have limitations with complex terminal interactions
- Requires the
vtermpackage - Better terminal emulation
- More responsive and feature-complete
- Handles complex terminal UI better
To use vterm, ensure it’s installed:
(use-package vterm
:ensure t)
(setq opencode-terminal-type 'vterm)Start OpenCode in a dedicated buffer. If directory is provided, OpenCode starts in that directory; otherwise, it uses the project root or default-directory.
;; Start in current project
(opencode-open)
;; Start in specific directory
(opencode-open "~/my-project")Quit OpenCode and close its buffer. Respects opencode-confirm-kill setting.
Restart the OpenCode process in the same directory.
Toggle the visibility of the OpenCode buffer. If OpenCode isn’t running, this starts it.
Read file via OpenCode. Interactively prompts for the file path with completion.
(opencode-read-file "path/to/file.el")List directory contents via OpenCode. Interactively prompts for the directory path.
(opencode-list-directory "~/projects")Search for pattern in files. Optionally filter by file pattern with include.
;; Search all files
(opencode-grep "function.*foo")
;; Search only .el files
(opencode-grep "defun" "*.el")Show git status via OpenCode.
Show git diff via OpenCode.
Add files to git staging area. Interactively prompts for files.
(opencode-git-add "file1.el file2.el")
(opencode-git-add ".") ; Add all filesCommit changes with message. Interactively prompts for commit message.
(opencode-git-commit "Fix bug in opencode-toggle")Send bash command to OpenCode. The command is wrapped and executed in a bash context.
(opencode-send-bash-command "npm test")
(opencode-send-bash-command "ls -la")Send arbitrary command directly to OpenCode without modification.
(opencode-send-command "todoread")
(opencode-send-command "/help")Show the OpenCode todo list (if available).
Show OpenCode help information.
Open the transient menu interface for OpenCode commands.
These functions are used internally but may be useful for advanced customization:
opencode--directory- Get the root directory for OpenCode session
opencode--running-p- Check if OpenCode is currently running
opencode--send-command- Low-level command sending (use
opencode-send-commandinstead)
Error: OpenCode executable 'opencode' not found in PATH
Solution: Ensure OpenCode is installed and available in your PATH, or set opencode-executable-path to the full path:
(setq opencode-executable-path "/usr/local/bin/opencode")Error: The vterm package is required for vterm terminal backend
Solution: Either install vterm or switch to shell backend:
;; Option 1: Install vterm
(use-package vterm :ensure t)
;; Option 2: Use shell backend
(setq opencode-terminal-type 'shell)If commands appear to send but don’t execute in OpenCode, check:
- OpenCode is actually running:
M-x opencode-toggleto verify - The terminal backend is working correctly
- Try switching terminal backends if issues persist
If the OpenCode buffer isn’t appearing where expected:
;; Try different split directions
(setq opencode-split-direction 'horizontal) ; or 'verticalContributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
This project was built 100% using OpenCode, demonstrating the power of AI-assisted development. Every feature, from the initial implementation to documentation, was created through collaboration with OpenCode.
—
Note: This is an unofficial Emacs integration for OpenCode. For issues with the OpenCode CLI itself, please refer to the official OpenCode repository.
