2019-11-30 08:46:49 +01:00
|
|
|
|
;;; polymode-debug.el --- Interactive debugging utilities for polymode -*- lexical-binding: t -*-
|
|
|
|
|
;;
|
|
|
|
|
;; Copyright (C) 2016-2018 Vitalie Spinu
|
|
|
|
|
;; Author: Vitalie Spinu
|
2020-03-04 18:59:26 +01:00
|
|
|
|
;; URL: https://github.com/polymode/polymode
|
2019-11-30 08:46:49 +01:00
|
|
|
|
;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;
|
|
|
|
|
;; This file is *NOT* part of GNU Emacs.
|
|
|
|
|
;;
|
|
|
|
|
;; This program is free software; you can redistribute it and/or
|
|
|
|
|
;; modify it under the terms of the GNU General Public License as
|
|
|
|
|
;; published by the Free Software Foundation; either version 3, or
|
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
;;
|
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
;; General Public License for more details.
|
|
|
|
|
;;
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
|
|
(require 'polymode-core)
|
|
|
|
|
(require 'poly-lock)
|
|
|
|
|
(require 'trace)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; MINOR MODE
|
|
|
|
|
|
|
|
|
|
(defvar pm--underline-overlay
|
|
|
|
|
(let ((overlay (make-overlay (point) (point))))
|
|
|
|
|
(overlay-put overlay 'face '(:underline (:color "tomato" :style wave)))
|
|
|
|
|
overlay)
|
|
|
|
|
"Overlay used in function `pm-debug-mode'.")
|
|
|
|
|
|
|
|
|
|
(defvar pm--highlight-overlay
|
|
|
|
|
(let ((overlay (make-overlay (point) (point))))
|
|
|
|
|
(overlay-put overlay 'face '(:inverse-video t))
|
|
|
|
|
overlay)
|
|
|
|
|
"Overlay used by `pm-debug-map-over-spans-and-highlight'.")
|
|
|
|
|
|
|
|
|
|
(defvar pm-debug-minor-mode-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map (kbd "M-n M-i") #'pm-debug-info-on-current-span)
|
|
|
|
|
(define-key map (kbd "M-n i") #'pm-debug-info-on-current-span)
|
|
|
|
|
(define-key map (kbd "M-n M-p") #'pm-debug-print-relevant-variables)
|
|
|
|
|
(define-key map (kbd "M-n p") #'pm-debug-print-relevant-variables)
|
|
|
|
|
(define-key map (kbd "M-n M-h") #'pm-debug-map-over-spans-and-highlight)
|
|
|
|
|
(define-key map (kbd "M-n h") #'pm-debug-map-over-spans-and-highlight)
|
|
|
|
|
(define-key map (kbd "M-n M-t t") #'pm-toggle-tracing)
|
|
|
|
|
(define-key map (kbd "M-n M-t i") #'pm-debug-toogle-info-message)
|
|
|
|
|
(define-key map (kbd "M-n M-t f") #'pm-debug-toggle-fontification)
|
|
|
|
|
(define-key map (kbd "M-n M-t p") #'pm-debug-toggle-post-command)
|
|
|
|
|
(define-key map (kbd "M-n M-t c") #'pm-debug-toggle-after-change)
|
|
|
|
|
(define-key map (kbd "M-n M-t a") #'pm-debug-toggle-all)
|
|
|
|
|
(define-key map (kbd "M-n M-t M-t") #'pm-toggle-tracing)
|
|
|
|
|
(define-key map (kbd "M-n M-t M-i") #'pm-debug-toogle-info-message)
|
|
|
|
|
(define-key map (kbd "M-n M-t M-f") #'pm-debug-toggle-fontification)
|
|
|
|
|
(define-key map (kbd "M-n M-t M-p") #'pm-debug-toggle-post-command)
|
|
|
|
|
(define-key map (kbd "M-n M-t M-c") #'pm-debug-toggle-after-change)
|
|
|
|
|
(define-key map (kbd "M-n M-t M-a") #'pm-debug-toggle-all)
|
|
|
|
|
(define-key map (kbd "M-n M-f s") #'pm-debug-fontify-current-span)
|
|
|
|
|
(define-key map (kbd "M-n M-f b") #'pm-debug-fontify-current-buffer)
|
|
|
|
|
(define-key map (kbd "M-n M-f M-t") #'pm-debug-toggle-fontification)
|
|
|
|
|
(define-key map (kbd "M-n M-f M-s") #'pm-debug-fontify-current-span)
|
|
|
|
|
(define-key map (kbd "M-n M-f M-b") #'pm-debug-fontify-current-buffer)
|
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(define-minor-mode pm-debug-minor-mode
|
|
|
|
|
"Turns on/off useful facilities for debugging polymode.
|
|
|
|
|
|
|
|
|
|
Key bindings:
|
|
|
|
|
\\{pm-debug-minor-mode-map}"
|
|
|
|
|
nil
|
|
|
|
|
" PMDBG"
|
|
|
|
|
:group 'polymode
|
|
|
|
|
(if pm-debug-minor-mode
|
|
|
|
|
(progn
|
|
|
|
|
;; this is global hook. No need to complicate with local hooks
|
|
|
|
|
(add-hook 'post-command-hook 'pm-debug-highlight-current-span))
|
|
|
|
|
(delete-overlay pm--underline-overlay)
|
|
|
|
|
(delete-overlay pm--highlight-overlay)
|
|
|
|
|
(remove-hook 'post-command-hook 'pm-debug-highlight-current-span)))
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun pm-debug-minor-mode-on ()
|
|
|
|
|
;; activating everywhere (in case font-lock infloops in a polymode buffer )
|
|
|
|
|
;; this doesn't activate in fundamental mode
|
|
|
|
|
(unless (eq major-mode 'minibuffer-inactive-mode)
|
|
|
|
|
(pm-debug-minor-mode t)))
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(define-globalized-minor-mode pm-debug-mode pm-debug-minor-mode pm-debug-minor-mode-on)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; INFO
|
|
|
|
|
|
|
|
|
|
(cl-defgeneric pm-debug-info (chunkmode))
|
|
|
|
|
(cl-defmethod pm-debug-info (chunkmode)
|
|
|
|
|
(eieio-object-name chunkmode))
|
|
|
|
|
(cl-defmethod pm-debug-info ((chunkmode pm-inner-chunkmode))
|
|
|
|
|
(format "%s head-matcher:\"%s\" tail-matcher:\"%s\""
|
|
|
|
|
(cl-call-next-method)
|
|
|
|
|
(eieio-oref chunkmode 'head-matcher)
|
|
|
|
|
(eieio-oref chunkmode 'tail-matcher)))
|
|
|
|
|
(cl-defmethod pm-debug-info ((_chunkmode pm-inner-auto-chunkmode))
|
|
|
|
|
(cl-call-next-method))
|
|
|
|
|
|
|
|
|
|
(defvar syntax-ppss-wide)
|
|
|
|
|
(defvar syntax-ppss-last)
|
|
|
|
|
(defun pm--debug-info (&optional span as-list)
|
|
|
|
|
(let* ((span (or span (and polymode-mode (pm-innermost-span))))
|
|
|
|
|
(message-log-max nil)
|
|
|
|
|
(beg (nth 1 span))
|
|
|
|
|
(end (nth 2 span))
|
|
|
|
|
(obj (nth 3 span))
|
|
|
|
|
(type (and span (or (car span) 'host))))
|
|
|
|
|
(let ((out (list (current-buffer)
|
|
|
|
|
(point-min) (point) (point-max)
|
|
|
|
|
major-mode
|
|
|
|
|
type beg end
|
|
|
|
|
(and obj (pm-debug-info obj))
|
|
|
|
|
(format "lppss:%s"
|
|
|
|
|
(if pm--emacs>26
|
|
|
|
|
(car syntax-ppss-wide)
|
|
|
|
|
syntax-ppss-last)))))
|
|
|
|
|
(if as-list
|
|
|
|
|
out
|
|
|
|
|
(apply #'format
|
|
|
|
|
"(%s) min:%d pos:%d max:%d || (%s) type:%s span:%s-%s %s %s"
|
|
|
|
|
out)))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-info-on-current-span (no-cache)
|
|
|
|
|
"Show info on current span.
|
|
|
|
|
With NO-CACHE prefix, don't use cached values of the span."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if (not polymode-mode)
|
|
|
|
|
(message "not in a polymode buffer")
|
|
|
|
|
(let ((span (pm-innermost-span nil no-cache)))
|
|
|
|
|
(message (pm--debug-info span))
|
|
|
|
|
;; (move-overlay pm--highlight-overlay (nth 1 span) (nth 2 span) (current-buffer))
|
|
|
|
|
(pm-debug-flick-region (nth 1 span) (nth 2 span)))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-report-points (&optional where)
|
|
|
|
|
(when polymode-mode
|
|
|
|
|
(let* ((bufs (eieio-oref pm/polymode '-buffers))
|
|
|
|
|
(poses (mapcar (lambda (b)
|
|
|
|
|
(format "%s:%d" b (with-current-buffer b (point))))
|
|
|
|
|
bufs)))
|
|
|
|
|
(message "<%s> cb:%s %s" (or where "") (current-buffer) poses)))
|
|
|
|
|
nil)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; TOGGLING
|
|
|
|
|
|
|
|
|
|
(defvar pm-debug-display-info-message nil)
|
|
|
|
|
(defun pm-debug-toogle-info-message ()
|
|
|
|
|
"Toggle permanent info display."
|
|
|
|
|
(interactive)
|
|
|
|
|
(setq pm-debug-display-info-message (not pm-debug-display-info-message)))
|
|
|
|
|
|
|
|
|
|
(defvar poly-lock-allow-fontification)
|
|
|
|
|
(defun pm-debug-toggle-fontification ()
|
|
|
|
|
"Enable or disable fontification in polymode buffers."
|
|
|
|
|
(interactive)
|
|
|
|
|
(if poly-lock-allow-fontification
|
|
|
|
|
(progn
|
|
|
|
|
(message "fontificaiton disabled")
|
|
|
|
|
(dolist (b (buffer-list))
|
|
|
|
|
(with-current-buffer b
|
|
|
|
|
(when polymode-mode
|
|
|
|
|
(setq poly-lock-allow-fontification nil
|
|
|
|
|
font-lock-mode nil
|
|
|
|
|
fontification-functions nil)))))
|
|
|
|
|
(message "fontificaiton enabled")
|
|
|
|
|
(dolist (b (buffer-list))
|
|
|
|
|
(with-current-buffer b
|
|
|
|
|
(when polymode-mode
|
|
|
|
|
(setq poly-lock-allow-fontification t
|
|
|
|
|
font-lock-mode t
|
|
|
|
|
fontification-functions '(poly-lock-function)))))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-toggle-after-change ()
|
|
|
|
|
"Allow or disallow polymode actions in `after-change-functions'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(if pm-allow-after-change-hook
|
|
|
|
|
(progn
|
|
|
|
|
(message "after-change disabled")
|
|
|
|
|
(setq pm-allow-after-change-hook nil))
|
|
|
|
|
(message "after-change enabled")
|
|
|
|
|
(setq pm-allow-after-change-hook t)))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-toggle-post-command ()
|
|
|
|
|
"Allow or disallow polymode actions in `post-command-hook'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(if pm-allow-post-command-hook
|
|
|
|
|
(progn
|
|
|
|
|
(message "post-command disabled")
|
|
|
|
|
(setq pm-allow-post-command-hook nil))
|
|
|
|
|
(message "post-command enabled")
|
|
|
|
|
(setq pm-allow-post-command-hook t)))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-toggle-all ()
|
|
|
|
|
"Toggle all polymode guards back and forth."
|
|
|
|
|
(interactive)
|
|
|
|
|
(if poly-lock-allow-fontification
|
|
|
|
|
(progn
|
|
|
|
|
(message "fontificaiton, after-chnage and command-hook disabled")
|
|
|
|
|
(setq poly-lock-allow-fontification nil
|
|
|
|
|
pm-allow-after-change-hook nil
|
|
|
|
|
pm-allow-post-command-hook nil))
|
|
|
|
|
(message "fontificaiton, after-change and command-hook enabled")
|
|
|
|
|
(setq poly-lock-allow-fontification t
|
|
|
|
|
pm-allow-after-change-hook t
|
|
|
|
|
pm-allow-post-command-hook t)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; FONT-LOCK
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-fontify-current-span ()
|
|
|
|
|
"Fontify current span."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((span (pm-innermost-span))
|
|
|
|
|
(poly-lock-allow-fontification t))
|
|
|
|
|
(poly-lock-flush (nth 1 span) (nth 2 span))
|
|
|
|
|
(poly-lock-fontify-now (nth 1 span) (nth 2 span))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-fontify-current-buffer ()
|
|
|
|
|
"Fontify current buffer."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((poly-lock-allow-fontification t))
|
|
|
|
|
(font-lock-unfontify-buffer)
|
|
|
|
|
(poly-lock-flush (point-min) (point-max))
|
|
|
|
|
(poly-lock-fontify-now (point-min) (point-max))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; TRACING
|
|
|
|
|
|
|
|
|
|
(defvar pm-traced-functions
|
|
|
|
|
'(
|
|
|
|
|
;; core initialization
|
|
|
|
|
(0 (pm-initialize
|
|
|
|
|
pm--common-setup
|
|
|
|
|
pm--mode-setup))
|
|
|
|
|
;; core hooks
|
|
|
|
|
(1 (polymode-post-command-select-buffer
|
|
|
|
|
polymode-after-kill-fixes
|
|
|
|
|
;; this one indicates the start of a sequence
|
|
|
|
|
poly-lock-after-change))
|
|
|
|
|
;; advises
|
|
|
|
|
(2 (pm-override-output-cons
|
|
|
|
|
pm-around-advice
|
|
|
|
|
polymode-with-current-base-buffer))
|
|
|
|
|
;; font-lock
|
|
|
|
|
(3 (font-lock-default-fontify-region
|
|
|
|
|
font-lock-fontify-keywords-region
|
|
|
|
|
font-lock-fontify-region
|
|
|
|
|
font-lock-fontify-syntactically-region
|
|
|
|
|
font-lock-unfontify-region
|
|
|
|
|
jit-lock--run-functions
|
|
|
|
|
jit-lock-fontify-now
|
|
|
|
|
poly-lock--after-change-internal
|
|
|
|
|
poly-lock--extend-region
|
|
|
|
|
poly-lock--extend-region-span
|
|
|
|
|
poly-lock-after-change
|
|
|
|
|
poly-lock-flush
|
|
|
|
|
poly-lock-fontify-now
|
|
|
|
|
poly-lock-function))
|
|
|
|
|
;; syntax
|
|
|
|
|
(4 (syntax-ppss
|
|
|
|
|
pm--call-syntax-propertize-original
|
|
|
|
|
polymode-syntax-propertize
|
|
|
|
|
polymode-restrict-syntax-propertize-extension
|
|
|
|
|
pm-flush-syntax-ppss-cache
|
|
|
|
|
pm--reset-ppss-cache))
|
|
|
|
|
;; core functions
|
|
|
|
|
(5 (pm-select-buffer
|
|
|
|
|
pm-map-over-spans
|
|
|
|
|
pm--get-intersected-span
|
|
|
|
|
pm--cached-span))
|
|
|
|
|
;; (13 . "^syntax-")
|
|
|
|
|
(14 . "^polymode-")
|
|
|
|
|
(15 . "^pm-")))
|
|
|
|
|
|
|
|
|
|
(defvar pm--do-trace nil)
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun pm-toggle-tracing (level)
|
|
|
|
|
"Toggle polymode tracing.
|
|
|
|
|
With numeric prefix toggle tracing for that LEVEL. Currently
|
|
|
|
|
universal argument toggles maximum level of tracing (4). Default
|
|
|
|
|
level is 3."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq level (prefix-numeric-value (or level 3)))
|
|
|
|
|
(with-current-buffer (get-buffer-create "*Messages*")
|
|
|
|
|
(read-only-mode -1))
|
|
|
|
|
(setq pm--do-trace (not pm--do-trace))
|
|
|
|
|
(if pm--do-trace
|
|
|
|
|
(progn (dolist (kv pm-traced-functions)
|
|
|
|
|
(when (<= (car kv) level)
|
|
|
|
|
(if (stringp (cdr kv))
|
|
|
|
|
(pm-trace-functions-by-regexp (cdr kv))
|
|
|
|
|
(dolist (fn (cadr kv))
|
|
|
|
|
(pm-trace fn)))))
|
|
|
|
|
(message "Polymode tracing activated"))
|
|
|
|
|
(untrace-all)
|
|
|
|
|
(message "Polymode tracing deactivated")))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun pm-trace (fn)
|
|
|
|
|
"Trace function FN.
|
|
|
|
|
Use `untrace-function' to untrace or `untrace-all' to untrace all
|
|
|
|
|
currently traced functions."
|
|
|
|
|
(interactive (trace--read-args "Trace: "))
|
|
|
|
|
(let ((buff (get-buffer "*Messages*")))
|
|
|
|
|
(unless (advice-member-p trace-advice-name fn)
|
|
|
|
|
(advice-add
|
|
|
|
|
fn :around
|
|
|
|
|
(let ((advice (trace-make-advice
|
|
|
|
|
fn buff 'background
|
|
|
|
|
#'pm-trace--tracing-context)))
|
|
|
|
|
(lambda (body &rest args)
|
|
|
|
|
(when (eq fn 'polymode-flush-syntax-ppss-cache)
|
|
|
|
|
(with-current-buffer buff
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert "\n"))))
|
|
|
|
|
(if polymode-mode
|
|
|
|
|
(apply advice body args)
|
|
|
|
|
(apply body args))))
|
|
|
|
|
`((name . ,trace-advice-name)
|
|
|
|
|
(depth . -100))))))
|
|
|
|
|
|
|
|
|
|
(defun pm-trace-functions-by-regexp (regexp)
|
|
|
|
|
"Trace all functions whose name matched REGEXP."
|
|
|
|
|
(interactive "sRegex: ")
|
|
|
|
|
(cl-loop for sym being the symbols
|
|
|
|
|
when (and (fboundp sym)
|
|
|
|
|
(not (memq sym '(pm-toggle-tracing
|
|
|
|
|
pm-trace--tracing-context
|
|
|
|
|
pm-format-span
|
|
|
|
|
pm-fun-matcher
|
|
|
|
|
pm--find-tail-from-head)))
|
|
|
|
|
(not (string-match "^pm-\\(trace\\|debug\\)" (symbol-name sym)))
|
|
|
|
|
(string-match regexp (symbol-name sym)))
|
|
|
|
|
do (pm-trace sym)))
|
|
|
|
|
|
|
|
|
|
(defun pm-trace--tracing-context ()
|
|
|
|
|
(let ((span (or *span*
|
|
|
|
|
(get-text-property (point) :pm-span))))
|
|
|
|
|
(format " [%s pos:%d(%d-%d) %s%s (%f)]"
|
|
|
|
|
(current-buffer) (point) (point-min) (point-max)
|
|
|
|
|
(or (when span
|
|
|
|
|
(when (not (and (= (point-min) (nth 1 span))
|
|
|
|
|
(= (point-max) (nth 2 span))))
|
|
|
|
|
"UNPR "))
|
|
|
|
|
"")
|
|
|
|
|
(when span
|
|
|
|
|
(pm-format-span span))
|
|
|
|
|
(float-time))))
|
|
|
|
|
|
|
|
|
|
;; fix object printing
|
|
|
|
|
(defun pm-trace--fix-1-arg-for-tracing (arg)
|
|
|
|
|
(cond
|
|
|
|
|
((eieio-object-p arg) (eieio-object-name arg))
|
|
|
|
|
((and (listp arg) (eieio-object-p (nth 3 arg)))
|
|
|
|
|
(list (nth 0 arg) (nth 1 arg) (nth 2 arg) (eieio-object-name (nth 3 arg))))
|
|
|
|
|
(arg)))
|
|
|
|
|
|
|
|
|
|
(defun pm-trace--fix-args-for-tracing (orig-fn fn level args context)
|
|
|
|
|
(let ((args (or (and (listp args)
|
|
|
|
|
(listp (cdr args))
|
|
|
|
|
(ignore-errors (mapcar #'pm-trace--fix-1-arg-for-tracing args)))
|
|
|
|
|
args)))
|
|
|
|
|
(funcall orig-fn fn level args context)))
|
|
|
|
|
|
|
|
|
|
(advice-add #'trace-entry-message :around #'pm-trace--fix-args-for-tracing)
|
|
|
|
|
(advice-add #'trace-exit-message :around #'pm-trace--fix-args-for-tracing)
|
|
|
|
|
;; (advice-remove #'trace-entry-message #'pm-trace--fix-args-for-tracing)
|
|
|
|
|
;; (advice-remove #'trace-exit-message #'pm-trace--fix-args-for-tracing)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; RELEVANT VARIABLES
|
|
|
|
|
|
|
|
|
|
(defvar pm-debug-relevant-variables
|
|
|
|
|
`(:change
|
|
|
|
|
(before-change-functions after-change-functions)
|
|
|
|
|
:command (pre-command-hook
|
|
|
|
|
post-command-hook)
|
|
|
|
|
:font-lock (fontification-functions
|
|
|
|
|
font-lock-function
|
|
|
|
|
font-lock-flush-function
|
|
|
|
|
font-lock-ensure-function
|
|
|
|
|
font-lock-fontify-region-function
|
|
|
|
|
font-lock-fontify-buffer-function
|
|
|
|
|
font-lock-unfontify-region-function
|
|
|
|
|
font-lock-unfontify-buffer-function
|
|
|
|
|
jit-lock-after-change-extend-region-functions
|
|
|
|
|
jit-lock-functions
|
|
|
|
|
poly-lock-defer-after-change)
|
|
|
|
|
;; If any of these are reset by host mode it can create issues with
|
|
|
|
|
;; font-lock and syntax (e.g. scala-mode in #195)
|
|
|
|
|
:search (parse-sexp-lookup-properties
|
|
|
|
|
parse-sexp-ignore-comments
|
|
|
|
|
;; (syntax-table)
|
|
|
|
|
;; font-lock-syntax-table
|
|
|
|
|
case-fold-search)
|
|
|
|
|
:indent (indent-line-function
|
|
|
|
|
indent-region-function
|
|
|
|
|
pm--indent-line-function-original)
|
|
|
|
|
:revert (revert-buffer-function
|
|
|
|
|
before-revert-hook
|
|
|
|
|
after-revert-hook)
|
|
|
|
|
:save (after-save-hook
|
|
|
|
|
before-save-hook
|
|
|
|
|
write-contents-functions
|
|
|
|
|
local-write-file-hooks
|
|
|
|
|
write-file-functions)
|
|
|
|
|
:syntax (syntax-propertize-function
|
|
|
|
|
syntax-propertize-extend-region-functions
|
|
|
|
|
pm--syntax-propertize-function-original)))
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun pm-debug-relevant-variables (&optional out-type)
|
|
|
|
|
"Get the relevant polymode variables.
|
|
|
|
|
If OUT-TYPE is 'buffer, print the variables in the dedicated
|
|
|
|
|
buffer, if 'message issue a message, if nil just return a list of values."
|
|
|
|
|
(interactive (list 'buffer))
|
|
|
|
|
(let* ((cbuff (current-buffer))
|
|
|
|
|
(vars (cl-loop for v on pm-debug-relevant-variables by #'cddr
|
|
|
|
|
collect (cons (car v)
|
|
|
|
|
(mapcar (lambda (v)
|
|
|
|
|
(cons v (buffer-local-value v cbuff)))
|
|
|
|
|
(cadr v))))))
|
|
|
|
|
(require 'pp)
|
|
|
|
|
(cond
|
|
|
|
|
((eq out-type 'buffer)
|
|
|
|
|
(with-current-buffer (get-buffer-create "*polymode-vars*")
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert (format "\n================== %s ===================\n" cbuff))
|
|
|
|
|
(insert (pp-to-string vars))
|
|
|
|
|
(toggle-truncate-lines -1)
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(view-mode)
|
|
|
|
|
(display-buffer (current-buffer))))
|
|
|
|
|
((eq out-type 'message)
|
|
|
|
|
(message "%s" (pp-to-string vars)))
|
|
|
|
|
(t vars))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-diff-local-vars (&optional buffer1 buffer2)
|
|
|
|
|
"Print differences between local variables in BUFFER1 and BUFFER2."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let* ((buffer1 (or buffer1 (read-buffer "Buffer1: " (buffer-name (current-buffer)))))
|
|
|
|
|
(buffer2 (or buffer2 (read-buffer "Buffer2: " (buffer-name (nth 2 (buffer-list))))))
|
|
|
|
|
(vars1 (buffer-local-variables (get-buffer buffer1)))
|
|
|
|
|
(vars2 (buffer-local-variables (get-buffer buffer2)))
|
|
|
|
|
(all-keys (delete-dups (append (mapcar #'car vars1)
|
|
|
|
|
(mapcar #'car vars2))))
|
|
|
|
|
(out-buf (get-buffer-create "*pm-debug-output")))
|
|
|
|
|
(with-current-buffer out-buf
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(pp (delq nil
|
|
|
|
|
(mapcar (lambda (k)
|
|
|
|
|
(let ((val1 (cdr (assoc k vars1)))
|
|
|
|
|
(val2 (cdr (assoc k vars2))))
|
|
|
|
|
(unless (equal val1 val2)
|
|
|
|
|
(list k val1 val2))))
|
|
|
|
|
all-keys))
|
|
|
|
|
out-buf))
|
|
|
|
|
(pop-to-buffer out-buf)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; HIGHLIGHT
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-highlight-current-span ()
|
|
|
|
|
(when polymode-mode
|
|
|
|
|
(with-silent-modifications
|
|
|
|
|
(unless (memq this-command '(pm-debug-info-on-current-span
|
|
|
|
|
pm-debug-highlight-last-font-lock-error-region))
|
|
|
|
|
(delete-overlay pm--highlight-overlay))
|
|
|
|
|
(condition-case-unless-debug err
|
|
|
|
|
(let ((span (pm-innermost-span)))
|
|
|
|
|
(when pm-debug-display-info-message
|
|
|
|
|
(message (pm--debug-info span)))
|
|
|
|
|
(move-overlay pm--underline-overlay (nth 1 span) (nth 2 span) (current-buffer)))
|
|
|
|
|
(error (message "%s" (error-message-string err)))))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-flick-region (start end &optional delay)
|
|
|
|
|
(move-overlay pm--highlight-overlay start end (current-buffer))
|
|
|
|
|
(run-with-timer (or delay 0.4) nil (lambda () (delete-overlay pm--highlight-overlay))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-map-over-spans-and-highlight ()
|
|
|
|
|
"Map over all spans in the buffer and highlight briefly."
|
|
|
|
|
(interactive)
|
|
|
|
|
(pm-map-over-spans (lambda (span)
|
|
|
|
|
(let ((start (nth 1 span))
|
|
|
|
|
(end (nth 2 span)))
|
|
|
|
|
(pm-debug-flick-region start end)
|
|
|
|
|
(sit-for 1)))
|
|
|
|
|
(point-min) (point-max) nil nil t))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-map-over-modes-and-highlight (&optional beg end)
|
|
|
|
|
"Map over all spans between BEG and END and highlight modes."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((cbuf (current-buffer)))
|
|
|
|
|
(pm-fast-map-over-modes
|
|
|
|
|
(lambda (beg end)
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
;; (dbg beg end (pm-format-span))
|
|
|
|
|
(with-current-buffer cbuf
|
|
|
|
|
(recenter-top-bottom)
|
|
|
|
|
(pm-debug-flick-region (max beg (point-min))
|
|
|
|
|
(min end (point-max))))
|
|
|
|
|
(sit-for 1))
|
|
|
|
|
(or beg (point-min))
|
|
|
|
|
(or end (point-max)))))
|
|
|
|
|
|
|
|
|
|
(defun pm-debug-run-over-check (no-cache)
|
|
|
|
|
"Map over all spans and report the time taken.
|
|
|
|
|
Switch to buffer is performed on every position in the buffer.
|
|
|
|
|
On prefix NO-CACHE don't use cached spans."
|
|
|
|
|
(interactive)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(let ((start (current-time))
|
|
|
|
|
(count 1)
|
|
|
|
|
(pm-initialization-in-progress no-cache))
|
|
|
|
|
(pm-switch-to-buffer)
|
|
|
|
|
(while (< (point) (point-max))
|
|
|
|
|
(setq count (1+ count))
|
|
|
|
|
(forward-char)
|
|
|
|
|
(pm-switch-to-buffer))
|
|
|
|
|
(let ((elapsed (float-time (time-subtract (current-time) start))))
|
|
|
|
|
(message "Elapsed: %s per-char: %s" elapsed (/ elapsed count)))))
|
|
|
|
|
|
|
|
|
|
(defun pm-dbg (msg &rest args)
|
|
|
|
|
(let ((cbuf (current-buffer))
|
|
|
|
|
(cpos (point)))
|
|
|
|
|
(with-current-buffer (get-buffer-create "*pm-dbg*")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(insert "\n")
|
|
|
|
|
(insert (apply 'format (concat "%f [%s at %d]: " msg)
|
|
|
|
|
(float-time) cbuf cpos args))))))
|
|
|
|
|
|
|
|
|
|
(provide 'polymode-debug)
|
|
|
|
|
;;; polymode-debug.el ends here
|