Skip to content

Commit 4625d3a

Browse files
committed
home: Throw the burden of setting up dwl-guile to an init script
1 parent d9c4db3 commit 4625d3a

File tree

3 files changed

+184
-3
lines changed

3 files changed

+184
-3
lines changed

dwl-guile/.config/dwl-guile/init.scm

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
;; Sets a list of options and their corresponding values,
2+
;; automatically quoting each option, transforming it into a symbol.
3+
;; In other words, this can be used just like @code{set}, but without
4+
;; needing to quote each option manually.
5+
6+
;; @example
7+
;; (setq border-px 10
8+
;; border-color \"#00FF00\")
9+
;; @end example
10+
(define-syntax setq-args
11+
(syntax-rules ()
12+
((setq-args)
13+
(syntax-error "Missing arguments to setq"))
14+
((setq-args option)
15+
(syntax-error "Missing value to option in setq"))
16+
((setq-args option exp)
17+
`(option ,exp))
18+
((setq-args option exp rest ...)
19+
(append `(option ,exp) (setq-args rest ...)))))
20+
21+
(define-syntax setq
22+
(syntax-rules ()
23+
((setq)
24+
(syntax-error "Missing arguments to setq"))
25+
((setq option)
26+
(syntax-error "Missing value to option in setq"))
27+
((setq rest ...)
28+
(apply set (setq-args rest ...)))))
29+
30+
(define* (dwl:run-async fn #:optional (callback #f))
31+
"Evalutes FN asynchronously, without blocking the main thread.
32+
CALLBACK will be executed once FN has finished its execution, being
33+
passed the potential return value from FN. If no callback is provided,
34+
the return value will be ignored.
35+
36+
For thread safety, FN should not make use of dwl-guile bindings, although
37+
some bindings can be used without issue, such as @code{dwl:spawn}. Instead,
38+
try to move dwl-guile calls to the callback."
39+
((@ (ice-9 futures) make-future)
40+
(lambda ()
41+
;; This is a really hacky (but easy) solution for ensuring thread safety
42+
;; while still allowing for dwl-guile bindings to be called asynchronously.
43+
;; Essentially, we are executing a shell command from the Guile context
44+
;; in order to send a command to the main thread Guile context, via
45+
;; the Wayland socket. A lot of overhead, but speed is not of great concern
46+
;; when doing async calls (it is still quite fast).
47+
(dwl:spawn dwl:%binary-path "-e" (object->string (callback (fn)))))))
48+
49+
(define* (dwl:start-repl-server)
50+
"Starts a local Guile REPL server, listening on a UNIX socket at path
51+
@path{/tmp/dwl-guile.socket}. This REPL allows you to execute expressions
52+
in the dwl-guile context, just like @code{dwl-guile -e \"<exp\"}, but with
53+
a more user-friendly interface.
54+
55+
The preferred way of connecting to the REPL server is using Geiser in Emacs.
56+
You can connect to the server by calling @code{geiser-connect-local}, and
57+
specifying the UNIX-socket path.
58+
59+
Note that this needs to be explicitly called in order for the REPL server to
60+
be started!
61+
"
62+
(use-modules (system repl server))
63+
64+
;; REPL socket path is dependent on the type of build, i.e. stable or devel.
65+
;; Therefore, this variable is set during the initial configuration load in C.
66+
(define (kill-server)
67+
(when (file-exists? dwl:%repl-socket-path)
68+
(delete-file dwl:%repl-socket-path)
69+
(stop-server-and-clients!)))
70+
71+
(unless (file-exists? dwl:%repl-socket-path)
72+
(begin
73+
(spawn-server (make-unix-domain-server-socket #:path dwl:%repl-socket-path))
74+
(add-hook! dwl:hook-quit kill-server))))
75+
76+
(define* (dwl:list-options)
77+
"Lists all available options that can be configured using the @code{set}
78+
procedure."
79+
(hash-fold
80+
(lambda (key value acc)
81+
;; Discard value since it just contains C-related metadata
82+
(cons key acc))
83+
'()
84+
dwl:%metadata))
85+
86+
(define* (dwl:list-keysyms)
87+
"Lists all available keysyms and their respective keycode that can be used
88+
when binding keys and buttons using the @code{bind} procedure."
89+
(define (iterator key value acc)
90+
(cons `(,key ,value) acc))
91+
92+
(hash-fold iterator
93+
(hash-fold iterator '() dwl:%keycodes)
94+
dwl:%keycodes-mouse))
95+
96+
(define* (dwl:show-options)
97+
"Same as @code{dwl:list-options}, but the list of options are printed
98+
in a readable format."
99+
(for-each
100+
(lambda (option) (display (string-append (symbol->string option) "\n")))
101+
(sort-list (dwl:list-options)
102+
(lambda (x y) (string< (symbol->string x)
103+
(symbol->string y))))))
104+
105+
(define* (dwl:show-keysyms)
106+
"Same as @code{dwl:list-keysyms}, but the list of keysyms are printed
107+
in a readable format."
108+
(for-each
109+
(lambda (pair)
110+
(display (string-append (car pair) " = " (number->string (cadr pair)) "\n")))
111+
(sort-list (dwl:list-keysyms)
112+
(lambda (x y) (< (cadr x) (cadr y))))))
113+
114+
(define* (dwl:set-tty-keys modifiers #:optional (ttys 12))
115+
"Helper procedure for binding all ttys to MODIFIERS + F[1-TTYS]."
116+
(for-each
117+
(lambda (v)
118+
(set-keys (string-append modifiers "-<F" (number->string v) ">") `(dwl:chvt ,v)))
119+
(iota ttys 1)))
120+
121+
(define* (dwl:set-tag-keys view-modifiers move-modifiers #:optional (tags 9))
122+
"Helper procedure for adding bindings for viewing and moving clients to
123+
tags 1-TAGS. The key modifiers used for viewing and moving can be set by
124+
VIEW-MODIFIERS, and MOVE-MODIFIERS, respectively."
125+
(for-each
126+
(lambda (t)
127+
(set-keys (string-append view-modifiers "-" (number->string t)) `(dwl:view ,t)
128+
(string-append move-modifiers "-" (number->string t)) `(dwl:tag ,t)))
129+
(iota tags 1)))
130+
131+
;; Set required options.
132+
;; These can not be inhibited, but they can easily be overridden if needed.
133+
(setq tags (map number->string (iota 9 1)))
134+
135+
;; Define layouts before monitor rules to make sure layout is available.
136+
(set-layouts 'default "[]=" 'dwl:tile)
137+
138+
;; There must be a default monitor rule (i.e. with name == NULL)
139+
(set-monitor-rules '((masters . 1)
140+
(master-factor . 0.55)
141+
(scale . 2)
142+
(transform . TRANSFORM-NORMAL)
143+
(layout . default)))
144+
145+
(set-xkb-rules '((options . "compose:prsc,caps:hyper")))
146+
(load "./keys.scm")

dwl-guile/.config/dwl-guile/keys.scm

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
(dwl:set-tty-keys "C-M")
2+
(dwl:set-tag-keys "s" "s-S")
3+
4+
(set-keys "s-p" '(dwl:spawn "wofi" "--show=run,drun")
5+
"s-<return>" '(dwl:spawn "kitty")
6+
"s-j" '(dwl:focus-stack 1)
7+
"s-k" '(dwl:focus-stack -1)
8+
"s-l" '(dwl:change-master-factor 0.05)
9+
"s-h" '(dwl:change-master-factor -0.05)
10+
"s-<page-up>" '(dwl:change-masters 1)
11+
"s-<page-down>" '(dwl:change-masters -1)
12+
"s-t" '(dwl:cycle-layout 1)
13+
"s-<left>" '(dwl:focus-monitor 'DIRECTION-LEFT)
14+
"s-<right>" '(dwl:focus-monitor 'DIRECTION-RIGHT)
15+
"s-<up>" '(dwl:focus-monitor 'DIRECTION-UP)
16+
"s-<down>" '(dwl:focus-monitor 'DIRECTION-DOWN)
17+
"s-S-<left>" '(dwl:tag-monitor 'DIRECTION-LEFT)
18+
"s-S-<right>" '(dwl:tag-monitor 'DIRECTION-RIGHT)
19+
"s-S-<up>" '(dwl:tag-monitor 'DIRECTION-UP)
20+
"s-S-<down>" '(dwl:tag-monitor 'DIRECTION-DOWN)
21+
"s-q" 'dwl:kill-client
22+
"s-<space>" 'dwl:zoom
23+
"s-<tab>" 'dwl:view
24+
"s-S-0" '(dwl:view 0) ;; 0 will show all tags
25+
"s-f" 'dwl:toggle-fullscreen
26+
"S-s-<space>" 'dwl:toggle-floating
27+
"S-s-<escape>" 'dwl:quit
28+
"<XF86PowerOff>" 'dwl:quit
29+
"s-<mouse-left>" 'dwl:move
30+
"s-<mouse-middle>" 'dwl:toggle-floating
31+
"s-<mouse-right>" 'dwl:resize)

