vikix.GuideInstallSource

11 Neovim and Emacs

Vikix has two editors, Neovim and Emacs, each with a config ready to use, the language servers for the languages you added, and AI: a chat on the model Super+i uses, and your agent (the one Super+a starts) beside your code. Neither is installed until you ask for it:

vikix add neovim        # or: vikix add emacs; the developer bundle brings both
vikix remove emacs      # takes it away again; your files stay

essentials brings Emacs; developer and everything bring both. $EDITOR is nvim unless you set another.


11.1 Starting them

v FILE

Neovim, in this terminal

Super+x

An Emacs window

e FILE

The file in a new Emacs window (the terminal waits until you close it)

eg FILE

The same, with the terminal free at once

ec FILE

Emacs inside this terminal

eq

Emacs with no config at all: for finding out whether the config is the problem

emacs-restart

A fresh Emacs, after you changed its config (it refuses while a file is unsaved, and asks before ending open chats)

Emacs runs as a server from the moment you log in, so Super+x and e open a window at once. The first time Emacs starts on a new machine, it downloads its packages in the background: give it a few minutes before the first e.


11.2 Who owns what

Neovim’s config is Vikix’s own, split in two like the desktop’s:

~/.local/share/vikix/nvim

Whose: Vikix’s
What: AstroNvim and Vikix’s plugins. A link into ~/vikix: vikix update keeps it current, so don’t edit it

~/.config/nvim

Whose: yours
What: init.lua (your settings go at its end), your plugins in lua/plugins/, and lazy-lock.json, the plugins’ versions

Emacs’s config is a separate repository, the author’s own (emacs-void):

~/.emacs.d

Whose: a git clone
What: The config, config.org. vikix update pulls it; a change of yours there can stop the pull (the update says so and carries on)

~/.local/share/vikix/emacs

Whose: Vikix’s
What: vikix-ai.el, the AI setup, vikix-theme.el, which makes Emacs follow vikix theme, vikix-notes.el, your Org notes in ~/Dropbox/notes under C-c n (the agenda, the journal, org-roam’s links and graph), and vikix-python.el, Python as an IDE under C-c p (below). A link into ~/vikix, kept current by vikix update; the config loads them when they’re there

Both are in Where everything is, with the rest of your files.


11.3 Neovim

Neovim is AstroNvim with a few choices of Vikix’s: Typst with a live preview (:TypstPreview), a function’s parameters shown while you type its call, jk or jj to leave insert mode, and the AI keys below. Space is the leader: press it and wait, and a menu shows what comes next.

Your own plugins go in ~/.config/nvim/lua/plugins/, one or more files that each return plugin specs. They load after Vikix’s, so yours win. example.lua there shows a plugin more, an AstroNvim setting, one of Vikix’s plugins switched off, and another colour scheme. Plain settings (vim.opt.…) and keys (vim.keymap.set(…)) can go at the end of ~/.config/nvim/init.lua, after the line that loads Vikix’s part.

The plugins are installed at the versions Vikix tested, and vikix update moves them on when Vikix tests newer ones. Plugins you add keep their own versions. After a :Lazy update of yours, Vikix’s plugins keep your versions too: updates leave them alone and say once how to take Vikix’s again.


11.4 Emacs

Emacs’s config is organised in ~/.emacs.d/config.org, one section per concern (completion, Org, Lisp, languages, tools), and each section explains itself. Emacs reads it at start. SLIME in it talks to the running window manager on port 4004 (see How it fits together).

To change it, edit config.org and run emacs-restart. vikix update brings Vikix’s new AI setup into an Emacs that’s running, with your chats left open; an Emacs started without it (before Vikix 0.59) is told to restart, and vikix doctor says which you have. The clone is yours to change, but a change there can stop vikix update from pulling the author’s newer version: keep your changes in a commit of your own, or in a config of your own (below).


11.5 Python in Emacs

