|
25 | 25 | :accessor nil
|
26 | 26 | :reader input
|
27 | 27 | :documentation "User input.")
|
| 28 | + (input-queue |
| 29 | + (lpara.queue:make-queue) |
| 30 | + :type lpara.queue:queue |
| 31 | + :export nil |
| 32 | + :documentation "All user inputs. |
| 33 | +See `input-delay'.") |
| 34 | + (input-delay |
| 35 | + 0.05 |
| 36 | + :type float |
| 37 | + :documentation "When input is changed, time after which the source is updated. |
| 38 | +This is useful to avoid updating the sources") |
| 39 | + (input-reader |
| 40 | + nil |
| 41 | + :export nil |
| 42 | + :documentation "The Lparallel `future' that reads the various inputs during `input-delay'.") |
28 | 43 |
|
29 | 44 | (prompt
|
30 | 45 | ""
|
@@ -199,14 +214,32 @@ Only if the PROMPTER current source has `actions-on-current-suggestion-enabled-p
|
199 | 214 | (:documentation "Set the action to be run on the newly selected suggestion.
|
200 | 215 | See also `run-action-on-current-suggestion'."))
|
201 | 216 |
|
| 217 | +(defun drain-queue (queue) |
| 218 | + "Drain and return last element of the `lparallel.queue:queue'." |
| 219 | + (labels ((pop (last-value) |
| 220 | + (multiple-value-bind (element hit?) |
| 221 | + (lparallel.queue:try-pop-queue queue) |
| 222 | + (if hit? |
| 223 | + (pop element) |
| 224 | + last-value)))) |
| 225 | + (pop nil))) |
| 226 | + |
202 | 227 | (export-always 'input)
|
203 | 228 | (defmethod (setf input) (text (prompter prompter))
|
204 |
| - "Update PROMPTER sources and return TEXT." |
205 |
| - (let ((old-input (slot-value prompter 'input))) |
206 |
| - (unless (string= old-input text) |
207 |
| - (setf (slot-value prompter 'input) text) |
208 |
| - (update-sources prompter text) |
209 |
| - (first-suggestion prompter))) |
| 229 | + "Update PROMPTER sources and return TEXT. |
| 230 | +This is non-blocking: the source update is done in parallel." |
| 231 | + (when (or (null (input-reader prompter)) |
| 232 | + (lpara:fulfilledp (input-reader prompter))) |
| 233 | + (setf (input-reader prompter) |
| 234 | + (lparallel:future |
| 235 | + (sleep (input-delay prompter)) |
| 236 | + (let ((input (drain-queue (input-queue prompter)))) |
| 237 | + (let ((old-input (slot-value prompter 'input))) |
| 238 | + (unless (string= old-input text) |
| 239 | + (setf (slot-value prompter 'input) text) |
| 240 | + (update-sources prompter text) |
| 241 | + (first-suggestion prompter))))))) |
| 242 | + (lpara.queue:push-queue input (input-queue prompter)) |
210 | 243 | text)
|
211 | 244 |
|
212 | 245 | (export-always 'destroy)
|
|
0 commit comments