~ilmu/vegur

e398b5241a456c2ee113e3431dc0591f60eaaa7f — ilmu 7 months ago 5e4038e master
New machine, had some trouble setting it up so I am but it wrks
40 files changed, 622 insertions(+), 0 deletions(-)

R bootstrap-figs/emacs/init.el => desktop/bootstrap-figs/emacs/init.el
R bootstrap-figs/stumpwm/commands.lisp => desktop/bootstrap-figs/stumpwm/commands.lisp
R bootstrap-figs/stumpwm/config => desktop/bootstrap-figs/stumpwm/config
R bootstrap-figs/stumpwm/internals.lisp => desktop/bootstrap-figs/stumpwm/internals.lisp
R bootstrap-figs/stumpwm/keymaps.lisp => desktop/bootstrap-figs/stumpwm/keymaps.lisp
R bootstrap-figs/stumpwm/swank.lisp => desktop/bootstrap-figs/stumpwm/swank.lisp
R channel-specs.scm => desktop/channel-specs.scm
R config.scm => desktop/config.scm
R emacs.scm => desktop/emacs.scm
A laptop/channels.scm
A laptop/configuration.scm
A laptop/emacs/early-init.el
A laptop/emacs/eln-cache/28.2-460d8c88/evil-command-window-f8852368-3d9a9aa9.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-common-7a2c5620-3debeaf2.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-core-e7391498-60c1d32e.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-digraphs-4bf12bb1-cb6eb693.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-ex-c4a4a6b5-2b81baf2.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-integration-4a7422ad-938a720f.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-jumps-d89cca52-e71cb458.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-macros-ade0e65a-f93572f3.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-maps-86e061f9-e84eebe5.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-repeat-7be47db1-871c3f6a.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-search-d728ff16-a36ff245.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-states-2206af36-13a16a2f.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-types-575c90da-779b5236.eln
A laptop/emacs/eln-cache/28.2-460d8c88/evil-vars-1ed0079c-b52e4613.eln
A laptop/emacs/eln-cache/28.2-460d8c88/geiser-autoloads-a0c52ae5-51d108db.eln
A laptop/emacs/eln-cache/28.2-460d8c88/guix-emacs-cd6be341-4fc13f36.eln
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-726561642d6b65792d73657175656e6365_read_key_sequence_0.eln
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-73656c6563742d77696e646f77_select_window_0.eln
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7365742d77696e646f772d627566666572_set_window_buffer_0.eln
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7573652d676c6f62616c2d6d6170_use_global_map_0.eln
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7573652d6c6f63616c2d6d6170_use_local_map_0.eln
A laptop/emacs/init.el
A laptop/emacs/instructions
A laptop/stumpwm/commands.lisp
A laptop/stumpwm/config
A laptop/stumpwm/internals.lisp
A laptop/stumpwm/keymaps.lisp
A laptop/stumpwm/swank.lisp
R bootstrap-figs/emacs/init.el => desktop/bootstrap-figs/emacs/init.el +0 -0
R bootstrap-figs/stumpwm/commands.lisp => desktop/bootstrap-figs/stumpwm/commands.lisp +0 -0
R bootstrap-figs/stumpwm/config => desktop/bootstrap-figs/stumpwm/config +0 -0
R bootstrap-figs/stumpwm/internals.lisp => desktop/bootstrap-figs/stumpwm/internals.lisp +0 -0
R bootstrap-figs/stumpwm/keymaps.lisp => desktop/bootstrap-figs/stumpwm/keymaps.lisp +0 -0
R bootstrap-figs/stumpwm/swank.lisp => desktop/bootstrap-figs/stumpwm/swank.lisp +0 -0
R channel-specs.scm => desktop/channel-specs.scm +0 -0
R config.scm => desktop/config.scm +0 -0
R emacs.scm => desktop/emacs.scm +0 -0
A laptop/channels.scm => laptop/channels.scm +22 -0
@@ 0,0 1,22 @@
(list (channel
        (name 'nonguix)
        (url "https://gitlab.com/nonguix/nonguix")
        (branch "master")
        (commit
          "639c25bb691129607b4aa5bd87ad13f9c3d2667c")
        (introduction
          (make-channel-introduction
            "897c1a470da759236cc11798f4e0a5f7d4d59fbc"
            (openpgp-fingerprint
              "2A39 3FFF 68F4 EF7A 3D29  12AF 6F51 20A0 22FB B2D5"))))
      (channel
        (name 'guix)
        (url "https://git.savannah.gnu.org/git/guix.git")
        (branch "master")
        (commit
          "541b1c3e74cbb7965b7398d342882a038c893fbb")
        (introduction
          (make-channel-introduction
            "9edb3f66fd807b096b48283debdcddccfea34bad"
            (openpgp-fingerprint
              "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))))

A laptop/configuration.scm => laptop/configuration.scm +69 -0
@@ 0,0 1,69 @@
;; TODO: investigate whether to set XDG_DATA_HOME .cache or to keep it at .local/share
(use-modules (gnu)
	     (nongnu packages linux)
	     (nongnu system linux-initrd))
(use-package-modules wm)
(use-service-modules
  cups
  desktop
  sound
  networking
  ssh
  xorg)

(operating-system
  (kernel linux)
  (initrd microcode-initrd)
  (firmware (list linux-firmware))
  (locale "en_IE.utf8")
  (timezone "Europe/London")
  (keyboard-layout
    (keyboard-layout "us,is" "altgr-intl" 
		     #:options '("grp:win_space_toggle" "caps:super" "grp_led:caps")))
  (host-name "vegur")
  (users (cons* 
                (user-account
                  (name "ilmu")
                  (comment "ilmu")
                  (group "users")
                  (home-directory "/home/ilmu")
                  (supplementary-groups
                    '("wheel" "netdev" "audio" "video")))
                %base-user-accounts))
  (packages
    (append
      (map specification->package ;; TODO: clean this up
        (list "git" "xclip" "kitty" "neovim" "pavucontrol" "curl"
            "emacs-geiser" "emacs-evil" "emacs-evil-collection" 
            "emacs-sly" "sbcl" "stumpwm-with-slynk" "sbcl-slynk"
            "emacs" "guile" "zathura" "zathura-pdf-mupdf" "tree"
	    "ungoogled-chromium" "setxkbmap" "font-dejavu" "fd"
            "sbcl-stumpwm-ttf-fonts" "qutebrowser" "xterm" 
	    "nyxt" "nss-certs"))

      (list `(,stumpwm "lib"))
      %base-packages))
  (services
    (append
      (list (service openssh-service-type)
            (service cups-service-type)
            ;; (service alsa-service-type)
            (set-xorg-configuration
              (xorg-configuration
                (keyboard-layout keyboard-layout))))
      %desktop-services))
  (bootloader
    (bootloader-configuration
      (bootloader grub-bootloader)
      (targets (list "/dev/sda"))
      (keyboard-layout keyboard-layout)))
  (file-systems
    (cons* (file-system
             (mount-point "/")
             (device "/dev/sda3")
             (type "ext4"))
           %base-file-systems)))

;/dev/sda2: UUID="19ae1dc2-a19e-4d64-89b0-c6df02ff0937" TYPE="swap" PARTUUID="28782707-02"
;/dev/sda3: LABEL="my-root" UUID="1885360f-654e-437f-bdf9-77fac7afd392" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="28782707-03"
;/dev/sda1: UUID="903A-97A6" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="28782707-01"

A laptop/emacs/early-init.el => laptop/emacs/early-init.el +54 -0
@@ 0,0 1,54 @@
;; yay
(require 'evil) ;; emacs-evil emacs-evil-collection
(evil-mode 1)
(tool-bar-mode -1)
(menu-bar-mode -1)
(toggle-scroll-bar -1)
(show-paren-mode 1)
(setq scroll-step 1
      scroll-conservatively 10000)
(setq backup-directory-alist `(("." . "~/.cache/emacs")))

(defun open-init-file ()
  (interactive)
  (find-file "~/.config/emacs/init.el"))

(evil-set-leader '(normal visual) (kbd ","))

(evil-define-key 'normal 'global (kbd "Æ") 'evil-ex) ;; icelandic keyboard Æw
(evil-define-key 'normal 'global (kbd "<leader>c") 'open-init-file)
(evil-define-key 'normal 'global (kbd "<leader>wj") 'evil-window-down)
(evil-define-key 'normal 'global (kbd "<leader>wk") 'evil-window-up)
(evil-define-key 'normal 'global (kbd "<leader>wl") 'evil-window-right)
(evil-define-key 'normal 'global (kbd "<leader>wh") 'evil-window-left)
(evil-define-key 'normal 'global (kbd "<leader>b") 'list-buffers)
(evil-define-key 'normal 'global (kbd "<leader>d") 'evil-delete-buffer)
(evil-define-key 'normal 'global (kbd "<leader>g") 'switch-to-buffer)
(evil-define-key 'normal 'global (kbd "<leader>f") 'make-frame)
(evil-define-key 'normal 'global (kbd "<leader>o") 'find-file)
(evil-define-key 'normal 'global (kbd "<leader>ws") 'evil-window-split)
(evil-define-key 'normal 'global (kbd "<leader>wv") 'evil-window-vsplit)
(evil-define-key 'normal 'global (kbd "<leader>wd") 'evil-window-delete)
(evil-define-key 'visual 'global (kbd "<leader>e") 'eval-region)

;; emacs-geiser
;; Make into hook          -- memnomic is "tools scheme"
(evil-define-key 'normal 'global (kbd "<leader>ts") 'run-geiser)
(evil-define-key 'visual scheme-mode-map (kbd "<leader>e") 'geiser-eval-region)
(evil-define-key 'normal scheme-mode-map (kbd "<leader>e") 'geiser-eval-last-sexp)
(evil-define-key 'normal scheme-mode-map (kbd "<leader>h") 'geiser-doc-symbol-at-point)

;; emacs-sly
;; "tools lisp"
(evil-define-key 'normal 'global (kbd "<leader>tl") 'sly)
(evil-define-key 'visual sly-mode-map (kbd "<leader>e") 'sly-eval-region)
(evil-define-key 'normal sly-mode-map (kbd "<leader>e") 'sly-eval-last-expression)
(evil-define-key 'normal sly-mode-map (kbd "<leader>h") 'sly-documentation)
;; Fix annoying thing in sly repl.
(evil-define-key 'insert sly-mode-map (kbd ",") 'self-insert-command)

;; emacs-youtube-dl


;; emacs-evil-*something about parenthesis*


A laptop/emacs/eln-cache/28.2-460d8c88/evil-command-window-f8852368-3d9a9aa9.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-command-window-f8852368-3d9a9aa9.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-common-7a2c5620-3debeaf2.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-common-7a2c5620-3debeaf2.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-core-e7391498-60c1d32e.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-core-e7391498-60c1d32e.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-digraphs-4bf12bb1-cb6eb693.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-digraphs-4bf12bb1-cb6eb693.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-ex-c4a4a6b5-2b81baf2.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-ex-c4a4a6b5-2b81baf2.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-integration-4a7422ad-938a720f.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-integration-4a7422ad-938a720f.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-jumps-d89cca52-e71cb458.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-jumps-d89cca52-e71cb458.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-macros-ade0e65a-f93572f3.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-macros-ade0e65a-f93572f3.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-maps-86e061f9-e84eebe5.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-maps-86e061f9-e84eebe5.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-repeat-7be47db1-871c3f6a.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-repeat-7be47db1-871c3f6a.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-search-d728ff16-a36ff245.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-search-d728ff16-a36ff245.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-states-2206af36-13a16a2f.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-states-2206af36-13a16a2f.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-types-575c90da-779b5236.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-types-575c90da-779b5236.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/evil-vars-1ed0079c-b52e4613.eln => laptop/emacs/eln-cache/28.2-460d8c88/evil-vars-1ed0079c-b52e4613.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/geiser-autoloads-a0c52ae5-51d108db.eln => laptop/emacs/eln-cache/28.2-460d8c88/geiser-autoloads-a0c52ae5-51d108db.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/guix-emacs-cd6be341-4fc13f36.eln => laptop/emacs/eln-cache/28.2-460d8c88/guix-emacs-cd6be341-4fc13f36.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-726561642d6b65792d73657175656e6365_read_key_sequence_0.eln => laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-726561642d6b65792d73657175656e6365_read_key_sequence_0.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-73656c6563742d77696e646f77_select_window_0.eln => laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-73656c6563742d77696e646f77_select_window_0.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7365742d77696e646f772d627566666572_set_window_buffer_0.eln => laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7365742d77696e646f772d627566666572_set_window_buffer_0.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7573652d676c6f62616c2d6d6170_use_global_map_0.eln => laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7573652d676c6f62616c2d6d6170_use_global_map_0.eln +0 -0
A laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7573652d6c6f63616c2d6d6170_use_local_map_0.eln => laptop/emacs/eln-cache/28.2-460d8c88/subr--trampoline-7573652d6c6f63616c2d6d6170_use_local_map_0.eln +0 -0
A laptop/emacs/init.el => laptop/emacs/init.el +54 -0
@@ 0,0 1,54 @@
;; yay
(require 'evil) ;; emacs-evil emacs-evil-collection
(evil-mode 1)
(tool-bar-mode -1)
(menu-bar-mode -1)
(toggle-scroll-bar -1)
(show-paren-mode 1)
(setq scroll-step 1
      scroll-conservatively 10000)
(setq backup-directory-alist `(("." . "~/.cache/emacs")))

(defun open-init-file ()
  (interactive)
  (find-file "~/.config/emacs/init.el"))

(evil-set-leader '(normal visual) (kbd ","))

(evil-define-key 'normal 'global (kbd "Æ") 'evil-ex) ;; icelandic keyboard Æw
(evil-define-key 'normal 'global (kbd "<leader>c") 'open-init-file)
(evil-define-key 'normal 'global (kbd "<leader>wj") 'evil-window-down)
(evil-define-key 'normal 'global (kbd "<leader>wk") 'evil-window-up)
(evil-define-key 'normal 'global (kbd "<leader>wl") 'evil-window-right)
(evil-define-key 'normal 'global (kbd "<leader>wh") 'evil-window-left)
(evil-define-key 'normal 'global (kbd "<leader>b") 'list-buffers)
(evil-define-key 'normal 'global (kbd "<leader>d") 'evil-delete-buffer)
(evil-define-key 'normal 'global (kbd "<leader>g") 'switch-to-buffer)
(evil-define-key 'normal 'global (kbd "<leader>f") 'make-frame)
(evil-define-key 'normal 'global (kbd "<leader>o") 'find-file)
(evil-define-key 'normal 'global (kbd "<leader>ws") 'evil-window-split)
(evil-define-key 'normal 'global (kbd "<leader>wv") 'evil-window-vsplit)
(evil-define-key 'normal 'global (kbd "<leader>wd") 'evil-window-delete)
(evil-define-key 'visual 'global (kbd "<leader>e") 'eval-region)

;; emacs-geiser
;; Make into hook          -- memnomic is "tools scheme"
(evil-define-key 'normal 'global (kbd "<leader>ts") 'run-geiser)
(evil-define-key 'visual scheme-mode-map (kbd "<leader>e") 'geiser-eval-region)
(evil-define-key 'normal scheme-mode-map (kbd "<leader>e") 'geiser-eval-last-sexp)
(evil-define-key 'normal scheme-mode-map (kbd "<leader>h") 'geiser-doc-symbol-at-point)

;; emacs-sly
;; "tools lisp"
(evil-define-key 'normal 'global (kbd "<leader>tl") 'sly)
(evil-define-key 'visual sly-mode-map (kbd "<leader>e") 'sly-eval-region)
(evil-define-key 'normal sly-mode-map (kbd "<leader>e") 'sly-eval-last-expression)
(evil-define-key 'normal sly-mode-map (kbd "<leader>h") 'sly-documentation)
;; Fix annoying thing in sly repl.
(evil-define-key 'insert sly-mode-map (kbd ",") 'self-insert-command)

;; emacs-youtube-dl


;; emacs-evil-*something about parenthesis*


A laptop/emacs/instructions => laptop/emacs/instructions +11 -0
@@ 0,0 1,11 @@
Troubleshooting init
--------------------

https://www.emacswiki.org/emacs/InitFile
M-x describe-variable RET user-init-file RET

"No such file or directory, /home/ilmu/.guix-profile/share/emacs/site-lisp"
Solution is to check $EMACSLOADPATH exporting it with only the /run/current-system/... path.




A laptop/stumpwm/commands.lisp => laptop/stumpwm/commands.lisp +124 -0
@@ 0,0 1,124 @@
#| QUESTLOG

Commands I want:
----------------
Name window so that s-e (query stack) becomes useful (currently shows bash,bash,bash..)
Open emacs with stumpwm config file $FILE
Open emacs with sly repl into stumpwm
Chaining commands sequentially             :~: (run-commands cmd1 cmd2 ...)
Query layout left/right/top/down
Switch modes (rebind *top-map*)
Intercept unmodified keys by rebinding in *top-map*
Split frame, close split
Move window between frames and create / close splits as necessary
Move windows in frame to other group
Summon windows from frame in other group as new split (so the stack abstraction)
Name windows / name frames / name groups
Serialize and load / unload for various state
API for datalisp (maybe via swank thread)
|#


;; queries : check whether layout offers motion or if split is required

;; check-window
;; move-focus direction
;; check-window -> (if same (progn split (move-window direct))
;;                          (progn (fprev) ;; moves selection to previous
;;                                 (move-window direction)))


;; splits : make necessary split to perform motion given query
;; NOTE use exchange-windows in direction of split == moving window with split.
;; NOTE not needed since the internals don't have to send window when splitting

;; only :~: removes all splits.
;; remove-split
;; hsplit  (-equally -uniformly)  | These are rewritten to split in hjkl-like
;; vsplit                         | directions. see internals.lisp for details.

;; motions : package queries and splits into useful actions

#|
;; all of these require sb-thread. may fail with earlier bug
;; see https://config.phundrak.com/stumpwm.html
(defcommand term (&optional program) ()
  "Invoke a terminal, possibly with a @arg{program}."
  (sb-thread:make-thread
   (lambda ()
     (run-shell-command (if program
			    (format nil "kitty ~A" program)
			    "kitty")))))

(defcommand sly-start-server (port) ((:string "Port number: "))
  "Start a slynk server for sly."
  (sb-thread:make-thread (lambda () (slynk:create-server :port (parse-integer port)
							 :dont-close t))))

(defcommand sly-stop-server (port) ((:string "Port number: "))
  "Stop current slynk server for sly."
  (sb-thread:make-thread (lambda () (slynk:stop-server (parse-integer port)))))
|#
(defcommand window-send-clipboard () ()
  (window-send-string (get-x-selection)))

;; FIXME: make interactive by echoing selection and doing y-or-n-p.
(defcommand eval-selection () () 
  (eval-line (get-x-selection)))

#| NAVIGATION

The idea is that you have stacks of windows inside frames.
You can move focus between frames and then flip through the windows of the frame.
You can also take the window on top with you as you move the focus, if you do then
new frames will be made as necessary by splitting in the desired direction.

Finally, if you move a window from a frame so that the frame becomes empty then
the split will be closed and the frame collapsed.

The idea here is that you can easily rearrange the desktop if you have few
windows in total or a main stack that you split off-of to work.

Groups are only used to send and receive stacks of windows (frames) that are
not required in the current context (group).

The group > frame > window organization can be subverted in future by menus
and tags. Then you can use a hook when switching groups to move windows into
frames on newly active group which are "shared memory" and should also be in
that group. Ideally very few commands are needed for navigation and these
concepts can be avoided by user who just opens, closes and rearranges windows.
|#

(defcommand (dirsplit tile-group) (dir) ((:direction "Direction: "))
"Split the current frame into 2 frames in the desired direction."
  (split-frame-in-dir (current-group) dir 1/2))

#| Case analysis

Last window -> If move in valid direction: close split, otherwise: noop.
Not last window -> If move in invalid direction: open split and move-window, otherwise: move-window.

|#

(defcommand (move tile-group) (dir) ((:direction "Direction: "))
  "Split the frame if necessary to move in direction. Closes split if it leaves empty frame."
  (if (detect-last-window (current-group))
      (unless (detect-monitor-edge (current-group) dir)
	(let ((last-frame (tile-group-current-frame (current-group))))
	  (move-window dir)
	  (remove-split (current-group) last-frame)))
      (progn
	(when (detect-monitor-edge (current-group) dir)
	  (dirsplit dir))
	(move-window dir))))

;; such a soup of accessors, find some simple example to work from... really need repl!
;;( (frame-windows (current-group) (tile-group-current-frame (current-group)))

;; scraps

                     ;; args 
(defcommand dump-top-map () () ;; interactive args
  (with-open-file (s (append-to-path *data-dir* "top-map.sexp") :direction :output)))



A laptop/stumpwm/config => laptop/stumpwm/config +41 -0
@@ 0,0 1,41 @@
(in-package :stumpwm)

;; utils

(defun show-config-pathname (filename)
  (uiop:xdg-config-home #p"stumpwm/" filename))

(defun load-config-file (file)
  (load (show-config-pathname file)))

#| REGARDING CACHE DIRECTORY
~/.cache is less permanent data, should be recoverable if it is destroyed.
~/.local/share is XDG_DATA_HOME by default, this data is not as transient.
|#

(defun show-cache-pathname (filename)
  (uiop:xdg-data-home #p"stumpwm/" filename))


;; init

(require :ttf-fonts)
(setf *data-dir* (show-cache-pathname ""))
(setf xft:*font-dirs* '("/run/current-system/profile/share/fonts/"))
(setf clx-truetype:+font-cache-filename+ (concat (getenv "HOME") "/.fonts/font-cache.sexp"))
(xft:cache-fonts)
(set-font (make-instance 'xft:font :family "DejaVu Sans Mono" :subfamily "Book" :size 11))


;; TODO: causal relation between keyboard options in guix system config and key-bindings in stump
;;       will be kept track of in the datalisp template logic that generates the configuration file.

(load-config-file "internals.lisp") ;; patches to stump core, useful for commands.
(load-config-file "commands.lisp")  ;; define various commands that can be bound.
(load-config-file "keymaps.lisp")   ;; bind commands to keys in keymaps to interact.

#| bind keys to *root-map* for C-t prefixed commands and *top-map* for unprefixed commands.
(stumpwm:define-key stumpwm:*root-map* (stumpwm:kbd "u") "exec kitty")
|#



A laptop/stumpwm/internals.lisp => laptop/stumpwm/internals.lisp +134 -0
@@ 0,0 1,134 @@
#| INTERNALS

These things are basically bug reports to the stump core.

A real solution would rewrite the internals rather than hack around it like this.

|#



;; splitting functions

(defun split-frame-dir (group dir ratio)
  "Return 2 new frames. The first one stealing P's number and window"
  (let* ((p  (tile-group-current-frame group))
	 (w (if (or (eq dir :left)
		    (eq dir :right))
		(ratio-or-pixel (frame-width p) ratio)
		(frame-width p)))
         (h (if (or (eq dir :up)
		    (eq dir :down))
		(ratio-or-pixel (frame-height p) ratio)
		(frame-height p)))
	 (x (if (eq dir :right)
		(+ (frame-x p) w)
		(frame-x p)))
	 (y (if (eq dir :down)
		(+ (frame-y p) h)
		(frame-y p)))
	 (wh (if (or (eq dir :left)
		     (eq dir :right))
		 (cons (- (frame-width p) w) h)
		 (cons w (- (frame-height p) h))))
	 (f (make-frame :number (find-free-frame-number group)
			:x x
			:y y
			:width (car wh)
			:height (cdr wh)
			:window nil)))
    ;; adjust the parameters of parent frame
    (setf (frame-width p) w
	  (frame-height p) h)
    (when (eq dir :up)
      (setf (frame-y p) (+ (frame-y p) h)))
    (when (eq dir :left)
      (setf (frame-x p) (+ (frame-x p) w)))
    ;; bureaucracy
    (run-hook-with-args *new-frame-hook* f)
    (if (or (eq dir :up) (eq dir :left))
	(run-hook-with-args *split-frame-hook* p f p)
	(run-hook-with-args *split-frame-hook* p p f))
    (values p f)))

(defun split-frame (group dir &optional (ratio 1/2))
  "Split the current frame into 2 frames. Return new frame number, if
it succeeded. NIL otherwise. RATIO is a fraction of the screen to
allocate to the new split window. If ratio is an integer then the
number of pixels will be used. This can be handy to setup the
desktop when starting."
  (check-type dir (member :row :column :up :down :right :left))
  (let* ((frame (tile-group-current-frame group))
         (head (frame-head group frame)))
    ;; backwards compat
    (when (eq dir :row)     (setf dir :right))
    (when (eq dir :column)  (setf dir :down))
    ;; don't create frames smaller than the minimum size
    (when (or (and (member dir '(:up :down))
		   (>= (frame-height frame) (* *min-frame-height* 2)))
	      (and (member dir '(:left :right))
		   (>= (frame-width frame) (* *min-frame-width* 2))))
      (multiple-value-bind (f1 f2) (split-frame-dir group dir ratio)
	;; swap f1 and f2 when we insert new window above or before old window
	(when (or (eq dir :left) (eq dir :up)) (rotatef f1 f2))
	(setf (tile-group-frame-head group head)
		 (if (atom (tile-group-frame-head group head))
		     (list f1 f2)
		     (funcall-on-node (tile-group-frame-head group head)
				      (lambda (tree)                                                         
					(substitute (list f1 f2) frame tree))                                
				      (lambda (tree)
					(unless (atom tree)
					  (find frame tree))))))
	;; undo swap, the windows stay in the resized parent window
	(when (or (eq dir :left) (eq dir :up)) (rotatef f1 f2))
	(migrate-frame-windows group frame f1)
	;; NOTE: this default is noisy for my intended purposes
	;; (choose-new-frame-window f2 group) ;; moves a window to new frame
	(when (eq frame (tile-group-current-frame group))
	  (setf (tile-group-current-frame group) f1))
	(setf (tile-group-last-frame group) f2)
	(sync-frame-windows group f1)
	(sync-frame-windows group f2)
	;; we also need to show the window we moved to the new frame (if we did)
	(when (frame-window f2)
	  (unhide-window (frame-window f2)))
	(frame-number f2)))))

    
(defun split-frame-in-dir (group dir &optional (ratio 1/2))
  (let ((f (tile-group-current-frame group)))
    (if (split-frame group dir ratio)
        (progn
          (when (frame-window f)
            (update-decoration (frame-window f)))
          (show-frame-indicator group))
        (message "Cannot split smaller than minimum size."))))  


;; query functions

(defun detect-monitor-edge (group direction)
  "Checks if there is a frame in the given direction"
  (let ((frame (tile-group-current-frame group)))
    (move-focus direction)
    (if (eq (frame-number frame)
	    (frame-number (tile-group-current-frame group)))
	t
	(progn
	  (fselect frame)
	  nil))))

(defun detect-last-window (group &optional (frame nil))
  "Checks if the current frame has only one window"
  (unless frame (setf frame (tile-group-current-frame (current-group))))
  (= 1 (length (frame-windows (current-group) frame))))

(defun detect-empty-frame (group &optional (frame nil))
  "Checks if the current frame has only one window"
  (unless frame (setf frame (tile-group-current-frame (current-group))))
  (= 0 (length (frame-windows (current-group) frame))))

(defcommand test-detection () ()
  (when (detect-monitor-edge (current-group) :up)
    (echo "something")))

A laptop/stumpwm/keymaps.lisp => laptop/stumpwm/keymaps.lisp +102 -0
@@ 0,0 1,102 @@
#| Keymaps

The top map with caps lock (hyper) allows launching and traversing windows.
A mode switch gives access to rearranging and resizing frames / windows.
Menus are used to access niche or bulk behaviours as well as catalogue windows.
Groups are largely ignored (by user) in favour of menus, they are "window RAM".

There are various modes that can be switched to or accessed via prefix:
- rearrange  : commands for moving windows defined in commands.lisp also has resize cmds from stump src.
- meta       : datalisp interop, useful for naming, exporting, importing, launching and documenting.
- commands   : default *root-map* not useful since all useful commands will be accessible via other binds.

FIXME: NOTES REGARDING CURRENT MACHINE

H- doesn't work! FIXME!!
M- is Alt_L or Alt_R
S- is shift! remember that!
s- is windows key and caps via guix config.

TODO: List all actions I need

|#

;; ROOT MAP
(define-key *root-map* (kbd "u") "exec chromium")
(define-key *root-map* (kbd "z") "exec xterm") ;; kitty needs opengl

;; TOP MAP - META = MODIFY
(define-key *top-map* (kbd "M-e") "eval-selection") ;; fixme
(define-key *top-map* (kbd "M-n") "gnew")
(define-key *top-map* (kbd "M-w") "pull-from-windowlist")
(define-key *top-map* (kbd "M-Up") "gnext")
(define-key *top-map* (kbd "M-Down") "gprev")
(define-key *top-map* (kbd "M-h") "move left")
(define-key *top-map* (kbd "M-l") "move right")
(define-key *top-map* (kbd "M-j") "move down")
(define-key *top-map* (kbd "M-k") "move up")

;; TOP MAP - SUPER = TRAVERSE
(define-key *top-map* (kbd "s-z") "exec xterm") ;; kitty needs opengl
(define-key *top-map* (kbd "s-x") "exec")
(define-key *top-map* (kbd "s-c") "colon")
(define-key *top-map* (kbd "s-f") "fullscreen")
(define-key *top-map* (kbd "s-Up") "gnext")
(define-key *top-map* (kbd "s-Down") "gprev")
(define-key *top-map* (kbd "s-e") "echo-frame-windows")
(define-key *top-map* (kbd "s-b") "prev-in-frame")
(define-key *top-map* (kbd "s-n") "next-in-frame")
(define-key *top-map* (kbd "s-h") "move-focus left")
(define-key *top-map* (kbd "s-l") "move-focus right")
(define-key *top-map* (kbd "s-j") "move-focus down")
(define-key *top-map* (kbd "s-k") "move-focus up")
(define-key *top-map* (kbd "s-H") "move left")
(define-key *top-map* (kbd "s-L") "move right")
(define-key *top-map* (kbd "s-J") "move down")
(define-key *top-map* (kbd "s-K") "move up")

#| REARRANGE MODE

Ideally I could use a,s,d,f,q,w,e,r as modifiers for hjkl while in the mode.

a: 
s: move with split even if not at screen edge
d: delete the split and move entire frame with focus (same as if only one window was in frame when moving)
f: float window and move it as if being dragged around by the mouse, single tap f would cycle focus of floating
q: query focus for context and open results in frame direction from focus. (or query for relation to frame dir)
w: window moves with focus (same as shift would do I suppose)
e: entire frame moves with focus, swaps frames rather than deleting splits like d does.
r: resize focused window

(define-interactive-keymap (rearrange tile-group) (:on-enter #'enter-rearrange-mode
						   :on-exit #'exit-rearrange-mode
						   :abort-if #'abort-rearrange-mode-p)
  ((kbd "k") "move window up somehow")
  ...)
|#

;; TODO: META MODE
;;       once tala works.

#| deprecated in favour of define-interactive-keymap macro

;; structure of command-mode switch in stump

(defun rearrange-mode-start-message ()
  (message "Press q to exit rearrange-mode."))
(defun rearrange-mode-end-message ()
  (message "Exited rearrange mode"))

(defvar *rearrange-mode-start-hook* '(rearrange-mode-start-message)
  "A hook callled whenever rearrange mode is started")
(defvar *rearrange-mode-end-hook* '(rearrange-mode-end-message)
  "A hook called whenever rearrange mode is ended")

(defcommand rearrange-mode () ()
  "Rearrange mode allows you to invoke StumpWM commands, without prefix, to rearrange windows
   by opening or closing splits as necessary for the frames to contain the moving window in
   relation to all other windows. To exit command mode, type @key{q}."
  (run-hook *rearrange-mode-start-hook*)
  (push-top-map *rearrange-map*))

|#

A laptop/stumpwm/swank.lisp => laptop/stumpwm/swank.lisp +11 -0
@@ 0,0 1,11 @@
;; credit https://github.com/kitnil/dotfiles/blob/c247e7a3cab9b7159fad1f37fab6c0e36d0ba21b/dot_stumpwm.d/swank.lisp

(require :slynk)

(defcommand slynk (port) ((:string "Port number: "))
  (sb-thread:make-thread
   (lambda ()
     (let ((slynk:*loopback-interface* "127.0.0.1"))
       (slynk:create-server :port (parse-integer port)
                            :dont-close t)))
   :name "slynk"))