From 1420ce4ed2667a5f8562eefe86479dae150c90eb Mon Sep 17 00:00:00 2001 From: Robby Findler Date: Sun, 10 Feb 2013 10:14:18 -0600 Subject: [PATCH] clarify colorer docs Also, some cleanups of the code and make the syntax-color/ library docs point to color:text<%> instead of color:text% (as the interesting information is attached to the interface, not the class) --- collects/scribblings/framework/color.scrbl | 150 ++++++++++++--------- collects/syntax-color/syntax-color.scrbl | 16 ++- 2 files changed, 96 insertions(+), 70 deletions(-) diff --git a/collects/scribblings/framework/color.scrbl b/collects/scribblings/framework/color.scrbl index 19b84ee72b..184fb0efbf 100644 --- a/collects/scribblings/framework/color.scrbl +++ b/collects/scribblings/framework/color.scrbl @@ -8,24 +8,25 @@ This interface describes how coloring is stopped and started for text that knows how to color itself. It also describes how to query the lexical and s-expression structure of the text. - @defmethod*[(((start-colorer (token-sym->style (-> symbol? string?)) - (get-token (or/c (-> input-port? - (values any/c - symbol? - (or/c symbol? #f) - (or/c exact-nonnegative-integer? #f) - (or/c exact-nonnegative-integer? #f))) - (-> input-port? - exact-nonnegative-integer? - any/c - (values any/c - symbol? - (or/c symbol? #f) - (or/c exact-nonnegative-integer? #f) - (or/c exact-nonnegative-integer? #f) - exact-nonnegative-integer? - any/c)))) - (pairs (listof (list/c symbol? symbol?)))) void?))]{ + @defmethod[(start-colorer (token-sym->style (-> symbol? string?)) + (get-token (or/c (-> input-port? + (values any/c + symbol? + (or/c symbol? #f) + (or/c exact-positive-integer? #f) + (or/c exact-positive-integer? #f))) + (-> input-port? + exact-nonnegative-integer? + any/c + (values any/c + symbol? + (or/c symbol? #f) + (or/c exact-positive-integer? #f) + (or/c exact-positive-integer? #f) + exact-nonnegative-integer? + any/c)))) + (pairs (listof (list/c symbol? symbol?)))) + void?]{ Starts tokenizing the buffer for coloring and parenthesis matching. The @racket[token-sym->style] argument will be passed the first return @@ -49,8 +50,11 @@ been consumed.} @item{A symbol indicating how the token should be treated by the paren matcher or @racket[#f]. This symbol should be in the pairs argument.} - @item{The starting position of the token (or @racket[#f] if eof).} - @item{The ending position of the token (or @racket[#f] if eof).}] + @item{The starting position of the token (or @racket[#f] if eof); this + number is relative to the third result of @racket[get-port-location] + when applied to the input port that gets passed to @racket[get-token].} + @item{The ending position of the token (or @racket[#f] if eof); this + is also relative to the port's location, just like the previous value.}] When @racket[get-token] accepts an offset and mode value in addition to an input port, it must also return two extra results, which are a backup @@ -68,9 +72,7 @@ token) and for re-parsing after a change to the editor within the token's region. - The @racket[get-token] function is usually be implemented with a lexer using the - @racket[parser-tools/lex] library. The - @racket[get-token] function must obey the following invariants: + The @racket[get-token] function must obey the following invariants: @itemize[ @item{Every position in the buffer must be accounted for in exactly one token, and every token must have a non-zero width.} @@ -102,39 +104,60 @@ closing match for tokens with @racket['|[|]. When trying to correct a mismatched closing parenthesis, each closing symbol in pairs will be converted to a string and tried as a closing parenthesis. + + The @racket[get-token] function is usually be implemented with a lexer using the + @racket[parser-tools/lex] library, but can be implemented directly. + For example, here is a lexer that colors alternating characters as if they + were symbols and strings: + @racketblock[(λ (port offset mode) + (define-values (line col pos) (port-next-location port)) + (define c (read-char port)) + (cond + [(eof-object? c) + (values c 'eof #f #f #f 0 mode)] + [else + (values (string c) + (if mode 'symbol 'string) + #f + (+ pos) + (+ pos 1) + 0 + (not mode))]))] + } - @defmethod*[(((stop-colorer (clear-colors boolean? #t)) void?))]{ + @defmethod[(stop-colorer [clear-colors? boolean? #t]) void?]{ Stops coloring and paren matching the buffer. - If @racket[clear-colors] is true all the text in the buffer will have its + If @racket[clear-colors?] is true all the text in the buffer will have its style set to Standard. } - @defmethod*[(((force-stop-colorer (stop? boolean?)) void?))]{ + @defmethod[(force-stop-colorer [stop? boolean?]) void?]{ Causes the entire tokenizing/coloring system to become inactive. Intended for debugging purposes only. @racket[stop?] determines whether the system is being forced to stop or allowed to wake back up. } - @defmethod*[(((is-stopped?) boolean?))]{ + @defmethod[(is-stopped?) boolean?]{ Indicates if the colorer for this editor has been stopped, or not. } - @defmethod*[(((is-frozen?) boolean?))]{ + @defmethod[(is-frozen?) boolean?]{ Indicates if this editor's colorer is frozen. See also @method[color:text<%> freeze-colorer] and @method[color:text<%> thaw-colorer]. } - @defmethod*[(((freeze-colorer) void?))]{ + @defmethod[(freeze-colorer) void?]{ Keep the text tokenized and paren matched, but stop altering the colors. @racket[freeze-colorer] will not return until the coloring/tokenization of the entire text is brought up-to-date. It must not be called on a locked text. } - @defmethod*[(((thaw-colorer (recolor boolean? #t) (retokenize boolean? #f)) void?))]{ + @defmethod[(thaw-colorer (recolor? boolean? #t) (retokenize? boolean? #f)) + void?]{ Start coloring a frozen buffer again. If @racket[recolor?] is @racket[#t], the text is re-colored. If it is @@ -146,11 +169,11 @@ background after the call to @racket[thaw-colorer] returns. } - @defmethod*[(((reset-region (start natural-number/c) (end (or/c (quote end) natural-number/c))) void?))]{ + @defmethod[(reset-region (start exact-nonnegative-integer?) (end (or/c exact-nonnegative-integer? 'end))) void?]{ Set the region of the text that is tokenized. } - @defmethod*[(((reset-regions (regions (listof (list/c number? (or/c (quote end) number?))))) void?))]{ + @defmethod[(reset-regions (regions (listof (list/c exact-nonnegative-integer? (or/c exact-nonnegative-integer? 'end))))) void?]{ Sets the currently active regions to be @racket[regions]. } @@ -175,12 +198,15 @@ If the result is @racket[#f], then the default dictionary is used. } - @defmethod*[(((get-regions) (listof (list/c number? (or/c (quote end) number?)))))]{ + @defmethod[(get-regions) (listof (list/c exact-nonnegative-integer? (or/c exact-nonnegative-integer? 'end)))]{ This returns the list of regions that are currently being colored in the editor. } - @defmethod*[(((skip-whitespace (position natural-number/c) (direction (symbols (quote forward) (quote backward))) (comments? boolean?)) natural-number/c))]{ + @defmethod[(skip-whitespace (position exact-nonnegative-integer?) + (direction (or/c 'forward 'backward)) + (comments? boolean?)) + exact-nonnegative-integer?]{ Returns the next non-whitespace character. Starts from position and skips whitespace in the direction indicated by @@ -190,7 +216,8 @@ Must only be called while the tokenizer is started. } - @defmethod*[(((backward-match (position natural-number/c) (cutoff natural-number/c)) (or/c natural-number/c false?)))]{ + @defmethod[(backward-match [position exact-nonnegative-integer?] [cutoff exact-nonnegative-integer?]) + (or/c exact-nonnegative-integer? #f)]{ Skip all consecutive whitespaces and comments (using @racket[skip-whitespace]) immediately preceding the position. If the token @@ -200,14 +227,16 @@ Must only be called while the tokenizer is started. } - @defmethod*[(((backward-containing-sexp (position natural-number/c) (cutoff natural-number/c)) (or/c natural-number/c false?)))]{ + @defmethod[(backward-containing-sexp [position exact-nonnegative-integer?] [cutoff exact-nonnegative-integer?]) + (or/c exact-nonnegative-integer? #f)]{ Return the starting position of the interior of the (non-atomic) s-expression containing position, or @racket[#f] is there is none. Must only be called while the tokenizer is started. } - @defmethod*[(((forward-match (position natural-number/c) (cutoff natural-number/c)) (or/c natural-number/c false?)))]{ + @defmethod[(forward-match [position exact-nonnegative-integer?] [cutoff exact-nonnegative-integer?]) + (or/c exact-nonnegative-integer? #f)]{ Skip all consecutive whitespaces and comments (using @racket[skip-whitespace]) immediately following position. If the token at @@ -217,9 +246,10 @@ Must only be called while the tokenizer is started. } - @defmethod*[(((insert-close-paren (position natural-number/c) (char char?) - (flash? boolean?) (fixup? boolean?) - (smart-skip? (or/c #f 'adjacent 'forward) #f)) void?))]{ + @defmethod[(insert-close-paren (position exact-nonnegative-integer?) (char char?) + (flash? boolean?) (fixup? boolean?) + (smart-skip? (or/c #f 'adjacent 'forward) #f)) + void?]{ Inserts a close parentheses, or, under scenarios described further below, skips past a subsequent one. The @racket[position] is the place to put the parenthesis, or from which to start searching for a subsequent one, and @@ -252,7 +282,8 @@ @racket[smart-skip?], if there is no subsequent parenthesis, then a parenthesis is simply inserted, as previously described. } - @defmethod*[(((classify-position (position exact-nonnegative-integer?)) (or/c symbol? #f)))]{ + @defmethod[(classify-position [position exact-nonnegative-integer?]) + (or/c symbol? #f)]{ Return a symbol for the lexer-determined token type for the token that contains the item after @racket[position]. @@ -287,27 +318,20 @@ @defmixin[color:text-mixin (text:basic<%>) (color:text<%>)]{ Adds the functionality needed for on-the-fly coloring and parenthesis matching based on incremental tokenization of the text. - @defmethod*[#:mode override (((lock) void?))]{ - } - @defmethod*[#:mode override (((on-focus) void?))]{ - } - @defmethod*[#:mode augment (((after-edit-sequence) void?))]{ - } - @defmethod*[#:mode augment (((after-set-position) void?))]{ - } - @defmethod*[#:mode augment (((after-change-style) void?))]{ - } - @defmethod*[#:mode augment (((on-set-size-constraint) void?))]{ + @defmethod[#:mode override (lock) void?]{} + @defmethod[#:mode override (on-focus) void?]{} + @defmethod[#:mode augment (after-edit-sequence) void?]{} + @defmethod[#:mode augment (after-set-position) void?]{} + @defmethod[#:mode augment (after-change-style) void?]{} + @defmethod[#:mode augment (on-set-size-constraint) void?]{} + @defmethod[#:mode augment (after-insert) void?]{} + @defmethod[#:mode augment (after-delete) void?]{} +} - } - @defmethod*[#:mode augment (((after-insert) void?))]{ - } - @defmethod*[#:mode augment (((after-delete) void?))]{ - } -} @defclass[color:text% (color:text-mixin text:keymap%) ()]{} -@definterface[color:text-mode<%> ()]{ -} + +@definterface[color:text-mode<%> ()]{} + @defmixin[color:text-mode-mixin (mode:surrogate-text<%>) (color:text-mode<%>)]{ This mixin adds coloring functionality to the mode. @@ -318,10 +342,8 @@ The arguments are passed to @method[color:text<%> start-colorer]. } - @defmethod*[#:mode override (((on-disable-surrogate) void?))]{ - } - @defmethod*[#:mode override (((on-enable-surrogate) void?))]{ - } + @defmethod[#:mode override (on-disable-surrogate) void?]{} + @defmethod[#:mode override (on-enable-surrogate) void?]{} } @defclass[color:text-mode% (color:text-mode-mixin mode:surrogate-text%) ()]{} diff --git a/collects/syntax-color/syntax-color.scrbl b/collects/syntax-color/syntax-color.scrbl index a7f0007cb1..d5b863d76d 100644 --- a/collects/syntax-color/syntax-color.scrbl +++ b/collects/syntax-color/syntax-color.scrbl @@ -15,7 +15,7 @@ @author["Scott Owens"] The @filepath{syntax-color} collection provides the underlying data -structures and some helpful utilities for the @racket[color:text%] +structures and some helpful utilities for the @racket[color:text<%>] class of the @other-manual['(lib "scribblings/framework/framework.scrbl")]. @@ -44,7 +44,7 @@ Parenthesis matching code built on top of @racket[token-tree%]. A lexer for Racket, including reader extensions (@secref[#:doc'(lib "scribblings/reference/reference.scrbl")]{Reader_Extension}), built -specifically for @racket[color:text%]. +specifically for @racket[color:text<%>]. The @racket[racket-lexer] function returns 5 values: @@ -103,7 +103,7 @@ This function is used by @racket[scribble-lexer].} A lexer that only identifies @litchar{(}, @litchar{)}, @litchar{[}, @litchar{]}, @litchar["{"], and @litchar["}"] built specifically for -@racket[color:text%]. +@racket[color:text<%>]. @racket[default-lexer] returns 5 values: @@ -163,7 +163,7 @@ Like @racket[racket-lexer], but with several differences: @racket[get-info] function, then it is called with @racket['color-lexer]. If the result is not @racket[#f], then it should be a lexer function for use with - @racket[color:text%]. The result mode is the lexer---paired + @racket[color:text<%>]. The result mode is the lexer---paired with @racket[#f] if the lexer is a procedure arity 3---so that future calls will dispatch to the language-supplied lexer. @@ -276,5 +276,9 @@ Inserts @racket[tree1] into @racket[tree2] as the last thing, setting @defproc[(insert-last-spec! [tree (is-a?/c token-tree%)] [n natural-number/c] [v any/c]) void?]{ -Same as @racket[(insert-last! tree (new token-tree% [length n] [data -v]))]. This optimization is important for the colorer.} +Same as @racketblock[(insert-last! tree + (new token-tree% + [length n] + [data v]))] + +This optimization is important for the colorer.}