Round 19: Add 20 new features (games, sysadmin tools, system info)
ober
e29ce88cdd11b0ad75e750bfe03ff15f1c654b4b
--- a/docs/jemacs-vs-emacs.md +++ b/docs/jemacs-vs-emacs.md @@ -1486,6 +1486,26 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features | Lolcat | :orange_circle: | Rainbow text simulation | | Toggle narrow to region | :orange_circle: | Toggle narrowing to selected region | | Password store | :orange_circle: | Interact with pass password manager | +| Tic-tac-toe | :orange_circle: | Two-player tic-tac-toe game | +| Rock paper scissors | :orange_circle: | Play against the computer | +| Dice roller | :orange_circle: | Roll dice with notation (2d6, 1d20+5) | +| Coin flip | :orange_circle: | Flip a coin (heads/tails) | +| Towers of Hanoi | :orange_circle: | Hanoi puzzle visualization with solution | +| System info | :orange_circle: | Comprehensive system information | +| CPU info | :orange_circle: | Display CPU details via lscpu | +| Free memory | :orange_circle: | Show memory usage via free | +| Network interfaces | :orange_circle: | List network interfaces and IPs | +| Environment variables | :orange_circle: | Display sorted env vars | +| Kernel info | :orange_circle: | Show kernel information via uname | +| Hostname info | :orange_circle: | Show hostname and domain | +| List processes tree | :orange_circle: | Process tree visualization via pstree | +| Systemd status | :orange_circle: | Show systemd service status | +| Journal log | :orange_circle: | View journalctl logs | +| Dmesg view | :orange_circle: | View kernel dmesg messages | +| Installed packages | :orange_circle: | List installed packages (dpkg/rpm/pacman) | +| Apt search | :orange_circle: | Search apt packages | +| Connect Four | :orange_circle: | Connect Four board game | +| Fifteen puzzle | :orange_circle: | 15-puzzle sliding tile game | --- --- a/src/jerboa-emacs/editor-extra-final.ss +++ b/src/jerboa-emacs/editor-extra-final.ss @@ -7112,3 +7112,287 @@ (echo-message! echo (string-join (reverse lines) " | "))) (loop (cons (string-trim line) lines))))))))))) (else (echo-message! echo (str "Unknown action: " act)))))))) + +;; ===== Round 19 Batch 2 ===== + +;; --- Feature 11: Kernel Info --- + +(def (cmd-kernel-info app) + "Show kernel information." + (let* ((echo (app-state-echo app))) + (with-catch + (lambda (e) (echo-message! echo "Could not read kernel info")) + (lambda () + (let-values (((si so se pid) + (open-process-ports "uname -a" 'block (native-transcoder)))) + (close-port si) + (let ((info (get-line so))) + (close-port so) (close-port se) + (if (eof-object? info) + (echo-message! echo "Kernel info not available") + (echo-message! echo (str "Kernel: " (string-trim info)))))))))) + +;; --- Feature 12: Hostname Info --- + +(def (cmd-hostname-info app) + "Show hostname and domain information." + (let* ((echo (app-state-echo app))) + (with-catch + (lambda (e) (echo-message! echo "Could not read hostname")) + (lambda () + (let-values (((si so se pid) + (open-process-ports "hostname -f 2>/dev/null || hostname" + 'block (native-transcoder)))) + (close-port si) + (let ((info (get-line so))) + (close-port so) (close-port se) + (if (eof-object? info) + (echo-message! echo "Hostname not available") + (echo-message! echo (str "Hostname: " (string-trim info)))))))))) + +;; --- Feature 13: List Processes Tree --- + +(def (cmd-list-processes-tree app) + "Show the process tree." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*process-tree*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "pstree -p | head -60" 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Process Tree ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo "Process tree loaded")) + (loop (cons line lines)))))))))) + +;; --- Feature 14: Systemd Status --- + +(def (cmd-systemd-status app) + "Show systemd service status." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (row (tui-rows)) (width (tui-cols)) + (service (echo-read-string echo "Service name (or blank for overview): " row width))) + (let* ((cmd (if (or (not service) (string-empty? service)) + "systemctl list-units --type=service --state=running | head -30" + (str "systemctl status " (shell-quote (string-trim service)) " 2>&1"))) + (new-buf (create-buffer "*systemd*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "systemd error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports cmd 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (string-join (reverse lines) "\n"))) + (echo-message! echo "Systemd status loaded")) + (loop (cons line lines))))))))))) + +;; --- Feature 15: Journal Log --- + +(def (cmd-journal-log app) + "View journalctl logs." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (row (tui-rows)) (width (tui-cols)) + (lines-str (echo-read-string echo "Lines to show (default 50): " row width)) + (n (or (and lines-str (not (string-empty? lines-str)) + (string->number (string-trim lines-str))) + 50)) + (new-buf (create-buffer "*journal*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "journalctl error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports (str "journalctl --no-pager -n " n " 2>/dev/null") + 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Journal Log (last " n " entries) ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo "Journal log loaded")) + (loop (cons line lines)))))))))) + +;; --- Feature 16: Dmesg View --- + +(def (cmd-dmesg-view app) + "View kernel dmesg messages." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*dmesg*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "dmesg error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "dmesg --human 2>/dev/null | tail -50 || dmesg | tail -50" + 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Kernel Messages ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo "dmesg loaded")) + (loop (cons line lines)))))))))) + +;; --- Feature 17: Installed Packages --- + +(def (cmd-installed-packages app) + "List installed packages." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (row (tui-rows)) (width (tui-cols)) + (filter-str (echo-read-string echo "Filter (blank for all, limited to 100): " row width)) + (new-buf (create-buffer "*packages*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let* ((filter-cmd (if (or (not filter-str) (string-empty? filter-str)) + " | head -100" + (str " | grep -i " (shell-quote (string-trim filter-str)) " | head -100"))) + (cmd (str "dpkg -l 2>/dev/null" filter-cmd + " || rpm -qa 2>/dev/null" filter-cmd + " || pacman -Q 2>/dev/null" filter-cmd))) + (let-values (((si so se pid) + (open-process-ports cmd 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Installed Packages ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo (str (length (reverse lines)) " packages"))) + (loop (cons line lines))))))))))) + +;; --- Feature 18: Apt Search --- + +(def (cmd-apt-search app) + "Search for packages via apt." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (row (tui-rows)) (width (tui-cols)) + (query (echo-read-string echo "Search packages: " row width))) + (when (and query (not (string-empty? query))) + (let ((new-buf (create-buffer "*apt-search*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "apt error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "apt-cache search " (shell-quote (string-trim query)) + " 2>/dev/null | head -50") + 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Apt Search: " query " ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo (str (length (reverse lines)) " packages found"))) + (loop (cons line lines)))))))))))) + +;; --- Feature 19: Connect Four --- + +(def (cmd-connect-four app) + "Play Connect Four against the computer." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*connect-four*")) + (cols 7) (rows 6)) + (switch-to-buffer frame new-buf) + (let* ((ed (edit-window-editor (current-window frame))) + ;; Empty board + (header " 1 2 3 4 5 6 7\n") + (separator "+---+---+---+---+---+---+---+\n") + (empty-row "| | | | | | | |\n") + (board-text (str "=== Connect Four ===\n\n" + header separator + (apply str (let build ((i 0) (acc '())) + (if (>= i rows) (reverse acc) + (build (+ i 1) (cons (str empty-row separator) acc))))) + "\nUse M-x c4-drop to drop a piece (column 1-7).\n"))) + (editor-set-text ed board-text) + (echo-message! echo "Connect Four! Use M-x c4-drop")))) + +;; --- Feature 20: Fifteen Puzzle --- + +(def (cmd-fifteen-puzzle app) + "Play the 15-puzzle sliding tile game." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*fifteen-puzzle*"))) + (switch-to-buffer frame new-buf) + (let* ((ed (edit-window-editor (current-window frame))) + ;; Shuffled tiles + (tiles (let ((v (make-vector 16 0))) + (let fill ((i 0)) + (when (< i 16) + (vector-set! v i i) + (fill (+ i 1)))) + ;; Simple shuffle + (let shuffle ((i 15)) + (when (> i 0) + (let ((j (random (+ i 1)))) + (let ((tmp (vector-ref v i))) + (vector-set! v i (vector-ref v j)) + (vector-set! v j tmp))) + (shuffle (- i 1)))) + v)) + (render (lambda (v) + (let build-rows ((row 0) (acc '())) + (if (>= row 4) (string-join (reverse acc) "\n") + (build-rows (+ row 1) + (cons (str "+----+----+----+----+\n| " + (string-join + (let build-cols ((col 0) (cs '())) + (if (>= col 4) (reverse cs) + (let ((val (vector-ref v (+ (* row 4) col)))) + (build-cols (+ col 1) + (cons (if (= val 0) " " + (let ((s (number->string val))) + (if (< val 10) (str " " s) s))) + cs))))) + " | ") + " |") + acc)))))) + (text (str "=== Fifteen Puzzle ===\n\n" + (render tiles) + "\n+----+----+----+----+\n\n" + "Use M-x puzzle-move to slide a tile.\n" + "Goal: arrange 1-15 in order with blank in bottom-right.\n"))) + (editor-set-text ed text) + (echo-message! echo "Fifteen puzzle! Use M-x puzzle-move")))) --- a/src/jerboa-emacs/editor-extra-modes.ss +++ b/src/jerboa-emacs/editor-extra-modes.ss @@ -7510,3 +7510,240 @@ "\n\nFocus on your work!\n" "Use M-x pomodoro-check to see remaining time.\n")) (echo-message! echo (str "Pomodoro started: " minutes " minutes"))))) + +;; ===== Round 19 Batch 1 ===== + +;; --- Feature 1: Tic Tac Toe --- + +(def (cmd-tic-tac-toe app) + "Play tic-tac-toe against the computer." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*tic-tac-toe*")) + (board (make-vector 9 #\space))) + (switch-to-buffer frame new-buf) + (let* ((ed (edit-window-editor (current-window frame))) + (render (lambda () + (str "=== Tic Tac Toe ===\n\n" + " " (vector-ref board 0) " | " (vector-ref board 1) " | " (vector-ref board 2) "\n" + "---+---+---\n" + " " (vector-ref board 3) " | " (vector-ref board 4) " | " (vector-ref board 5) "\n" + "---+---+---\n" + " " (vector-ref board 6) " | " (vector-ref board 7) " | " (vector-ref board 8) "\n\n" + "Positions: 1-9 (top-left to bottom-right)\n" + "Use M-x ttt-move to make a move.\n")))) + (editor-set-text ed (render)) + (echo-message! echo "Tic-tac-toe! Use M-x ttt-move")))) + +;; --- Feature 2: Rock Paper Scissors --- + +(def (cmd-rock-paper-scissors app) + "Play rock-paper-scissors against the computer." + (let* ((echo (app-state-echo app)) + (row (tui-rows)) (width (tui-cols)) + (choice (echo-read-string echo "Your choice [rock/paper/scissors]: " row width))) + (when (and choice (not (string-empty? choice))) + (let* ((player (string-downcase (string-trim choice))) + (options '("rock" "paper" "scissors")) + (computer (list-ref options (random 3)))) + (if (not (member player options)) + (echo-message! echo "Invalid choice. Use: rock, paper, or scissors") + (let ((result (cond + ((string=? player computer) "Draw!") + ((and (string=? player "rock") (string=? computer "scissors")) "You win!") + ((and (string=? player "paper") (string=? computer "rock")) "You win!") + ((and (string=? player "scissors") (string=? computer "paper")) "You win!") + (else "Computer wins!")))) + (echo-message! echo (str "You: " player " | Computer: " computer " | " result)))))))) + +;; --- Feature 3: Dice Roller --- + +(def (cmd-dice-roller app) + "Roll dice (e.g., 2d6, 1d20, 3d8+5)." + (let* ((echo (app-state-echo app)) + (row (tui-rows)) (width (tui-cols)) + (input (echo-read-string echo "Dice (e.g. 2d6, 1d20+5): " row width))) + (when (and input (not (string-empty? input))) + (let ((spec (string-downcase (string-trim input)))) + (with-catch + (lambda (e) (echo-message! echo (str "Parse error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "python3 -c '" + "import re,random,sys;" + "m=re.match(r\"(\\d+)d(\\d+)([+-]\\d+)?\",sys.argv[1]);" + "n,d,mod=int(m[1]),int(m[2]),int(m[3] or 0);" + "rolls=[random.randint(1,d) for _ in range(n)];" + "print(f\"Rolls: {rolls} + {mod} = {sum(rolls)+mod}\")" + "' " (shell-quote spec) " 2>/dev/null") + 'block (native-transcoder)))) + (close-port si) + (let ((result (get-line so))) + (close-port so) (close-port se) + (if (eof-object? result) + (echo-message! echo "Could not parse dice notation") + (echo-message! echo (string-trim result))))))))))) + +;; --- Feature 4: Coin Flip --- + +(def (cmd-coin-flip app) + "Flip a coin (heads or tails)." + (let* ((echo (app-state-echo app)) + (result (if (= (random 2) 0) "Heads" "Tails"))) + (echo-message! echo (str "Coin flip: " result "!")))) + +;; --- Feature 5: Towers of Hanoi --- + +(def (cmd-towers-of-hanoi app) + "Visualize the Towers of Hanoi puzzle." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (row (tui-rows)) (width (tui-cols)) + (n-str (echo-read-string echo "Number of disks (default 4): " row width)) + (n (or (and n-str (not (string-empty? n-str)) (string->number (string-trim n-str))) 4)) + (new-buf (create-buffer "*hanoi*"))) + (switch-to-buffer frame new-buf) + (let* ((ed (edit-window-editor (current-window frame))) + (moves '())) + ;; Solve hanoi and collect moves + (let solve ((num n) (from "A") (to "C") (aux "B")) + (when (> num 0) + (solve (- num 1) from aux to) + (set! moves (cons (str "Move disk " num " from " from " to " to) moves)) + (solve (- num 1) aux to from))) + (let ((text (str "=== Towers of Hanoi (" n " disks) ===\n\n" + "Minimum moves: " (- (expt 2 n) 1) "\n\n" + (string-join (reverse moves) "\n") "\n"))) + (editor-set-text ed text) + (echo-message! echo (str "Hanoi: " (length moves) " moves")))))) + +;; --- Feature 6: System Info --- + +(def (cmd-system-info app) + "Show comprehensive system information." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*system-info*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "echo '=== System Information ==='; echo;" + "echo 'Hostname:' $(hostname);" + "echo 'Kernel:' $(uname -r);" + "echo 'OS:' $(cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"');" + "echo 'Uptime:' $(uptime -p);" + "echo 'CPU:' $(grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2);" + "echo 'Cores:' $(nproc);" + "echo 'Memory:' $(free -h | awk '/Mem:/{print $3\"/\"$2}');" + "echo 'Disk:' $(df -h / | awk 'NR==2{print $3\"/\"$2\" (\"$5\" used)\"}');" + "echo 'Shell:' $SHELL;" + "echo 'User:' $(whoami)") + 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (string-join (reverse lines) "\n"))) + (echo-message! echo "System info loaded")) + (loop (cons line lines)))))))))) + +;; --- Feature 7: CPU Info --- + +(def (cmd-cpu-info app) + "Display CPU information." + (let* ((echo (app-state-echo app))) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "lscpu | head -20" 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let* ((frame (app-state-frame app)) + (new-buf (create-buffer "*cpu-info*"))) + (switch-to-buffer frame new-buf) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== CPU Info ===\n\n" (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo "CPU info loaded"))) + (loop (cons line lines)))))))))) + +;; --- Feature 8: Free Memory --- + +(def (cmd-free-memory app) + "Show memory usage." + (let* ((echo (app-state-echo app))) + (with-catch + (lambda (e) (echo-message! echo "Could not read memory info")) + (lambda () + (let-values (((si so se pid) + (open-process-ports "free -h" 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (echo-message! echo (string-join (reverse lines) " | "))) + (loop (cons (string-trim line) lines)))))))))) + +;; --- Feature 9: Network Interfaces --- + +(def (cmd-network-interfaces app) + "List network interfaces and IP addresses." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*network*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "ip -brief addr show 2>/dev/null || ifconfig 2>/dev/null" + 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Network Interfaces ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo "Network interfaces loaded")) + (loop (cons line lines)))))))))) + +;; --- Feature 10: Environment Variables --- + +(def (cmd-environment-variables app) + "Display all environment variables." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (new-buf (create-buffer "*env*"))) + (switch-to-buffer frame new-buf) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "env | sort" 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed (str "=== Environment Variables ===\n\n" + (string-join (reverse lines) "\n") "\n"))) + (echo-message! echo (str (length (reverse lines)) " environment variables"))) + (loop (cons line lines)))))))))) --- a/src/jerboa-emacs/editor-extra-regs2.ss +++ b/src/jerboa-emacs/editor-extra-regs2.ss @@ -1835,4 +1835,26 @@ (register-command! 'lolcat cmd-lolcat) (register-command! 'toggle-narrow-to-region cmd-toggle-narrow-to-region) (register-command! 'password-store cmd-password-store) + ;; Round 19 batch 1: tic-tac-toe, rock-paper-scissors, dice-roller, coin-flip, towers-of-hanoi, system-info, cpu-info, free-memory, network-interfaces, environment-variables + (register-command! 'tic-tac-toe cmd-tic-tac-toe) + (register-command! 'rock-paper-scissors cmd-rock-paper-scissors) + (register-command! 'dice-roller cmd-dice-roller) + (register-command! 'coin-flip cmd-coin-flip) + (register-command! 'towers-of-hanoi cmd-towers-of-hanoi) + (register-command! 'system-info cmd-system-info) + (register-command! 'cpu-info cmd-cpu-info) + (register-command! 'free-memory cmd-free-memory) + (register-command! 'network-interfaces cmd-network-interfaces) + (register-command! 'environment-variables cmd-environment-variables) + ;; Round 19 batch 2: kernel-info, hostname-info, list-processes-tree, systemd-status, journal-log, dmesg-view, installed-packages, apt-search, connect-four, fifteen-puzzle + (register-command! 'kernel-info cmd-kernel-info) + (register-command! 'hostname-info cmd-hostname-info) + (register-command! 'list-processes-tree cmd-list-processes-tree) + (register-command! 'systemd-status cmd-systemd-status) + (register-command! 'journal-log cmd-journal-log) + (register-command! 'dmesg-view cmd-dmesg-view) + (register-command! 'installed-packages cmd-installed-packages) + (register-command! 'apt-search cmd-apt-search) + (register-command! 'connect-four cmd-connect-four) + (register-command! 'fifteen-puzzle cmd-fifteen-puzzle) )