macro-stepper: syntax display speedups (?)

switched from style-deltas to styles
  tree traversal of ranges, avoid idempotent style changes

svn: r16407
This commit is contained in:
Ryan Culpepper 2009-10-22 06:00:15 +00:00
parent 98ce5f37af
commit 07321ca17c
4 changed files with 134 additions and 57 deletions

View File

@ -1,19 +1,35 @@
#lang scheme/base #lang scheme/base
(require scheme/class (require scheme/class
scheme/gui scheme/gui
scheme/match scheme/list
macro-debugger/util/class-iop macro-debugger/util/class-iop
(only-in mzlib/etc begin-with-definitions)
"pretty-printer.ss" "pretty-printer.ss"
"interfaces.ss" "interfaces.ss"
"util.ss") "util.ss")
(provide print-syntax-to-editor (provide print-syntax-to-editor
code-style) code-style)
(define TIME-PRINTING? #f)
(define-syntax-rule (now)
(if TIME-PRINTING?
(current-inexact-milliseconds)
0))
(define eprintf
(if TIME-PRINTING?
(let ([eport (current-error-port)])
(lambda (fmt . args) (apply fprintf eport fmt args)))
void))
;; FIXME: assumes text never moves ;; FIXME: assumes text never moves
;; print-syntax-to-editor : syntax text controller<%> config number number ;; print-syntax-to-editor : syntax text controller<%> config number number
;; -> display<%> ;; -> display<%>
(define (print-syntax-to-editor stx text controller config columns insertion-point) (define (print-syntax-to-editor stx text controller config columns insertion-point)
(begin-with-definitions
(define **entry (now))
(define output-port (open-output-string/count-lines)) (define output-port (open-output-string/count-lines))
(define range (define range
(pretty-print-syntax stx output-port (pretty-print-syntax stx output-port
@ -21,23 +37,39 @@
(send: config config<%> get-colors) (send: config config<%> get-colors)
(send: config config<%> get-suffix-option) (send: config config<%> get-suffix-option)
columns)) columns))
(define **range (now))
(define output-string (get-output-string output-port)) (define output-string (get-output-string output-port))
(define output-length (sub1 (string-length output-string))) ;; skip final newline (define output-length (sub1 (string-length output-string))) ;; skip final newline
(fixup-parentheses output-string range) (fixup-parentheses output-string range)
(let ([display (define **fixup (now))
(define display
(new display% (new display%
(text text) (text text)
(controller controller) (controller controller)
(config config) (config config)
(range range) (range range)
(base-style (standard-font text config))
(start-position insertion-point) (start-position insertion-point)
(end-position (+ insertion-point output-length)))]) (end-position (+ insertion-point output-length))))
(send text begin-edit-sequence) (send text begin-edit-sequence)
(define **editing (now))
(send text insert output-length output-string insertion-point) (send text insert output-length output-string insertion-point)
(define **inserted (now))
(add-clickbacks text range controller insertion-point) (add-clickbacks text range controller insertion-point)
(set-standard-font text config insertion-point (+ insertion-point output-length)) (define **clickbacks (now))
(send display initialize) (send display initialize)
(define **colorize (now))
(send text end-edit-sequence) (send text end-edit-sequence)
(define **finished (now))
(when TIME-PRINTING?
(eprintf "** pretty-print: ~s\n" (- **range **entry))
(eprintf "** fixup, begin-edit-sequence: ~s\n" (- **editing **range))
(eprintf "** > insert: ~s\n" (- **inserted **editing))
(eprintf "** > clickback: ~s\n" (- **clickbacks **inserted))
(eprintf "** > colorize: ~s\n" (- **colorize **clickbacks))
(eprintf "** finish: ~s\n" (- **finished **colorize))
(eprintf "** total: ~s\n" (- **finished **entry))
(eprintf "\n"))
display)) display))
;; add-clickbacks : text% range% controller<%> number -> void ;; add-clickbacks : text% range% controller<%> number -> void
@ -51,11 +83,8 @@
(send: controller selection-manager<%> (send: controller selection-manager<%>
set-selected-syntax stx)))))) set-selected-syntax stx))))))
;; set-standard-font : text% config number number -> void (define (standard-font text config)
(define (set-standard-font text config start end) (code-style text (send: config config<%> get-syntax-font-size)))
(send text change-style
(code-style text (send: config config<%> get-syntax-font-size))
start end))
;; display% ;; display%
(define display% (define display%
@ -64,6 +93,7 @@
[config config<%>] [config config<%>]
[range range<%>]) [range range<%>])
(init-field text (init-field text
base-style
start-position start-position
end-position) end-position)
@ -71,6 +101,7 @@
;; initialize : -> void ;; initialize : -> void
(define/public (initialize) (define/public (initialize)
(send text change-style base-style start-position end-position #f)
(apply-primary-partition-styles) (apply-primary-partition-styles)
(refresh)) (refresh))
@ -125,26 +156,30 @@
;; Changes the foreground color according to the primary partition. ;; Changes the foreground color according to the primary partition.
;; Only called once, when the syntax is first drawn. ;; Only called once, when the syntax is first drawn.
(define/private (apply-primary-partition-styles) (define/private (apply-primary-partition-styles)
(define style-list (send text get-style-list))
(define (color-style color) (define (color-style color)
(let ([delta (new style-delta%)]) (let ([delta (new style-delta%)])
(send delta set-delta-foreground color) (send delta set-delta-foreground color)
delta)) (send style-list find-or-create-style base-style delta)))
(define color-styles (define color-styles
(list->vector (map color-style (send: config config<%> get-colors)))) (list->vector (map color-style (send: config config<%> get-colors))))
(define overflow-style (color-style "darkgray")) (define overflow-style (color-style "darkgray"))
(define color-partition (define color-partition
(send: controller mark-manager<%> get-primary-partition)) (send: controller mark-manager<%> get-primary-partition))
(define offset start-position) (define offset start-position)
(for-each ;; Optimization: don't call change-style when new style = old style
(lambda (range) (let tr*loop ([trs (send: range range<%> get-treeranges)] [old-style #f])
(let ([stx (range-obj range)] (for ([tr trs])
[start (range-start range)] (define stx (treerange-obj tr))
[end (range-end range)]) (define start (treerange-start tr))
(send text change-style (define end (treerange-end tr))
(primary-style stx color-partition color-styles overflow-style) (define subs (treerange-subs tr))
(+ offset start) (define new-style
(+ offset end)))) (primary-style stx color-partition color-styles overflow-style))
(send: range range<%> all-ranges))) (unless (eq? old-style new-style)
(send text change-style new-style (+ offset start) (+ offset end) #f))
(tr*loop subs new-style)))
(void))
;; primary-style : syntax partition (vector-of style-delta%) style-delta% ;; primary-style : syntax partition (vector-of style-delta%) style-delta%
;; -> style-delta% ;; -> style-delta%

View File

@ -109,6 +109,9 @@
(;; get-ranges : datum -> (list-of (cons number number)) (;; get-ranges : datum -> (list-of (cons number number))
get-ranges get-ranges
;; get-treeranges : -> (listof TreeRange)
get-treeranges
;; all-ranges : (list-of Range) ;; all-ranges : (list-of Range)
;; Sorted outermost-first ;; Sorted outermost-first
all-ranges all-ranges
@ -120,6 +123,8 @@
;; A Range is (make-range datum number number) ;; A Range is (make-range datum number number)
(define-struct range (obj start end)) (define-struct range (obj start end))
;; A TreeRange is (make-treerange syntax nat nat (listof TreeRange))
(define-struct treerange (obj start end subs))
;; syntax-prefs<%> ;; syntax-prefs<%>
(define-interface syntax-prefs<%> () (define-interface syntax-prefs<%> ()

View File

@ -29,8 +29,10 @@
(let-values ([(line column position) (port-next-location port)]) (let-values ([(line column position) (port-next-location port)])
(sub1 position))) (sub1 position)))
(define (pp-pre-hook obj port) (define (pp-pre-hook obj port)
(send range-builder push! obj (current-position))
(send range-builder set-start obj (current-position))) (send range-builder set-start obj (current-position)))
(define (pp-post-hook obj port) (define (pp-post-hook obj port)
(send range-builder pop! (flat=>stx obj) (current-position))
(let ([start (send range-builder get-start obj)] (let ([start (send range-builder get-start obj)]
[end (current-position)] [end (current-position)]
[stx (flat=>stx obj)]) [stx (flat=>stx obj)])
@ -110,16 +112,40 @@
(hash-set! starts obj n)) (hash-set! starts obj n))
(define/public (get-start obj) (define/public (get-start obj)
(hash-ref starts obj (lambda _ #f))) (hash-ref starts obj #f))
(define/public (add-range obj range) (define/public (add-range obj range)
(hash-set! ranges obj (cons range (get-ranges obj)))) (hash-set! ranges obj (cons range (get-ranges obj))))
(define (get-ranges obj) (define (get-ranges obj)
(hash-ref ranges obj (lambda () null))) (hash-ref ranges obj null))
(define/public (range:get-ranges) ranges) (define/public (range:get-ranges) ranges)
;; ----
(define/public (get-subs)
working-subs)
(define working-start #f)
(define working-subs null)
(define saved-starts null)
(define saved-subss null)
(define/public (push! obj start)
(set! saved-starts (cons working-start saved-starts))
(set! saved-subss (cons working-subs saved-subss))
(set! working-start start)
(set! working-subs null))
(define/public (pop! stx end)
(define latest (make-treerange stx working-start end (reverse working-subs)))
(set! working-start (car saved-starts))
(set! working-subs (car saved-subss))
(set! saved-starts (cdr saved-starts))
(set! saved-subss (cdr saved-subss))
(set! working-subs (cons latest working-subs)))
(super-new))) (super-new)))
;; range% ;; range%
@ -130,17 +156,22 @@
(super-new) (super-new)
(define ranges (hash-copy (send range-builder range:get-ranges))) (define ranges (hash-copy (send range-builder range:get-ranges)))
(define subs (reverse (send range-builder get-subs)))
(define/public (get-ranges obj) (define/public (get-ranges obj)
(hash-ref ranges obj (lambda _ null))) (hash-ref ranges obj null))
(define/public (get-treeranges)
subs)
(define/public (all-ranges) (define/public (all-ranges)
sorted-ranges) (force sorted-ranges))
(define/public (get-identifier-list) (define/public (get-identifier-list)
identifier-list) identifier-list)
(define sorted-ranges (define sorted-ranges
(delay
(sort (sort
(apply append (apply append
(hash-map (hash-map
@ -149,5 +180,7 @@
(map (lambda (v) (make-range k (car v) (cdr v))) vs)))) (map (lambda (v) (make-range k (car v) (cdr v))) vs))))
(lambda (x y) (lambda (x y)
(>= (- (range-end x) (range-start x)) (>= (- (range-end x) (range-start x))
(- (range-end y) (range-start y)))))))) (- (range-end y) (range-start y)))))))
))

View File

@ -11,9 +11,13 @@
[(with-unlock text . body) [(with-unlock text . body)
(let* ([t text] (let* ([t text]
[locked? (send t is-locked?)]) [locked? (send t is-locked?)])
(send t lock #f) (send* t
(lock #f)
(begin-edit-sequence #f))
(begin0 (let () . body) (begin0 (let () . body)
(send t lock locked?)))])) (send* t
(end-edit-sequence)
(lock locked?))))]))
;; make-text-port : text (-> number) -> port ;; make-text-port : text (-> number) -> port
;; builds a port from a text object. ;; builds a port from a text object.