Mercurial > core / lisp/lib/cli/prompt.lisp
changeset 698: |
96958d3eb5b0 |
parent: |
1816f9c53453
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 ;;; lib/cli/prompt.lisp --- Basic CLI Prompts 6 (in-package :cli/prompt) 7 (declaim (optimize (speed 3) (debug 1))) 9 (defvar *completion-trigger* "?") 11 (defun completing-read (prompt collection 12 &key (history nil) (default nil) 17 "A simplified COMPLETING-READ for common-lisp. 19 The Emacs completion framework includes a function called 20 `completing-read' which prompts the user for input from the 21 mini-buffer. It is a very flexible interface which can be used to read 22 user input programatically. This is incredibly useful for building 23 data entry interfaces -- for example see the `defprompt' macro. 25 Obviously writing a completion framework is out-of-scope, but we can 26 simulate one by embedding a DSL in our prompters if we choose. For 27 example, perhaps we treat a single '?' character as a request from the 28 user to list valid options while continue waiting for input." 29 (declare (list collection) 31 (boolean require-match) 32 (stream input output)) 33 (labels ((print-coll () 34 (println collection output)) 37 (finish-output output) 39 (let ((line (the string (read-line input)))) 40 (if (equalp *completion-trigger* line) 44 (if (> (length line) 0) 48 (when history (push res history)) 49 (if (and collection require-match) 50 (find res collection :test test) 53 (defmacro defprompt (var &key (prompt ">") collection default input output) 54 "Generate a 'prompter' from list or variable VAR and optional 57 This isn't an ideal solution as it does in fact expose a dynamic 58 variable (VAR-prompt-history). We should generate accessors and 59 keep the variables within lexical scope of the generated 62 `(let ((,h ',(symbolicate '* var '-prompt-history*))) ;; history symbol 63 (defvar ,(symbolicate '* var '-prompt-history*) nil) 64 (defun ,(symbolicate var '-prompt) () 65 ,(format nil "Prompt for a value from `~A', use DEFAULT if non-nil 66 and no value is provided by user, otherwise fallback to the `car' 67 of `~A-PROMPT-HISTORY'." var var) 69 (format nil "~A [~A]: " 71 (or ,default (car (symbol-value ,h)))) 75 ,@(when input (list :input input)) 76 ,@(when output (list :output output)))))))