diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/eos/jao-borgmatic.el | 148 | 
1 files changed, 148 insertions, 0 deletions
| diff --git a/lib/eos/jao-borgmatic.el b/lib/eos/jao-borgmatic.el new file mode 100644 index 0000000..e9fc79f --- /dev/null +++ b/lib/eos/jao-borgmatic.el @@ -0,0 +1,148 @@ +;;; jao-borgmatic.el --- Simple access to borgmatic  -*- lexical-binding: t; -*- + +;; Copyright (C) 2022  jao + +;; Author: jao <mail@jao.io> +;; Keywords: convenience + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program.  If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; An emacs front-end for borgmatic + +;;; Code: + +(defconst jao-borgmatic--buffer "*borgmatic*") +(defun jao-borgmatic--buffer () +  (get-buffer-create jao-borgmatic--buffer)) + +(defvar jao-borgmatic-extract-path "/tmp/borgmatic") + +(defvar jao-borgmatic-mode-map +  (let ((map (make-keymap))) +    (suppress-keymap map) +    (define-key map [?q] 'bury-buffer) +    (define-key map [?n] 'next-line) +    (define-key map [?p] 'previous-line) +    (define-key map [?g] 'jao-borgmatic-list) +    (define-key map [?x] 'jao-borgmatic-extract) +    (define-key map [?c] 'jao-borgmatic-check) +    map)) + +;;;###autoload +(defun jao-borgmatic-mode () +  "A very simple mode to show the output of borgmatic commands." +  (interactive) +  (kill-all-local-variables) +  (buffer-disable-undo) +  (use-local-map jao-borgmatic-mode-map) +  ;; (setq-local font-lock-defaults '(jao-borgmatic-font-lock-keywords)) +  (setq-local truncate-lines t) +  (setq-local next-line-add-newlines nil) +  (setq major-mode 'jao-bormagtic-mode) +  (setq mode-name "borgmatic") +  (read-only-mode 1)) + +(defun jao-borgmatic--do (things &optional buffer) +  "Execute a borgmatic command THINGS in the given BUFFER." +  (let ((b (or buffer (pop-to-buffer (get-buffer-create jao-borgmatic--buffer))))) +    (let ((inhibit-read-only t) +          (cmd (format "borgmatic %s" things))) +      (unless buffer +        (with-current-buffer b (delete-region (point-min) (point-max)))) +      (message "Running: %s ...." cmd) +      (shell-command cmd b) +      (message "")))) + +(defun jao-borgmatic--archive-at-point () +  (save-excursion +    (beginning-of-line) +    (when (looking-at "- \\([^ ]+\\)") +      (match-string-no-properties 1)))) + +(defvar jao-borgmatic--archive-history nil) +(defvar-local jao-borgmatic--archives nil) + +(defun jao-borgmatic--archives (&optional retrieve) +  (or (and (not retrieve) jao-borgmatic--archives) +      (let ((c (shell-command-to-string +                "borgmatic list --format '{archive}  {time}*'"))) +        (setq jao-borgmatic--archives (cdr (split-string c  "\\*\\|\n")))))) + +(defun jao-borgmatic--read-archive (&optional retrieve) +  (car (split-string (completing-read "Archive: " +                                      (jao-borgmatic--archives retrieve) +                                      nil +                                      nil +                                      nil +                                      'jao-borgmatic--archive-history +                                      (jao-borgmatic--archive-at-point))))) + +;;;###autoload +(defun jao-borgmatic-list () +  (interactive) +  (with-current-buffer (jao-borgmatic--buffer) +    (jao-borgmatic-mode) +    (let ((inhibit-read-only t) +          (archives (with-temp-message "Retrieving archives list..." +                      (jao-borgmatic--archives t)))) +      (delete-region (point-min) (point-max)) +      (insert "Archives: \n\n") +      (dolist (a archives) +        (unless (string-blank-p a) (insert "- " a "\n"))) +      (insert "\n" (with-temp-buffer +                     (jao-borgmatic--do "info" (current-buffer)) +                     (buffer-string))))) +  (pop-to-buffer (jao-borgmatic--buffer)) +  (goto-line 3)) + +(defconst jao-borgmatic--extract-output " *borgmatic-extract output*") + +(defun jao-borgmatic--extract-sentinel (paths) +  (lambda (proc &rest _) +    (when (and (eq (process-status proc) 'exit) +               (y-or-n-p "Borg extraction finished, show?")) +      (if (eq (process-exit-status proc) 0) +          (let ((d (file-name-directory (car paths)))) +            (dired (expand-file-name d jao-borgmatic-extract-path))) +        (pop-to-buffer jao-borgmatic--extract-output))))) + +(defvar jao-borgmatic--extract-history nil) + +;;;###autoload +(defun jao-borgmatic-extract () +  (interactive) +  (let* ((archive (jao-borgmatic--read-archive)) +         (path (read-string "Path(s) (e.g. home/jao/emacs.d/init.el): " +                            nil 'jao-borgmatic--extract-history)) +         (paths (if (string-blank-p path) +                    (not (or (y-or-n-p "Extract the full archive?") +                             (error "Cancelled"))) +                  (split-string path))) +         (default-directory jao-borgmatic-extract-path)) +    (make-directory default-directory t) +    (message "Extracting %s/%s to directory %s in the background" +             archive path default-directory) +    (make-process :name "borgmatic-extract" +                  :buffer jao-borgmatic--extract-output +                  :command (append `("borgmatic" "extract" +                                     "--archive" ,archive +                                     "--destination" ,default-directory) +                                   (when paths (cons "--path" paths))) +                  :sentinel (jao-borgmatic--extract-sentinel paths) +                  :stderr nil))) + +(provide 'jao-borgmatic) +;;; jao-borgmatic.el ends here | 
