i3-ipc.scm added by sECuRE on Mon Aug 27 22:26:23 2012
(use medea) (use shell) (use srfi-4) (use socket) ;; tell medea to always use lists for arrays, not vectors (json-parsers (alist-update! 'array identity (json-parsers))) (define (i3-socket-path) (string-trim-right (capture "i3 --get-socketpath"))) ;; writes a 32-bit unsigned integer (define (write-u32 val) (write-u8vector (blob->u8vector/shared (u32vector->blob/shared (u32vector val))))) (define (read-u32) (u32vector-ref (blob->u32vector (u8vector->blob (read-u8vector 4))) 0)) (define (i3-format-ipc-message payload type) (with-output-to-string (lambda () (display "i3-ipc") (write-u32 (string-length payload)) (write-u32 type) (display payload)))) (define (i3-command msg #!optional (type 0)) (let ((ipc (socket af/unix sock/stream))) (socket-connect ipc (unix-address (i3-socket-path))) (socket-send-all ipc (i3-format-ipc-message msg type)) (socket-receive ipc (string-length "i3-ipc")) (let* ((reply-length (with-input-from-string (socket-receive ipc 4) (cut read-u32))) (reply-type (with-input-from-string (socket-receive ipc 4) (cut read-u32))) (reply (read-json (socket-receive ipc reply-length)))) (socket-close ipc) reply))) (define (i3-tree) (i3-command "" 4)) (define (i3-workspaces) (i3-command "" 1)) ;; returns the name of the currently focused workspace by filtering ;; the list of workspaces for the one which has focused == true (define (i3-get-focused-workspace-name) (cdr (assoc 'name (find (lambda (ws) (cdr (assoc 'focused ws))) (i3-workspaces))))) (define (i3-containers tree predicate) (if (null? tree) (list) ; what’s idiomatic for empty-list? (append (if (predicate tree) (list tree) (list)) (apply append (filter-map (lambda (node) (i3-containers node predicate)) (cdr (assoc 'nodes tree)))))))