--- orig/lisp/ChangeLog +++ mod/lisp/ChangeLog @@ -1,3 +1,15 @@ +2006-04-11 Michael Olson + + * emacs-lisp/tq.el (tq-queue-head-question): New accessor + function. + (tq-queue-head-regexp, tq-queue-head-closure, tq-queue-head-fn): + Update for modified queue structure. + (tq-queue-add): Accept `question' argument. + (tq-queue-pop): If a question is pending, send it. + (tq-enqueue): Accept new optional argument `delay-question'. If + this is non-nil, and at least one other question is pending a + response, queue the question rather than sending it immediately. + 2006-04-10 Bill Wohler * custom.el (defcustom, custom-handle-keyword): Add --- orig/lisp/emacs-lisp/tq.el +++ mod/lisp/emacs-lisp/tq.el @@ -32,9 +32,9 @@ ;; handler functions ;; Our basic structure is the queue/process/buffer triple. Each entry -;; of the queue is a regexp/closure/function triple. We buffer -;; bytes from the process until we see the regexp at the head of the -;; queue. Then we call the function with the closure and the +;; of the queue is a question/regexp/closure/function quadruple. We +;; buffer bytes from the process until we see the regexp at the head +;; of the queue. Then we call the function with the closure and the ;; collected bytes. ;;; Code: @@ -55,32 +55,45 @@ tq)) ;;; accessors -(defun tq-queue (tq) (car tq)) -(defun tq-process (tq) (car (cdr tq))) -(defun tq-buffer (tq) (cdr (cdr tq))) +(defun tq-queue (tq) (car tq)) +(defun tq-process (tq) (car (cdr tq))) +(defun tq-buffer (tq) (cdr (cdr tq))) +(defun tq-queue-head-question (tq) (car (car (tq-queue tq)))) +(defun tq-queue-head-regexp (tq) (car (cdr (car (tq-queue tq))))) +(defun tq-queue-head-closure (tq) (car (cdr (cdr (car (tq-queue tq)))))) +(defun tq-queue-head-fn (tq) (cdr (cdr (cdr (car (tq-queue tq)))))) -(defun tq-queue-add (tq re closure fn) +(defun tq-queue-empty (tq) (not (tq-queue tq))) + +(defun tq-queue-add (tq question re closure fn) (setcar tq (nconc (tq-queue tq) - (cons (cons re (cons closure fn)) nil))) + (cons (cons question (cons re (cons closure fn))) nil))) 'ok) -(defun tq-queue-head-regexp (tq) (car (car (tq-queue tq)))) -(defun tq-queue-head-fn (tq) (cdr (cdr (car (tq-queue tq))))) -(defun tq-queue-head-closure (tq) (car (cdr (car (tq-queue tq))))) -(defun tq-queue-empty (tq) (not (tq-queue tq))) -(defun tq-queue-pop (tq) (setcar tq (cdr (car tq))) (null (car tq))) - +(defun tq-queue-pop (tq) + (setcar tq (cdr (car tq))) + (let ((question (tq-queue-head-question tq))) + (when question + (process-send-string (tq-process tq) question))) + (null (car tq))) ;;; must add to queue before sending! -(defun tq-enqueue (tq question regexp closure fn) +(defun tq-enqueue (tq question regexp closure fn &optional delay-question) "Add a transaction to transaction queue TQ. This sends the string QUESTION to the process that TQ communicates with. When the corresponding answer comes back, we call FN with two arguments: CLOSURE, and the answer to the question. REGEXP is a regular expression to match the entire answer; -that's how we tell where the answer ends." - (tq-queue-add tq regexp closure fn) - (process-send-string (tq-process tq) question)) +that's how we tell where the answer ends. + +If DELAY-QUESTION is non-nil, delay sending this question until +the process has finished replying to any previous questions. +This produces more reliable results with some processes." + (let ((sendp (or (not delay-question) + (not (tq-queue-head-question tq))))) + (tq-queue-add tq (and delay-question question) regexp closure fn) + (when sendp + (process-send-string (tq-process tq) question)))) (defun tq-close (tq) "Shut down transaction queue TQ, terminating the process."