diff options
| author | Pierre Courtieu | 2006-09-06 09:41:12 +0000 |
|---|---|---|
| committer | Pierre Courtieu | 2006-09-06 09:41:12 +0000 |
| commit | cef854b93888b79d08b0410cc0600b53c9790d28 (patch) | |
| tree | 19aee76b965498e9e8d5b160b2dc7caca6811622 | |
| parent | 07088a47b162ebc8b46acb53d0fc3b4e0e9d1dc6 (diff) | |
Making error highlighting more robust (for both emacsen) and use a
span instead of region.
| -rw-r--r-- | coq/coq.el | 96 | ||||
| -rw-r--r-- | generic/proof-config.el | 4 |
2 files changed, 82 insertions, 18 deletions
@@ -1383,7 +1383,7 @@ be asked to the user." (define-key coq-keymap [(control ?l)] 'coq-LocateConstant) (define-key coq-keymap [(control ?n)] 'coq-LocateNotation) (define-key coq-keymap [(control ?g)] 'coq-Show) -(define-key coq-keymap [?'] 'coq-highlight-error) +;(define-key coq-keymap [?'] 'coq-highlight-error) @@ -1392,22 +1392,86 @@ be asked to the user." ;;;;;;;;;;;;;;;;;;;;;;;; -(defun coq-highlight-error () - "Parses the last coq output looking at an error message. put mark and point -around the text pointed by it." - (let ((mtch (string-match "> \\( *\\)\\(\\^+\\)\n" proof-shell-last-output))) +(defvar last-coq-error-location nil + "The last error message seen by `coq-get-last-error-location' and +`coq-highlight-error'.") + + +;; I don't use proof-shell-last-ouput here since it is not always set to the +;; really last ouptut (specially when a *tactic* gives an error) instead I go +;; directly to the response buffer. This allows also to clean the response +;; buffer (better to only scroll it?) +(defun coq-get-last-error-location (&optional parseresp clean) + "Return location information on last error sent by coq. Return a three +elements list (pos lgth) if successful, nil otherwise. pos is the number of +characters preceding the underlined expression, and lgth is its length. +Coq error message must be like this: + +\" +> command with an error here ... +> ^^^^ +\" + +If PARSERESP is nil, don't really parse response buffer but take the value of +`last-coq-error-location' instead, otherwise parse response buffer and updates +`last-coq-error-location'. + +If PARSERESP and CLEAN are non-nil, delete the error location from the response +buffer." + (if (not parseresp) last-coq-error-location + (save-excursion + ;; proof-shell-handle-error-or-interrupt-hook is called from shell buffer + (set-buffer proof-response-buffer) + (goto-char (point-max)) + (let ((mtch (re-search-backward "\n>[^\n]+\n> \\( *\\)\\(\\^+\\)\n" nil 'dummy))) + ;; clean the response buffer from ultra-ugly underlined command line + ;; parsed above. Don't kill the first \n + (when (and clean mtch) (delete-region (+ mtch 1) (match-end 0))) + (goto-char (point-max)) + (when mtch + (let* ((pos (length (match-string 1))) + (lgth (length (match-string 2))) + (res (list pos lgth))) + (setq last-coq-error-location res) + res)))))) + +(defun coq-highlight-error (&optional parseresp clean) + "Parses the last coq output looking at an error message. Highlight the text +pointed by it. Coq error message must be like this: + +\" +> command with an error here ... +> ^^^^ +\" + +If PARSERESP is nil, don't really parse response buffer but take the value of +`last-coq-error-location' instead, otherwise parse response buffer and updates +`last-coq-error-location'. + +If PARSERESP and CLEAN are non-nil, delete the error location from the response +buffer." + (interactive) + (let ((mtch (coq-get-last-error-location parseresp clean))) (when mtch - (let ((pos (length (match-string 1))) - (lgth (length (match-string 2)))) - (save-excursion - ;; proof-shell-handle-error-or-interrupt-hook is called from response buffer - (switch-to-buffer proof-script-buffer) - (goto-char (+ (proof-locked-end) 1)) - (coq-find-real-start) - (forward-char pos) - (push-mark (+ (point) lgth) t t)))))) - -(add-hook 'proof-shell-handle-error-or-interrupt-hook 'coq-highlight-error t) + (let ((pos (car mtch)) + (lgth (cadr mtch))) + (set-buffer proof-script-buffer) + (goto-char (+ (proof-locked-end) 1)) + (coq-find-real-start) + (forward-char pos) + (let ((sp (make-span (point) (+ (point) lgth)))) + (set-span-face sp 'proof-warning-face) + ;; delete timer if exist + ;;(setq coq-highlight-error-timer (run-with-timer 10 nil 'delete-span sp)) + (ignore-errors (sit-for 20)) ; errors here would skip the next delete + (delete-span sp) + ))))) + +(defun coq-highlight-error-hook () + (save-excursion (coq-highlight-error t t))) + + +(add-hook 'proof-shell-handle-error-or-interrupt-hook 'coq-highlight-error-hook t) (provide 'coq) diff --git a/generic/proof-config.el b/generic/proof-config.el index 6ea95171..09c32a7d 100644 --- a/generic/proof-config.el +++ b/generic/proof-config.el @@ -2316,8 +2316,8 @@ values for this hook include: which move the cursor in the scripting buffer on an error or error/interrupt. -Remark: This hook is called from response buffer. If you want to do -something in scripting buffer, save excursion and switch buffer." +Remark: This hook is called from shell buffer. If you want to do +something in scripting buffer, `save-excursion' and/or `set-buffer'." :type '(repeat function) :group 'proof-shell) |
