vikix.GuideInstallSource

8 Making it yours

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.


8.1 Before you change anything

vikix 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.


8.2 The desktop: ~/.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.


8.2.1 Keys

(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.


8.2.2 Keys inside a map

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.


8.2.3 The rule for keys

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:

Super

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

Super+Shift

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

Super+Alt

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

Super+Ctrl

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.


8.2.4 Workspaces past the nine

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.


8.2.5 Which keys do you use?

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.


8.2.6 Start a program with the desktop

(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).


8.2.7 Rules: what the desktop does by itself

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.


8.2.8 Saved layouts

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.


8.2.9 Your windows back after a restart

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.


8.2.10 The drawer

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*).


8.2.11 The terminal, focus, and fonts

(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

8.2.12 The Super+m menu

The menu opens on its sections: Start, Help, Vikix, AI, Work, Notifications, Desktop, Windows, System, Apps, and Power last. Each row says what the section holds. Enter (or Right) opens one, and Escape (or Left) comes back; a second Escape closes the menu. Typing at the top looks through every entry of every section at once, so printers, theme or F10 is one step away (plain words, in any order and any case; a key’s name counts, so ctrl+d finds what Super+Ctrl+d does). An entry that has a key shows it at the right, a web app’s and a plugin’s too.

A command written with define-vikix-command and :menu is in its section already (Keys, above). The menu itself is a list you can change as a whole. Each entry is a label and either a command or a Lisp form; then, if you like, what it needs: a program on PATH, or a file ("~/..."); and then its section. An entry whose need isn’t there is left out of the menu, which is how Vikix hides JupyterLab or Printers until you add their features (and, in *vikix-apps-menu*, which the section Apps shows, each video, graphics or study program until it is installed):

(setf *vikix-menu*
      (append *vikix-menu*
              '(("Obsidian" (run-shell-command "obsidian") "obsidian" "Apps")   ; in Apps, and only with obsidian installed
                ("Keys"     vikix-keys nil "Help")                              ; needs nothing; in Help
                ("Tides"    (run-shell-command "tides")))))                     ; no section: in one called Yours

A section can have a name of your own ("Sailing"): it comes after Vikix’s, before Power. A section with one entry is not a row to open: the entry itself is at the top. Inside a section the entries keep the list’s order, except that lines about the same thing (Layout: save ..., Layout: put back ...) stay together.


8.2.13 The bar

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"))

8.2.14 Try it live first

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.


8.3 The look

The whole theme

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).

A theme of your own

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.

The colours of an agent’s terminal

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.

A theme from Omarchy

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.

The wallpaper

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.

Terminal font, size, padding

~/.config/alacritty/alacritty.toml. Open windows change at once.

GTK and Qt programs (Firefox, PCManFM, LibreOffice)

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

One program’s colours, keeping the theme for the rest

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.

Text size on a high-resolution screen

Xft.dpi in ~/.Xresources (the file suggests values), then log in again

A program whose boxes should float in front, like dialogs

(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

Shadows, fading, transparency

~/.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.

Notifications: where, how long, how big

~/.config/dunst/dunstrc, then dunstctl reload

The launcher and menus

~/.config/rofi/config.rasi


8.4 The machine

Keyboard layout, Caps Lock

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.

When the screen locks, goes dark, suspends

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

Night light hours and warmth

~/.config/gammastep/config.ini. Super+Ctrl+l switches it off and on.

Which program opens a kind of file

~/.config/mimeapps.list, or xdg-mime default org.pwmt.zathura.desktop application/pdf

Screens at a desk

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.

What backups leave out

~/.config/vikix/backup-exclude


8.4.1 When the battery runs low

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.


8.5 The shell

~/.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.


8.6 Programs and services


8.7 Web apps

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.


8.8 The editors

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.


8.9 Projects

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

8.10 Your documents, and your pages for "what is this?"

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.)


8.11 AI

Each of these is one of your files, so it has an undo too. Working with AI says what each does.

The model Super+i uses (and the editors’ chats, Super+F10 and 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)

The agent Super+a starts (and the editors, and Super+F11)

vikix agent --default opencode; vikix agent --which says which (Another agent)

Dictation’s language

vikix dictate models small (or large-v3-turbo, the best) for many languages, base.en for English (Dictation)

The voice that answers, or no voice at all

vikix voice voices alan; speak=no or idle= in ~/.config/vikix/voice (Talking with the AI)

The notes note reads

note index FOLDER --skip A,B once; folder=, skip=, embed= in ~/.config/vikix/notes (Asking your notes: note)

What the agent may do on the desktop without asking

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)


8.12 Changing Vikix itself

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:

  1. Fork github.com/vukini/vikix and point your checkout at the fork: git -C ~/vikix remote set-url origin https://github.com/YOU/vikix.git
  2. Make the change in ~/vikix, run tests/run.sh, and commit it.
  3. 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.