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)

original commit: 1420ce4ed2667a5f8562eefe86479dae150c90eb
This commit is contained in:
Robby Findler 2013-02-10 10:14:18 -06:00
parent 0bce7bb082
commit 73787f6170

View File

@ -8,24 +8,25 @@
This interface describes how coloring is stopped and started for text This interface describes how coloring is stopped and started for text
that knows how to color itself. It also describes how to query the that knows how to color itself. It also describes how to query the
lexical and s-expression structure of the text. lexical and s-expression structure of the text.
@defmethod*[(((start-colorer (token-sym->style (-> symbol? string?)) @defmethod[(start-colorer (token-sym->style (-> symbol? string?))
(get-token (or/c (-> input-port? (get-token (or/c (-> input-port?
(values any/c (values any/c
symbol? symbol?
(or/c symbol? #f) (or/c symbol? #f)
(or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f)
(or/c exact-nonnegative-integer? #f))) (or/c exact-positive-integer? #f)))
(-> input-port? (-> input-port?
exact-nonnegative-integer? exact-nonnegative-integer?
any/c any/c
(values any/c (values any/c
symbol? symbol?
(or/c symbol? #f) (or/c symbol? #f)
(or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f)
(or/c exact-nonnegative-integer? #f) (or/c exact-positive-integer? #f)
exact-nonnegative-integer? exact-nonnegative-integer?
any/c)))) any/c))))
(pairs (listof (list/c symbol? symbol?)))) void?))]{ (pairs (listof (list/c symbol? symbol?))))
void?]{
Starts tokenizing the buffer for coloring and parenthesis matching. Starts tokenizing the buffer for coloring and parenthesis matching.
The @racket[token-sym->style] argument will be passed the first return The @racket[token-sym->style] argument will be passed the first return
@ -49,8 +50,11 @@
been consumed.} been consumed.}
@item{A symbol indicating how the token should be treated by the paren @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.} 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 starting position of the token (or @racket[#f] if eof); this
@item{The ending position of the token (or @racket[#f] if eof).}] 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 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 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 token) and for re-parsing after a change to the editor within the token's
region. region.
The @racket[get-token] function is usually be implemented with a lexer using the The @racket[get-token] function must obey the following invariants:
@racket[parser-tools/lex] library. The
@racket[get-token] function must obey the following invariants:
@itemize[ @itemize[
@item{Every position in the buffer must be accounted for in exactly one @item{Every position in the buffer must be accounted for in exactly one
token, and every token must have a non-zero width.} 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 closing match for tokens with @racket['|[|]. When trying to correct a
mismatched closing parenthesis, each closing symbol in pairs will be mismatched closing parenthesis, each closing symbol in pairs will be
converted to a string and tried as a closing parenthesis. 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. 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. 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. Causes the entire tokenizing/coloring system to become inactive.
Intended for debugging purposes only. Intended for debugging purposes only.
@racket[stop?] determines whether the system is being forced to stop or @racket[stop?] determines whether the system is being forced to stop or
allowed to wake back up. 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. 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 Indicates if this editor's colorer is frozen. See also
@method[color:text<%> freeze-colorer] @method[color:text<%> freeze-colorer]
and and
@method[color:text<%> thaw-colorer]. @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. Keep the text tokenized and paren matched, but stop altering the colors.
@racket[freeze-colorer] will not return until the coloring/tokenization of @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 the entire text is brought up-to-date. It must not be called on a locked
text. 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. Start coloring a frozen buffer again.
If @racket[recolor?] is @racket[#t], the text is re-colored. If it is 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. 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. 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]. 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. 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 This returns the list of regions that are currently being colored in the
editor. 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. Returns the next non-whitespace character.
Starts from position and skips whitespace in the direction indicated by Starts from position and skips whitespace in the direction indicated by
@ -190,7 +216,8 @@
Must only be called while the tokenizer is started. 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 Skip all consecutive whitespaces and comments (using
@racket[skip-whitespace]) immediately preceding the position. If the token @racket[skip-whitespace]) immediately preceding the position. If the token
@ -200,14 +227,16 @@
Must only be called while the tokenizer is started. 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) Return the starting position of the interior of the (non-atomic)
s-expression containing position, or @racket[#f] is there is none. s-expression containing position, or @racket[#f] is there is none.
Must only be called while the tokenizer is started. 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 Skip all consecutive whitespaces and comments (using
@racket[skip-whitespace]) immediately following position. If the token at @racket[skip-whitespace]) immediately following position. If the token at
@ -217,9 +246,10 @@
Must only be called while the tokenizer is started. Must only be called while the tokenizer is started.
} }
@defmethod*[(((insert-close-paren (position natural-number/c) (char char?) @defmethod[(insert-close-paren (position exact-nonnegative-integer?) (char char?)
(flash? boolean?) (fixup? boolean?) (flash? boolean?) (fixup? boolean?)
(smart-skip? (or/c #f 'adjacent 'forward) #f)) void?))]{ (smart-skip? (or/c #f 'adjacent 'forward) #f))
void?]{
Inserts a close parentheses, or, under scenarios described further below, skips 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 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 from which to start searching for a subsequent one, and
@ -252,7 +282,8 @@
@racket[smart-skip?], if there is no subsequent parenthesis, then @racket[smart-skip?], if there is no subsequent parenthesis, then
a parenthesis is simply inserted, as previously described. 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 Return a symbol for the lexer-determined token type for the token that
contains the item after @racket[position]. contains the item after @racket[position].
@ -287,27 +318,20 @@
@defmixin[color:text-mixin (text:basic<%>) (color:text<%>)]{ @defmixin[color:text-mixin (text:basic<%>) (color:text<%>)]{
Adds the functionality needed for on-the-fly coloring and parenthesis Adds the functionality needed for on-the-fly coloring and parenthesis
matching based on incremental tokenization of the text. matching based on incremental tokenization of the text.
@defmethod*[#:mode override (((lock) 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 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?))]{
}
}
@defclass[color:text% (color:text-mixin text:keymap%) ()]{} @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<%>)]{ @defmixin[color:text-mode-mixin (mode:surrogate-text<%>) (color:text-mode<%>)]{
This mixin adds coloring functionality to the mode. This mixin adds coloring functionality to the mode.
@ -318,10 +342,8 @@
The arguments are passed to The arguments are passed to
@method[color:text<%> start-colorer]. @method[color:text<%> start-colorer].
} }
@defmethod*[#:mode override (((on-disable-surrogate) void?))]{ @defmethod[#:mode override (on-disable-surrogate) void?]{}
} @defmethod[#:mode override (on-enable-surrogate) void?]{}
@defmethod*[#:mode override (((on-enable-surrogate) void?))]{
}
} }
@defclass[color:text-mode% (color:text-mode-mixin mode:surrogate-text%) ()]{} @defclass[color:text-mode% (color:text-mode-mixin mode:surrogate-text%) ()]{}