From a89f5ca015760a2676feeced8d03594ab976e808 Mon Sep 17 00:00:00 2001 From: Aner Zakobar Date: Mon, 11 May 2026 14:50:45 +0300 Subject: [PATCH] Added hl-line externally plus automount --- azos-core | 2 +- modules/home-manager/default.nix | 1 + modules/home-manager/udiskie.nix | 22 +++++++ modules/nixos/default.nix | 2 +- modules/nixos/udisks.nix | 19 ++++++ pkgs/elisp/azos-emacs-lauretta.org | 94 ++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 modules/home-manager/udiskie.nix create mode 100644 modules/nixos/udisks.nix diff --git a/azos-core b/azos-core index 57293e1..d92e5ba 160000 --- a/azos-core +++ b/azos-core @@ -1 +1 @@ -Subproject commit 57293e150c398b78cda25789e980bcb7ae23751a +Subproject commit d92e5ba3443597837bf0eb7452d1364e0e287adc diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix index 2dab3a5..637593a 100755 --- a/modules/home-manager/default.nix +++ b/modules/home-manager/default.nix @@ -19,5 +19,6 @@ ./snx-rs.nix ./ytdl.nix ./nextcloud-client.nix + ./udiskie.nix ]; } diff --git a/modules/home-manager/udiskie.nix b/modules/home-manager/udiskie.nix new file mode 100644 index 0000000..66ed952 --- /dev/null +++ b/modules/home-manager/udiskie.nix @@ -0,0 +1,22 @@ +{ + lib, + config, + pkgs, + ... +}: let + isEnabled = + config.azos.udiskie.enable; +in { + options.azos.udiskie.enable = lib.mkOption { + default = true; + example = true; + type = lib.types.bool; + }; + + config = lib.mkIf isEnabled { + services.udiskie = { + enable = true; + tray = "never"; + }; + }; +} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 5d88243..22c6f7e 100755 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -1,3 +1,3 @@ { - imports = [./audio.nix ./binfmt.nix ./bluetooth.nix ./steam.nix ./virtualization.nix]; + imports = [./audio.nix ./binfmt.nix ./bluetooth.nix ./steam.nix ./udisks.nix ./virtualization.nix]; } diff --git a/modules/nixos/udisks.nix b/modules/nixos/udisks.nix new file mode 100644 index 0000000..4101951 --- /dev/null +++ b/modules/nixos/udisks.nix @@ -0,0 +1,19 @@ +{ + lib, + config, + pkgs, + ... +}: let + isEnabled = + config.azos.udisks.enable; +in { + options.azos.udisks.enable = lib.mkOption { + default = true; + example = true; + type = lib.types.bool; + }; + + config = lib.mkIf isEnabled { + services.udisks2.enable = true; + }; +} diff --git a/pkgs/elisp/azos-emacs-lauretta.org b/pkgs/elisp/azos-emacs-lauretta.org index 7a39f27..156d6eb 100644 --- a/pkgs/elisp/azos-emacs-lauretta.org +++ b/pkgs/elisp/azos-emacs-lauretta.org @@ -46,6 +46,100 @@ (kbd "h") 'azos/connect-headphones) #+end_src +** Storage + +#+begin_src emacs-lisp +(defun azos/storage--lsblk-field (dev field) + "Get FIELD from lsblk DEV hash table." + (when (hash-table-p dev) + (gethash field dev))) + +(defun azos/storage--list-devices () + "Return flat list of partitions/devices from lsblk, with bare disks included." + (let* ((json-str (shell-command-to-string + "lsblk --json -o NAME,SIZE,LABEL,MOUNTPOINT,TYPE")) + (data (condition-case nil (json-parse-string json-str) (error nil))) + (devs '())) + (when (hash-table-p data) + (seq-do + (lambda (dev) + (let ((children (azos/storage--lsblk-field dev "children"))) + (if (and (vectorp children) (> (length children) 0)) + (seq-do (lambda (child) (push child devs)) children) + (push dev devs)))) + (gethash "blockdevices" data))) + (nreverse devs))) + +(defun azos/storage--null-p (val) + "Return t if VAL is a JSON null (i.e. :null)." + (eq val :null)) + +(defun azos/storage--label-str (dev) + "Format label for DEV, returning empty string if absent." + (let ((label (azos/storage--lsblk-field dev "label"))) + (if (and label (not (azos/storage--null-p label))) + (format " [%s]" label) + ""))) + +(defun azos/storage/mount () + "Mount an unmounted block device using udisksctl." + (interactive) + (let* ((devs (azos/storage--list-devices)) + (unmounted (seq-filter + (lambda (d) + (let ((mp (azos/storage--lsblk-field d "mountpoint")) + (type (azos/storage--lsblk-field d "type"))) + (and (member type '("part" "disk")) + (or (null mp) (azos/storage--null-p mp))))) + devs)) + (choices (mapcar + (lambda (d) + (let ((name (azos/storage--lsblk-field d "name")) + (size (azos/storage--lsblk-field d "size"))) + (cons (format "/dev/%s %s%s" name size (azos/storage--label-str d)) + (format "/dev/%s" name)))) + unmounted))) + (if choices + (let* ((selected (completing-read "Mount device: " (mapcar #'car choices) nil t)) + (device (cdr (assoc selected choices)))) + (message "%s" (string-trim + (shell-command-to-string + (format "udisksctl mount -b %s" device))))) + (message "No unmounted partitions found.")))) + +(defun azos/storage/unmount () + "Unmount a mounted block device using udisksctl." + (interactive) + (let* ((devs (azos/storage--list-devices)) + (mounted (seq-filter + (lambda (d) + (let ((mp (azos/storage--lsblk-field d "mountpoint"))) + (and mp + (not (azos/storage--null-p mp)) + (not (string-prefix-p "/nix" mp)) + (not (string-prefix-p "/boot" mp)) + (not (equal mp "/"))))) + devs)) + (choices (mapcar + (lambda (d) + (let ((name (azos/storage--lsblk-field d "name")) + (size (azos/storage--lsblk-field d "size")) + (mp (azos/storage--lsblk-field d "mountpoint"))) + (cons (format "/dev/%s %s -> %s%s" name size mp (azos/storage--label-str d)) + (format "/dev/%s" name)))) + mounted))) + (if choices + (let* ((selected (completing-read "Unmount device: " (mapcar #'car choices) nil t)) + (device (cdr (assoc selected choices)))) + (message "%s" (string-trim + (shell-command-to-string + (format "udisksctl unmount -b %s" device))))) + (message "No mounted user partitions found.")))) + +(define-key azos/global-minor-mode/open-keymap (kbd "s m") 'azos/storage/mount) +(define-key azos/global-minor-mode/open-keymap (kbd "s u") 'azos/storage/unmount) +#+end_src + ** Tab bar setup #+begin_src emacs-lisp