aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Okay <okay@toyful.space>2022-02-22 18:15:27 -0600
committerColin Okay <okay@toyful.space>2022-02-22 18:15:27 -0600
commit379480e6af030dee3d225fa4f76735fa43db36de (patch)
tree9009d0f2846c5c8c8f5506b8f0937905443f47fc
parent6ae6672f8c6c2064fe59893ddb08c31670890dc3 (diff)
using readline. implmented editing of oneliners
-rw-r--r--clpmfile.lock17
-rw-r--r--oneliners.cli.asd3
-rw-r--r--src/lib.lisp67
3 files changed, 50 insertions, 37 deletions
diff --git a/clpmfile.lock b/clpmfile.lock
index e70d3e8..e852e8c 100644
--- a/clpmfile.lock
+++ b/clpmfile.lock
@@ -52,6 +52,8 @@
("cl-cookie" :version "2019-10-07" :source "quicklisp" :systems ("cl-cookie"))
("cl-ppcre" :version "2022-02-20" :source "quicklisp" :systems
("cl-ppcre" "cl-ppcre-unicode"))
+("cl-readline" :version "2021-10-21" :source "quicklisp" :systems
+ ("cl-readline"))
("cl-str" :version "2022-02-20" :source "quicklisp" :systems ("str"))
("cl-syntax" :version "2015-04-07" :source "quicklisp" :systems
("cl-syntax" "cl-syntax-annot"))
@@ -66,7 +68,6 @@
("flexi-streams" :version "2022-02-20" :source "quicklisp" :systems
("flexi-streams"))
("jonathan" :version "2020-09-25" :source "quicklisp" :systems ("jonathan"))
-("linedit" :version "2018-04-30" :source "quicklisp" :systems ("linedit"))
("local-time" :version "2021-01-24" :source "quicklisp" :systems ("local-time"))
("magic-ed" :version "2020-03-25" :source "quicklisp" :systems ("magic-ed"))
("named-readtables" :version "2022-02-20" :source "quicklisp" :systems
@@ -84,7 +85,6 @@
("split-sequence"))
("static-vectors" :version "2021-06-30" :source "quicklisp" :systems
("static-vectors"))
-("terminfo" :version "2021-01-24" :source "quicklisp" :systems ("terminfo"))
("trivial-clipboard" :version "2021-02-28" :source "quicklisp" :systems
("trivial-clipboard"))
("trivial-features" :version "2021-12-09" :source "quicklisp" :systems
@@ -110,10 +110,10 @@
((:system :name "quri") (:system :name "alexandria"))
((:system :name "proc-parse") (:system :name "alexandria"))
((:system :name "osicat") (:system :name "alexandria"))
- ((:system :name "linedit") (:system :name "alexandria"))
((:system :name "fast-io") (:system :name "alexandria"))
((:system :name "fast-http") (:system :name "alexandria"))
((:system :name "dexador") (:system :name "alexandria"))
+ ((:system :name "cl-readline") (:system :name "alexandria"))
((:system :name "cl-cookie") (:system :name "alexandria"))
((:system :name "cl-annot") (:system :name "alexandria"))
((:system :name "cl+ssl") (:system :name "alexandria"))
@@ -138,7 +138,7 @@
((:system :name "osicat") (:system :name "cffi"))
((:system :name "osicat") (:system :name "cffi-grovel"))
((:system :name "net.didierverna.clon.termio") (:system :name "cffi"))
- ((:system :name "linedit") (:system :name "cffi"))
+ ((:system :name "cl-readline") (:system :name "cffi"))
((:system :name "cl+ssl") (:system :name "cffi"))
((:system :name "cffi-toolchain") (:system :name "cffi"))
((:system :name "cffi-grovel") (:system :name "cffi"))
@@ -186,6 +186,8 @@
((:system :name "cl-change-case") (:system :name "cl-ppcre"))
((:system :name "cl-change-case") (:system :name "cl-ppcre-unicode")))
+("cl-readline" ((:system :name "oneliners.cli") (:system :name "cl-readline")))
+
("cl-str" ((:system :name "oneliners.cli") (:system :name "str")))
("cl-syntax" ((:system :name "jonathan") (:system :name "cl-syntax"))
@@ -214,8 +216,6 @@
("jonathan" ((:system :name "oneliners.cli") (:system :name "jonathan")))
-("linedit" ((:system :name "oneliners.cli") (:system :name "linedit")))
-
("local-time" ((:system :name "cl-cookie") (:system :name "local-time")))
("magic-ed" ((:system :name "oneliners.cli") (:system :name "magic-ed")))
@@ -231,8 +231,7 @@
("oneliners.cli.asd" (t (:asd-file :name "oneliners.cli.asd")))
-("osicat" ((:system :name "oneliners.cli") (:system :name "osicat"))
- ((:system :name "linedit") (:system :name "osicat")))
+("osicat" ((:system :name "oneliners.cli") (:system :name "osicat")))
("proc-parse" ((:system :name "jonathan") (:system :name "proc-parse"))
((:system :name "fast-http") (:system :name "proc-parse"))
@@ -248,8 +247,6 @@
("static-vectors" ((:system :name "fast-io") (:system :name "static-vectors")))
-("terminfo" ((:system :name "linedit") (:system :name "terminfo")))
-
("trivial-clipboard"
((:system :name "oneliners.cli") (:system :name "trivial-clipboard")))
diff --git a/oneliners.cli.asd b/oneliners.cli.asd
index c255c1d..d71980c 100644
--- a/oneliners.cli.asd
+++ b/oneliners.cli.asd
@@ -8,7 +8,8 @@
"dexador"
"osicat"
"net.didierverna.clon"
- "linedit"
+ "cl-readline"
+ ;"linedit"
"magic-ed"
"oneliners.api-client")
:components ((:module "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)