
specifically, add a mode that avoids breaking the edges of the rectangle when you type and add a keystroke for adding a new in the existing row
1437 lines
59 KiB
Racket
1437 lines
59 KiB
Racket
#lang scribble/doc
|
|
@(require scribble/manual scribble/extract)
|
|
@(require (for-label framework racket/gui))
|
|
@title{Text}
|
|
|
|
@definterface[text:basic<%> (editor:basic<%> text%)]{
|
|
Classes matching this interface are expected to implement the basic
|
|
functionality needed by the framework.
|
|
@defmethod[(highlight-range [start exact-nonnegative-integer?]
|
|
[end exact-nonnegative-integer?]
|
|
[color (or/c string? (is-a?/c color%))]
|
|
[caret-space boolean? #f]
|
|
[priority (or/c 'high 'low) 'low]
|
|
[style (or/c 'rectangle 'ellipse 'hollow-ellipse 'dot) 'rectangle]
|
|
[#:adjust-on-insert/delete adjust-on-insert/delete boolean? #f]
|
|
[#:key key any/c #f])
|
|
(if adjust-on-insert/delete
|
|
void?
|
|
(-> void?))]{
|
|
This function highlights a region of text in the buffer.
|
|
|
|
The range between @racket[start] and @racket[end] will be highlighted with
|
|
the given @racket[color], if the style is @racket['rectangle] (the default). If
|
|
the style is @racket['ellipse], then an ellipse is drawn around the range
|
|
in the editor, using the color. If the style is @racket['hollow-ellipse],
|
|
then the outline of an ellipse is drawn around the range in the editor,
|
|
using the color.
|
|
|
|
If the style is @racket['dot], then @racket[start] and @racket[end] must be
|
|
the same, and a dot is drawn at the bottom of that position in the editor.
|
|
|
|
If @racket[caret-space?] is not @racket[#f], the left edge of the range
|
|
will be one pixel short, to leave space for the caret. The caret does not
|
|
interfere with the right hand side of the range. Note that under some
|
|
platforms, the caret is drawn with XOR, which means almost anything can
|
|
happen. So if the caret is in the middle of the range it may be hard to
|
|
see, or if it is on the left of the range and @racket[caret-space?] is
|
|
@racket[#f] it may also be hard to see.
|
|
|
|
The @racket[priority] argument indicates the relative priority for drawing
|
|
overlapping regions. If two regions overlap and have different priorities,
|
|
the region with @racket['high] priority will be drawn second and only it
|
|
will be visible in the overlapping region.
|
|
|
|
If @racket[adjust-on-insert/delete?] is @racket[#t], then insertions
|
|
and deletions to the text will adjust the @racket[start] and @racket[end]
|
|
of the range. Insertions and deletions before the range move the range forward
|
|
and backward; insertions and deletions after the range will be ignored. An insertion
|
|
in the middle of the range will enlarge the range and a deletion that overlaps
|
|
the range adjusts the range to reflect the deleted portion of the range and its
|
|
new position.
|
|
|
|
The @racket[key] argument can be used with
|
|
@method[text:basic<%> unhighlight-ranges/key]
|
|
and
|
|
@method[text:basic<%> unhighlight-ranges]
|
|
to identify ranges whose start and end positions may have changed.
|
|
Symbols whose names begin with @litchar{plt:} are reserved
|
|
for internal use.
|
|
|
|
If this method returns a thunk, invoking the thunk will turn off the
|
|
highlighting from this range.
|
|
|
|
Note that if @racket[adjust-on-insert/delete] is a true value, then
|
|
the result is not a thunk and instead
|
|
@method[text:basic<%> unhighlight-range],
|
|
@method[text:basic<%> unhighlight-ranges/key], or
|
|
@method[text:basic<%> unhighlight-ranges]
|
|
must be called directly to remove the highlighting.
|
|
}
|
|
|
|
@defmethod[(unhighlight-range
|
|
(start exact-nonnegative-integer?)
|
|
(end exact-nonnegative-integer?)
|
|
(color (or/c string? (is-a?/c color%)))
|
|
(caret-space boolean? #f)
|
|
(style (or/c 'rectangle 'ellipse 'hollow-ellipse) 'rectangle))
|
|
void?]{
|
|
This method removes the highlight from a region of text in the buffer.
|
|
|
|
The region must match up to a region specified from an earlier call to
|
|
@method[text:basic<%> highlight-range].
|
|
|
|
This method does a linear scan over all of the regions currently set.
|
|
If you expect to call this method many times (when there are many
|
|
ranges set)
|
|
consider instead calling @method[text:basic<%> unhighlight-ranges].
|
|
}
|
|
|
|
@defmethod[(unhighlight-ranges/key [key any/c]) void?]{
|
|
This method removes the highlight from regions in the buffer
|
|
that have the key @racket[key]
|
|
(as passed to @method[text:basic<%> highlight-range]).
|
|
}
|
|
|
|
@defmethod[(unhighlight-ranges
|
|
[pred? (-> exact-nonnegative-integer?
|
|
exact-nonnegative-integer?
|
|
(is-a?/c color%)
|
|
boolean?
|
|
(or/c 'rectangle 'ellipse 'hollow-ellipse)
|
|
(or/c boolean? exact-nonnegative-integer?)
|
|
any/c
|
|
boolean?)])
|
|
void?]{
|
|
This method removes the highlight from regions in the buffer as
|
|
selected by @racket[pred?]. The arguments to @racket[pred?] are the
|
|
same as the arguments to
|
|
@method[text:basic<%> highlight-range] when it was originally called,
|
|
unless the @racket[_adjust-on-insert/delete] argument was a true value, in which case the
|
|
first two arguments to the predicate will reflect the current state
|
|
of the bubble, if it is changed.
|
|
|
|
}
|
|
|
|
@defmethod*[(((get-highlighted-ranges) (listof text:range?)))]{
|
|
Returns a list of (opaque) values representing the active ranges in the
|
|
editor.
|
|
}
|
|
|
|
@defmethod*[(((get-styles-fixed) boolean?))]{
|
|
If the result of this function is @racket[#t], the styles in this
|
|
@racket[text:basic<%>] will be fixed. This means that any text inserted to
|
|
this editor has its style set to this editor's @racket[style-list%]'s
|
|
@racket["Standard"] style.
|
|
|
|
See also @method[text:basic<%> set-styles-fixed].
|
|
}
|
|
|
|
@defmethod*[(((get-fixed-style) (is-a?/c style<%>)))]{
|
|
Returns the style used by @method[text:basic<%> set-styles-fixed]when
|
|
setting the styles.
|
|
}
|
|
|
|
@defmethod*[(((set-styles-fixed (fixed? boolean?)) void?))]{
|
|
Sets the styles fixed parameter of this @racket[text%]. See also
|
|
@method[text:basic<%> get-styles-fixed] and @method[text:basic<%>
|
|
get-fixed-style].
|
|
}
|
|
|
|
@defmethod[(move/copy-to-edit [dest-text (is-a?/c text%)]
|
|
[start exact-integer?]
|
|
[end exact-integer?]
|
|
[dest-pos exact-integer?]
|
|
[#:try-to-move? try-to-move? boolean? #t])
|
|
void?]{
|
|
This moves or copies text and snips to another edit.
|
|
|
|
Moves or copies from the edit starting at @racket[start] and ending at
|
|
@racket[end]. It puts the copied text and snips in @racket[dest-text]
|
|
starting at location @racket[dest-pos].
|
|
|
|
If @racket[try-to-move] is @racket[#t], then the snips are removed;
|
|
and if it is @racket[#f], then they are copied.
|
|
|
|
If a snip refused to be moved, it will be copied and deleted from the editor,
|
|
otherwise it will be moved. A snip may refuse to be moved by returning
|
|
@racket[#f] from @method[snip% release-from-owner].
|
|
}
|
|
|
|
@defmethod*[(((initial-autowrap-bitmap) (or/c #f (is-a?/c bitmap%))))]{
|
|
The result of this method is used as the initial autowrap bitmap. Override
|
|
this method to change the initial @racket[bitmap%]. See also @method[text%
|
|
set-autowrap-bitmap]
|
|
|
|
Returns the result of @racket[icon:get-autowrap-bitmap] by default.
|
|
}
|
|
|
|
@defmethod*[(((get-port-name) (or/c path-string? symbol? #f)))]{
|
|
The result of this method is a symbol that identifies this editor and that
|
|
is used as the port-name of a port that is read from this editor if this
|
|
editor is used in DrRacket. See also @method[text:basic<%>
|
|
port-name-matches?].
|
|
}
|
|
|
|
@defmethod[(port-name-matches? (id any/c)) boolean?]{
|
|
Indicates if @racket[id] matches the port name of this file. If the file is
|
|
saved, the port name matches when the save file is the path as
|
|
@racket[id]. If the file has not been saved, the port name matches if the
|
|
symbol is the same as the result of @method[text:basic<%> get-port-name].
|
|
|
|
This method calls @racket[normalize-path] and thus can be very expensive on
|
|
some filesystems. If it is called many times in a loop, cache the results
|
|
to avoid calling it too often.
|
|
}
|
|
|
|
@defmethod[(set-port-unsaved-name [name string?]) void?]{
|
|
When @method[text:basic<%> get-port-name] returns a symbol, the printed
|
|
representation of the symbol will be the same as @racket[name].
|
|
}
|
|
|
|
@defmethod[(after-set-port-unsaved-name) any/c]{
|
|
This method is called after @method[text:basic<%> set-port-unsaved-name] is
|
|
called. Override it to detect changes in what @method[text:basic<%> get-port-name]
|
|
returns.
|
|
}
|
|
|
|
@defmethod[(get-edition-number) exact-nonnegative-integer?]{
|
|
Returns a number that increments every time something in the editor
|
|
changes.
|
|
|
|
The number is updated in @xmethod[text% after-insert] and
|
|
@xmethod[text% after-delete].
|
|
}
|
|
|
|
@defmethod[(get-start-of-line [pos exact-nonnegative-integer?]) exact-nonnegative-integer?]{
|
|
This method is used by @racket[keymap:setup-global] to implement a
|
|
keybinding for the @racket["home"] key and for @racket["c:a"].
|
|
|
|
Its default implementation is
|
|
@racket[(#,(method text% line-start-position) (#,(method text% position-line) pos))].
|
|
}
|
|
}
|
|
|
|
@defmixin[text:basic-mixin (editor:basic<%> text%) (text:basic<%>)]{
|
|
This mixin implements the basic functionality needed for @racket[text%]
|
|
objects in the framework.
|
|
|
|
The class that this mixin produces uses the same initialization arguments as
|
|
its input.
|
|
|
|
@defmethod*[#:mode override (((on-paint (before? any/c)
|
|
(dc (is-a?/c dc<%>))
|
|
(left real?)
|
|
(top real?)
|
|
(right real?)
|
|
(bottom real?)
|
|
(dx real?)
|
|
(dy real?)
|
|
(draw-caret (or/c 'no-caret
|
|
'show-inactive-caret
|
|
'show-caret)))
|
|
void?))]{
|
|
Draws the rectangles installed by @method[text:basic<%> highlight-range].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((on-insert (start exact-nonnegative-integer?)
|
|
(end exact-nonnegative-integer?)) void?))]{
|
|
See @method[text:basic<%> set-styles-fixed].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-insert (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) void?))]{
|
|
See @method[text:basic<%> set-styles-fixed].
|
|
}
|
|
|
|
@defmethod*[#:mode override (((put-file (directory (or/c path? #f)) (default-name string?))
|
|
(or/c path? #f)))]{
|
|
Like @method[editor<%> put-file] but uses @racket[finder:put-file] instead
|
|
of @racket[put-file].
|
|
}
|
|
}
|
|
|
|
@definterface[text:line-spacing<%> (text:basic<%>)]{
|
|
Objects implementing this interface adjust their
|
|
spacing based on the @racket['framework:line-spacing-add-gap?]
|
|
preference.
|
|
}
|
|
|
|
@defmixin[text:line-spacing-mixin (text:basic<%>) (text:line-spacing<%>)]{
|
|
Calls @method[text% set-line-spacing] to either @racket[0] or @racket[1]
|
|
when an object is created, based
|
|
on the @racket['framework:line-spacing-add-gap?]
|
|
preference.
|
|
|
|
Also registers a callback (via @racket[preferences:add-callback]) to call
|
|
@method[text% set-line-spacing] when the @racket['framework:line-spacing-add-gap?]
|
|
preference changes.
|
|
}
|
|
|
|
@definterface[text:ascii-art-enlarge-boxes<%> ()]{
|
|
@defmethod[(set-ascii-art-enlarge [e? any/c]) void?]{
|
|
Enables or disables the ascii art box enlarging mode based on @racket[e?]'s true value.
|
|
}
|
|
@defmethod[(get-ascii-art-enlarge) boolean?]{
|
|
Returns @racket[#t] if ascii art box enlarging mode is enabled and @racket[#f] otherwise.
|
|
}
|
|
}
|
|
|
|
@defmixin[text:ascii-art-enlarge-boxes-mixin (text%) (text:ascii-art-enlarge-boxes<%>)]{
|
|
@defmethod[#:mode override (on-local-char [event (is-a?/c key-event%)]) void?]{
|
|
When the @method[key-event% get-key-code] method of @racket[event] returns either
|
|
@racket['numpad-enter] or @racket[#\return] and
|
|
@method[text:ascii-art-enlarge-boxes<%> get-ascii-art-enlarge] returns
|
|
@racket[#t], this method handles
|
|
the return key by adding an additional line in the containing unicode ascii art
|
|
box and moving the insertion point to the first character on the new line that
|
|
is in the containing cell.
|
|
|
|
It does not call the @racket[super] method (in that case).
|
|
}
|
|
@defmethod[#:mode override (on-default-char [event (is-a?/c key-event%)]) void?]{
|
|
When the @method[key-event% get-key-code] method of @racket[event] returns either
|
|
a character or symbol that corresponds to the insertion of a single character
|
|
@method[text:ascii-art-enlarge-boxes<%> get-ascii-art-enlarge] returns
|
|
@racket[#t], this method first makes room in the box and then calls the
|
|
@racket[super] method. If the @method[text% get-overwrite-mode] returns
|
|
@racket[#f], then it always opens up a column in the box. If @method[text% get-overwrite-mode]
|
|
returns @racket[#t], then it opens up a column only when the character to
|
|
be inserted would overwrite one of the walls.
|
|
}
|
|
}
|
|
|
|
@definterface[text:first-line<%> (text%)]{
|
|
|
|
Objects implementing this interface, when @method[text:first-line<%>
|
|
highlight-first-line] is invoked with @racket[#t], always show their first
|
|
line, even with scrolled (as long as @method[text:first-line<%>
|
|
first-line-currently-drawn-specially?] returns @racket[#t]).
|
|
|
|
@defmethod[#:mode public-final (highlight-first-line [on? boolean?]) void?]{
|
|
Call this method to enable special treatment of the first line in the editor.
|
|
}
|
|
|
|
@defmethod[#:mode public-final (first-line-currently-drawn-specially?) boolean?]{
|
|
Returns @racket[#t] if @method[text:first-line<%> is-special-first-line?]
|
|
returned @racket[#t] for the current first line and if the buffer is
|
|
scrolled down so that the first line would not (ordinarily) be visible.
|
|
}
|
|
|
|
@defmethod[#:mode public-final (get-first-line-height) number?]{
|
|
Returns the height, in pixels, of the first line.
|
|
}
|
|
|
|
@defmethod[(is-special-first-line? [line string?]) boolean?]{
|
|
Override this method to control when the first line is always visible. The
|
|
argument is the first line, as a string.
|
|
}
|
|
}
|
|
|
|
@defmixin[text:first-line-mixin (text%) (text:first-line<%>)]{
|
|
Provides the implementation of @racket[text:first-line<%>]. Does so by just
|
|
painting the text of the first line over top of what is already there and
|
|
overriding @method[text:first-line-mixin scroll-editor-to] to patch up
|
|
scrolling and @method[text:first-line-mixin on-event] to patch up mouse
|
|
handling.
|
|
|
|
@defmethod[#:mode override
|
|
(on-paint [before? any/c]
|
|
[dc (is-a?/c dc<%>)]
|
|
[left real?]
|
|
[top real?]
|
|
[right real?]
|
|
[bottom real?]
|
|
[dx real?]
|
|
[dy real?]
|
|
[draw-caret (one-of/c 'no-caret 'show-inactive-caret 'show-caret)])
|
|
void?]{
|
|
Based on the various return values of the methods in
|
|
@racket[text:first-line], draws the first actual line of the editor over
|
|
top of the first visible line in the editor.
|
|
}
|
|
|
|
@defmethod[#:mode override
|
|
(on-event [event (is-a?/c mouse-event%)])
|
|
void?]{
|
|
Clicks in the first line cause the editor to scroll to the actual first
|
|
line.
|
|
}
|
|
|
|
@defmethod[#:mode override
|
|
(scroll-editor-to [localx real?]
|
|
[localy real?]
|
|
[width (and/c real? (not/c negative?))]
|
|
[height (and/c real? (not/c negative?))]
|
|
[refresh? any/c]
|
|
[bias (one-of/c 'start 'end 'none)])
|
|
void?]{
|
|
Scrolls a little bit more, when a scroll would be requested that scrolls
|
|
something so that it is line underneath the first line.
|
|
}
|
|
}
|
|
|
|
@definterface[text:foreground-color<%> (text:basic<%> editor:standard-style-list<%>)]{
|
|
}
|
|
|
|
@defmixin[text:foreground-color-mixin (text:basic<%> editor:standard-style-list<%>)
|
|
(text:foreground-color<%>)]{
|
|
This mixin changes the default text style to have the foreground color
|
|
controlled by @racket[editor:set-default-font-color].
|
|
|
|
@defmethod*[#:mode override (((default-style-name) string?))]{
|
|
Returns the result of @racket[editor:get-default-color-style-name].
|
|
}
|
|
|
|
@defmethod*[#:mode override (((get-fixed-style) (is-a?/c style<%>)))]{
|
|
Returns the style named by @racket[editor:get-default-color-style-name].
|
|
}
|
|
}
|
|
|
|
@definterface[text:hide-caret/selection<%> (text:basic<%>)]{
|
|
This class hides the caret, except when the selection is active.
|
|
|
|
Instances of this class are useful for editors that used for displaying
|
|
purposes, but still allow users to copy their text.
|
|
}
|
|
|
|
@defmixin[text:hide-caret/selection-mixin (text:basic<%>) (text:hide-caret/selection<%>)]{
|
|
@defmethod*[#:mode augment (((after-set-position) void?))]{
|
|
Calls @method[text% hide-caret] to hide the caret when there is only a
|
|
caret and no selection.
|
|
}
|
|
}
|
|
|
|
@definterface[text:nbsp->space<%> (text%)]{
|
|
Classes that implement this interface silently change non-breaking spaces, ie
|
|
the character @racket[(integer->char 160)], to regular spaces when inserted
|
|
into the editor.
|
|
}
|
|
|
|
@defmixin[text:nbsp->space-mixin (text%) (text:nbsp->space<%>)]{
|
|
@defmethod*[#:mode augment (((on-insert (start exact-nonnegative-integer?)
|
|
(end exact-nonnegative-integer?))
|
|
void?))]{
|
|
Starts an edit-sequence by calling @method[editor<%> begin-edit-sequence].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-insert (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?))
|
|
void?))]{
|
|
Replaces all non-breaking space characters @racket[(integer->char 160)] by
|
|
@racket[#\space] characters.
|
|
|
|
Ends the edit sequence (by calling @method[editor<%> end-edit-sequence])
|
|
started in @method[text:nbsp->space-mixin on-insert].
|
|
}
|
|
}
|
|
|
|
@definterface[text:column-guide<%> (text%)]{
|
|
Classes that implement this interface show a vertical line
|
|
at a specified column width (when the content in the
|
|
text has any lines wider than that column width).
|
|
|
|
The column width is determined by the @racket['framework:column-guide-width]
|
|
preference; that preference is a list of length two where the
|
|
first element is a boolean indicating if the line should be
|
|
visible at all, and the second is the width where the line
|
|
would be visible (if the first is @racket[#t]).
|
|
|
|
The position of the line is determined by taking the
|
|
width of the @litchar{x} character in the @racket["Standard"]
|
|
style (or, if there is no @racket["Standard"] style, then
|
|
the @racket["Basic"] style) and multiplying that by the
|
|
preference value.
|
|
|
|
}
|
|
|
|
@defmixin[text:column-guide-mixin (text%) (text:column-guide<%>)]{
|
|
@defmethod[#:mode extend (on-paint [before? any/]
|
|
[dc (is-a?/c dc<%>)]
|
|
[left real?]
|
|
[top real?]
|
|
[right real?]
|
|
[bottom real?]
|
|
[dx real?]
|
|
[dy real?]
|
|
[draw-caret (or/c 'no-caret 'show-inactive-caret 'show-caret
|
|
(cons/c exact-nonnegative-integer?
|
|
exact-nonnegative-integer?))])
|
|
void?]{
|
|
Draws the column guide (if appropriate; see @racket[text:column-guide<%>]).
|
|
}
|
|
@defmethod[#:mode augment (on-change) void?]{
|
|
Checks to see if any of the state that would cause the line to draw
|
|
in a different place has changed (via calls to @method[editor<%> get-extent] and
|
|
@method[text% get-padding]; if so makes (up to) two calls to
|
|
@method[editor<%> invalidate-bitmap-cache] with rectangles that cover the
|
|
old and new locations of the line.
|
|
}
|
|
}
|
|
|
|
@definterface[text:normalize-paste<%> (text:basic<%>)]{
|
|
@defmethod[(ask-normalize?) boolean?]{
|
|
Prompts the user if the pasted text should be normalized (and updates
|
|
various preferences based on the response).
|
|
|
|
Override this method in the mixin to avoid all GUI and preferences
|
|
interactions.
|
|
}
|
|
|
|
@defmethod[(string-normalize [s string?]) string?]{
|
|
Normalizes @racket[s]. Defaults to:
|
|
@racketblock[(regexp-replace*
|
|
#rx"\u200b"
|
|
(regexp-replace*
|
|
#rx"\u2212"
|
|
(string-normalize-nfkc s)
|
|
"-")
|
|
"")]
|
|
}
|
|
}
|
|
|
|
@defmixin[text:normalize-paste-mixin (text:basic<%>) (text:normalize-paste<%>)]{
|
|
@defmethod[#:mode override
|
|
(do-paste [start exact-nonnegative-integer?] [time exact-integer?])
|
|
void?]{
|
|
Overridden to detect when insertions are due to pasting. Sets some internal
|
|
state and calls the super.
|
|
}
|
|
|
|
@defmethod[#:mode augment (on-insert [start exact-nonnegative-integer?]
|
|
[len exact-nonnegative-integer?]) void?]{
|
|
Calls @method[editor<%> begin-edit-sequence].
|
|
}
|
|
|
|
@defmethod[#:mode augment (after-insert [start exact-nonnegative-integer?]
|
|
[len exact-nonnegative-integer?]) void?]{
|
|
Normalizes any next text and calls @method[editor<%> end-edit-sequence].
|
|
}
|
|
}
|
|
|
|
@definterface[text:all-string-snips<%> ()]{
|
|
@defmethod[(all-string-snips?) boolean?]{
|
|
Returns @racket[#t] if all of the snips in the @racket[text%] object
|
|
are @racket[string-snip%]s.
|
|
|
|
This method usually returns quickly, tracking changes to the editor
|
|
to update internal state. But if a non-@racket[string-snip%] is deleted,
|
|
then the next call to @method[text:all-string-snips<%> all-string-snips?]
|
|
traverses the entire content to search to see if there are other
|
|
non-@racket[string-snip%]s.
|
|
}
|
|
}
|
|
|
|
@defmixin[text:all-string-snips-mixin (text%) (text:all-string-snips<%>)]{
|
|
@defmethod[#:mode augment (on-insert [start exact-nonnegative-integer?]
|
|
[len exact-nonnegative-integer?]) void?]{
|
|
Checks to see if there were any non-@racket[string-snip%]s inserted
|
|
in the given range and, if so, updates the internal state.
|
|
}
|
|
|
|
@defmethod[#:mode augment (after-delete [start exact-nonnegative-integer?]
|
|
[len exact-nonnegative-integer?]) void?]{
|
|
Checks to see if there were any non-@racket[string-snip%]s deleted
|
|
in the given range and, if so, updates the internal state.
|
|
}
|
|
}
|
|
|
|
@definterface[text:searching<%> (editor:keymap<%> text:basic<%>)]{
|
|
Any object matching this interface can be searched.
|
|
|
|
@defmethod[(set-searching-state [str (or/c #f (and/c string? (not/c "")))]
|
|
[cs? boolean?]
|
|
[replace-mode? boolean?]
|
|
[notify-frame? boolean?])
|
|
void?]{
|
|
If @racket[str] is not @racket[#f], then this method initiates a search for
|
|
every occurrence of @racket[str] in the editor. If @racket[str] is @racket[#f],
|
|
then it clears all of the search highlighting in the buffer.
|
|
|
|
If @racket[cs?] is @racket[#f], the search is case-insensitive, and otherwise
|
|
it is case-sensitive.
|
|
|
|
The @racket[replace-mode?] boolean determines if the resulting search should
|
|
be tracking the next-to-replace search hit as the insertion point moves
|
|
around in the editor. Also, when @racket[replace-mode?] is @racket[#f], then
|
|
the bubbles are are uniform medium purple color (@racket["plum"] in
|
|
@racket[the-color-database]) and otherwise they are either a lighter
|
|
purple or a darker purple, with every bubble except the one just following
|
|
the insertion the lighter color.
|
|
|
|
The search does not complete before @method[text:searching<%> set-searching-state]
|
|
returns. Accordingly, @method[text:searching<%> get-search-hit-count] may
|
|
have out-of-date results for a while, until the search process is finished.
|
|
If @racket[notify-frame?] is @racket[#t] then
|
|
@method[frame:searchable<%> search-hits-changed]
|
|
is called when the search completes.
|
|
}
|
|
|
|
@defmethod[(set-search-anchor [position (or/c #f number?)]) void?]{
|
|
Sets the anchor's position in the editor. Only takes effect if the
|
|
@racket['framework:anchored-search] preference is on.
|
|
}
|
|
|
|
@defmethod[(get-search-hit-count) (values number? number?)]{
|
|
Returns the number of hits for the search in the buffer before the
|
|
insertion point and the total number of hits. Both are based on the count
|
|
found last time that a search completed.
|
|
}
|
|
|
|
@defmethod[(get-replace-search-hit) (or/c number? #f)]{
|
|
Returns the position of the nearest search hit that comes after the
|
|
insertion point.
|
|
}
|
|
|
|
@defmethod[(set-replace-start [pos (or/c number? #f)]) void?]{
|
|
This method is ignored. (The next replacement start is now
|
|
tracked via the @method[text% after-set-position] method.)
|
|
}
|
|
|
|
@defmethod[(finish-pending-search-work) void?]{
|
|
Finishes any pending work in computing and
|
|
drawing the search bubbles.
|
|
}
|
|
|
|
@defmethod[(get-search-bubbles)
|
|
(listof (list/c (cons/c number? number?)
|
|
(or/c 'normal-search-color
|
|
'dark-search-color
|
|
'light-search-color)))]{
|
|
Returns information about the search bubbles in the editor. Each item in
|
|
the outermost list corresponds to a single bubble. The pair of numbers is
|
|
the range of the bubble and the symbol is the color of the
|
|
bubble.
|
|
|
|
This method is intended for use in test suites.
|
|
}
|
|
}
|
|
|
|
@defmixin[text:searching-mixin (editor:keymap<%> text:basic<%>) (text:searching<%>)]{
|
|
This @racket[text%] can be searched.
|
|
|
|
The result of this mixin uses the same initialization arguments as the
|
|
mixin's argument.
|
|
|
|
@defmethod*[#:mode override (((get-keymaps) (listof (is-a?/c keymap%))))]{
|
|
This returns a list containing the super-class's keymaps, plus the result
|
|
of @racket[keymap:get-search].
|
|
}
|
|
|
|
@defmethod[#:mode augment (after-insert [start exact-nonnegative-integer?]
|
|
[len exact-nonnegative-integer?]) void?]{
|
|
Re-does any search now that the contents of the window have changed.
|
|
}
|
|
|
|
@defmethod[#:mode augment (after-delete [start exact-nonnegative-integer?]
|
|
[len exact-nonnegative-integer?]) void?]{
|
|
Re-does any search now that the contents of the window have changed.
|
|
}
|
|
|
|
@defmethod[#:mode override (on-focus [on? boolean?]) void?]{
|
|
Tells the frame containing the editor to search based on this editor via
|
|
the @method[frame:searchable<%> set-text-to-search] method.
|
|
}
|
|
}
|
|
|
|
@definterface[text:return<%> (text%)]{
|
|
Objects supporting this interface were created by @racket[text:return-mixin].
|
|
}
|
|
|
|
@defmixin[text:return-mixin (text%) (text:return<%>)]{
|
|
Use this buffer to perform some special action when return is typed.
|
|
|
|
@defconstructor[((return (-> boolean?)))]{
|
|
}
|
|
|
|
@defmethod*[#:mode override
|
|
(((on-local-char (event (is-a?/c key-event%))) void?))]{
|
|
If @racket[key] is either return or newline, only invoke the
|
|
@racket[return] thunk (initialization argument) and do nothing else.
|
|
}
|
|
}
|
|
|
|
@definterface[text:wide-snip<%> (text:basic<%>)]{
|
|
|
|
@defmethod*[(((add-wide-snip (snip (is-a?/c snip%))) void?))]{
|
|
Registers a snip in this editor to be resized when its viewing area
|
|
changes. Ensures the snip is as wide as the viewing area.
|
|
|
|
This method should only be called by
|
|
@xmethod[canvas:wide-snip<%> add-wide-snip].
|
|
}
|
|
|
|
@defmethod*[(((add-tall-snip (snip (is-a?/c snip%))) void?))]{
|
|
Registers a snip in this editor. It is resized when the viewing area of the
|
|
editor changes.
|
|
|
|
This method should only be called by
|
|
@xmethod[canvas:wide-snip<%> add-tall-snip].
|
|
}
|
|
}
|
|
|
|
@defmixin[text:wide-snip-mixin (text:basic<%>) (text:wide-snip<%>)]{
|
|
}
|
|
|
|
@definterface[text:delegate<%> (text:basic<%>)]{
|
|
Implementations of this interface copy all of the changes to this editor to
|
|
the result of @method[text:delegate<%> get-delegate] except instead of
|
|
regular string and tab snips, instead instances of
|
|
@racket[text:1-pixel-string-snip%] and @racket[text:1-pixel-tab-snip%] are
|
|
created.
|
|
|
|
The contents of the two editor are kept in sync, as modifications to this
|
|
object happen.
|
|
|
|
@defmethod*[(((get-delegate) (or/c #f (is-a?/c text%))))]{
|
|
The result of this method is the @racket[text%] object that the contents of
|
|
this editor are being delegated to, or @racket[#f], if there is none.
|
|
}
|
|
|
|
@defmethod*[(((set-delegate (delegate (or/c #f (is-a?/c text%)))) void?))]{
|
|
This method sets the current delegate.
|
|
|
|
When it is set, all of the snips are copied from this object to
|
|
@racket[delegate]. Additionally, if this object implements
|
|
@racket[racket:text<%>] the tab settings of @racket[delegate] are updated
|
|
to match this objects.
|
|
}
|
|
}
|
|
|
|
@defclass[text:1-pixel-string-snip% string-snip% ()]{
|
|
This class re-uses the implementation of @racket[string-snip%] to implement a
|
|
string snip that just draws a single pixel for each character in the string.
|
|
|
|
See also @racket[text:1-pixel-tab-snip%] for a similar extension to the
|
|
@racket[tab-snip%] class.
|
|
|
|
This snip is used in conjunction with the @racket[frame:delegate<%>] and
|
|
@racket[text:delegate<%>] interfaces.
|
|
|
|
@defmethod*[#:mode override (((split (position exact-nonnegative-integer?)
|
|
(first (box/c (is-a?/c snip%)))
|
|
(second (box/c (is-a?/c snip%))))
|
|
void?))]{
|
|
Fills the boxes with instance of @racket[text:1-pixel-string-snip%]s.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((copy) (is-a?/c snip%)))]{
|
|
Creates and returns an instance of @racket[text:1-pixel-string-snip%].
|
|
}
|
|
|
|
@defmethod*[#:mode override
|
|
(((get-extent
|
|
(dc (is-a?/c dc<%>))
|
|
(x real?) (y real?)
|
|
(w (or/c (box/c (and/c real? (not/c negative?))) #f) #f)
|
|
(h (or/c (box/c (and/c real? (not/c negative?))) #f) #f)
|
|
(descent (or/c (box/c (and/c real? (not/c negative?))) #f) #f)
|
|
(space (or/c (box/c (and/c real? (not/c negative?))) #f) #f)
|
|
(lspace (or/c (box/c (and/c real? (not/c negative?))) #f) #f)
|
|
(rspace (or/c (box/c (and/c real? (not/c negative?))) #f) #f))
|
|
void?))]{
|
|
|
|
Sets the descent, space, lspace, and rspace to zero. Sets the height to
|
|
1. Sets the width to the number of characters in the string.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((insert (s string?)
|
|
(len exact-nonnegative-integer?)
|
|
(pos exact-nonnegative-integer? 0))
|
|
void?))]{
|
|
}
|
|
|
|
@defmethod*[#:mode override (((draw (dc (is-a?/c dc<%>))
|
|
(x real?)
|
|
(y real?)
|
|
(left real?)
|
|
(top real?)
|
|
(right real?)
|
|
(bottom real?)
|
|
(dx real?)
|
|
(dy real?)
|
|
(draw-caret (or/c 'no-caret 'show-inactive-caret 'show-caret)))
|
|
void?))]{
|
|
Draws black pixels for non-whitespace characters and draws nothing for
|
|
whitespace characters.
|
|
}
|
|
}
|
|
|
|
@defclass[text:1-pixel-tab-snip% tab-snip% ()]{
|
|
This class re-uses the implementation of @racket[tab-snip%] to implement a
|
|
string snip that is always one pixel high.
|
|
|
|
See also @racket[text:1-pixel-string-snip%] for a similar extension to the
|
|
@racket[string-snip%] class.
|
|
|
|
This snip is used in conjunction with the @racket[frame:delegate<%>] and
|
|
@racket[text:delegate<%>] interfaces.
|
|
|
|
@defmethod*[#:mode override (((split (position exact-nonnegative-integer?)
|
|
(first (box/c (is-a?/c snip%)))
|
|
(second (box/c (is-a?/c snip%))))
|
|
void?))]{
|
|
Fills the boxes with instance of @racket[text:1-pixel-tab-snip%]s.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((copy) (is-a?/c snip%)))]{
|
|
Creates and returns an instance of @racket[text:1-pixel-tab-snip%].
|
|
}
|
|
|
|
@defmethod*[#:mode
|
|
override
|
|
(((get-extent (dc (is-a?/c dc<%>))
|
|
(x real?)
|
|
(y real?)
|
|
(w (or/c (box/c (and/c real? (not/c negative?)) #f)) #f)
|
|
(h (or/c (box/c (and/c real? (not/c negative?)) #f)) #f)
|
|
(descent (or/c (box/c (and/c real? (not/c negative?)) #f)) #f)
|
|
(space (or/c (box/c (and/c real? (not/c negative?)) #f)) #f)
|
|
(lspace (or/c (box/c (and/c real? (not/c negative?)) #f)) #f)
|
|
(rspace (or/c (box/c (and/c real? (not/c negative?)) #f)) #f))
|
|
void?))]{
|
|
Sets the descent, space, lspace, and rspace to zero. Sets the height to
|
|
1. Sets the width to the width of tabs as returned in the
|
|
@racket[tab-width] parameter of the @method[text% get-tabs] method.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((draw (dc (is-a?/c dc<%>))
|
|
(x real?)
|
|
(y real?)
|
|
(left real?)
|
|
(top real?)
|
|
(right real?)
|
|
(bottom real?)
|
|
(dx real?)
|
|
(dy real?)
|
|
(draw-caret (or/c 'no-caret 'show-inactive-caret 'show-caret)))
|
|
void?))]{
|
|
Draws nothing.
|
|
}
|
|
}
|
|
|
|
@defmixin[text:delegate-mixin (text:basic<%>) (text:delegate<%>)]{
|
|
This mixin provides an implementation of the @racket[text:delegate<%>]
|
|
interface.
|
|
|
|
@defmethod*[#:mode override (((highlight-range (start exact-integer?)
|
|
(end exact-nonnegative-integer?)
|
|
(color (or/c string? (is-a?/c color%)))
|
|
(caret-space boolean? #f)
|
|
(priority (or/c 'high 'low) 'low)
|
|
(style (or/c 'rectangle 'ellipse 'hollow-ellipse 'dot) 'rectangle))
|
|
(-> void?)))]{
|
|
In addition to calling the super method, @method[text:basic<%>
|
|
highlight-range], this method forwards the highlighting to the delegatee.
|
|
}
|
|
|
|
@defmethod[#:mode override
|
|
(unhighlight-range
|
|
(start exact-nonnegative-integer?)
|
|
(end exact-nonnegative-integer?)
|
|
(color (or/c string? (is-a?/c color%)))
|
|
(caret-space boolean? #f)
|
|
(style (or/c 'rectangle 'ellipse 'hollow-ellipse) 'rectangle))
|
|
void?]{
|
|
This method propagates the call to the delegate and calls the super method.
|
|
}
|
|
@defmethod*[#:mode override
|
|
(((on-paint (before? any/c)
|
|
(dc (is-a?/c dc<%>))
|
|
(left real?)
|
|
(top real?)
|
|
(right real?)
|
|
(bottom real?)
|
|
(dx real?)
|
|
(dy real?)
|
|
(draw-caret (one-of/c 'no-caret 'show-inactive-caret 'show-caret)))
|
|
void?))]{
|
|
Draws a blue region in the delegatee editor that shows where the visible
|
|
region of the delegate editor is.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((on-edit-sequence) void?))]{
|
|
starts an edit sequence in the delegate.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-edit-sequence) void?))]{
|
|
ends an edit sequence in the delegate.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((resized (snip (is-a?/c snip%)) (redraw-now? boolean?)) void?))]{
|
|
Sends a message to the delegate to update the size of the copied snip, if
|
|
there is one.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-insert (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) void?))]{
|
|
forwards the change to the delegate
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-delete (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) void?))]{
|
|
forwards the change to the delegate.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-change-style (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) void?))]{
|
|
forwards the changed style to the delegate.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((on-load-file (filename string?) (format symbol?)) void?))]{
|
|
remembers the filename, for use in
|
|
@method[text:delegate-mixin after-load-file].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-load-file (success? boolean?)) void?))]{
|
|
updates the delegate with the new contents of the text.
|
|
}
|
|
}
|
|
|
|
@definterface[text:info<%> (text:basic<%>)]{
|
|
Objects supporting this interface are expected to send information about
|
|
themselves to the frame that is displaying them.
|
|
}
|
|
@defmixin[text:info-mixin (editor:keymap<%> text:basic<%>) (text:info<%>)]{
|
|
This mixin adds support for supplying information to objects created with
|
|
@racket[frame:info-mixin]. When this @racket[editor:basic<%>] is displayed in
|
|
a frame, that frame must have been created with @racket[frame:info-mixin].
|
|
|
|
@defmethod*[#:mode override (((set-anchor (on? any/c)) void?))]{
|
|
Calls the @method[frame:text-info<%> anchor-status-changed] method of the
|
|
frame that is viewing this object. It uses @method[editor<%> get-canvas] to
|
|
get the canvas for this frame, and uses that canvas's
|
|
@racket[top-level-window<%>] as the frame.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((set-overwrite-mode (on? any/c)) void?))]{
|
|
Calls the @method[frame:text-info<%> overwrite-status-changed]method of the
|
|
frame that is viewing this object. It uses @method[editor<%> get-canvas] to
|
|
get the canvas for this frame, and uses that canvas's
|
|
@racket[top-level-window<%>] as the frame.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-set-position) void?))]{
|
|
Calls the @method[frame:text-info<%> editor-position-changed] method of the
|
|
frame that is viewing this object. It uses @method[editor<%> get-canvas] to
|
|
get the canvas for this frame, and uses that canvas's
|
|
@racket[top-level-window<%>] as the frame.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-insert (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) void?))]{
|
|
Calls the @method[frame:text-info<%> editor-position-changed] method of the
|
|
frame that is viewing this object. It uses @method[editor<%> get-canvas] to
|
|
get the canvas for this frame, and uses that canvas's
|
|
@racket[top-level-window<%>] as the frame.
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-delete (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) void?))]{
|
|
Calls the @method[frame:text-info<%> editor-position-changed] method of the
|
|
frame that is viewing this object. It uses @method[editor<%> get-canvas] to
|
|
get the canvas for this frame, and uses that canvas's
|
|
@racket[top-level-window<%>] as the frame.
|
|
}
|
|
}
|
|
|
|
@definterface[text:clever-file-format<%> (text%)]{
|
|
Objects supporting this interface are expected to support a clever
|
|
file format when saving.
|
|
}
|
|
|
|
@defmixin[text:clever-file-format-mixin (text%) (text:clever-file-format<%>)]{
|
|
The result of this mixin uses the same initialization arguments as the
|
|
mixin's argument.
|
|
|
|
When files are saved from this @racket[text%], a check is made to see if
|
|
there are any non-@racket[string-snip%] objects in the @racket[text%]. If so,
|
|
it is saved using the file format @racket['std]. (see @method[text%
|
|
set-file-format] for more information. If not, the file format passed to
|
|
@method[editor<%> save-file] is used.
|
|
|
|
@defmethod*[#:mode augment (((on-save-file (filename path?)
|
|
(format (or/c 'guess 'standard 'text
|
|
'text-force-cr 'same 'copy)))
|
|
void?))]{
|
|
If the method @method[text% get-file-format] returns @racket['standard] and
|
|
the text has only @racket[string-snip%]s, the file format is set to
|
|
@racket['text].
|
|
|
|
If the method @method[text% get-file-format] returns @racket['text] and the
|
|
text has some non @racket[string-snip%]s, the file format is set to
|
|
@racket['standard].
|
|
|
|
Depending on the user's preferences, the user may also be queried.
|
|
|
|
Also, the changes to the file format only happen if the argument
|
|
@racket[file-format] is @racket['copy] or @racket['same].
|
|
}
|
|
}
|
|
|
|
@definterface[text:crlf-line-endings<%> (text%)]{
|
|
Objects supporting this interface use
|
|
@method[editor<%> use-file-text-mode] to
|
|
change the line ending style under windows. See
|
|
@method[text:crlf-line-endings-mixin after-load-file] for more information.
|
|
}
|
|
|
|
|
|
@defmixin[text:crlf-line-endings-mixin (text%) (text:crlf-line-endings<%>)]{
|
|
@defmethod[#:mode override (after-load-file [success? any/c]) void?]{
|
|
Checks to see if the newly loaded file has any lines terminated with
|
|
@racket["\n"] (i.e., not @racket["\r\n"]) or if the file is empty.
|
|
If so, and if the @racket[system-type] returns @racket['windows], then
|
|
this method calls @method[editor<%> use-file-text-mode], passing @racket[#f].
|
|
|
|
Otherwise, calls @method[editor<%> use-file-text-mode] with @racket[#t].
|
|
}
|
|
}
|
|
|
|
@definterface[text:file<%> (editor:file<%> text:basic<%>)]{
|
|
Mixins that implement this interface lock themselves when the file they are
|
|
editing is read only.
|
|
|
|
@defmethod*[(((get-read-write?) boolean?))]{
|
|
Indicates whether or not this editor is in read-write mode.
|
|
}
|
|
|
|
@defmethod*[(((while-unlocked (thunk (-> any/c))) any/c))]{
|
|
Unlocks the editor, calls the thunk, and then relocks the editor, all using
|
|
a @racket[dynamic-wind].
|
|
}
|
|
}
|
|
|
|
@defmixin[text:file-mixin (editor:file<%> text:basic<%>) (text:file<%>)]{
|
|
@defmethod*[#:mode augment
|
|
(((can-insert? (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?))
|
|
boolean?))]{
|
|
|
|
Returns false if the result of @method[text:file<%> get-read-write?] is
|
|
true, otherwise returns the result of calling @racket[inner].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((can-delete? (start exact-nonnegative-integer?)
|
|
(len exact-nonnegative-integer?)) boolean?))]{
|
|
Returns false if the result of @method[text:file<%> get-read-write?] is
|
|
true, otherwise returns the result of calling @racket[inner].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-save-file) void?))]{
|
|
Checks if the newly saved file is write-only in the filesystem. If so,
|
|
locks the editor with the @method[editor<%> lock] method. Otherwise unlocks
|
|
the buffer
|
|
|
|
For each canvas returned from @method[editor<%> get-canvases] it checks to
|
|
see if the @racket[canvas%]'s @method[area<%> get-top-level-window] matches
|
|
the @racket[frame:editor<%>] interface. If so, it calls
|
|
@method[frame:editor-mixin set-label] with the last part of the filename
|
|
(ie, the name of the file, not the directory the file is in).
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((after-load-file) void?))]{
|
|
Checks if the newly loaded file is write-only in the filesystem. If so,
|
|
locks the editor with the @method[editor<%> lock] method. Otherwise unlocks
|
|
the buffer
|
|
|
|
For each canvas returned from @method[editor<%> get-canvases] it checks to
|
|
see if the @racket[canvas%]'s @method[area<%> get-top-level-window] matches
|
|
the @racket[frame:editor<%>] interface. If so, it calls
|
|
@method[frame:editor-mixin set-label] with the last part of the filename
|
|
(ie, the name of the file, not the directory the file is in).
|
|
}
|
|
}
|
|
|
|
@definterface[text:ports<%> ()]{
|
|
Classes implementing this interface (via the associated mixin) support input
|
|
and output ports that read from and to the editor.
|
|
|
|
There are two input ports: the normal input port just reads from the editor's
|
|
contents directly and the box input port inserts an editor snip into this
|
|
text and uses input typed into the box as input into the port.
|
|
|
|
There are three output ports, designed to match stdout, stderr, and a special
|
|
port for printing values. The only difference between them is the output is
|
|
rendered in different colors when it comes in via the different ports.
|
|
|
|
They create three threads to mediate access to the input and output ports
|
|
(one for each input port and one for all of the output ports).
|
|
|
|
@defmethod*[(((delete/io (start exact-integer?) (end exact-integer?)) void?))]{
|
|
Deletes the text between @racket[start] and @racket[end] without changing
|
|
the behavior of the ports (otherwise, deleting the text would break
|
|
internal invariants of the port).
|
|
|
|
Both @racket[start] and @racket[end] must be less than
|
|
@method[text:ports<%> get-insertion-point] (or else it is safe to delete
|
|
them via @method[text% delete], so you don't need this method).
|
|
}
|
|
|
|
@defmethod[(insert/io [str string?] [pos exact-integer?]) void?]{
|
|
Inserts @racket[str] at the position @racket[start] without changing
|
|
the behavior of the ports (otherwise, inserting the text would break
|
|
internal invariants of the port).
|
|
|
|
The @racket[pos] argument must be less than
|
|
@method[text:ports<%> get-insertion-point] (or else it is safe to insert
|
|
the string via @method[text% insert], so you don't need this method).
|
|
|
|
@history[#:added "1.2"]
|
|
}
|
|
|
|
@defmethod[(do-submission) void?]{
|
|
Triggers a submission to the input port with what is currently pending
|
|
in the editor.
|
|
}
|
|
|
|
@defmethod*[(((get-insertion-point) exact-integer?))]{
|
|
Returns the position where characters put into the output port will appear.
|
|
}
|
|
|
|
@defmethod*[(((set-insertion-point (ip exact-integer?)) void?))]{
|
|
Sets the position where the output port will insert characters. See also
|
|
@method[text:ports<%> get-insertion-point].
|
|
}
|
|
|
|
@defmethod*[(((get-unread-start-point) exact-integer?))]{
|
|
Returns the position where input will be taken into the input port (after
|
|
the next time return is typed).
|
|
}
|
|
|
|
@defmethod*[(((set-unread-start-point (usp exact-integer?)) void?))]{
|
|
Sets the position where input will be taken into the input port (after the
|
|
next time return is typed).
|
|
|
|
See also @method[text:ports<%> get-unread-start-point].
|
|
}
|
|
|
|
@defmethod*[(((set-allow-edits (allow-edits? boolean?)) void?))]{
|
|
Enables or disables editing in the buffer. Be sure to update the unread
|
|
start point (via @method[text:ports<%> set-unread-start-point]) and the
|
|
insertion point (via @method[text:ports<%> set-insertion-point]) after
|
|
making changes to the buffer.
|
|
}
|
|
|
|
@defmethod*[(((get-allow-edits) boolean?))]{
|
|
Indicates if editing is allowed in the buffer at this point.
|
|
}
|
|
|
|
@defmethod*[(((insert-between (str (or/c (is-a?/c snip%) string?))) void?))]{
|
|
Inserts some text between the unread start point and the insertion point
|
|
(and updates them properly). To insert before the two points, see
|
|
@method[text:ports<%> insert-before].
|
|
|
|
See also @method[text:ports<%> set-unread-start-point] and
|
|
@method[text:ports<%> set-insertion-point].
|
|
}
|
|
|
|
@defmethod*[(((insert-before (str (or/c (is-a?/c snip%) string?))) void?))]{
|
|
Inserts some text before the unread start point and updates it and the
|
|
insertion point properly. To insert between the two points, see
|
|
@method[text:ports<%> insert-between].
|
|
|
|
See also @method[text:ports<%> set-unread-start-point] and
|
|
@method[text:ports<%> set-insertion-point].
|
|
}
|
|
|
|
@defmethod*[(((submit-to-port? (key (is-a?/c key-event%))) boolean?))]{
|
|
Augment this method to help control when characters should be submitted to
|
|
the input port.
|
|
|
|
Return @racket[#t] or the result of calling @racket[inner].
|
|
}
|
|
|
|
@defmethod*[(((on-submit) void?))]{
|
|
This method is called when text is sent into the input port.
|
|
|
|
Does nothing.
|
|
}
|
|
|
|
@defmethod*[(((send-eof-to-in-port) void?))]{
|
|
This method puts an eof into the input port.
|
|
}
|
|
|
|
@defmethod*[(((send-eof-to-box-in-port) void?))]{
|
|
This method puts an eof into the box input port.
|
|
}
|
|
|
|
@defmethod*[(((reset-input-box) void?))]{
|
|
This method removes the current input box from the editor (and all input in
|
|
it is lost).
|
|
}
|
|
|
|
@defmethod*[(((clear-output-ports) void?))]{
|
|
Flushes all of the data in all of the output ports that hasn't appeared in
|
|
the editor yet.
|
|
}
|
|
|
|
@defmethod*[(((clear-input-port) void?))]{
|
|
Flushes all of the data in the input port that hasn't yet been
|
|
read. Reading will now block.
|
|
}
|
|
|
|
@defmethod*[(((clear-box-input-port) void?))]{
|
|
Flushes all of the data in the box input port that hasn't yet been
|
|
read. Reading will now block.
|
|
}
|
|
|
|
@defmethod*[(((get-out-style-delta) (or/c (is-a?/c style-delta%) string?)))]{
|
|
The result of this method is the style that is used to color text submitted
|
|
to the result of @method[text:ports<%> get-out-port].
|
|
|
|
If the result is a string that is not mapped in the editor's style list,
|
|
the style named @racket["Standard"] is used and if that isn't mapped, the
|
|
style named @racket["Basic"] is used.
|
|
|
|
This method is called during the initialization of the class.
|
|
|
|
By default, returns @racket["text:ports out"] which is mapped to a blue
|
|
style in the style list returned by @racket[editor:get-standard-style-list].
|
|
}
|
|
|
|
@defmethod*[(((get-err-style-delta) (or/c (is-a?/c style-delta%) string?)))]{
|
|
The result of this method is the style that is used to color text submitted
|
|
to the result of @method[text:ports<%> get-err-port].
|
|
|
|
If the result is a string that is not mapped in the editor's style list,
|
|
the style named @racket["Standard"] is used and if that isn't mapped, the
|
|
style named @racket["Basic"] is used.
|
|
|
|
This method is called during the initialization of the class.
|
|
|
|
By default, returns @racket["text:ports err"] which is mapped to a red
|
|
italic style in the style list returned by
|
|
@racket[editor:get-standard-style-list].
|
|
}
|
|
|
|
@defmethod*[(((get-value-style-delta) (or/c (is-a?/c style-delta%) string?)))]{
|
|
The result of this method is the style (or the name of the style) that is
|
|
used to color text submitted to the result of @method[text:ports<%>
|
|
get-value-port].
|
|
|
|
If the result is a string that is not mapped in the editor's style list,
|
|
the style named @racket["Standard"] is used and if that isn't mapped, the
|
|
style named @racket["Basic"] is used.
|
|
|
|
This method is called during the initialization of the class.
|
|
|
|
By default, returns @racket["text:ports value"] which is mapped to a blue
|
|
style in the style list returned by
|
|
@racket[editor:get-standard-style-list].
|
|
}
|
|
|
|
@defmethod*[(((get-in-port) input-port?))]{
|
|
Returns the input port that data in this editor is sent to.
|
|
}
|
|
|
|
@defmethod*[(((get-in-box-port) input-port?))]{
|
|
Returns the box input port that data in this editor is sent to.
|
|
}
|
|
|
|
@defmethod*[(((get-out-port) output-port?))]{
|
|
Returns an output port that writes into this editor. The only difference
|
|
between this port and the ports returned by @method[text:ports<%>
|
|
get-err-port] and @method[text:ports<%> get-value-port] is the font style
|
|
and color.
|
|
}
|
|
|
|
@defmethod*[(((get-err-port) output-port?))]{
|
|
Returns an output port that writes into this editor. The only difference
|
|
between this port and the ports returned by @method[text:ports<%>
|
|
get-err-port] and @method[text:ports<%> get-out-port] is the font style and
|
|
color.
|
|
}
|
|
|
|
@defmethod*[(((get-value-port) output-port?))]{
|
|
Returns an output port that writes into this editor. The only difference
|
|
between this port and the ports returned by @method[text:ports<%>
|
|
get-err-port] and @method[text:ports<%> get-out-port] is the font style and
|
|
color.
|
|
}
|
|
|
|
@defmethod*[(((after-io-insertion) void?))]{
|
|
This method is called after an insertion due to IO occurs.
|
|
}
|
|
|
|
@defmethod*[(((get-box-input-editor-snip%) (subclass?/c editor-snip%)))]{
|
|
The result of this method is used as the class of editor snips that is
|
|
inserted by the box port in this editor.
|
|
}
|
|
|
|
@defmethod*[(((get-box-input-text%) (is-a?/c text:input-box<%>)))]{
|
|
The result of this method is instantiated and placed inside the result of
|
|
@method[text:ports<%> get-box-input-editor-snip%].
|
|
}
|
|
}
|
|
|
|
@defmixin[text:ports-mixin (text:wide-snip<%>) (text:ports<%>)]{
|
|
|
|
@defmethod*[#:mode augment (((can-insert? (start exact-integer?) (len exact-integer?)) boolean?))]{
|
|
Returns the results of the @racket[inner] call, unless
|
|
@method[text:ports<%> get-allow-edits] returns @racket[#f].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((can-delete? (start exact-integer?) (len exact-integer?)) boolean?))]{
|
|
Returns the results of the @racket[inner] call, unless
|
|
@method[text:ports<%> get-allow-edits] returns @racket[#f].
|
|
}
|
|
|
|
@defmethod*[#:mode override (((on-local-char (event (is-a?/c key-event%))) void?))]{
|
|
Sends the data between the last position and the result of
|
|
@method[text:ports<%> get-unread-start-point] to the input port, unless
|
|
@method[text:ports<%> submit-to-port?] returns @racket[#f].
|
|
|
|
Also calls @method[text:ports<%> on-submit].
|
|
}
|
|
|
|
@defmethod*[#:mode augment (((on-display-size) void?))]{
|
|
Adjusts the embedded editor-snip (used for reading input to the
|
|
@method[text:ports<%> get-in-box-port]) to match the width of the editor.
|
|
}
|
|
}
|
|
|
|
@definterface[text:input-box<%> (text%)]{
|
|
Classes that implement this interface are used as the editors for the box
|
|
input port in @racket[text:ports%].
|
|
}
|
|
|
|
@defmixin[text:input-box-mixin (text%) (text:input-box<%>)]{
|
|
This mixin provides an implementation of @racket[text:input-box<%>] for use
|
|
with @racket[text:ports<%>].
|
|
|
|
@defmethod*[#:mode override
|
|
(((on-default-char (event (is-a?/c key-event%))) void?))]{
|
|
Notifies the @racket[text:ports<%>] enclosing this editor that a new line
|
|
of input has been provided.
|
|
}
|
|
}
|
|
|
|
@definterface[text:autocomplete<%> (text%)]{
|
|
The mixin implementing this interface provides an unintrusive autocompletion
|
|
menu when a particular (configurable) keystroke is pressed.
|
|
|
|
@defmethod*[(((auto-complete) void?))]{
|
|
Starts a completion.
|
|
}
|
|
|
|
@defmethod*[(((get-autocomplete-border-color) (or/c string? (is-a?/c color%))))]{
|
|
The border color for the autocomplete menu. Defaults to @racket["black"].
|
|
}
|
|
|
|
@defmethod*[(((get-autocomplete-background-color) (or/c string? (is-a?/c color%))))]{
|
|
The background color for the non-selected menu items. Defaults to
|
|
@racket["lavender"].
|
|
}
|
|
|
|
@defmethod*[(((get-autocomplete-selected-color) (or/c string? (is-a?/c color%))))]{
|
|
The background color for the selected menu item. Defaults to
|
|
@racket[(make-object color% 204 153 255)].
|
|
}
|
|
|
|
@defmethod*[(((completion-mode-key-event? (key-event (is-a?/c key-event%))) boolean?))]{
|
|
Returns true when the key event passed to it should initiate the
|
|
completions menu.
|
|
}
|
|
|
|
@defmethod*[(((get-all-words) (listof string?)))]{
|
|
Returns the list of the words that autocompletion should
|
|
choose from.
|
|
}
|
|
|
|
@defmethod*[(((get-word-at (pos exact-positive-integer?)) string?))]{
|
|
Given an editor location, returns the prefix ending at that location
|
|
that autocompletion should try to complete.
|
|
}
|
|
}
|
|
|
|
@defmixin[text:autocomplete-mixin (text%) (text:autocomplete<%>)]{
|
|
|
|
@defmethod*[#:mode override (((on-paint) void?))]{
|
|
Draws the completion menu (when it is popped up).
|
|
}
|
|
|
|
@defmethod*[#:mode override (((on-char) void?))]{
|
|
Takes over the handling of key events when the completions menu is
|
|
visible. Also, when the completions menu is not visible, it calls the
|
|
@method[text:completion<%> completion-mode-key-event?] method to see if it
|
|
should start completing.
|
|
}
|
|
|
|
@defmethod*[#:mode override (((on-event) void?))]{
|
|
This method is overridden to allow mouse access of the completions menu. It
|
|
only handles events when there is a menu open and the mouse is in the menu,
|
|
in which case it makes the menu trace the mouse.
|
|
|
|
The only time it does not call the super method is when the mouse is button
|
|
is pushed.
|
|
}
|
|
}
|
|
|
|
@definterface[text:overwrite-disable<%> ()]{
|
|
Classes implementing this interface disable overwrite mode when
|
|
the overwrite mode keybindings are turned off.
|
|
}
|
|
|
|
@defmixin[text:overwrite-disable-mixin (text%) (text:set-overwrite-mode<%>)]{
|
|
This mixin adds a callback for @racket['framework:overwrite-mode-keybindings]
|
|
via @racket[preferences:add-callback] that calls @method[text% set-overwrite-mode]
|
|
with @racket[#f] when the preference is set to @racket[#f].
|
|
}
|
|
|
|
@defclass[text:basic% (text:basic-mixin (editor:basic-mixin text%)) ()]{}
|
|
@defclass[text:line-spacing% (text:line-spacing-mixin text:basic%) ()]{}
|
|
@defclass[text:hide-caret/selection% (text:hide-caret/selection-mixin text:line-spacing%) ()]{}
|
|
@defclass[text:nbsp->space% (text:nbsp->space-mixin text:line-spacing%) ()]{}
|
|
@defclass[text:normalize-paste% (text:normalize-paste-mixin text:line-spacing%) ()]{}
|
|
@defclass[text:delegate% (text:delegate-mixin text:line-spacing%) ()]{}
|
|
@defclass[text:wide-snip% (text:wide-snip-mixin text:line-spacing%) ()]{}
|
|
@defclass[text:standard-style-list% (editor:standard-style-list-mixin text:wide-snip%) ()]{}
|
|
@defclass[text:input-box% (text:input-box-mixin text:standard-style-list%) ()]{}
|
|
@defclass[text:keymap%
|
|
(text:overwrite-disable-mixin (editor:keymap-mixin text:standard-style-list%))
|
|
()]{}
|
|
@defclass[text:return% (text:return-mixin text:keymap%) ()]{}
|
|
@defclass[text:autowrap% (editor:autowrap-mixin text:keymap%) ()]{}
|
|
@defclass[text:file% (text:file-mixin (editor:file-mixin text:autowrap%)) ()]{}
|
|
@defclass[text:clever-file-format% (text:clever-file-format-mixin text:file%) ()]{}
|
|
@defclass[text:backup-autosave% (editor:backup-autosave-mixin text:clever-file-format%) ()]{}
|
|
@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?))]{
|
|
Draws the 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.
|
|
}
|
|
}
|
|
|
|
@(include-previously-extracted "main-extracts.rkt" #rx"^text:")
|