Function: xterm--query

xterm--query is a byte-compiled function defined in xterm.el.gz.

Signature

(xterm--query QUERY HANDLERS &optional NO-ASYNC)

Documentation

Send QUERY string to the terminal and watch for a response.

HANDLERS is an alist with elements of the form (STRING . FUNCTION). We run the first FUNCTION whose STRING matches the input events.

Source Code

;; Defined in /usr/src/emacs/lisp/term/xterm.el.gz
(defun xterm--query (query handlers &optional no-async)
  "Send QUERY string to the terminal and watch for a response.
HANDLERS is an alist with elements of the form (STRING . FUNCTION).
We run the first FUNCTION whose STRING matches the input events."
  ;; We used to query synchronously, but the need to use `discard-input' is
  ;; rather annoying (bug#6758).  Maybe we could always use the asynchronous
  ;; approach, but it's less tested.
  ;; FIXME: Merge the two branches.
  (let ((register
         (lambda (handlers)
           (dolist (handler handlers)
             (define-key input-decode-map (car handler)
               (lambda (&optional _prompt)
                 ;; Unregister the handler, since we don't expect
                 ;; further answers.
                 (dolist (handler handlers)
                   (define-key input-decode-map (car handler) nil))
                 (funcall (cdr handler))
                 []))))))
    (if (and (or (null xterm-query-timeout) (input-pending-p))
             (not no-async))
        (progn
          (funcall register handlers)
          (send-string-to-terminal query))
      ;; Pending input can be mistakenly returned by the calls to
      ;; read-event below: discard it.
      (discard-input)
      (send-string-to-terminal query)
      (while handlers
        (let ((handler (pop handlers))
              (i 0))
          (while (and (< i (length (car handler)))
                      (let ((evt (xterm--read-event-for-query)))
                        (if (and (null evt) (= i 0) (not no-async))
                            ;; Timeout on the first event: fallback on async.
                            (progn
                              (funcall register (cons handler handlers))
                              (setq handlers nil)
                              nil)
                          (or (eq evt (aref (car handler) i))
                              (progn (if evt (push evt unread-command-events))
                                     nil)))))
            (setq i (1+ i)))
          (if (= i (length (car handler)))
              (progn (setq handlers nil)
                     (funcall (cdr handler)))
            (while (> i 0)
              (push (aref (car handler) (setq i (1- i)))
                    unread-command-events))))))))