comparison lisp/simple.el @ 5854:ccb0cff115d2

Update message-stack to reflect START and END supplied to #'append-message lisp/ChangeLog addition: 2015-03-11 Aidan Kehoe <kehoea@parhasard.net> Correct #'clear-message and friends so the START and END supplied to #'append-message are reflected when restoring messages from the message stack. * simple.el (remove-message-hook): Update this to reflect the START and END keyword arguments. * simple.el (log-message): Update this to take START and END keyword arguments. * simple.el (clear-message): Update this to reflect a changed `message-stack' alist structure. * simple.el (remove-message): Update this to reflect a changed `message-stack' alist structure; don't do `with-trapping-errors' and resignal use #'call-with-condition-handler directly instead, for better backtraces and easier debugging. * simple.el (append-message): Update this to reflect a changed message-stack structure.
author Aidan Kehoe <kehoea@parhasard.net>
date Wed, 11 Mar 2015 15:06:05 +0000
parents 9e5f3a0d4e66
children 0bddb59072b6
comparison
equal deleted inserted replaced
5853:1044acf60048 5854:ccb0cff115d2
4164 `display-message'/`clear-message' functions.") 4164 `display-message'/`clear-message' functions.")
4165 4165
4166 (defvar remove-message-hook 'log-message 4166 (defvar remove-message-hook 'log-message
4167 "A function or list of functions to be called when a message is removed 4167 "A function or list of functions to be called when a message is removed
4168 from the echo area at the bottom of the frame. The label of the removed 4168 from the echo area at the bottom of the frame. The label of the removed
4169 message is passed as the first argument, and the text of the message 4169 message is passed as the first argument, the text of the message as the second
4170 as the second argument.") 4170 argument, and the start and end of the substring of the message can be
4171 supplied as keyword arguments.")
4171 4172
4172 (defcustom log-message-max-size 50000 4173 (defcustom log-message-max-size 50000
4173 "Maximum size of the \" *Message-Log*\" buffer. See `log-message'." 4174 "Maximum size of the \" *Message-Log*\" buffer. See `log-message'."
4174 :type 'integer 4175 :type 'integer
4175 :group 'log-message) 4176 :group 'log-message)
4298 4299
4299 (defun log-message-filter-errors-only (label message) 4300 (defun log-message-filter-errors-only (label message)
4300 "For use as the `log-message-filter-function'. Only logs error messages." 4301 "For use as the `log-message-filter-function'. Only logs error messages."
4301 (eq label 'error)) 4302 (eq label 'error))
4302 4303
4303 (defun log-message (label message) 4304 (defun* log-message (label message &key (start 0) end)
4304 "Stuff a copy of the message into the \" *Message-Log*\" buffer, 4305 "Stuff a copy of the message into the \" *Message-Log*\" buffer,
4305 if it satisfies the `log-message-filter-function'. 4306 if it satisfies the `log-message-filter-function'.
4306 4307
4307 For use on `remove-message-hook'." 4308 For use on `remove-message-hook'."
4308 (when (and (not noninteractive) 4309 (when (and (not noninteractive)
4314 (goto-char (point-max)) 4315 (goto-char (point-max))
4315 ;(insert (concat (upcase (symbol-name label)) ": " message "\n")) 4316 ;(insert (concat (upcase (symbol-name label)) ": " message "\n"))
4316 (let (extent) 4317 (let (extent)
4317 ;; Mark multiline message with an extent, which `view-lossage' 4318 ;; Mark multiline message with an extent, which `view-lossage'
4318 ;; will recognize. 4319 ;; will recognize.
4319 (save-match-data 4320 (when (find ?\n message :start start :end end)
4320 (when (string-match "\n" message) 4321 (setq extent (make-extent (point) (point)))
4321 (setq extent (make-extent (point) (point))) 4322 (set-extent-properties extent '(end-open nil message-multiline t)))
4322 (set-extent-properties extent '(end-open nil message-multiline t))) 4323 (write-line message (current-buffer) :start start :end end)
4323 )
4324 (insert message "\n")
4325 (when extent 4324 (when extent
4326 (set-extent-property extent 'end-open t))) 4325 (set-extent-property extent 'end-open t)))
4327 (when (> (point-max) (max log-message-max-size (point-min))) 4326 (when (> (point-max) (max log-message-max-size (point-min)))
4328 ;; Trim log to ~90% of max size. 4327 ;; Trim log to ~90% of max size.
4329 (goto-char (max (- (point-max) 4328 (goto-char (max (- (point-max)
4375 (set-device-clear-left-side (frame-device frame) nil) 4374 (set-device-clear-left-side (frame-device frame) nil)
4376 (send-string-to-terminal ?\n stdout-p)) 4375 (send-string-to-terminal ?\n stdout-p))
4377 (if no-restore 4376 (if no-restore
4378 nil ; just preparing to put another msg up 4377 nil ; just preparing to put another msg up
4379 (if message-stack 4378 (if message-stack
4380 (let ((oldmsg (cdr (car message-stack)))) 4379 (let ((oldmsg (second (car message-stack))))
4381 (raw-append-message oldmsg frame stdout-p) 4380 (prog1
4382 oldmsg) 4381 ;; #### Doesn't pass back information about the substring of
4382 ;; OLDMSG displayed. None of our callers use this, as of
4383 ;; 20150311, though.
4384 oldmsg
4385 (raw-append-message oldmsg frame stdout-p
4386 :start (third (car message-stack))
4387 :end (fourth (car message-stack)))))
4383 ;; #### Should we (redisplay-echo-area) here? Messes some 4388 ;; #### Should we (redisplay-echo-area) here? Messes some
4384 ;; things up. 4389 ;; things up.
4385 nil)))) 4390 nil))))
4386 4391
4387 (defun remove-message (&optional label frame) 4392 (defun remove-message (&optional label frame)
4388 ;; If label is nil, we want to remove all matching messages. 4393 "Remove any message with a specified LABEL from `message-stack'.
4389 ;; Must reverse the stack first to log them in the right order. 4394
4390 (let ((log nil)) 4395 With nil LABEL, remove all messages from `message-stack'. Calls those
4391 (while (and message-stack 4396 functions specified by `remove-message-hook' with the details of each removed
4392 (or (null label) ; null label means clear whole stack 4397 message."
4393 (eq label (car (car message-stack))))) 4398 (let (log)
4394 (push (car message-stack) log) 4399 (if label
4395 (setq message-stack (cdr message-stack))) 4400 (setq log (reverse (remove* label message-stack :test-not #'eq
4396 (let ((s message-stack)) 4401 :key #'car))
4397 (while (cdr s) 4402 message-stack (delete* label message-stack :key #'car))
4398 (let ((msg (car (cdr s)))) 4403 ;; If label is nil, we want to remove all messages. Must reverse the
4399 (if (eq label (car msg)) 4404 ;; stack first to log them in the right order.
4400 (progn 4405 (setq log (nreverse message-stack)
4401 (push msg log) 4406 message-stack nil))
4402 (setcdr s (cdr (cdr s))))
4403 (setq s (cdr s))))))
4404 ;; (possibly) log each removed message 4407 ;; (possibly) log each removed message
4405 (while log 4408 (while log
4406 (with-trapping-errors 4409 (call-with-condition-handler
4407 :operation 'remove-message-hook 4410 ((macro . (lambda (function) (subst '#:xEbgpd2 'error function)))
4408 :class 'message-log 4411 #'(lambda (error)
4409 :error-form (progn 4412 (setq remove-message-hook nil)
4410 (setq remove-message-hook nil) 4413 (let ((inhibit-read-only t))
4411 (let ((inhibit-read-only t)) 4414 (erase-buffer " *Echo Area*"))
4412 (erase-buffer " *Echo Area*"))) 4415 (lwarn 'message-log 'warning
4413 :resignal t 4416 "Error in `remove-message-hook': %s\n\nBacktrace follows:\n%s"
4414 (run-hook-with-args 'remove-message-hook 4417 (error-message-string error)
4415 (car (car log)) (cdr (car log)))) 4418 (backtrace-in-condition-handler-eliminating-handler 'error))))
4419 #'run-hook-with-args 'remove-message-hook (caar log)
4420 (cadar log) :start (third (car log)) :end (fourth (car log)))
4416 (setq log (cdr log))))) 4421 (setq log (cdr log)))))
4417 4422
4418 (defun* append-message (label message &optional frame stdout-p 4423 (defun* append-message (label message &optional frame stdout-p
4419 &key (start 0) end) 4424 &key (start 0) end)
4420 "Add MESSAGE to the message-stack, or append it to the existing text. 4425 "Add MESSAGE to the message-stack, or append it to the existing text.
4434 ;; If outputting to the terminal, make sure output from anyone else clears 4439 ;; If outputting to the terminal, make sure output from anyone else clears
4435 ;; the left side first, but don't do it ourselves, otherwise we won't be 4440 ;; the left side first, but don't do it ourselves, otherwise we won't be
4436 ;; able to append to an existing message. 4441 ;; able to append to an existing message.
4437 (if (eq 'stream (frame-type frame)) 4442 (if (eq 'stream (frame-type frame))
4438 (set-device-clear-left-side (frame-device frame) nil)) 4443 (set-device-clear-left-side (frame-device frame) nil))
4439 (let ((top (car message-stack))) 4444 (if (eq label (caar message-stack))
4440 (if (eq label (car top)) 4445 (setf (cadar message-stack)
4441 (setcdr top (concat (cdr top) message)) 4446 (concat (subseq (cadar message-stack) (third (car message-stack))
4442 (push (cons label message) message-stack))) 4447 (fourth (car message-stack)))
4448 (if (or end (not (eql start 0)))
4449 (subseq message start end)
4450 message))
4451 (caddar message-stack) nil
4452 (car (cdddar message-stack)) nil)
4453 (push (list label message start end) message-stack))
4443 (raw-append-message message frame stdout-p :start start :end end) 4454 (raw-append-message message frame stdout-p :start start :end end)
4444 (if (eq 'stream (frame-type frame)) 4455 (if (eq 'stream (frame-type frame))
4445 (set-device-clear-left-side (frame-device frame) t))) 4456 (set-device-clear-left-side (frame-device frame) t)))
4446 4457
4447 ;; Really append the message to the echo area. No fiddling with 4458 ;; Really append the message to the echo area. No fiddling with