I think you want to count paragraphs not lines (and leave space when lines wrap). Otherwise the numbers won't match up with the error messages.
Robby On Wednesday, November 3, 2010, <rafk...@racket-lang.org> wrote: > rafkind has updated `master' from c990d602b0 to 68c197f639. > http://git.racket-lang.org/plt/c990d602b0..68c197f639 > > =====[ 3 Commits ]====================================================== > > Directory summary: > 92.7% collects/framework/private/ > 7.2% collects/scribblings/framework/ > > ~~~~~~~~~~ > > 4a69c36 Jon Rafkind <rafk...@racket-lang.org> 2010-11-03 14:56 > : > | use line locations instead of counting snips > : > M collects/framework/private/text.rkt | 30 ++++++++++++++++++++++++++++++ > > ~~~~~~~~~~ > > 7f56e67 Jon Rafkind <rafk...@racket-lang.org> 2010-11-03 15:09 > : > | add line number interface documentation > : > M collects/scribblings/framework/text.scrbl | 23 +++++++++++++++++++++++ > > ~~~~~~~~~~ > > 68c197f Jon Rafkind <rafk...@racket-lang.org> 2010-11-03 15:15 > : > | clean up line numbers code > : > M collects/framework/private/text.rkt | 172 +++---------------------------- > > =====[ Overall Diff ]=================================================== > > collects/framework/private/text.rkt > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/framework/private/text.rkt > +++ NEW/collects/framework/private/text.rkt > @@ -3707,17 +3707,25 @@ designates the character that triggers autocompletion > showing-line-numbers? > set-line-numbers-color)) > > +;; draws line numbers on the left hand side of a text% object > (define line-numbers-mixin > (mixin ((class->interface text%)) (line-numbers<%>) > (super-new) > (inherit get-visible-line-range > get-visible-position-range > find-position > + line-location > line-start-position > line-end-position) > > (init-field [line-numbers-color "black"]) > (init-field [show-line-numbers? #t]) > + > + ;; maybe make this a configurable field? > + (define number-space "10000") > + ;; add an extra 0 so it looks nice > + (define number-space+1 (string-append number-space "0")) > + > (define cached-snips (list)) > (define need-to-recalculate-snips #f) > > @@ -3739,153 +3747,37 @@ designates the character that triggers autocompletion > (send style-list basic-style))]) > (send std get-font))) > > - ;; get the y position of a snip > - (define (get-snip-y snip) > - (define x (box 0)) > - (define y (box 0)) > - (send this get-snip-location snip x y) > - (unbox y)) > - > - ;; returns an ordered list of snip y positions > - ;; the point is to get a list of snips positions that define > - ;; where lines start. for snips that take up more than one > - ;; line, like images, subsequent snips might be merged in with > - ;; the line that the image sits on. if you have > - ;; 2: II > - ;; IIx > - ;; Where the I's represent a contiguous image and the 'x' is just a > letter > - ;; then the 'x' snip shouldn't produce a line, it will be on line 2 along > - ;; with the I image. > - ;; To compute this we just test if the 'x' snip's y position is within > the > - ;; bounds of the I image [I.y, I.y + I.height]. It might look like we > should > - ;; test if the entire bounds of the 'x' snip is within the bounds of the > image, > - ;; that is test the height of 'x' too, but the bottom of 'x' might be > below > - ;; the bottom of I. In that case they are still considered to be on the > same > - ;; line, so we only consider the top of 'x' (its y location). > - (define (snip-heights snip dc) > - (define-struct snip-size (start end)) > - (define (get-size snip) > - (define x (box 0)) > - (define y (box 0)) > - (send this get-snip-location snip x y) > - (define width (box 0)) > - (define height (box 0)) > - (send snip get-extent dc (unbox x) (unbox y) width height) > - (make-snip-size (unbox y) (+ (unbox y) (unbox height)))) > - ;; size2 can be merged into size1 > - (define (can-merge? size1 size2) > - ;; just consider the top of the second snip > - (and (between (snip-size-start size1) > - (snip-size-start size2) > - (snip-size-end size1)) > - ;; and ignore its bottom > - #; > - (between (snip-size-start size1) > - (snip-size-end size2) > - (snip-size-end size1)))) > - ;; merge snips heights together for when snips span multiple lines > - (define (merge-sizes sizes) > - (match sizes > - [(list size1 size2 rest ...) > - (if (can-merge? size1 size2) > - (merge-sizes (cons size1 rest)) > - (cons size1 (merge-sizes (cons size2 rest))))] > - [else sizes])) > - > - ;; get a list of all snips, sort them, merge them > - (let loop ([all '()] > - [snip snip]) > - (if snip > - (loop (cons (get-size snip) all) (send snip next)) > - (map (lambda (size) > - (snip-size-start size)) > - (merge-sizes (remove-duplicates > - (sort (reverse all) > - (lambda (a b) > - (< (snip-size-start a) > - (snip-size-start b)))))))))) > - > - ;; not used, just for testing > - (define (show-all-snips dc) > - (define snip (send this find-first-snip)) > - (newline) > - (define (next snip) > - (when snip > - (define x (box 0)) > - (define y (box 0)) > - (send this get-snip-location snip x y) > - #; > - (printf "Snip ~a at ~a,~a\n" snip (unbox x) (unbox y)) > - (next (send snip next)))) > - (next snip)) > - > ;; a <= b <= c > (define (between low what high) > (and (>= what low) > (<= what high))) > > - ;; finds the first item in the sequence for which `ok?' returns true > - (define (find-first sequence ok?) > - (define-values (more? get) (sequence-generate sequence)) > - (let loop () > - (if (more?) > - (if (ok? (get)) > - #t > - (loop)) > - #f))) > - > - ;; true if the `y' location is within the positions specified by the > - ;; lines `start' and `end' > - (define (ok-height y start end) > - (define position (find-position 0 y)) > - ;; this is why we need some `break' ability in for loops > - (find-first (in-range start end) > - (lambda (line) > - (define low (line-start-position line)) > - (define high (line-end-position line)) > - (between low position high)))) > - > - ;; lazily reload the snip heights > - ;; this isn't quite incremental but its better than recalculating > - ;; on every redraw > - (define/augment (on-insert start length) > - (set! need-to-recalculate-snips #t) > - (inner (void) on-insert start length)) > - > - (define (get-snip-heights dc) > - (when need-to-recalculate-snips > - (set! need-to-recalculate-snips #f) > - (set! cached-snips (snip-heights (send this find-first-snip) dc))) > - cached-snips) > - > ;; set the dc stuff to values we want > (define (setup-dc dc) > (send dc set-font (get-style-font)) > (send dc set-text-foreground (make-object color% line-numbers-color))) > > - (define (draw-line-numbers dc left top right bottom dx dy) > + (define (draw-numbers dc top bottom dy start-line end-line) > (define (draw-text . args) > (send/apply dc draw-text args)) > - (define old-pen (send dc get-pen)) > - (setup-dc dc) > - #; > - (define-values (font-width font-height baseline space) > - (send dc get-text-extent "a")) > + (for ([line (in-range start-line end-line)]) > + (define y (line-location line)) > + (when (between top y bottom) > + (draw-text (number->string (add1 line)) 0 (+ dy y))))) > + > + ;; draw the line between the line numbers and the actual text > + (define (draw-separator dc top bottom dy x) > + (send dc draw-line x (+ dy top) x (+ dy bottom))) > > - (define heights (get-snip-heights dc)) > + (define (draw-line-numbers dc left top right bottom dx dy) > + (setup-dc dc) > (define start-line (box 0)) > (define end-line (box 0)) > (get-visible-line-range start-line end-line #f) > - (for ([y heights] > - [line (in-naturals 1)]) > - (when (and (between top y bottom) > - (ok-height y (unbox start-line) (add1 (unbox end-line)))) > - (draw-text (number->string line) 0 (+ dy y)))) > > - ;; draw the line between the line numbers and the actual text > - (define line-x (text-width dc "10000")) > - (send dc draw-line line-x (+ dy top) line-x (+ dy bottom)) > - ) > + ;; draw it! > + (draw-numbers dc top bottom dy (unbox start-line) (add1 (unbox > end-line))) > + (draw-separator dc top bottom dy (text-width dc "10000"))) > > (define (text-width dc stuff) > (define-values (font-width font-height baseline space) > @@ -3904,11 +3796,11 @@ designates the character that triggers autocompletion > (when show-line-numbers? > (if before? > (let () > + ;; FIXME: Moving the origin and setting the clipping rectangle > + ;; will probably go away when 'margin's are added to editors > + ;; > ;; save old origin and push it to the right a little bit > ;; TODO: maybe allow the line numbers to be drawn on the right > hand side? > - (define number-space "10000") > - ;; add an extra 0 so it looks nice > - (define number-space+1 "100000") > (define-values (x y) (send dc get-origin)) > (set! old-origin-x x) > (set! old-origin-y y) > > collects/scribblings/framework/text.scrbl > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > --- OLD/collects/scribblings/framework/text.scrbl > +++ NEW/collects/scribblings/framework/text.scrbl > @@ -1164,6 +1164,24 @@ > �...@defclass[text:searching% (text:searching-mixin text:backup-autosave%) > ()]{} > �...@defclass[text:info% (text:info-mixin (editor:info-mixin > text:searching%)) ()]{} > > +...@definterface[text:line-numbers<%> ()]{ > + > + �...@defmethod*[(((show-line-numbers! (show boolean?)) void))]{ > + > + Enables or disables line number drawing. > + } > + > + �...@defmethod*[(((show-line-numbers?) boolean?))]{ > + > + Returns whether or not line drawing is enabled. > + } > + > + �...@defmethod*[(((set-line-numbers-color (color string?)) void?))]{ > + > + Sets the color of the line numbers. > + } > +} > + > �...@defmixin[text:line-numbers-mixin (text%) (text:line-numbers<%>)]{ > > @defmethod*[#:mode override (((on-paint) void))]{ > @@ -1180,6 +1198,11 @@ > > Returns whether or not line drawing is enabled. > } > + > + �...@defmethod*[(((set-line-numbers-color (color string?)) void?))]{ > + > + Sets the color of the line numbers. > + } > } > > @(include-previously-extracted "main-extracts.ss" #rx"^text:") > _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev