Structured Source Editing (SSE) Component
Structured Source Editing (SSE) Component Overview |
Last modified September 20, 2005 |
|
[This document is a work in progress. It is an attempt to capture the key concepts of the WTP SSE Component. Note that the concepts presented here may differ from what is found in the currently released code. This document describes the architecture, or "end goal", of the SSE component. Once this document is finalized, the intent is to bring the code and its specs into line with this document.] |
|
SSE UI | |
While there is a UI component to SSE, it has little API and is intended to be a relatively thin layer on top of the base Eclipse Text Editing API. SSE tries not to introduce UI API unless we've found it necessary to go beyond functionality provided by the Eclipse. |
|
The most important, probably long-term, difference from the
Eclipse text editing component that we attempt to make all
parts of the editor configurable according to the platform
content type of the input being edited, and in many cases,
based on the document partition types within the file. This
combination is the foundation of SSE's approach to handling
mixed content in a re-usable way. As such, one of the most
important areas to understand is the
|
|
I mention this as a "long term" difference, since the text
infrastructure allows editors to specify whole "processors"
(e.g. for content assist) whereas our philosophy is to
provide a processor that allows clients to participate in
creating the results. No implementation exists for Content
Assist at this time, but a working example of this pattern
can be found within SSE's "as you type" validation (see
|
|
Another area we differ from text infrastructure is in syntax highlighting. We attempt to take direct advantage of StyledText widget's callbacks to achieve greater efficiency over preparing highlighting information in advance (this is the theory, we still have some implementation work to do to achieve in practice, in WTP Release 1.0). |
|
Another change is that while me make use of the platform's selection service to communicate selection changes within our editor , we also provide more information to listeners than most text editors. |
|
Issues we hope to remove as differences: there are currently a number of overrides in SSE UI of Eclipse text functionality that were originally made due to limitations in Eclipse's text infrastructure (SSE dates back, in some form, to before Eclipse 1.0). Many of those limitations have since been improved upon or are improving in Eclipse's 3.1 stream. We are currently investigating transitioning to the provided infrastructure (some of which is new to Eclipse 3.1) instead of providing an incompatible workalike. These include:
|
|
Extension Points | |
Editor Configuration |
|
The Editor Configuration extension point takes the loose coupling of the Eclipse SourceViewer and SourceViewerConfiguration classes one step further by allowing the viewer configuration itself to be dynamically discovered and loaded instead of being statically specified through code. The configuration class is most frequently specified according to the platform content type being edited. SSE also extends the viewer configuration pattern to its outline and property sheet pages and also allows for certain configurations to be specified according to document partition type and editor IDs. |
|
Source Page Validation |
|
Allows participants to provide an
|
|
The enablement ("what" the validators can operate on) of the
source validators can be specified by content type (
|
|
|
|
This is likely the same
|
|
The validation messages are displayed to the user on the source page as as "temporary" annotations. These show up in the text as "squiggles" beneath the text and in the overview ruler as rectangles. The validation message itself is displayed by hovering the squiggle or rectangle. |
|
Line Style Participants |
|
[? to provide more] Line Style Participants are similar to the Eclipse IPresentationRepairers, but are designed to operate on structured documents. |
|
Content Assist Participants |
|
[not committed -- ? to provide] |
|
Editor related IDs |
|
Structured Text editor clients can contribute actions to the editor as well as the help context id (infopop). Currently this can be done through extension points offered by the base (like org.eclipse.ui.editorActions, org.eclipse.ui.popupMenus) Infopop can be contributed by the standard infopop hooks (help context id points to actual help) |
|
To contribute, a "target id" of some kind is needed. For Structured Text editors, the target id is generated based on the content type in the editor, type of editor, place to contribute. The target id looks like: >content type<.>editor type keyword<.>place to contribute keyword< |
|
This are the current editor types supported followed by their keyword (the last in list are reserved for possible future use):
|
|
These are the following places clients can contribute to followed by their keyword: editor popup menu : EditorContext editor vertical ruler popup menu : RulerContext outline view popup menu : OutlineContext help context id : HelpId |
|
Here are some examples: To contribute to *xml source editor's popup menu*, use target id "org.eclipse.core.runtime.xml.source.EditorContext" |
|
To contribute to *xsd graph editor's outline view's popup menu*, use target id "org.eclipse.wst.xsd.contentmodel.xsdsource.graph.OutlineContext" |
|
To provide infopop for *html source page editor*, use help context id "org.eclipse.wst.html.core.htmlsource.source.HelpId" |
|
SSE Core | |
The more substantial contribution of SSE is its core APIs. |
|
Structured Documents | |
Once central concept is the
|
|
The IStructuredDocument is conceptually a stream of characters made up of (divided into) IStructuredDocumentRegions. The main constraint on what types of languages are appropriate for structured documents and structured regions is whether or not it has the concept of having a syntactically determined end. This is used to know how to correctly handle reparsing (deciding what is a "safe start" and "safe end" for the reparse operation). |
|
Parsers and re-parsers | |
The parser/reparser pair has a few conceptual requirements. They must be able to handle any text (legal or not) and must return regions that completely cover the input text (for example, whitespace can not simply be ignored). More difficult to implement, another constraint is that for any (correctly specified) subset of text, the reparser must give the same results that the parser would if parsed from top to bottom. |
|
It might be useful to note, for anyone looking at detail at the parsers and re-parser implementations, for cases involving "invalid input", heuristics are often used to make these decisions so sometimes we can and do "guess right" (based on what a user might be in the process of typing) and sometimes not -- in other words, its not always easily predictable as it is for "clean" text but is based on doing a reasonable job which would not invalidate subsequent reparsing. |
|
Structured Document Events | |
The StructuredDocumentEvents are similar to IDocument's DocumentEvents, but provide much more information about the nature of the change in terms of IStructuredDocumentRegions (and the ITextRegions of which they are composed). Listeners, such as DOM parsers, can make use of this to minimize the amount of reparsing/rebuilding they have to do. |
|
Structured Models | |
Structured models are mostly interesting due to is extended types and implementers and exists as an abstraction to provide a consistent way to manage shared models and also to access its underlying structured document. |
|
Node Notification and Adaption | |
In addition to IAdaptable and whole model state listeners, many "Node" structures in SSE related models make use of a finer level of adaption and notification. This mechanism can be used to have improved UI updates or can be used to keep related models "in synch" (for example, a DOM model change can cause a change in an EMF model, and vis versa). |
|
Model Management | |
Another important contribution of sse.core is the IModelManager. Its purpose is to provide a StructuredModel, appropriate to contentType, that can be shared between many clients at runtime. This increases efficiency since each client doesn't have to (re)create their own, but just as importantly, it is an easy way for clients to all stay "in synch"--a change in the model made by one client will be known by all others clients. The other motivation for this is it allows looser coupling, since clients who may not even know about each other can share the resource (model) without passing it around to each other. |