With vikix add python and vikix add emacs, a .py file opens as an IDE: the mode line says Py[.venv], and everything started from the file uses that venv. The venv is found by itself: the nearest .venv up from the file (the one uv venv makes in a project); for a loose script or the examples, ~/dev/python/.venv, the shared one JupyterLab runs on (Py[dev]); and for a project that declares its dependencies (pyproject.toml, requirements.txt) but has no .venv yet, none (Py[no venv]), since its packages aren’t in the shared venv: C-c p v offers to make its own. The language server (pyright, through eglot) sees the venv’s packages, the REPL is the venv’s ipython (its python when ipython isn’t in it), ruff’s findings are shown beside pyright’s as you type, and the buffer is formatted with ruff when you save it.

C-c p t

Test the function at point: pytest FILE::name

C-c p T

Test this file

C-c p P

Test the project

C-c p r

Run this file

C-c p s

The REPL, from the venv

C-c p f

Format the buffer with ruff

C-c p F

Format on save: on or off, for this buffer (on to begin with)

C-c p c

ruff check the project

C-c p v

Which venv this buffer uses; none, offers uv venv

C-c p i

The IDE: code left, the REPL top right, the tests’ output below it

C-c p d

The offline Python docs, in the browser

C-c p q

Close the project: its files (a changed one is asked about), the REPL, the tests’ window and pyright; then the frame, so a terminal’s e FILE gets its prompt back

Tests and runs go to a compilation buffer, where a failing line is a link: Enter on it opens the file there, M-g M-n goes to the next. A key for something that isn’t installed says what to do (uv pip install pytest in the project, say) instead of failing. Nothing of this changes your own python.el or eglot settings: the venv is given to each buffer, so two projects open at once each keep theirs. C-c p F turns formatting on save off for a buffer; (setq vikix-python-format-on-save nil) in your config turns it off everywhere. A debugger isn’t part of it yet.


11.5.1 A project, start to finish

Say a project of yours at ~/src/pub: a pyproject.toml that lists its packages, a uv.lock, pub.py and tests/test_pub.py, and no venv yet.

  1. Open it: e ~/src/pub/pub.py. The mode line says Py[no venv]: the project declares its packages but has no .venv, so the shared venv is not used. pyright starts on the system Python meanwhile and marks the project’s imports as unresolved: that is the sign to make the venv.
  2. Make the venv: C-c p v, then y. uv makes .venv in the project, fetching the Python the pyproject asks for if it isn’t on the machine. Then, in a terminal in the folder, bring the packages and pytest in:
    uv sync
    uv pip install pytest
    

    Reopen the file (C-x C-v Enter). The mode line reads Py[.venv], and pyright sees the packages. For the ipython prompt, uv pip install ipython the same way; plain python -i otherwise.

  3. Lay it out: C-c p i. The code stays left, the REPL opens top right, and the tests’ window waits below it. In the REPL the project is importable as it is: from pub import load, since it starts in the project’s folder. C-c C-c sends the buffer to it, as always in Emacs.
  4. Change and test: edit, save. The save runs ruff format, and ruff’s findings (an unused import, a name that isn’t defined) are underlined beside pyright’s. Put point inside a test in tests/test_pub.py and press C-c p t: the window below runs pytest on that one function, by its class when it has one. A failure’s tests/test_pub.py:36: line is a link; Enter on it goes there. C-c p T runs the file, C-c p P the whole suite.
  5. Check before committing: C-c p c runs ruff check over the project in the same window, a clickable line per finding. C-c p r runs the file as a script. Then magit (C-x g) as usual.
  6. Stuck on the language: C-c p d opens the offline Python docs in the browser.
  7. Put it away: C-c p q. A changed file is asked about, then the project’s buffers, the REPL and pyright go, and the frame closes, so the terminal that ran e gets its prompt back. Files of another project in the same Emacs stay.

Two projects open at once each keep their own venv, so you can read one while the other’s REPL runs. A file that shouldn’t be reformatted gets C-c p F once.


11.6 Language servers

