From 319901adb2bb84afa4cd70012f865857fc190ad9 Mon Sep 17 00:00:00 2001 From: Jonathan Jin Date: Fri, 7 Jun 2024 17:40:29 +0100 Subject: [PATCH] kele-list: enable getting owner resource from table (#215) Closes #212. --- docs/how-tos/usage.md | 5 +++ docs/references/changelog.md | 2 + kele.el | 76 +++++++++++++++++++++++++++++++----- tests/unit/test-kele.el | 27 +++++++++++++ 4 files changed, 100 insertions(+), 10 deletions(-) diff --git a/docs/how-tos/usage.md b/docs/how-tos/usage.md index 503539d..88011fa 100644 --- a/docs/how-tos/usage.md +++ b/docs/how-tos/usage.md @@ -93,6 +93,11 @@ separate buffer in a table. From here, you can: separate buffer; - Delete a resource with `k`. +!!! tip + + Hitting `RET` with your cursor on the **Owner(s)** column will open the + **owner resource**. + ### Refreshing a resource You can press `g` in a `kele-get` buffer to re-fetch and refresh the current resource. diff --git a/docs/references/changelog.md b/docs/references/changelog.md index 65e89ef..704cc0e 100644 --- a/docs/references/changelog.md +++ b/docs/references/changelog.md @@ -22,6 +22,8 @@ versioning][semver]. highlighting in resource buffers - Added output to `kele-list` buffers indicating the context - Added additional columns to `kele-list` output, e.g. owner references +- In a `kele-list` table, `RET` now either opens the corresponding resource + **or** the owning resource, depending on cursor position - Added binding `g` for refreshing a `kele-list` buffer ### Fixed diff --git a/kele.el b/kele.el index b8d0f2a..6ceaade 100644 --- a/kele.el +++ b/kele.el @@ -1625,6 +1625,66 @@ prompting and the function simply returns the single option." kind) gvs))))) +(defvar kele--list-context nil + "The context corresponding to the current `kele-list-mode' buffer.") + +(defvar kele--list-gvk nil + "The group-version-kind corresponding to the current `kele-list-mode' buffer.") + +(defun kele--list-get-at-point () + "`kele-get's the current object at point." + (let-alist (vtable-current-object) + (kele-get kele--list-context .metadata.namespace kele--list-gvk .metadata.name))) + +(defun kele-list-table-dwim () + "Run the default action on `kele-list' table entries. + +If the cursor is over an Owner cell, `kele-get' the first owning +resource. + +Otherwise, simply `kele-get' the resource at point." + (interactive nil kele-list-mode) + (let* ((tbl (vtable-current-table)) + (col (vtable-current-column)) + (colname (vtable-column tbl col))) + (if (string-equal colname "Owner(s)") + (let-alist (vtable-current-object) + ;; TODO: Implement selection for multi-owner + (cond ((>= (length .metadata.ownerReferences) 1) + (kele-get + kele--list-context + .metadata.namespace + (kele--gvk-create :kind + (alist-get 'name + (kele--get-discovery-resource + kele--global-discovery-cache + (alist-get 'kind (elt .metadata.ownerReferences 0)) + :lookup-key + 'kind))) + (alist-get 'name (elt .metadata.ownerReferences 0)))) + (t (kele--list-get-at-point)))) + (kele--list-get-at-point)))) + +(defun kele-list-kill () + "Delete the resource at the current line." + (interactive nil kele-list-mode) + (let-alist (vtable-current-object) + (kele-delete + kele--list-context + .metadata.namespace + (kele--gv-string kele--list-gvk) + (oref kele--list-gvk kind) + .metadata.name)) + (vtable-revert-command)) + +(defvar kele-list-table-map + (let ((map (make-sparse-keymap))) + ;; FIXME: Bind `g' to refresh the table **anywhere** the cursor is on the + ;; buffer, not just when hovering over the table itself + (define-key map (kbd "RET") #'kele-list-table-dwim) + (define-key map (kbd "k") #'kele-list-kill) + map)) + (defun kele--make-list-vtable (gvk context namespace) "Construct an interactive vtable listing resources of GVK. @@ -1645,16 +1705,7 @@ serve to further specify the resources to list." (:name "GVK" :width 10 :align left) (:name "Owner(s)" :width 20 :align left) (:name "Created" :width 30 :align left)) - ;; FIXME: Bind `g' to refresh the table **anywhere** the cursor is on the - ;; buffer, not just when hovering over the table itself - :actions - `("RET" (lambda (object) - (let-alist object - (kele-get ,context ,namespace ,gvk .metadata.name))) - "k" (lambda (object) - (let-alist object - (kele-delete ,context ,namespace ,(kele--gv-string gvk) ,(oref gvk kind) .metadata.name) - (vtable-revert-command)))) + :keymap kele-list-table-map :getter (lambda (object column vtable) (let-alist object (pcase (vtable-column vtable column) @@ -1753,6 +1804,11 @@ is not namespaced, returns an error." context namespace)))) (with-current-buffer buf + (setq-local kele--list-context context) + (setq-local kele--list-gvk gvk) + (put 'kele--list-context 'permanent-local t) + (put 'kele--list-gvk 'permanent-local t) + (let ((inhibit-read-only t)) (erase-buffer) (insert "Context: " context "\n") diff --git a/tests/unit/test-kele.el b/tests/unit/test-kele.el index 78f5951..18efcc1 100644 --- a/tests/unit/test-kele.el +++ b/tests/unit/test-kele.el @@ -693,4 +693,31 @@ metadata: (expect (kele--gv-string (kele--gvk-create :group "apps" :version "v1")) :to-equal "apps/v1")))) +(describe "`kele-list-mode' functions" + (before-each + (setq kele-confirm-deletions nil) + (setq kele--list-context "fake-context") + (setq kele--list-gvk (kele--gvk-create + :group "fake-group" + :version "v999" + :kind "fake-kind")) + (spy-on 'vtable-revert-command) + (spy-on 'kele-delete)) + (describe "`kele-list-kill'" + (before-each + (spy-on 'vtable-current-object :and-return-value + '((metadata . ((namespace . "fake-namespace") + (name . "fake-name")))))) + (it "kills the current object" + (kele-list-kill) + (expect 'kele-delete :to-have-been-called-with + "fake-context" + "fake-namespace" + "fake-group/v999" + "fake-kind" + "fake-name")) + (it "refreshes the table" + (kele-list-kill) + (expect 'vtable-revert-command :to-have-been-called)))) + ;;; test-kele.el ends here