guix-home.scm

+7-3
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@
130130
home-xdg-configuration-files-service-type
131131
`(("kitty/kitty.conf" ,(local-file "kitty/.config/kitty/kitty.conf"))))
132132

133+
(simple-service 'dwl-guile-config
134+
home-xdg-configuration-files-service-type
135+
`(("dwl-guile/keys.scm" ,(local-file "dwl-guile/.config/dwl-guile/keys.scm"))
136+
("dwl-guile/init.scm" ,(local-file "dwl-guile/.config/dwl-guile/init.scm"))))
137+
133138
;; Create and add the dtao-guile home service to your home configuration.
134139
(service home-dtao-guile-service-type
135140
(home-dtao-guile-configuration
@@ -202,7 +207,7 @@
202207
;; dwl:startup-hook in your Guile config.
203208
;;
204209
;; By default, this option is not used.
205-
(startup-command "kitty")
210+
;; (startup-command "kitty <&-")
206211

207212
;; If QT-applications should be rendered natively. Enabled by default.
208213
;; This will set QT_QPA_PLATFORM="wayland-egl" and install
@@ -217,8 +222,7 @@
217222
;; dynamically, without restarting dwl-guile.
218223
(reload-config-on-change? #t)
219224

220-
;; Create a custom configuration for dwl.
221-
(config '((set-xkb-rules '((options . "compose:prsc,caps:hyper")))))))
225+
(config (list '((load "/home/danny/.config/dwl-guile/init.scm"))))))
222226

223227
;; Catch locally installed fonts, also git dotfiles fonts
224228
(simple-service 'additional-fonts-service

0 commit comments

Comments
 (0)