[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/kubed 603a4d413a 38/70: Enhance 'kubed-list-read-filter
From: |
ELPA Syncer |
Subject: |
[elpa] externals/kubed 603a4d413a 38/70: Enhance 'kubed-list-read-filter' |
Date: |
Tue, 6 Aug 2024 06:58:29 -0400 (EDT) |
branch: externals/kubed
commit 603a4d413a0aafb498d7e91c89b7d6c164ce5c09
Author: Eshel Yaron <me@eshelyaron.com>
Commit: Eshel Yaron <me@eshelyaron.com>
Enhance 'kubed-list-read-filter'
Add in-minibuffer feedback for invalid filters and completion for
column names and column values.
* kubed.el (kubed-list-validate-atomic-filter)
(kubed-list-validate-filter): Refine validation.
(kubed--list-read-filter-target-buffer): New local var.
(kubed-list-try-read-filter): New command.
(kubed-list-read-filter-map): New keymap.
(kubed-list-read-filter): Use it, add completion support.
---
kubed.el | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 111 insertions(+), 11 deletions(-)
diff --git a/kubed.el b/kubed.el
index ac8bbc798a..793dec02f9 100644
--- a/kubed.el
+++ b/kubed.el
@@ -141,20 +141,35 @@ If FILTER is omitted or nil, it defaults to
`kubed-list-filter'."
(defun kubed-list-validate-atomic-filter (atom)
"Return string explaining why ATOM is invalid, or nil if it is valid."
+ (unless (consp atom)
+ (throw 'validation-error
+ (format (substitute-quotes
+ "Invalid atomic filter `%S', must be a list")
+ atom)))
(if (eq (car-safe atom) 'quote)
(kubed-list-validate-atomic-filter (cadr atom))
- (if (memq (car-safe atom) '(= ~))
- (unless (ignore-errors
- (tabulated-list--column-number (symbol-name (nth 1 atom))))
- (throw 'validation-error (format "Unknown column `%S'" (nth 1
atom))))
- (throw 'validation-error (format "Unknown filter operator `%S'" (car
atom))))))
+ (unless (length= atom 3)
+ (throw 'validation-error
+ (format (substitute-quotes
+ "Invalid atomic filter `%S', must have three elements")
+ atom)))
+ (unless (memq (car atom) '(= ~))
+ (throw 'validation-error
+ (format (substitute-quotes
+ "Invalid filter operator `%S', must be one of `=', `~'")
+ (car atom))))
+ (unless (ignore-errors
+ (tabulated-list--column-number (symbol-name (nth 1 atom))))
+ (throw 'validation-error (format (substitute-quotes
+ "Invalid column name `%S'")
+ (nth 1 atom))))))
(defun kubed-list-validate-filter (filter)
"Return string explaining why FILTER is invalid, or nil if it is valid."
(catch 'validation-error
- (if (listp (car filter))
+ (if (listp (car-safe filter))
(dolist (disjunction filter)
- (if (listp (car disjunction))
+ (if (and (consp disjunction) (listp (car disjunction)))
(dolist (disjunct disjunction)
(kubed-list-validate-atomic-filter disjunct))
(kubed-list-validate-atomic-filter disjunction)))
@@ -163,12 +178,97 @@ If FILTER is omitted or nil, it defaults to
`kubed-list-filter'."
(defvar-local kubed-list-filter-history-variable nil
"History list variable to use for filter history in the current buffer.")
+(defvar-local kubed--list-read-filter-target-buffer nil
+ "Resource list buffer for which this minibuffer is reading a filter.")
+
+(defun kubed-list-try-read-filter ()
+ "Try to read a resource list filter in the minibuffer.
+
+Exit the minibuffer if successful, else report the error and move point
+to the location of the error. If point is not already at the location
+of the error, push a mark before moving point."
+ (interactive "" minibuffer-mode)
+ (let* ((prompt-end (minibuffer-prompt-end))
+ (contents (minibuffer-contents))
+ (error-point nil) (error-message nil) (form nil) (inval nil))
+ (with-temp-buffer
+ (condition-case err
+ (progn
+ ;; FIXME: There is a small edge case here that could get
+ ;; better treatment: when `contents' ends with " ?", it
+ ;; espaces the terminating closing parenthesis and leads us
+ ;; to incorrectly report the input as incomplete.
+ (insert "(" contents ")")
+ (goto-char (point-min))
+ (setq form (read (current-buffer))))
+ (error (setq error-point (+ prompt-end (1- (point)))
+ error-message err))))
+ (cond
+ (error-point
+ (unless (= (point) error-point) (push-mark))
+ (goto-char error-point)
+ (minibuffer-message (error-message-string error-message)))
+ ((setq inval (with-current-buffer kubed--list-read-filter-target-buffer
+ (kubed-list-validate-filter form)))
+ (minibuffer-message inval))
+ (t (exit-minibuffer)))))
+
+(defvar-keymap kubed-list-read-filter-map
+ :parent minibuffer-local-map
+ "TAB" #'completion-at-point
+ "<remap> <exit-minibuffer>" #'kubed-list-try-read-filter)
+
(defun kubed-list-read-filter (prompt)
"Prompt with PROMPT for a filter for the current buffer."
- (let ((filter (read-string
- (format-prompt prompt "disable")
- (mapconcat #'prin1-to-string kubed-list-filter " ")
- kubed-list-filter-history-variable "")))
+ (let* ((buf (current-buffer))
+ (cols (seq-map #'car tabulated-list-format))
+ (vals (let ((tmp nil))
+ (dolist (ent (let ((kubed-list-filter nil))
+ (funcall tabulated-list-entries)))
+ (let ((i 0))
+ (dolist (col cols)
+ (push (aref (cadr ent) i)
+ (alist-get col tmp nil nil #'string=))
+ (setq i (1+ i)))))
+ (mapcar #'delete-dups tmp)))
+ (filter
+ (minibuffer-with-setup-hook
+ (lambda ()
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (setq-local kubed-list-read-filter-target-buffer buf)
+ (add-hook
+ 'completion-at-point-functions
+ (lambda ()
+ (let ((cont (buffer-substring
+ (minibuffer-prompt-end) (point)))
+ (bounds (or (bounds-of-thing-at-point 'symbol)
+ (cons (point) (point)))))
+ (with-temp-buffer
+ (set-syntax-table emacs-lisp-mode-syntax-table)
+ (insert "(" cont)
+ (when-let ((f-a (elisp--fnsym-in-current-sexp))
+ ((car f-a))
+ (a (cadr f-a)))
+ (cond
+ ((= a 1)
+ ;; Complete column names.
+ (list (car bounds) (cdr bounds) cols))
+ ((= a 2)
+ ;; Complete column values.
+ (when-let ((beg (nth 1 (syntax-ppss)))
+ (col (save-excursion
+ (goto-char beg)
+ (forward-char 1)
+ (forward-sexp 2)
+ (thing-at-point 'symbol))))
+ (list (car bounds) (cdr bounds)
+ (alist-get col vals nil nil
#'string=)))))))))
+ nil t))
+ (read-from-minibuffer
+ (format-prompt prompt "disable")
+ (mapconcat #'prin1-to-string kubed-list-filter " ")
+ kubed-list-read-filter-map nil
+ kubed-list-filter-history-variable ""))))
(car (ignore-errors (read-from-string (format "(%s)" filter))))))
(defun kubed-list-set-filter (filter)
- [elpa] externals/kubed 0923d8031a 28/70: ; * kubed.el (kubed-define-resource): Remove extraneous quote., (continued)
- [elpa] externals/kubed 0923d8031a 28/70: ; * kubed.el (kubed-define-resource): Remove extraneous quote., ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 645845fcac 36/70: Add common parent mode for resource lists mode, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 9e1b34f139 45/70: ; * kubed.texi (Browsing Resources): Fix markup., ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 847bc985d0 59/70: New manual section about displaying resources, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed fd3f899d7b 69/70: ; Exclude README.md from ELPA tarball, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed b79802ac85 65/70: ; Add .elpaignore file, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 888f6492f8 62/70: ; Fix population of 'kubed--columns', ELPA Syncer, 2024/08/06
- [elpa] externals/kubed d257fe1ef5 30/70: Bind 'kubed-restart-deployment' in 'kubed-deployment-prefix-map', ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 8463c1bb8a 34/70: Ensure SPC is self-inserting when reading kubectl command line, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed f6ebd33c16 35/70: Use multi-column layout for transient menus, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 603a4d413a 38/70: Enhance 'kubed-list-read-filter',
ELPA Syncer <=
- [elpa] externals/kubed d73c4fac3f 41/70: (kubed-list-read-filter-map): Bind 'completion-help-at-point'., ELPA Syncer, 2024/08/06
- [elpa] externals/kubed ed6d13e196 57/70: New command 'kubed-display-resource-jump-to-list', ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 977ac8d324 61/70: Major cleanup: simplify and extend resource lists, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 51cdf1d100 64/70: ; Update copyright notices for GNU ELPA, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 018d529c3b 33/70: New command 'kubed-transient-rollout', ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 1a6d51981c 02/70: ; * README.md (Getting Started): Fix typo, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed b7227ed155 12/70: ; README.md: Add figure showing pods context menu., ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 9aa3c97dcc 14/70: Extend resource name reading functions with namespace arg, ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 1047609241 26/70: * kubed.texi (Extending Kubed): Populate., ELPA Syncer, 2024/08/06
- [elpa] externals/kubed 667ccdb4a2 27/70: New commands for creating jobs from cronjobs, ELPA Syncer, 2024/08/06