A language server is what lets the editor complete names, jump to a definition and underline mistakes as you type. Each comes with its language, so vikix add c brings C’s, and both editors find them on PATH:

C, C++

Server: ccls, clangd
Comes with: vikix add c

Go

Server: gopls
Comes with: vikix add go

Rust

Server: rust-analyzer
Comes with: vikix add rust

Zig

Server: zls
Comes with: vikix add zig

Lua

Server: lua-language-server
Comes with: vikix add lua

JavaScript, TypeScript

Server: typescript-language-server
Comes with: either editor (npm, in ~/.local/bin)

Python

Server: pyright
Comes with: either editor (npm)

Bash

Server: bash-language-server
Comes with: either editor (npm)

OCaml

Server: ocaml-lsp-server
Comes with: opam install ocaml-lsp-server, after vikix add ocaml

Neovim also gets efm-langserver, which runs linters and formatters. In Emacs, eglot starts the server when you open a C, C++, JavaScript, TypeScript, Python, Zig or Odin file.


11.7 AI in the editors

Both editors do the same four things, each on the settings you already made for the desktop:

A chat on the model Super+i uses

Neovim: Space A c
Emacs: C-c g

Ask about the selection, or change it

Neovim: Space A q
Emacs: C-c g with a selection, or C-c G (gptel’s menu)

A chat with your agent

Neovim: Space A g
Emacs: C-c a

Your agent in a terminal

Neovim: Space A t
Emacs: C-c A

The chat follows vikix ai use: local for a model on this laptop (vikix ai setup first), or claude for Claude (with your key: vikix ai key set anthropic). A model set with model= in ~/.config/vikix/ai is used here too. Emacs reads that file again at each C-c g, so a change reaches an Emacs that’s already open; a model you pick in gptel’s menu stays until the file changes. On a laptop’s CPU a local model can take minutes to begin answering, because it first reads the chat’s instructions (Neovim’s are long); Claude answers in seconds.

Your agent is the one Super+a starts (Claude Code unless you chose another: vikix agent --default NAME). The editors start it the same way, with vikix agent: it gets the guide to Vikix, no API keys or SSH agent (the editors have them, the agent doesn’t need them), and a snapshot first, so vikix changes shows what it did and vikix undo takes it back. It signs in with its own login, the one it uses in a terminal. In a chat it talks over ACP (the Agent Client Protocol): Claude Code, Codex, Gemini CLI and OpenCode speak it, and vikix agent --install NAME adds one with what it needs (running it again for an agent you have adds only what’s missing). Aider and Antigravity CLI don’t: their place is the terminal key.

In Emacs, each agent chat’s transcript is kept in ~/.local/state/vikix/agent-shell/, one file per chat, named after the project, in a folder only you can read; not in the project, where agent-shell would put it. Screenshots and images you give the agent do go in the project’s .agent-shell/, which agent-shell keeps out of git.

C-c a goes back to the chat this project already has; in a folder without one it asks first (New shell starts one here), and C-u C-c a always starts another. In Neovim, a chat’s top line says who answers before you type.

Nothing starts or connects until you press a key. When something’s missing (a key, the local model, the agent or its adapter), the key says what to type, and does nothing else. Working with AI has the rest: keys, local models, and choosing an agent.


11.8 A config of your own

To use your own config for either editor, install Vikix with VIKIX_NVIM_REPO= or VIKIX_EMACS_REPO= set to your repository, or put yours in the folder yourself: a git clone at ~/.config/nvim or ~/.emacs.d is pulled by updates, and any other folder of yours is left alone.

In a Neovim config of your own, Vikix’s plugins aren’t there. In an Emacs config of your own, the AI setup can still be: load it after your gptel setup,

(load (expand-file-name "~/.local/share/vikix/emacs/vikix-ai") t t)

and bind vikix-ai-agent and vikix-ai-agent-terminal to keys of yours. On a machine without Vikix the file isn’t there, and the line does nothing.


11.9 When an editor doesn’t work