Each section says which file to change and how to make the change take effect. Every file here is yours, so no update will overwrite it. Where everything is has the full list.
~/.stumpwm.d/user.lispvikix snapshot "before: bigger bar font" # record your files as they are # ... make the change ... vikix changes # see exactly what changed vikix undo # changed your mind: back to the snapshot
In a terminal, vikix undo first lists the files it will put back and asks. Say no if that isn’t the snapshot you meant (an AI agent takes one when it starts, so the one before may be the agent’s), and pick another from vikix history with vikix undo ID. After an undo, Super+m → Reload config makes StumpWM use the old settings again. vikix undo --help shows the four commands together.
Or ask the AI agent: Super+a starts Claude Code (or the agent you chose), which knows these rules (from ~/.claude/skills/vikix) and takes a snapshot before it starts. Working with AI says how.
~/.stumpwm.d/user.lisp ¶Everything about StumpWM goes in this one file: keys, startup programs, the menu, the bar. It loads after all of Vikix’s files, so what you set here wins. Apply a change with Super+m → Reload config. If there’s a mistake, the error shows on screen, and everything else still loads.
To see how Vikix does something before changing it, read its layer in ~/vikix/config/stumpwm/vikix/: keys.lisp for keys, commands.lisp for the menu, modeline.lisp for the bar.
(vikix-bind "s-w" "exec chromium") ; change what a key does (vikix-bind "s-M-o" "exec obsidian") ; a new key: Super+Alt+o (undefine-key *top-map* (kbd "s-M-s")) ; drop one of Vikix's keys
s- is Super, C- Ctrl, M- Alt, S- Shift, and a capital letter means Shift too: s-O is Super+Shift+o, s-M-o Super+Alt+o. The command is a StumpWM command: exec PROGRAM starts a program, and Super+m → All commands lists the others.
A key bound like that works, and nothing else knows of it. To have it on the key card (Super+/), in the key help (Super+F1) and in Super+m too, write it as a command, the way Vikix writes its own:
(define-vikix-command obsidian "Obsidian: my notes" :run "exec obsidian" :key "s-M-o" :menu "Apps" :needs "obsidian")
The name (obsidian) is yours to choose; the words after it are what the key card and the menu say. :run is the command and :key its key. :menu puts it in Super+m, in that section of it (Start, Help, Vikix, AI, Work, Notifications, Desktop, Windows, System, Apps); leave it out for a key alone. :label gives the menu other words than the key card’s, and :needs names a program or a file ("~/...") without which the menu leaves the entry out. Leave :key out for a menu entry with no key; then :do can take a Lisp form in place of :run. :agent t lets your AI agent run it by name, without asking you each time (Working with AI): only for something put back as easily as it is done. A mistake in the form is said when user.lisp loads, with what is wrong.
The key card is full, so a few keys open a map instead: Super+Ctrl+Space the layout keys (m main and stack, s strip, g grid, t tiles, w width, h height, u and r undo and redo, Space the menu), Super+Alt+d the desk keys (n a new desk, w a worker at one, r take one up again, c close one, h its handoff, o the Office, t test a desk’s work, p pause its agent or let it go, i a note for it, x dismiss it). The map’s keys show in a small card while it is open; a key acts and the card stays, so w, w, w goes through the widths, and Escape, the opening key again, or half a minute of nothing closes it ((setf *vikix-map-timeout* 60) in user.lisp for more, 5 for less). A key that starts a program closes the map first. The key card has the key that opens a map, whose words name its keys; Super+F1’s list and the README’s table have each as then m, and vikix used counts each as a key of its own.
To put a command of yours into a map, give it :map with the map’s name and the key: :map "layout x", beside :key or instead of it. A map of your own is a command whose :run is vikix-map NAME, with a key; the commands with :map "NAME k" written after it are its keys:
(define-vikix-command music "Music keys: p play or pause, n next, b back" :run "vikix-map music" :key "s-M-u") (define-vikix-command music-play "Play or pause" :run "exec playerctl play-pause" :map "music p") (define-vikix-command music-next "Next track" :run "exec playerctl next" :map "music n")
The words of the map’s command are what the card says of it, so name its keys there after a colon, a comma between, in the order you want them shown. The rule for keys judges a key inside a map by the key that opens the map (a map of programs goes on Super+Alt, a map of switches on Super+Ctrl).
Vikix’s own commands are written the same way, all in one file, registry.lisp in Vikix’s layer: its keys, its menu, and what agents may run all come from it. The older way still works, and is what a plugin or a web app does: add to the list the card and the help are built from, and bind the key.
(push '("s-M-o" "exec obsidian" "Obsidian") *vikix-bindings*)
(vikix-bind "s-M-o" "exec obsidian")
The card puts each key in a group by what it runs: a program started with exec goes under Apps (or AI & voice, Screenshots & recording and so on, when Vikix knows the program), and anything else under Other. To choose the group yourself, give it as a fourth item: '("s-t" "exec obsidian" "Obsidian" "Notes"). A group of your own comes after Vikix’s.
After Ctrl+t, StumpWM’s prefix, the keys that can follow appear if you wait (StumpWM’s which-key-mode, which Vikix turns on). To have it off, put (vikix-which-key nil) in user.lisp. Don’t call (which-key-mode) there: it switches on and off, so every reload would flip it.
The prefix can move, since many programs want Ctrl+t for themselves (a new tab, a transposition). In user.lisp:
(set-prefix-key (kbd "s-semicolon")) ; the prefix is Super+; (define-key *root-map* (kbd ";") "colon") ; and Super+; then ; is still the command prompt
The second line matters: StumpWM gives the plain key after the prefix (here ;) to "send this key through to the program", which is where the command prompt (colon) sat. The key card, Super+F1, the menu and vikix why all say the prefix as it is now.
Super+m → What does a key do? tells you what any key is bound to now.
Each modifier beside Super means one thing. Vikix’s keys keep to it, so do the plugins’ and the web apps’, and a key of yours is easiest to remember when it does too:
What they are for: Everyday: the six main apps (terminal, launcher, browser, files, editor, agent), the small tools, focus, and what is done to the window you’re in
Vikix’s, for example: Super+Return, Super+w, Super+h, Super+q, Super+f
What they are for: The same key, moving the window: move it, send it to a workspace, bring one here. Or the key’s other way: redo, previous
Vikix’s, for example: Super+Shift+h, Super+Shift+3, Super+Shift+g, Super+Shift+u
What they are for: Open something else: every other app, every web app and plugin
Vikix’s, for example: Super+Alt+p projects, Super+Alt+v passwords, Super+Alt+m mail
What they are for: Switch something on the desktop
Vikix’s, for example: Super+Ctrl+a keep awake, Super+Ctrl+l night light, Super+Ctrl+d do not disturb, Super+Ctrl+g gaps
So a new app goes on Super+Alt and a letter, a switch of your own on Super+Ctrl. Keys without Super keep their own ways: Print (Shift keeps a file, Ctrl is the window, Super the screen) and the laptop’s own keys.
Sending a window to a workspace is Super+Shift and the digit on any keyboard: Vikix asks the keyboard what Shift+digit types (! on a US one) and binds that, again after Super+m → Apply keyboard settings. On a keyboard where the digits themselves need Shift (French), it is Super+Ctrl and the digit.
There are nine workspaces, Super+1 to Super+9, and they are always there. Super+Left and Super+Right go to the one beside this one, in the bar’s order and round the ends, which is how a workspace past the nine is reached by key; with Shift the window comes along, and you with it (on a strip, its whole column). The letters h j k l stay inside the workspace: the focus goes that way, and with Shift the window does. When all nine have windows and something wants a workspace to itself, a worker’s desk (vikix agents worker) or a project (vikix project open), a tenth is made, named for it: wifi-fix, novel. Super+0 opens the named workspaces as a map: a letter each, the first letter of its name that no earlier one took (office is o, cuis is c), and the letter goes there, so Super+0, o is the Office; / in the map types a name instead (Tab completes; the palette, Super+Space, lists them too, and the overview, Super+o, draws them). Super+Shift+0 is the same map sending the window to the one you pick, you staying where you are. A new name typed at either makes a workspace of that name at once, whether or not one of the nine is empty, since you asked for it by name; so Super+Shift+0, /, reading, Enter puts the window on a workspace called reading. A named workspace is taken away again when you leave it with no window on it, a minute after it was made at the soonest, so the bar never fills with empty names. Workspaces you make yourself in user.lisp (gnewbg) are never touched, and a rule’s (workspace "reading") names one that exists.
Refiling them. After a day the windows sit on 3, 5 and 8. Super+m → Windows → Workspace: refile them (the command vikix-refile-workspaces; from a shell, vikix eval '(vikix-refile-workspaces)') moves every workspace left into the nearest empty one, as far as it can, so they end up on 1, 2 and 3 in the order they were. Each keeps its layout entire: its frames, what floats, a strip and its columns, grid or main-and-stack mode, and Super+u still undoes its own changes. The named workspaces past the nine have no left to move to and stay. It says what moved: Refiled: 3 to 1, 5 to 2, 8 to 3. If you would rather keep workspace 1 as a home that is never filled, (setf *vikix-refile-from* 2) in user.lisp starts the refile from 2.
vikix doctor names a key that breaks the rule: a plugin’s or a web app’s not on Super+Alt, a program of yours on plain Super, a switch somewhere else. The key still works; the doctor only says so. What Vikix counts as everyday, a switch or a move is three short lists at the top of ~/vikix/config/stumpwm/vikix/keys.lisp; add a command of your own to one in user.lisp, (push "my-toggle" *vikix-key-switches*), and the doctor knows it.
Before you move a key or give one up, look at what you press. The desktop counts each key that runs a command, each entry you pick in a menu or in the palette, and each command you type:
$ vikix used
Counting since 5 Oct 2026 (12 days).
Keys
412 Super+Return Terminal
388 Super+Space Everything in one box: windows, commands, projects ...
97 Super+f Fullscreen on/off
Menu entries
14 Reload config
61 of 107 keys never pressed: vikix used never
vikix used never lists the keys you have never pressed since counting began: the ones free to take for something of your own. vikix used all shows every count and when each was last used; vikix used forget starts again. Super+m has it as What you use. The door’s counts are in the same file, what an agent’s Lisp calls and what the door holds, and vikix door used reads them out (the door).
Only names and numbers are kept: the key, the command it is bound to, a menu entry’s words. Never a window’s title, and nothing you type into a program. The counts are in ~/.local/state/vikix/used, a text file you can read or delete, and nothing sends it anywhere.
(at-login (run "syncthing --no-browser"))
at-login runs once each time you log in. user.lisp runs again on every reload, and the rule doesn’t: there’s no need for a pgrep -x … || in front to keep a second copy from starting. A rule you add while logged in runs at the reload that brings it, once. It goes in rules.lisp or in user.lisp (Rules for the desktop).
A rule is one line that says where a window goes as it opens, or what happens at a time of day, on a low battery, or when you log in:
(when-window (:class "Firefox") (workspace 2)) ; Firefox opens on workspace 2 (when-window (:instance "vikix-nmtui") (float :width "65%" :height "80%")) (at "09:00" :weekdays (open-project "vikix")) ; each working day at nine (when-battery-below 20 (notify "Battery at 20%" "Where's the charger?"))
They live in a file of their own beside user.lisp, ~/.stumpwm.d/rules.lisp, which comes with every example switched off. Super+Shift+t writes one for you, for the window in front, and vikix rules lists them, says why a window went where it did, and tries them on the windows open now.
Rules for the desktop is their page: everything a rule can match and do, how to see what your rules did, and what happens when one goes wrong.
A workspace’s layout, the splits and which window sits in each (or a strip’s columns, their widths and what’s stacked), saved by name and put back later:
vikix layout save writing # this workspace, as it is now vikix layout writing # back as it was vikix layout list # the ones saved vikix layout rm writing
Or Super+m, Layout: save this workspace’s and Layout: put this workspace back. A rule can put one back too: (when-window (:class "Emacs" :title (:has "novel")) (layout "writing")).
Each is a file of plain Lisp in ~/.config/vikix/layouts/, to read and change by hand: windows are described by their class and title, not remembered as the windows they were, and a split’s place and size are parts of the screen, so a layout still fits after the windows have been closed and opened again, or on another screen. Putting one back matches the windows on the workspace to the saved ones (the same program first, then the closest title); a window it doesn’t mention stays, and a saved one that isn’t open is started again and placed as it comes (vikix layout NAME --no-start only names it). Each saved window says how: its :command and :directory, read from the program when the layout was saved; a terminal comes back in its shell’s folder (with what ran in it, when that wasn’t the shell), an Emacs window as emacsclient -c on the file it showed, Esploro on its folder. Since a layout can start programs, read one you were given before you put it back. A strip’s layout makes the workspace a strip, a tiled one tiles. Floating windows aren’t saved.
The desktop saves every workspace by itself, every five minutes and when it ends: which windows, where they stand, and how each was started. After a restart, the login asks whether to bring them back; Enter does it. Each workspace in turn is put back as it was, its programs started again in their folders, and you end on the workspace you were on.
vikix resume # what is saved, and what a login does vikix resume now # bring them back now (Super+m, Bring my windows back) vikix resume always # at login, bring them back without asking vikix resume never # at login, leave it vikix resume ask # at login, ask first: how it starts out
What comes back is what can be started again: a terminal in the folder it was in, with the program that ran in it; a program by its command line; a web app; an Emacs frame on its file. What a program had open inside it is the program’s own to bring back: Firefox reopens its tabs, an editor its files. An AI agent started with Super+a comes back as a new session in its folder (in Claude Code, claude --continue takes up the last conversation there). Floating windows and dialogs aren’t saved.
The saved workspaces are layouts like those above, kept apart in ~/.local/state/vikix/resume/; the choice is one word in ~/.config/vikix/resume.
A few programs you want often and for a moment: a calculator, your files, a page of notes. Super+Ctrl+b slides them in from the right edge of the screen, one above the other, over your windows, on whatever workspace you’re on; the key again slides them away. They keep running while they’re away, so the calculator keeps its sums and the files their folder. The windows underneath are not moved or made smaller.
As it comes, the drawer holds a terminal and PCManFM. Yours are a list in user.lisp, top to bottom, each a name and the command that starts it:
(setf *vikix-drawer-apps*
'(("Calculator" "speedcrunch")
("Files" "esploro --new ~" :class "Emacs" :title "Esploro")
("Notes" "emacsclient -c -n -a '' -F '((name . \"Notes\"))' ~/notes.org"
:class "Emacs" :title "Notes")))
(setf *vikix-drawer-side* :left) ; the edge: :right as it comes
(setf *vikix-drawer-width* "35%") ; of the screen, or pixels: 500
A program is started the first time the drawer comes out, and again when you closed it. Its window goes into the drawer whatever your rules say of that program: a rule that sends SpeedCrunch to workspace 1 still holds for a SpeedCrunch you start yourself, not for the drawer’s. The drawer knows a window by the program that made it. Where another program makes the window, say how to know it, the way a rule does (:class, :instance, :title, :role): an Emacs frame is made by Emacs’s server, whatever started it, and a second PCManFM window by the first PCManFM. xprop WM_CLASS WM_NAME and a click on a window give its class (the second word) and its title.
On another workspace the key brings the drawer there. A window of the drawer tiled with Super+t is an ordinary window from then on, and its program is started again for the drawer the next time. On a strip the drawer stands over the columns. It slides when a compositor runs, as a strip does (*viri-animate*).
(setf *vikix-terminal* "kitty") ; what Super+Return opens (setf *mouse-focus-policy* :click) ; focus on click, not when the pointer moves over a window (setf *vikix-font-size* 13) ; the bar, menus and messages (vikix-set-font)
Gaps between windows (Super+Ctrl+g) are 10px, 9px at the screen edge. The inner gap is on every side of each window, so two windows are twice it apart. To change them, or have them on from login:
(setf swm-gaps:*inner-gaps-size* 3 ; 6px between windows
swm-gaps:*outer-gaps-size* 3) ; plus this at the screen edge
(swm-gaps:toggle-gaps-on) ; gaps from login on
Super+Ctrl+h hides the bar on the screen you’re on, and the windows take its room; the key again brings it back (Super+m → The bar on/off (hide it for the whole screen) is the same). It isn’t remembered: the bar is there again after Reload config and at the next login.
The mouse works on it too: a workspace’s number goes there, a window’s title focuses it, volume opens the mixer (the wheel turns it up and down, the middle button mutes), the network opens the Wi-Fi picker (vikix wifi: it scans first, then lists the networks; on a cable, nmtui), and Bluetooth its settings. A click on any other field (the battery, the clock, updates) says what it is: the card Super+Alt+? shows for whatever the pointer is on (vikix what). A field Vikix writes is made an area with a name by vikix-ml-what in modeline.lisp, which is how the key knows what the pointer is on. The clickable parts are ^(:on-click ...) areas made by vikix-ml-clickable in modeline.lisp; when they overlap, as a long window title under the fields on the right, the narrowest wins.
The bar is one format string. Vikix sets it in modeline.lisp:
"%J %W^>%R%K%X%Y%G%Q%U%A%D%Z%O%T%V%E%d"
%J the workspaces, %W the windows, ^> right-aligns the rest: %R rec (or mic, while dictation listens), %F focus time and its break, %K awake, %X win (the Windows VM), %Y ai (a local model loaded), %G mem (memory low, and programs left over), %Q quiet, %U updates, %A backup, %D usb, %Z Dropbox, %O network, %T Bluetooth, %V volume, %E battery, %d date and time. Set your own in user.lisp to drop or reorder fields:
;; no Bluetooth, and the time without the date
(setf *time-modeline-string* "%H:%M"
*screen-mode-line-format* "%J %W^>%R%K%X%Y%Q%U%A%D%Z%O%V%E%d")
A field of your own can be a list entry (:eval FORM), run each time the bar redraws (every 10 seconds). Keep the form quick, since the whole desktop waits while it runs:
(setf *screen-mode-line-format*
(list "%J %W^>%R%K%X%Y%Q%U%A%D%Z%O%T%V%E"
'(:eval (format nil "load ~a " (first (uiop:split-string (uiop:read-file-string "/proc/loadavg")))))
"%d"))
vikix eval runs Lisp in the running StumpWM, so you can try a change before writing it down:
vikix eval '(vikix-bind "s-t" "exec obsidian")'
That lasts until the next reload or login. When it does what you want, put the same line in user.lisp.
vikix theme vikix-light (or Super+m → Theme, which shows each theme on the desktop as you move to it; Escape puts yours back). vikix theme lists them: vikix-light, vikix-dark, contrast-dark, gruvbox-dark, nord-dark, tokyo-night-dark, and yours; every name ends in -light or -dark. The old names (void, paper, nord, ...) still switch. An agent’s terminal session (Codex, Claude Code) is the one thing that doesn’t follow: its TUI reads the terminal’s background once, as it starts, and keeps drawing for it, so after a switch from dark to light its text is pastel on cream. The switch names such sessions, in the terminal and as a notification; start them again to read well (vikix agents resume DESK takes the conversation up again).
cp ~/vikix/themes/vikix-dark.theme ~/.config/vikix/themes/mine-dark.theme, change the colours, vikix theme mine-dark. A picture beside it, mine-dark.jpg, becomes its wallpaper. The name is letters, digits, - and _ only (my-theme, not my theme): a file named otherwise isn’t listed or used.
agent_asks, agent_released and agent_pushed in the theme file: what the bar’s window list, the title bar and the Office show while the agent waits for you, while its released desk waits for gup, and once that is pushed (Agents at work). A theme without them uses its color3, color2 and color6.
vikix theme import bjarneo/omarchy-ash-theme (OWNER/REPO on GitHub, or an https:// git URL). Omarchy’s themes, and its community’s at themes.omarchy.org, are git repositories with a colors.toml. The colours become ~/.config/vikix/themes/ash.theme (the repository’s name without omarchy- and -theme; give another as the next word), the first picture in backgrounds/ its wallpaper, and Vikix switches to it (--no-switch doesn’t). Nothing in the repository is run, and the rest of it is left out. --force replaces a theme of yours with the same name; the old files are kept as .vikix-bak.
It cycles: a new picture every 30 minutes from Vid’s collection (the feature wallpapers, which a fresh install has), ~/Pictures/Wallpapers and ~/wallpapers. vikix-wallpaper cycle 60 for every hour, vikix-wallpaper next for another now. To keep one: Super+m → Wallpaper, or vikix-wallpaper FILE; Theme there follows the theme, Cycle cycles again. vikix update brings the collection’s new pictures. My own tool in the picker stops Vikix touching it, for feh or nitrogen.
~/.config/alacritty/alacritty.toml. Open windows change at once.
They follow the theme by themselves: dark with a dark one, light with a light one, at once. GTK 4 programs take its colours too. To keep one look whatever the theme: your rules in ~/.config/gtk-4.0/gtk.css, below the line that imports the theme; for Qt, qt6ct
Set them in that program’s config, after the line that includes the theme. For dunst, a new file after the theme’s: ~/.config/dunst/dunstrc.d/90-mine.conf.
Xft.dpi in ~/.Xresources (the file suggests values), then log in again
(push "Class" *vikix-dialog-classes*) in user.lisp, the class being the second word xprop WM_CLASS prints when you click the window. Dialogs, password boxes (zenity, polkit, ssh-askpass, pinentry) already do
~/.config/picom/picom.conf. picom rereads the file when it changes. To change backend, pkill picom first, then edit, then picom -b: changing it while picom runs can freeze the screen.
~/.config/dunst/dunstrc, then dunstctl reload
~/.config/rofi/config.rasi
Super+m → Welcome → Set your keyboard layout picks one from a list and applies it. Or edit ~/.config/vikix/keyboard (VIKIX_KB_LAYOUT, options such as ctrl:nocaps), then Super+m → Apply keyboard settings. The starter swaps Caps Lock and Left Ctrl.
Make ~/.config/vikix/idle with any of LOCK=10, SCREEN_OFF=11, SUSPEND=20 (minutes; SUSPEND=0 disables idle suspend; suspend is on battery only), then log in again
~/.config/gammastep/config.ini. Super+Ctrl+l switches it off and on.
~/.config/mimeapps.list, or xdg-mime default org.pwmt.zathura.desktop application/pdf
A screen you plug in lights up by itself, to the right of the laptop’s, with the wallpaper across it, and comes back the same way next time. Super+Ctrl+p (or the laptop’s display key) for mirror, the other screen only, the laptop’s only, or arranging them by hand; what you choose is remembered for those screens.
~/.config/vikix/backup-exclude
The session’s vikix-battery watcher warns at 15% and automatically suspends at 5% or below while discharging, after checking that no charger is online. The session’s xss-lock locks the screen before sleep. Critical battery sleep still applies with keep awake on or SUSPEND=0: those settings control idle sleep only. After updating to this behaviour, log out and back in to start the new watcher.
It checks the first battery once a minute, every 15 seconds at low charge. After a successful sleep request it waits two minutes before checking again to give you time to connect power after waking. If sleep fails, it warns and retries after a minute. vikix-battery --once prints and warns without sleeping. The session environment’s VIKIX_BATTERY_LOW and VIKIX_BATTERY_CRITICAL override the percentages (1 <= critical <= low <= 100).
Sleep still consumes power. Plug in before the remaining charge runs out; this does not configure hibernation or preserve memory after total power loss.
~/.bashrc is yours. Vikix’s one block is at the top and loads its aliases and prompt (~/.config/vikix/vikix.bash), so what you write below it wins:
alias gs='git status' # your aliases PS1='\w \$ ' # your own prompt export EDITOR=nvim
Don’t edit between the # >>> vikix … >>> and # <<< vikix … <<< lines; Vikix rewrites those.
API keys don’t go here. An export ANTHROPIC_API_KEY=... line in ~/.bashrc is kept for ever in your files’ history. Use vikix ai key set anthropic instead: every shell still gets the variable (see the README). alias lists every alias, and the README explains them.
vikix pkg add NAME, or vikix pkg add alone to search every package in Void with a description beside each (Super+m → Install a program). xi NAME works too. It stays installed, and vikix update keeps it current along with everything else.
vikix features lists them and marks the ones you have; vikix add rust installs one, and every update keeps it; vikix remove rust uninstalls what only it needed, after showing you the list. Bundles add several at once: vikix add essentials (Emacs, C, Python, Lisp), developer, creative (video, graphics, Blender), everything. Your choices are ~/.config/vikix/features. The programs of the app features (video, graphics, blender, study, passwords, phone, cli-extras) are in Super+m → Apps, each once it’s installed. Windows (vikix windows setup, see Windows in a window) and web apps (the first vikix webapp add) choose their feature by themselves.
vikix pkg drop NAME, or vikix pkg drop alone to pick from what’s installed (Super+m → Remove a program). One that Vikix’s lists name goes on your skip list, ~/.config/vikix/packages-skip, so vikix update doesn’t bring it back; vikix pkg list shows it, and vikix pkg add NAME takes one off. For a whole language or editor, vikix remove is the better way: it says so. (xr NAME removes a package too, but an update would install it again.)
.desktop files in ~/.local/share/applications. Put yours there, with a Name= and an Exec=; a Keywords= line (Keywords=jlab;notebook;) makes it come up for other words you might type, as jlab finds JupyterLab.
sv-on NAME (the services are in /etc/sv/), sv-off NAME, svls to list. These are system services. A program for your desktop session goes in user.lisp instead (above).
A website you use like a program (mail, a CRM, a calendar) can have a window, a launcher entry and a key of its own:
vikix webapp add superhuman # presets: superhuman, fastmail, gmail, outlook, outlook-live vikix webapp add crm https://crm.example.com --key s-M-k # Super+Alt+k: web apps' keys are on Super+Alt vikix webapp key crm none # change its key, or drop it
Your list is ~/.config/vikix/webapps, one NAME URL [KEY] per line; editing it by hand works too (your comments stay), then Super+m → Reload config; vikix webapp list points out a line it can’t use. To start one at login, add (run-shell-command "vikix-webapp launch NAME") to user.lisp. See the README.
Emacs and Neovim are features: vikix add emacs, vikix add neovim. Neovim’s config is split like the desktop’s: Vikix’s part is ~/.local/share/vikix/nvim, and ~/.config/nvim is yours (your plugins go in its lua/plugins/, and win). Emacs’s is a git clone of the author’s at ~/.emacs.d, which vikix update pulls, and Vikix’s AI setup for it is ~/.local/share/vikix/emacs. Neovim and Emacs has the rest: keys, language servers, AI in each, and bringing a config of your own.
vikix project lists the folders under ~/src that have a log.md, and adds to their logs (the README has the commands and the log’s layout). Where it looks is ~/.config/vikix/projects, yours; it starts as comments only, so the defaults stand until you uncomment a line:
root=~/src # a folder your projects are in; one line each, as many as you like root=~/work depth=2 # how far down: 2 makes ~/src/series/book a project of the collection "series" logs=~/src/project-logs # a public repo ~/src/NAME with no log.md of its own uses logs/NAME/log.md
The change takes effect at once: each vikix project reads it again. A project whose build isn’t build.sh, make, src/build.sh or npm run build says so in its log’s Status, with a - Build: COMMAND line, and the same for its checks with - Check: COMMAND. vikix project new NAME adds a project (a folder in the first root= with its log); vikix today is the day across all of them. Super+Alt+p (or Super+m → Projects) picks one with rofi and opens a terminal in its folder and its log in Emacs (in $EDITOR, Neovim by default, without Emacs); the terminal is $VIKIX_TERMINAL, alacritty unless you set it.
vikix project open NAME (or Super+Alt+p) puts a project on a workspace of its own, the first empty one of the nine (a new one named for the project when all nine are in use, see Workspaces past the nine), with a terminal in its folder and its log in the editor. Arrange them as you like: when you leave that workspace its layout is saved (as a layout called project-NAME, see Saved layouts), and the next time you open the project it comes back that way. While the project’s workspace is still open, opening it again just goes there. vikix project save saves it at once. A window the saved layout names that isn’t open, a browser say, is started again and put in its place.
vikix day keeps a diary from the same projects: how long each had the screen, its entries and commits, a file a day in ~/journal (the README says what it reads). Its folder is folder=~/Notes/journal in ~/.config/vikix/day, a file you make; and (setf *vikix-day-on* nil) in user.lisp stops the desktop noting what is on the screen.
Where was I? When you come back to the laptop after ten minutes or more away, a notification with that title says where you were: how long you were gone, the project you were on and its next step, the files Emacs hasn’t saved, your last command, and your last note if you have the inbox plugin. Super+m → Where was I? (the project, its next step, what isn’t saved) shows it again, and vikix back in a terminal says more: the project’s last commit and your last few commands. It only reads what is kept anyway, the diary’s record of the screen among it, so there is no card while *vikix-day-on* is nil. To wait longer, or never show it, in user.lisp:
(setf *vikix-back-after* 1800) ; seconds away before the card: half an hour (600 as it comes) (setf *vikix-back-after* nil) ; never; vikix back still answers when you ask
Super+F2 searches a catalogue of every document on the machine (vikix docs), and Super+Alt+? explains a thing on a card (vikix what). One file of yours, ~/.config/vikix/docs, adds your own writing to both. Make it with lines like these:
own=~/books # every Markdown file under it, read a section at a time own=~/books site/out/*.html # these HTML pages too (patterns from that folder) own=~/papers **/*.pdf # PDFs by their text: a row a page, opened at the page agents=~/books/unix-by-hand # open this folder to the AI agents; the rest of yours stays closed what=~/books/what # your pages for vikix what
An own= folder’s documents are rows of the catalogue, one for each file and one for each second-level heading (##, or an <h2> with an id or a data-at tag), so a search lands on the section, and so does a chapter a page names. They open in the docs browser at that section, styled as the guide is (Ctrl+Enter: the file in Emacs). They are closed to the agents’ docs_search and docs_read, and to vikix docs ask when an agent runs it, until an agents= line opens a folder to them. A PDF named by a pattern is read by the text of its first twenty pages (pdftotext; a scanned one is listed by its name alone) and opens at the hit’s page in zathura, evince or mupdf.
A second file, ~/.config/vikix/docs-links, is your own links: a URL and its title a line, in either order (https://example.org/sv The sv page, # comments allowed). They are hits of the source web beside the websites of the packages you have installed and the links the language guides in ~/dev list, each wearing a globe in the list: the one kind of hit that opens on the web (your default browser), and nothing of them is ever fetched, not when the catalogue is read, not when it is searched, not for an answer from vikix docs ask.
A what= folder holds your pages, a file a kind of thing (process.md, service.md, and service-sshd.md for one thing by name): a paragraph in your words, which replaces Vikix’s on the card, then lines saying where to read on, yours before Vikix’s:
A process is a program while it runs. (Your words, sixty at most.) chapter: unix-by-hand/ch04-processes.md#A program that is running chapter: site/out/page.html#bus see: port
A chapter: line names a file under one of your own= folders and a section of it: the heading’s words for Markdown, the element’s id for HTML. vikix what check says which line names nothing, vikix what gaps lists what has no page or no chapter yet (the kinds, the bar’s fields, the services that run here): a writing list drawn from the machine. ("unix-by-hand" is a made-up book.)
Each of these is one of your files, so it has an undo too. Working with AI says what each does.
note)vikix ai use local, vikix ai use claude or vikix ai use codex (Super+i and Super+F10 only); vikix ai use alone says which. The model and the languages to translate into are in ~/.config/vikix/ai (Local or Claude)
vikix agent --default opencode; vikix agent --which says which (Another agent)
vikix dictate models small (or large-v3-turbo, the best) for many languages, base.en for English (Dictation)
vikix voice voices alan; speak=no or idle= in ~/.config/vikix/voice (Talking with the AI)
note readsnote index FOLDER --skip A,B once; folder=, skip=, embed= in ~/.config/vikix/notes (Asking your notes: note)
vikix mcp register gives it the desktop as tools; --allow-eval and --allow-undo add the two risky ones, and registering again without them takes them away (The desktop as tools)
Some things can only be changed in Vikix’s own files: a default for everyone, a bug, a new stage. Change them in a checkout you commit to, not in place:
git -C ~/vikix remote set-url origin https://github.com/YOU/vikix.git
~/vikix, run tests/run.sh, and commit it.
vikix update now pulls your fork. To take in new Vikix versions, merge them into the fork.
Or, if it would help everyone, open an issue or a pull request.