;; REVIEW: Fix auto-mode: https://gitlab.com/emacs-guix/emacs-guix/issues/3. (setq auto-mode-alist (delete '("/tmp/guix-build-\\(?:[-+._[:alnum:]]+\\)+\\.drv-[[:digit:]]+/environment-variables\\'" . guix-env-var-mode) auto-mode-alist)) ;; REVIEW: Implement guix-store: https://gitlab.com/emacs-guix/emacs-guix/issues/2. (require 'bui) (require 'cl-lib) (require 'guix-prettify) (defun guix-store-prettify-path (path) (replace-regexp-in-string guix-prettify-regexp "/…" path)) (defun guix-store-kill-items () "Delete marked items." (interactive) (let ((paths (or (bui-list-get-marked-id-list) (list (bui-list-current-id))))) (when (yes-or-no-p (format "Delete %s? " (mapconcat 'guix-store-prettify-path paths" "))) (apply 'call-process "guix" nil nil nil "gc" "--delete" paths) (setq guix-store-cache (seq-difference guix-store-cache paths (lambda (item path) (string= (guix-store-item-path item) path)))) (let ((old-point (point))) (revert-buffer nil t) (goto-char old-point))))) (defvar guix-store-cache nil) (cl-defstruct guix-store-item path status size) (defun guix-store-item->entry (item) `((id . ,(guix-store-item-path item)) (path . ,(guix-store-item-path item)) (status . ,(guix-store-item-status item)) (size . ,(guix-store-item-size item)))) (defun guix-store-build-cache (&optional live) "If LIVE is non-nil, cache live items instead." (message "Caching Guix store items...") (let (cache paths) (with-temp-buffer (call-process "guix" nil t nil "gc" (if live "--list-live" "--list-dead")) (goto-char (point-min)) ;; Skip status lines. (forward-line 2) (while (not (eobp)) (push (buffer-substring-no-properties (line-beginning-position) (line-end-position)) paths) (forward-line))) (dolist (path paths cache) (with-temp-buffer (call-process "du" nil t nil "-sb" path) (goto-char (point-min)) (push (make-guix-store-item :path path :status (if live 'live 'dead) :size (number-at-point)) cache))))) (defun guix-store-list-sort-items (a b) (let ((pretty-a (guix-store-prettify-path (aref (cadr a) 2))) (pretty-b (guix-store-prettify-path (aref (cadr b) 2)))) (string< pretty-a pretty-b))) (defun guix-store-get-entries () (unless guix-store-cache (setq guix-store-cache (guix-store-build-cache))) (mapcar 'guix-store-item->entry guix-store-cache)) (bui-define-interface guix-store list :buffer-name "*guix store*" :get-entries-function 'guix-store-get-entries :format '((status nil 4 t) (size nil 10 bui-list-sort-numerically-1 :right-align t) (path nil 80 guix-store-list-sort-items)) :sort-key '(size)) (let ((map guix-store-list-mode-map)) (define-key map (kbd "k") 'guix-store-kill-items)) ;;;###autoload (defun guix-store () "Display a list of store items." (interactive) (bui-get-display-entries 'guix-store 'list)) (provide 'patch-guix)