From 379480e6af030dee3d225fa4f76735fa43db36de Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Tue, 22 Feb 2022 18:15:27 -0600 Subject: using readline. implmented editing of oneliners --- src/lib.lisp | 67 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/lib.lisp b/src/lib.lisp index 173b9aa..147e294 100644 --- a/src/lib.lisp +++ b/src/lib.lisp @@ -3,7 +3,8 @@ (defpackage oneliners.cli (:use :cl) (:local-nicknames (#:api #:oneliners.api-client) - (#:a #:alexandria))) + (#:a #:alexandria) + (#:rl #:cl-readline))) (in-package :oneliners.cli) @@ -59,8 +60,9 @@ (namestring (merge-pathnames (format nil "~a" (gensym "oneliners")) (uiop:temporary-directory)))) -(defun string-from-editor () +(defun string-from-editor (&optional contents) (let ((filename (make-temp-file-name))) + (when contents (a:write-string-into-file contents filename :if-exists :supersede)) (unwind-protect (magic-ed:magic-ed filename :eval nil :output :string) (uiop:delete-file-if-exists filename)))) @@ -94,18 +96,27 @@ the directories that appear in the value of that variable." (defun prompt (prompt &key (expect (constantly t)) - retry-text) - - (loop - with prompt-text = prompt - with should-retry-p = t - while should-retry-p - for line = (linedit:linedit :prompt prompt-text) - when (funcall expect line) - do (setf should-retry-p nil) - when retry-text - do (setf prompt-text retry-text) - finally (return line))) + retry-text + (prefill "")) + ;; register a prefil hook + (rl:register-hook + :pre-input + (lambda () + (rl:insert-text prefill) + (rl:redisplay))) + (unwind-protect + (loop + with prompt-text = prompt + with should-retry-p = t + while should-retry-p + for line = (rl:readline :prompt prompt-text) + when (funcall expect line) + do (setf should-retry-p nil) + when retry-text + do (setf prompt-text retry-text) + finally (return line)) + ;; unregisters the hook. + (rl:register-hook :pre-input nil))) (defun cached-result (&optional n) (when (uiop:file-exists-p (last-search-file)) @@ -235,7 +246,8 @@ the directories that appear in the value of that variable." (string-upcase (prompt "Runstyle (auto or manual): " :expect 'valid-runstyle-p - :retry-text "Must be (auto or manual): "))) + :retry-text "Must be (auto or manual): " + :prefill "auto"))) (explanation (when (y-or-n-p "Provide an explanation?") (string-from-editor)))) @@ -258,25 +270,31 @@ the directories that appear in the value of that variable." (let* ((oneliner (prompt "Oneliner: " :expect 'valid-oneliner-string-p - :retry-text "Oneliners must contain at least one command: ")) - (init-tags - (tags-from-oneliner oneliner)) + :retry-text "Oneliners must contain at least one command: " + :prefill (getf ol :oneliner))) (brief (prompt "Brief Description: " :expect 'valid-brief-description-p - :retry-text "Too long. Must be <= 72 characters: ")) + :retry-text "Too long. Must be <= 72 characters: " + :prefill (getf ol :brief))) + (init-tags + (tags-from-oneliner oneliner)) (tags (append init-tags (ppcre:split " +" - (prompt (format nil "Tags in addition to ~{~a ~} ?" init-tags))))) + (prompt (format nil "Tags in addition to ~{~a ~}? " init-tags) + :prefill (str:join " " (set-difference (getf ol :tags) + init-tags + :test 'equal)))))) (runstyle (string-upcase (prompt "Runstyle (auto or manual): " :expect 'valid-runstyle-p - :retry-text "Must be (auto or manual): "))) + :retry-text "Must be (auto or manual): " + :prefill (getf ol :runstyle)))) (explanation (when (y-or-n-p "Provide an explanation?") - (string-from-editor)))) + (string-from-editor (getf ol :explanation))))) (api:request-with (:host (host) :body (jonathan:to-json @@ -287,10 +305,7 @@ the directories that appear in the value of that variable." :runstyle runstyle)) :content-type "application/json") (api:patch--oneliner-entry-edit (getf ol :id) :token (api-token)) - (format t "OK~%"))) - - - )) + (format t "OK~%"))))) (defun request-invite-code () (ensure-config) -- cgit v1.2.3