#!/usr/bin/env -S emacs -x ;; -*- lexical-binding: t; -*- (require 'cl-lib) (require 'dbus) (defconst connection-type-symbol-map '((:none . "󰈂 ") ;; no connection (:vpn . "󰖂 ") (:wifi . "󰖩 ") (:wired . "󰈁 ")) "Association list mapping connection types to their icons.") (defun connection-type (path) "Get the connection type for the active connection at PATH." ;; if the path is stale, just ignore it (ignore-error dbus-error (let ((type-string (dbus-get-property :system "org.freedesktop.NetworkManager" path "org.freedesktop.NetworkManager.Connection.Active" "Type"))) (cond ((equal type-string "wireguard") :vpn) ((string-suffix-p "wireless" type-string) :wifi) ((string-suffix-p "ethernet" type-string) :wired))))) (defun print-status-for-connection-types (conn-types) "Write a status message for the connections in CONN-TYPES." (princ (if (null conn-types) (alist-get :none connection-type-symbol-map) (mapconcat #'(lambda (type) (alist-get type connection-type-symbol-map)) conn-types))) (terpri) (flush-standard-output)) (defun process-connection-list (connections) "Process a list of paths to active connections." (print-status-for-connection-types (cl-loop for path in connections for type = (connection-type path) when type collect type))) (defun list-active-connections () "Return a list of paths to active NetworkManager connections." (dbus-get-property :system "org.freedesktop.NetworkManager" "/org/freedesktop/NetworkManager" "org.freedesktop.NetworkManager" "ActiveConnections")) (defun handler (_interface-name changed-properties _invalidated-properties) "Handler for property changes on NetworkManager." (dolist (property changed-properties) (when (equal (car property) "ActiveConnections") ;; the actual passed value may be stale (process-connection-list (list-active-connections))))) (dbus-register-signal :system "org.freedesktop.NetworkManager" ;; service "/org/freedesktop/NetworkManager" ;; path "org.freedesktop.DBus.Properties" ;; interface "PropertiesChanged" ;; signal #'handler) ;; print initial connection list (process-connection-list (list-active-connections)) (while t (let ((event (read-event))) (when (ignore-error dbus-error (dbus-check-event event)) (dbus-handle-event event)))) ;; Local Variables: ;; flycheck-disabled-checkers: (emacs-lisp-checkdoc) ;; End: