]> code.delx.au - gnu-emacs/commitdiff
* lisp/jit-lock.el (jit-lock-debug-mode): New minor mode.
authorStefan Monnier <monnier@iro.umontreal.ca>
Sun, 13 Jan 2013 01:23:48 +0000 (20:23 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Sun, 13 Jan 2013 01:23:48 +0000 (20:23 -0500)
(jit-lock--debug-fontifying): New var.
(jit-lock--debug-fontify): New function.
* lisp/subr.el (condition-case-unless-debug): Don't prevent catching the
error, just let the debbugger run.
* lisp/emacs-lisp/timer.el (timer-event-handler): Don't prevent debugging
timer code and don't drop errors silently.

etc/NEWS
lisp/ChangeLog
lisp/emacs-lisp/timer.el
lisp/jit-lock.el
lisp/subr.el

index 52429a3e21d04424794eb4a7318c00dd97645d8a..758d9c096be69c15d7bda4e27dbdcb0ecbe29412 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -66,6 +66,8 @@ bound to <f11> and M-<f10>, respectively.
 \f
 * Changes in Specialized Modes and Packages in Emacs 24.4
 
+** jit-lock-debug-mode lets you use the debuggers on code run via jit-lock.
+
 ** completing-read-multiple's separator can now be a regexp.
 The default separator is changed to allow surrounding spaces around the comma.
 
index 7723528c886177d4c653ac57bf636d7e0d441a6d..73e096adc5e19dab648326111de4aee0823f43a1 100644 (file)
@@ -1,3 +1,13 @@
+2013-01-13  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * jit-lock.el (jit-lock-debug-mode): New minor mode.
+       (jit-lock--debug-fontifying): New var.
+       (jit-lock--debug-fontify): New function.
+       * subr.el (condition-case-unless-debug): Don't prevent catching the
+       error, just let the debbugger run.
+       * emacs-lisp/timer.el (timer-event-handler): Don't prevent debugging
+       timer code and don't drop errors silently.
+
 2013-01-12  Michael Albinus  <michael.albinus@gmx.de>
 
        * autorevert.el (auto-revert-notify-watch-descriptor): Give it
index 3eaacd24ec82a7788618b778eeb854b008075478..8b019d0a7855c042c895f4eecd7e9c51d050e2e4 100644 (file)
@@ -307,13 +307,13 @@ This function is called, by name, directly by the C code."
          ;; Run handler.
          ;; We do this after rescheduling so that the handler function
          ;; can cancel its own timer successfully with cancel-timer.
-         (condition-case nil
+         (condition-case-unless-debug err
               ;; Timer functions should not change the current buffer.
               ;; If they do, all kinds of nasty surprises can happen,
               ;; and it can be hellish to track down their source.
               (save-current-buffer
                 (apply (timer--function timer) (timer--args timer)))
-           (error nil))
+           (error (message "Error in timer: %S" err)))
          (if retrigger
              (setf (timer--triggered timer) nil)))
       (error "Bogus timer event"))))
index 7be5df72c84f8e49e150605520046b97368d816c..668f1ec963a722540f293c9bd85614f0b895f3b3 100644 (file)
@@ -257,6 +257,47 @@ the variable `jit-lock-stealth-nice'."
         (remove-hook 'after-change-functions 'jit-lock-after-change t)
         (remove-hook 'fontification-functions 'jit-lock-function))))
 
+(define-minor-mode jit-lock-debug-mode
+  "Minor mode to help debug code run from jit-lock.
+When this minor mode is enabled, jit-lock runs as little code as possible
+during redisplay and moves the rest to a timer, where things
+like `debug-on-error' and Edebug can be used."
+  :global t
+  (when jit-lock-defer-timer
+    (cancel-timer jit-lock-defer-timer)
+    (setq jit-lock-defer-timer nil))
+  (when jit-lock-debug-mode
+    (setq jit-lock-defer-timer
+          (run-with-idle-timer 0 t #'jit-lock--debug-fontify))))
+
+(defvar jit-lock--debug-fontifying nil)
+
+(defun jit-lock--debug-fontify ()
+  "Fontify what was deferred for debugging."
+  (when (and (not jit-lock--debug-fontifying)
+             jit-lock-defer-buffers (not memory-full))
+    (let ((jit-lock--debug-fontifying t)
+          (inhibit-debugger nil))       ;FIXME: Not sufficient!
+      ;; Mark the deferred regions back to `fontified = nil'
+      (dolist (buffer jit-lock-defer-buffers)
+        (when (buffer-live-p buffer)
+          (with-current-buffer buffer
+            ;; (message "Jit-Debug %s" (buffer-name))
+            (with-buffer-prepared-for-jit-lock
+                (let ((pos (point-min)))
+                  (while
+                      (progn
+                        (when (eq (get-text-property pos 'fontified) 'defer)
+                          (let ((beg pos)
+                                (end (setq pos (next-single-property-change
+                                                pos 'fontified
+                                                nil (point-max)))))
+                            (put-text-property beg end 'fontified nil)
+                            (jit-lock-fontify-now beg end)))
+                        (setq pos (next-single-property-change
+                                   pos 'fontified)))))))))
+      (setq jit-lock-defer-buffers nil))))
+
 (defun jit-lock-register (fun &optional contextual)
   "Register FUN as a fontification function to be called in this buffer.
 FUN will be called with two arguments START and END indicating the region
@@ -504,7 +545,8 @@ non-nil in a repeated invocation of this function."
                      pos (setq pos (next-single-property-change
                                     pos 'fontified nil (point-max)))
                      'fontified nil))
-                  (setq pos (next-single-property-change pos 'fontified)))))))))
+                  (setq pos (next-single-property-change
+                              pos 'fontified)))))))))
     (setq jit-lock-defer-buffers nil)
     ;; Force fontification of the visible parts.
     (let ((jit-lock-defer-timer nil))
index 11e882d91588425c5a92d6bccf29a9359769f377..e1ab5298409a733509df05ea150428e42495b35a 100644 (file)
@@ -3367,16 +3367,17 @@ If BODY finishes, `while-no-input' returns whatever value BODY produced."
               (progn ,@body)))))))
 
 (defmacro condition-case-unless-debug (var bodyform &rest handlers)
-  "Like `condition-case' except that it does not catch anything when debugging.
-More specifically if `debug-on-error' is set, then it does not catch any signal."
+  "Like `condition-case' except that it does not prevent debugging.
+More specifically if `debug-on-error' is set then the debugger will be invoked
+even if this catches the signal."
   (declare (debug condition-case) (indent 2))
-  (let ((bodysym (make-symbol "body")))
-    `(let ((,bodysym (lambda () ,bodyform)))
-       (if debug-on-error
-           (funcall ,bodysym)
-         (condition-case ,var
-             (funcall ,bodysym)
-           ,@handlers)))))
+  `(condition-case ,var
+       ,bodyform
+     ,@(mapcar (lambda (handler)
+                 `((debug ,@(if (listp (car handler)) (car handler)
+                              (list (car handler))))
+                   ,@(cdr handler)))
+               handlers)))
 
 (define-obsolete-function-alias 'condition-case-no-debug
   'condition-case-unless-debug "24.1")