diff options
-rw-r--r-- | build-app.lisp | 14 | ||||
-rw-r--r-- | src/lib.lisp | 59 |
2 files changed, 54 insertions, 19 deletions
diff --git a/build-app.lisp b/build-app.lisp index 30eb88a..0a1bfd5 100644 --- a/build-app.lisp +++ b/build-app.lisp @@ -79,14 +79,18 @@ you run the oneliner, all positional variables appear first. (text :contents " ") (group (:header "ONELINER EXECUTION OPTIONS") (text :contents "Runs the Nth search result with possible arguments ARGS.") + (flag :long-name "id" + :description "Runs a oneliner by its id instead of by result number.") (flag :long-name "clip" :description "Put oneliner into clipboard instead of running it.") + (flag :long-name "clear-cache" + :description "Clears all cached search results from your system.") (lispobj :long-name "timeout" :argument-type :optional :argument-name "SECONDS" - :default-value 1.0 - :typespec 'float - :description "How long to wait for output before giving up. Make longer if you dont see any output.")) + :default-value 2 + :typespec 'integer + :description "How long to wait for standard output before giving up.")) (text :contents " ") (group (:header "HELP OPTIONS") (flag :long-name "explain" @@ -191,6 +195,9 @@ than the users." ((getopt :long-name "newest") (cli::newest-oneliners (getopt :long-name "limit"))) + ((getopt :long-name "clear-cache") + (cli::wipe-cache)) + (arguments ;; when the first argument is a number, try run a oneliner (a:when-let (hist-number (parse-integer (first arguments) :junk-allowed t)) @@ -213,6 +220,7 @@ than the users." (t (cli::run-item hist-number (rest arguments) + :by-id (getopt :long-name "id") :force-clip (getopt :long-name "clip") :timeout (getopt :long-name "timeout")))) (uiop:quit)) diff --git a/src/lib.lisp b/src/lib.lisp index 6f7f377..b87ffc6 100644 --- a/src/lib.lisp +++ b/src/lib.lisp @@ -13,7 +13,7 @@ (defvar *config* nil "A configuration plist") -(defvar *ol-output-timeout* 0.8) +(defvar *ol-output-timeout* 1) (defun valid-config-p (config) (and (listp config) @@ -72,6 +72,26 @@ (defun last-search-file () (merge-pathnames ".last_oneliners_search" (user-homedir-pathname))) +(defun cached-oneliners-file () + (merge-pathnames ".cached_oneliners" (user-homedir-pathname))) + +(defun wipe-cache () + (uiop:delete-file-if-exists (cached-oneliners-file)) + (uiop:delete-file-if-exists (last-search-file ))) + +(defun merge-into-cache (ols) + (if (uiop:file-exists-p (cached-oneliners-file)) + (let ((cached (with-open-file (input (cached-oneliners-file)) (read input)))) + (with-open-file (out (cached-oneliners-file) :direction :output :if-exists :supersede) + (print (nconc + ols + (remove-if + (lambda (old) + (member (getf old :id) ols :test 'equal :key (lambda (x) (getf x :id)))) + cached)) + out))) + (with-open-file (out (cached-oneliners-file) :direction :output :if-exists :supersede) + (print ols out)))) ;;; UTILITIES (defun make-temp-file-name () @@ -127,20 +147,22 @@ the directories that appear in the value of that variable." ;; unregisters the hook. (rl:register-hook :pre-input nil))) -(defun cached-result (&optional n) - (when (uiop:file-exists-p (last-search-file)) - (let ((contents (with-open-file (input (last-search-file)) (read input)))) - (if n - (nth n contents) - contents)))) +(defun cached-result (n &optional idp) + (if idp + (when (uiop:file-exists-p (cached-oneliners-file)) + (let ((contents (with-open-file (input (cached-oneliners-file)) (read input)))) + (find n contents :key (lambda (x) (getf x :id))))) + (when (uiop:file-exists-p (last-search-file)) + (let ((contents (with-open-file (input (last-search-file)) (read input)))) + (nth n contents))))) -(defmacro with-cached-result ((olvar n) &body body) +(defmacro with-cached-result ((olvar n &optional idp) &body body) (a:with-gensyms (nvar) `(let ((,nvar ,n)) (assert (plusp ,nvar) () "Item number must be 1 or greater") - (a:if-let (,olvar (cached-result (1- ,nvar))) + (a:if-let (,olvar ,(if idp `(cached-result ,nvar t) `(cached-result (1- ,nvar)))) (progn ,@body) - (format t "The last search was shorter than ~a" ,nvar))))) + (format t "Could not find the oneliner specified by ~a~%" ,nvar))))) (defun print-item-explanation (number) (with-cached-result (ol number) @@ -226,10 +248,13 @@ the directories that appear in the value of that variable." (handle-run-oneliner oneliner (or force-clip (equalp runstyle "manual")))))) -(defun run-item (item-number args &key force-clip (timeout nil timeout-p)) +(defun run-item (item-number args &key by-id force-clip (timeout nil timeout-p)) (let ((*ol-output-timeout* (if timeout-p timeout *ol-output-timeout*))) - (with-cached-result (ol item-number) - (bind-vars-and-run-oneliner ol args force-clip)))) + (if by-id + (with-cached-result (ol item-number t) + (bind-vars-and-run-oneliner ol args force-clip)) + (with-cached-result (ol item-number) + (bind-vars-and-run-oneliner ol args force-clip))))) (defun valid-oneliner-string-p (string) (and (not (find #\newline string)) @@ -459,12 +484,13 @@ the directories that appear in the value of that variable." (defun cache-search-results-to-last-search-file (results) (with-open-file (output (last-search-file) :direction :output :if-exists :supersede) - (print results output))) + (print results output)) + (merge-into-cache results)) (defun print-oneliner-result-for-user (number oneliner) (dotimes (n 80) (princ #\_)) (terpri) - (format t "~3a~a~a~a ~a" + (format t "~3a~a~a~a [~a] ~a" number (if (getf oneliner :isflagged) "⚠" " ") @@ -472,6 +498,7 @@ the directories that appear in the value of that variable." "🔒" " ") (if (equalp "manual" (getf oneliner :runstyle)) "📋" " ") + (getf oneliner :id) (getf oneliner :brief)) (format t "~% by: ~12a tags: ~{~a~^ ~}" (getf oneliner :createdby) (getf oneliner :tags)) (format t "~%~% ~a~%~%" (getf oneliner :oneliner))) @@ -480,7 +507,7 @@ the directories that appear in the value of that variable." (cache-search-results-to-last-search-file (loop for number from 1 for oneliner in (getf (jonathan:parse response) :oneliners) - collect (list* :result-number number oneliner) + collect oneliner do (print-oneliner-result-for-user number oneliner)))) (defun newest-oneliners (&optional limit) |