Advertisement
Guest User

Untitled

a guest
Apr 19th, 2021
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.24 KB | None | 0 0
  1. (defun check-menu-complete (menu key-seq)
  2.   "If the user entered a key not mapped in @var{*menu-map}, check if
  3.  he's trying to type an entry's name. Match is case insensitive. If
  4.  @var{key-seq} is nil, some other function has manipulated the
  5.  current-input and is requesting a re-computation of the match."
  6.   (let ((input-char (and key-seq (get-input-char key-seq))))
  7.     (when input-char
  8.       (vector-push-extend input-char (menu-state-current-input menu)))
  9.     (handler-case
  10.         (when (or input-char (not key-seq))
  11.           (labels ((match-p (table-item)
  12.                      (funcall (menu-state-filter-pred menu)
  13.                               (car table-item)
  14.                               (second table-item)
  15.                               (menu-state-current-input menu))))
  16.             (setf (menu-state-table menu) (remove-if-not #'match-p (menu-state-unfiltered-table menu))
  17.                   (menu-state-selected menu) 0)
  18.             (bound-check-menu menu)))
  19.       (cl-ppcre:ppcre-syntax-error ()))))
  20.  
  21. (defun select-from-menu (screen table &optional (prompt "Search:")
  22.                                         (initial-selection 0)
  23.                                         extra-keymap
  24.                                         (filter-pred #'menu-item-matches-regexp))
  25.   "Prompt the user to select from a menu on SCREEN. TABLE can be
  26. a list of values or an alist. If it's an alist, the CAR of each
  27. element is displayed in the menu. What is displayed as menu items
  28. must be strings.
  29. EXTRA-KEYMAP can be a keymap whose bindings will take precedence
  30. over the default bindings.
  31. FILTER-PRED should be a a function returning T when a certain menu
  32. item should be visible to the user.  It should accept arguments
  33. ITEM-STRING (the string shown to the user), ITEM-OBJECT (the object
  34. corresponding to the menu item), and USER-INPUT (the current user
  35. input). The default is MENU-ITEM-MATCHES-REGEXP.
  36. Returns the selected element in TABLE or nil if aborted. "
  37.   (check-type screen screen)
  38.   (check-type table list)
  39.   (check-type prompt (or null string))
  40.   (check-type initial-selection integer)
  41.  
  42.   (when table
  43.     (let* ((*record-last-msg-override* t)
  44.            (*suppress-echo-timeout* t)
  45.            (menu (make-menu-state
  46.                   :unfiltered-table table
  47.                   :table table
  48.                   :filter-pred filter-pred
  49.                   :prompt prompt
  50.                   :view-start 0
  51.                   :view-end 0
  52.                   :selected initial-selection))
  53.            (keymap (if extra-keymap
  54.                        (list extra-keymap *menu-map*)
  55.                        (list *menu-map*))))
  56.       (bound-check-menu menu)
  57.       (catch :menu-quit
  58.         (unwind-protect
  59.              (with-focus (screen-key-window screen)
  60.                (loop
  61.                   (let* ((sel (menu-state-selected menu))
  62.                          (start (menu-state-view-start menu))
  63.                          (end (menu-state-view-end menu))
  64.                          (len (length (menu-state-table menu)))
  65.                          (prompt-line (when (menu-prompt-visible menu)
  66.                                         (format nil "~@[~A ~]~A"
  67.                                                 prompt (menu-state-current-input menu))))
  68.                          (strings (mapcar #'menu-element-name
  69.                                           (subseq (menu-state-table menu)
  70.                                                   start end)))
  71.                          (highlight (- sel start)))
  72.                     (unless (zerop start)
  73.                       (setf strings (cons "..." strings))
  74.                       (incf highlight))
  75.                     (unless (= len end)
  76.                       (setf strings (nconc strings '("..."))))
  77.                     (when prompt-line
  78.                       (push prompt-line strings)
  79.                       (incf highlight))
  80.                     (echo-string-list screen strings highlight))
  81.                   (multiple-value-bind (action key-seq) (read-from-keymap keymap)
  82.                     (if action
  83.                         (progn (funcall action menu)
  84.                                (bound-check-menu menu))
  85.                         (check-menu-complete menu (first key-seq))))))
  86.           (unmap-all-message-windows))))))
  87.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement