Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
5.1 KiB

  1. ;;; docker-volume.el --- Emacs interface to docker-volume -*- lexical-binding: t -*-
  2. ;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
  3. ;; This file is NOT part of GNU Emacs.
  4. ;; This program is free software; you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation; either version 3, or (at your option)
  7. ;; any later version.
  8. ;;
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;;
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  16. ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. ;; Boston, MA 02110-1301, USA.
  18. ;;; Commentary:
  19. ;;; Code:
  20. (require 's)
  21. (require 'dash)
  22. (require 'json)
  23. (require 'tablist)
  24. (require 'magit-popup)
  25. (require 'docker-group)
  26. (require 'docker-process)
  27. (require 'docker-utils)
  28. (defgroup docker-volume nil
  29. "Docker volume customization group."
  30. :group 'docker)
  31. (defcustom docker-volume-default-sort-key '("Driver" . nil)
  32. "Sort key for docker volumes.
  33. This should be a cons cell (NAME . FLIP) where
  34. NAME is a string matching one of the column names
  35. and FLIP is a boolean to specify the sort order."
  36. :group 'docker-volume
  37. :type '(cons (choice (const "Driver")
  38. (const "Name"))
  39. (choice (const :tag "Ascending" nil)
  40. (const :tag "Descending" t))))
  41. (defun docker-volume-parse (line)
  42. "Convert a LINE from \"docker volume ls\" to a `tabulated-list-entries' entry."
  43. (condition-case nil
  44. (let ((data (json-read-from-string line)))
  45. (list (aref data 1) data))
  46. (json-readtable-error
  47. (error "Could not read following string as json:\n%s" line))))
  48. (defun docker-volume-entries ()
  49. "Return the docker volumes data for `tabulated-list-entries'."
  50. (let* ((fmt (if (docker-utils-podman-p) "json" "[{{json .Driver}},{{json .Name}}]"))
  51. (data (docker-run "volume ls" docker-volume-ls-arguments (format "--format=\"%s\"" fmt)))
  52. (lines (s-split "\n" data t)))
  53. (-map #'docker-volume-parse lines)))
  54. (defun docker-volume-refresh ()
  55. "Refresh the volumes list."
  56. (setq tabulated-list-entries (docker-volume-entries)))
  57. (defun docker-volume-read-name ()
  58. "Read a volume name."
  59. (completing-read "Volume: " (-map #'car (docker-volume-entries))))
  60. ;;;###autoload
  61. (defun docker-volume-dired (name)
  62. "Enter `dired' in the volume named NAME."
  63. (interactive (list (docker-volume-read-name)))
  64. (let ((path (docker-run "inspect" "-f" "\"{{ .Mountpoint }}\"" name)))
  65. (dired (format "/sudo::%s" path))))
  66. ;;;###autoload
  67. (defun docker-volume-rm (name)
  68. "Destroy the volume named NAME."
  69. (interactive (list (docker-volume-read-name)))
  70. (docker-run "volume rm" name))
  71. (defun docker-volume-dired-selection ()
  72. "Run `docker-volume-dired' on the volumes selection."
  73. (interactive)
  74. (docker-utils-select-if-empty)
  75. (--each (docker-utils-get-marked-items-ids)
  76. (docker-volume-dired it)))
  77. (defun docker-volume-rm-selection ()
  78. "Run \"docker volume rm\" on the volumes selection."
  79. (interactive)
  80. (--each (docker-utils-get-marked-items-ids)
  81. (docker-run "volume rm" it))
  82. (tablist-revert))
  83. (magit-define-popup docker-volume-ls-popup
  84. "Popup for listing volumes."
  85. 'docker-volume
  86. :man-page "docker-volume-ls"
  87. :options '((?f "Filter" "--filter "))
  88. :actions `((?l "List" ,(docker-utils-set-then-call 'docker-volume-ls-arguments 'tablist-revert))))
  89. (magit-define-popup docker-volume-rm-popup
  90. "Popup for removing volumes."
  91. 'docker-volume
  92. :man-page "docker-volume-rm"
  93. :actions '((?D "Remove" docker-volume-rm-selection))
  94. :setup-function #'docker-utils-setup-popup)
  95. (magit-define-popup docker-volume-help-popup
  96. "Help popup for docker volumes."
  97. 'docker-volume
  98. :actions '("Docker volumes help"
  99. (?D "Remove" docker-volume-rm-popup)
  100. (?d "Dired" docker-volume-dired-selection)
  101. (?l "List" docker-volume-ls-popup)))
  102. (defvar docker-volume-mode-map
  103. (let ((map (make-sparse-keymap)))
  104. (define-key map "?" 'docker-volume-help-popup)
  105. (define-key map "D" 'docker-volume-rm-popup)
  106. (define-key map "d" 'docker-volume-dired-selection)
  107. (define-key map "l" 'docker-volume-ls-popup)
  108. map)
  109. "Keymap for `docker-volume-mode'.")
  110. ;;;###autoload
  111. (defun docker-volumes ()
  112. "List docker volumes."
  113. (interactive)
  114. (docker-utils-pop-to-buffer "*docker-volumes*")
  115. (docker-volume-mode)
  116. (tablist-revert))
  117. (define-derived-mode docker-volume-mode tabulated-list-mode "Volumes Menu"
  118. "Major mode for handling a list of docker volumes."
  119. (setq tabulated-list-format [("Driver" 10 t)("Name" 10 t)])
  120. (setq tabulated-list-padding 2)
  121. (setq tabulated-list-sort-key docker-volume-default-sort-key)
  122. (add-hook 'tabulated-list-revert-hook 'docker-volume-refresh nil t)
  123. (tabulated-list-init-header)
  124. (tablist-minor-mode))
  125. (provide 'docker-volume)
  126. ;;; docker-volume.el ends here