(format-prompt prompt default) nil nil nil nil
'kubed-container-images-history default))
+(defvar kubed-command-line-completion-cache nil)
+
(defun kubed-command-line-completion-table (s p a)
"Completion table for `kubectl' command lines.
"")))
cands)))))
(let* ((lines
- (apply #'process-lines-ignore-status
- kubed-kubectl-executable "__complete"
- (let ((args (cdr (split-string-and-unquote s))))
- (if (string-suffix-p " " s)
- (nconc args '(""))
- args))))
+ (cdr
+ (if (string= s (car kubed-command-line-completion-cache))
+ kubed-command-line-completion-cache
+ (setq
+ kubed-command-line-completion-cache
+ (cons s
+ (apply #'process-lines-ignore-status
+ kubed-kubectl-executable "__complete"
+ (let ((args (cdr (split-string-and-unquote s))))
+ (if (string-suffix-p " " s)
+ (nconc args '(""))
+ args))))))))
(code nil)
(comps (seq-take-while
(lambda (line)
(setq code (string-to-number
(match-string 1 line))))))
lines)))
- (when (and code (not (zerop code)))
- (if (zerop (logand #b1001 code))
+ ;; `code' encodes "completion directives", as follows:
+ ;; #b000001: An error occurred, ignore completions.
+ ;; #b000010: Don't add space after completion.
+ ;; #b000100: Don't fall back to file completion.
+ ;; #b001000: Completions are really file extension filters.
+ ;; #b010000: Complete directory names.
+ ;; #b100000: Preserve completions order.
+ (when (and code (zerop (logand 1 code)))
+ ;; Error bit in unset, proceed.
+ (if (= #b100 (logand #b100 code))
+ ;; No file name completion.
(if (eq (car-safe a) 'boundaries)
- `(boundaries ,start . ,(and (string-match "[[:space:]=]" (cdr a))
- (match-beginning 0)))
- (let ((table (mapcar
- (lambda (comp)
- (pcase (split-string comp "\t" t)
- (`(,c ,a . ,_)
- (propertize c 'kubed-command-line-argument-description
- (car (split-string a "\\." t))))
- (`(,c . ,_) c)))
- comps)))
+ `(boundaries
+ ,start . ,(and (string-match "[[:space:]=]" (cdr a))
+ (match-beginning 0)))
+ (let ((table
+ (mapcar
+ ;; Annotate completion candidates.
+ (lambda (comp)
+ (pcase (split-string comp "\t" t)
+ (`(,c ,d . ,_)
+ (propertize
+ c 'kubed-command-line-argument-description
+ ;; Only keep first sentence.
+ (car (split-string d "\\." t))))
+ (`(,c . ,_) c)))
+ comps)))
(if a (complete-with-action a table (substring s start) p)
;; `try-completion'.
(let ((comp (complete-with-action a table (substring s start) p)))
(if (stringp comp) (concat (substring s 0 start) comp) comp)))))
- ;; File name completion. `comps' are valid extensions.
- (setq p (lambda (f)
+ ;; File name completion.
+ (setq p
+ (cond
+ ((= #b1000 (logand #b1000 code))
+ ;; `comps' are valid extensions.
+ (lambda (f)
(or (file-directory-p f)
(when (string-match "\\.[^.]*\\'" f)
(member (substring f (1+ (match-beginning 0)))
comps)))))
+ ((= #b10000 (logand #b10000 code))
+ ;; Directory name completion.
+ #'file-directory-p)))
(if (eq (car-safe a) 'boundaries)
;; Find nested boundaries.
(let* ((suf (cdr a))
Interactively, prompt for COMMAND with completion for `kubectl' arguments."
(interactive
(list (completing-read "Command: " #'kubed-command-line-completion-table
- nil nil "kubectl " 'kubed-kubectl-command-history)))
+ nil nil (concat kubed-kubectl-executable " ")
+ 'kubed-kubectl-command-history)))
(shell-command command))
;;;###autoload (autoload 'kubed-prefix-map "kubed" nil t 'keymap)