The Actipro Blog

All the latest UI control development news from Actipro

SyntaxEditor for WPF - Text statistics

SyntaxEditor 4.0 for WinForms has a neat feature that a lot of people may not know about.  It has a complete statistics engine built-in that can calculate a number of useful statistics about your text content.  The statistics can easily be obtained for the selected text within a view, the entire document, or even for your own custom text strings. 

Language definitions can append new statistics too.  For instance, a C# language definition may add a statistic counting the number of lines that contain comments.  This is extremely useful for apps that may examine a directory structure to calculate comment coverage over source code files.

SyntaxEditor for WPF also contains this text statistics engine (just added it today).  Check out the screenshot below of the QuickStart for this feature.

TestStatistics

The display of text statistics for the contents of a SyntaxEditor for WPF control

As you type in the document on the left, the statistics in the right ListView update live.  The ListView is populated by calling a method on the statistics results object to return a list of statistic items (each one with a name and value) and having that list be bound to the ListView.ItemsSource.

Filed under: Actipro, In development, WPF

SyntaxEditor for WPF - Snapshot translation

In this post I’d like to talk about an exciting new feature we’ve recently implemented in our SyntaxEditor for WPF codebase.  Again, we haven’t released the product yet but there is a lot of interest in it so I’ve been trying to post on some of the things we’re working on.  Everything discussed here is part of our next generation text/parsing model, which we eventually plan on making available to SyntaxEditor for WinForms too.

Be warned, this post gets a bit technical and is really meant for all the SyntaxEditor geeks out there! :)

Feature Overview

A snapshot of a document provides an immutable read-only representation of the document at a certain time.  The document always references the most current snapshot.

However say you start some time-consuming parsing on the most current snapshot, which we'll call snapshot 1.  While the parsing is executing, more text changes in the document are made, bringing us to what we'll call snapshot 2.  Then assume snapshot 1's parsing completes and returns an AST of the document.  All the offsets for the AST are based on the text found in snapshot 1.  Since snapshot 2 is the the most current snapshot, the offsets for the AST are most likely incorrect since they were not based on snapshot 2.

SyntaxEditor can translate offsets from one snapshot to another, taking any text changes into account.  So if we wanted to jump directly to a class name, whose offset we know from the AST based on snapshot 1, we can translate the offset from snapshot 1 to the current snapshot (snapshot 2), and move the caret right to the translated offset.

A QuickStart Example

Let’s walk through a QuickStart to show off this feature.  In this QuickStart we have two SyntaxEditor controls.  They both start off with the same document text, however they are separate documents.  The upper editor is read-only and just shows the original contents of both editors.  The lower editor can be modified.

SnapshotTranslation

The snapshot translation QuickStart

Both documents initially contain what is visible in the screenshot above in the upper editor, which is class declarations for MyClassA and MyClassB.  In the lower editor we deleted the MyClassA declaration.  Note the yellow line modification mark in the selection margin where our change was made.

Now back in the upper editor, we highlight the word MyClassB.  Then we click the Translate Selection button.  This takes any text changes that have been made since the original text was set, and translates the offsets of the upper editor’s selection to where the same offsets should now be in the lower editor.

The result is in the screenshot, where it highlights the lower editor’s MyClassB text.  If there was not translation mechanism in place, the selection would have been incorrectly made somewhere in the comment area of the lower editor instead.

Real-World Examples

Here are two real-word examples of using this sort of feature.

The first is based on the overview at the start of this post.  Say you have an AST that you generate based on one snapshot, and you use the resulting AST to render a TreeView containing the document outline.  A common feature is to allow double-clicking on a TreeView node to jump right the related declaration in code.  However considering that the TreeView is generally not in sync with the editor due to typing, etc., in the past it’s been a problem to ensure that we move the caret to the right spot.  With the use of the SyntaxEditor snapshot translation feature, we can almost always go to the correct spot, the only exception being if a text change has been made over the target offset after the time that the TreeView’s snapshot was taken.  However even in that case, the end result is still close.

The second example is find/replace results.  Say you do a replace all operation on a document and list the replace locations in a ListBox.  You could store the snapshot made after each replace in the related ListBox items.  This would allow you to move directly to the replaced text on double-clicks, even after multiple edits have been made following the replace all operation.

Conclusion

I hope that by illustrating this example you can see the power that this mechanism provides.  It will help ensure consistency for the end user’s point of view when making a lot of changes and dealing with find/replace results, AST-related operations, etc.

These sort of things are just some of the core enhancements we’re working on for the design of SyntaxEditor for WPF.  More to come!

Filed under: Actipro, In development, WPF

SyntaxEditor for WPF - Batching up replace operations

The past several days we’ve been working on a batch update feature.  Before I get into what that means, let’s first discuss how SyntaxEditor for WinForms works. 

The Problem

Each call to SyntaxEditor 4’s Document.InsertText, DeleteText, and ReplaceText methods is its own atomic unit, meaning that UI updates and a lot of other processing occurred after each individual change.  While normally this is ok, sometimes when doing thousands of sequential replace operations in a document, it can take a bit to update.

The Solution

In the next generation text model that we’re prototyping for our SyntaxEditor for WPF control (and will eventually migrate the WinForms control to use it as well), we’ve made a number of improvements for this particular problem.

In the new model, the document class still has InsertText, DeleteText, and ReplaceText methods.  If you call those directly then they will be executed like in the SE4 model.  However you now have an option to call a method named BeginTextChange.  What this does is allows you to start a “group” of replace operations.  Each BeginTextChange must eventually be followed by a corresponding EndTextChange.  The calls may be nested too.  Upon the final EndTextChange call, the batch of replace operations are executed as a single atomic unit.

The object model is such than an ITextChange is a thing that contains some high level data and a list of ITextChangeOperation objects.  Each ITextChangeOperation represents a single replace operation.  So when the document’s TextChanged event fires, it passes along in its event arguments the ITextChange.

A Real-World Sample

As a real world example, say you are going to be performing 1000 replace operations immediately to maybe properly indent 1000 lines of code, so one replace operation for each line of code.  Here is an ideal place to use the Begin/EndTextChange model.  You would start with a call to BeginTextChange, then call ReplaceText for each of your 1000 replace operations, then call EndTextChange.  At the time you call EndTextChange, the single ITextChange (containing 1000 ITextChangeOperation objects) that has been cached up is passed along to the undo mechanism, UI, etc. via the document’s TextChanged event.  Therefore for all these replace operations, the UI and other things only update once, thereby really speeding up response time.

The Bottom Line

I know that a lot of you are anxious to get your hands on SyntaxEditor for WPF and it’s taking a bit to get ready, however I hope that by posting information like this, you can see we’re really focusing on improving core fundamental structures and methodologies.  These things are going to open up a whole new realm of possibilities for the control.  While this does delay the initial release, in the long run we’ll have a far better and more robust product than any of our competition.

Filed under: Actipro, In development, WPF

WinForms products migrate to VS 2008 / VS 2005

As of today’s releases of our Windows Forms products, we have dropped support for VS 2003 projects and .NET 1.1 builds of our component libraries.  At this point, VS 2008 has been out for some time and anyone doing Windows Forms development should be on .NET 2.0 or later.

The latest maintenance releases now have both Visual Studio 2008 and Visual Studio 2005 sample projects included.

All the component libraries are built targeting .NET 2.0.  Please note that libraries that target .NET 2.0, can be used in any later .NET framework as well, such as .NET 3.0 or 3.5.

In development at Actipro – November 2008

We’ve had a lot of requests from customers asking what we’re currently focusing our development efforts on.  Let me post some details on the work we’re doing right now.

SyntaxEditor for WPF

SyntaxEditor continues to be a main focus for our development time.  The past several weeks we’ve been more into the backend document/parsing functionality which is why we haven’t posted many updates here in the blog.  Unfortunately with those things, there isn’t much to show.  :)

Today I’d like to talk about a couple new features that have been in development recently.

Reducing Memory and Processing for Large Files

A key enhancement that we’ve been focusing on is making strong efforts to dramatically improve support for large files.

A previous post (Large file editing in SyntaxEditor for WPF looks great so far) described a number of improvements we already made in that area.

One key drawback to how SyntaxEditor 4.0 does semantic parsing (not normal lexical parsing for highlighting) is that it creates a full text string copy of the document right before parsing occurs and the semantic parsing works on that.  While this is fast and ok for small-medium size documents, there are two bad things about this design.  First, it takes time to construct a full string copy of the document.  Usually this is pretty fast in practice though.  The more important thing is the memory usage involved.  We now essentially have two full copies of the document in memory, one stored by the document and the copy that will be used for semantic parsing. 

So you may be asking, why is a copy made for semantic parsing?  The reason is that semantic parsing works on a worker thread so that it doesn’t interfere with the UI response speed.  Say you kick off a semantic parsing operation and while it’s executing the user is typing more into the document.  That would cause issues if the semantic parser was referencing the live document since all of a sudden, offsets may be invalid.  Therefore the semantic parser has its own immutable copy of the document text at the time the parser started, and we don’t need to worry about issues introduced by threading and user modifications during parsing.

Back to what’s new.  Now we have a way that stores text and is able to reuse most of the memory between text changes.  Best of all, each copy of the text between changes is completely immutable.  This means that:

  1. The text copies are completely thread-safe since they are immutable.
  2. There is no complete reconstruction of the text needed for passing to a semantic parser, thereby reducing processing time.
  3. Most of the memory used to store two or more copies of the text (between changes) is shared between the copies, thereby reducing overall memory usage dramatically.

So as you can see, with some of the improvements we’ve been working on, this will really help with editing large files where processing speed and memory usage issues come into play.

Custom Highlighting of Text

A lot of customers in the past have request an ability to integrate into the syntax highlighting engine and change certain spans before they are displayed to the end user.  We’ve developed a nice system that should allow for this.

Essentially the language first runs its lexer to parse text and determine how it should be highlighted.  Then you can optionally add in classes to layer on top of that.  Each layer can look at previously run layers and view them, alter them, or add completely new spans for syntax highlighting that override ones in previously run layers.

How can this be used?  Say you are using a C# language that we develop but you want to highlight instances of URLs in comments, and lets assume our C# language doesn’t do that by default.  This is where you’d let our default language syntax highlighting run, then you add in a layer on top of that which can examine the highlighting spans and even see the tokens used to create them.  You can look for comment text and if you find some, examine the text for a URL.  If found add a new syntax highlighting span in your own layer that overrides the highlighting in the lowest layer and underlines the text.  Each layer gets “merged” together so you could just have your span say to add underlines but use the lowest layer’s colors.

This is still work in progress but the concepts are mostly in place already and we see this as introducing a whole new level of flexibility that isn’t available in SyntaxEditor 4.0.

Alpha Version

We get daily emails asking for a release date.  We want to get everything completed as fast as possible but we are taking our time and trying to develop a solid framework that should support a new generation of code editing functionality.  That being said we are getting closer to having an alpha version with limited functionality ready for closed testing.  We still have some pieces to get in place first but we are getting closer each day.  Keep an eye on this blog.  We’ll post more details soon.

Editors for WPF

The second main product we’re working on is Editors.  This product’s controls are intended to be used embedded in grids, property grids, or used standalone.

One of the core controls that will be offered in the Actipro Editors product is a parts-based editor. This editor will be extremely useful for working with objects like DateTime, as it allows the individual fields, such as the month or year, to be modified and configured independently. For example, this means that the "month" can be restricted to a static list of items (e.g. Jan, Feb, Mar, etc.) or the "day of the month" can be restricted to a specific range based on the current month (e.g. 1-28/29 for February).

Additionally, an associated spinner control can be used to update the active field, such as the "day of the month" or the "year". A drop-down button will be available, which can show a popup using any control or controls. These controls can be used to edit any or all of the fields. For example, a calendar and clock could be used (as seen in Microsoft Vista) to modify either the date or time of a DateTime object.

We plan on offering several controls that derive from the parts-based editor and are specifically designed for some common types, such as DateTime. This will get you up and running faster for the common types, while still allowing you to build your own parts-editor for your own types.

There are a lot of other features that we planned for this control, which we’ll get into in future posts.

Filed under: Actipro, In development, WPF

SyntaxEditor .NET Languages Add-on's IntelliPrompt improvements

 

We just released build 276 of SyntaxEditor and its add-ons.  This build has more general tweaks and bug fixes, along with some major updates to the IntelliPrompt capabilities for C#/VB via the .NET Languages Add-on.

Here are some of the major new updates.  There are a lot of small enhancements in IntelliPrompt across the board as well.

Anonymous Types

IntelliPrompt now works for anonymous types.  It will construct a type definition behind the scenes that contains the properties you specify and will use that type definition for constructing IntelliPrompt UI.

Anonymous

SyntaxEditor showing a member list for a property that is several levels deep in anonymous types

In the screen above, both abc and def are implicitly defined anonymous types.  You can see how SyntaxEditor correctly identifies the Now property on the abc anonymous type as a DateTime.

Extension Method Application

We have really enhanced the way that we determine which extension methods are applied to various types.  In previous builds there were a number of cases where extension methods could be applied to inappropriate types.  With our new code updates, the add-on attempts to resolve the parameters down to really determine if an extension method applies to a type, even if the type is a complex generic one.

Extension1 

A member list showing how extension methods are applied properly based on the source type

In the screen above, note how the AGoodTextExt extension method appears in the member list, while ABadTestExt does not since the latter is for enumerable int objects, not enumerable char objects.

Extension Method Quick/Parameter Info

The code updates also include some more updates to the quick and parameter info that is displayed for extension methods.  It will attempt to resolve the generic parameters into their "real" types for display to the end user.

Extension2

A member list showing how LINQ's Enumerable extension methods have been applied to a list variable, and how the quick info correctly displays the return value as IEnumerable<int>

In the screen above, the quick info used to say IEnumerable<T> in previous builds, but now says IEnumerable<int>.  We will be making other improvements in this area in the future.

Implicit Variable Declarations in VB

While our C# implementation has had var support for a while, we now have implicit variable declarations working in VB as well.

VBImplicit

A member list displayed for a variable that was implicitly declared

In the screen above, SyntaxEditor correctly displays the members for the ApplicationException type since that type was used to initialize the variable var.

SyntaxEditor for WPF block selection

As mentioned in previous posts, we're working very hard on the SyntaxEditor for WPF core editing capabilities.  One area that we've been working in this week is advanced selections such as block selections.

Block selections are where you create a rectangle of selection instead of the normal "snaking" variety of selection.

BlockSelection

Block selection in SyntaxEditor for WPF

As you can see from the screenshot above, we have block selection working already in SyntaxEditor for WPF.  And it even supports embedded right-to-left text properly!  Although the screenshot's selection looks a bit strange, that actually is the correct way to do a block selection when encountering right-to-left text.

We're making a very concerted effort to ensure that SyntaxEditor for WPF supports any culture.

Filed under: Actipro, In development, WPF

Large file editing in SyntaxEditor for WPF looks great so far

One area that we definitely want to improve with SyntaxEditor is the ability to have good response and performance when editing large files.  In SyntaxEditor for WinForms, there are a number of options you can turn off to help improve performance, yet it would would be much better to be able to leave options on and still have decent performance.  Also when editing huge documents, performance should still be considered good, not just satisfactory.

In our newer internal design that we're prototyping out in SyntaxEditor for WPF, we have already started implementing a number of improvements we've been brainstorming on for a long time.  Let's call these new ideas SyntaxEditor Next since after the WPF version is completed, we'll probably be looking at implementing similar techniques in the WinForms version 5.0.

Here is a list of some of the improved areas (let's assume a large document is 10MB in size for these comparisons):

  • Document loading - When loading a very large document, it may take 10-15 seconds to load and display in SyntaxEditor for WinForms.  In SyntaxEditor Next, it loads and displays instantaneously.
  • Typing performance - When editing a large document in SyntaxEditor for WinForms, there can be a noticeable delay when typing each character.  With our SyntaxEditor Next design, there is almost no noticeable slowdown in typing.
  • Word wrap activation - When switching to word wrap mode in SyntaxEditor for WinForms, very large documents might notice up to a several second delay before the switch is complete.  In SyntaxEditor Next, the change is instantaneous.
  • Word wrap memory - In SyntaxEditor for WinForms, word wrap mode took up a lot of additional memory when working with large files.  In SyntaxEditor Next, it uses almost no additional memory.

The observations above are comparisons made on the same 10MB file with highlighting enabled.

Please note that while SyntaxEditor for WPF (SyntaxEditor Next prototype) doesn't have outlining or semantic parsing implemented yet, to compare apples to apples we turned off outlining and semantic parsing in the WinForms version.  Therefore we are very optimistic that the performance results above can be maintained once outlining and semantic parsing are added to SyntaxEditor for WPF.

Filed under: Actipro, In development, WPF

SyntaxEditor for WPF will support bi-directional text (Arabic, etc.)

As I mentioned in the previous blog post, we've been working on core editing functionality for the WPF version of SyntaxEditor.  One feature that isn't in our WinForms version but that we always wanted to add is support for right-to-left languages inline with code.

Bi-directional display of text is a tricky thing because as soon as you enter a sequence of right-to-left characters such as Arabic or Hebrew, the entire sequence is flipped over and directional left/right arrow keys move the caret in the opposite direction.

 Bidi

SyntaxEditor for WPF showing the partial selection of some Arabic text

So in the screenshot above, say you have the caret at the left quote (fourth character) on line 6.  If you press your right arrow, the caret jumps to just before the right quote after the Arabic "Hello world" text, since this is considered "before" the Arabic sequence of characters.  If you press right arrow again, it moves one character to the left, and into the Arabic section.  This continues until you reach the leftmost side of the Arabic sequence, and the caret moves to the right quote again.  From that point on, right arrow moves to the right since it is back in left-to-right mode.

In the screenshot, the selection was anchored at the start of the "SyntaxEditor" word on line 5 and then the caret was moved down to line 6 into the Arabic sequence of characters.  You can see how the selection properly splits to show the contiguous sequence of characters that are selected.

Filed under: Actipro, In development, WPF

Actipro's WPF Product Roadmap - August 2008

Our previous WPF product roadmap posting presented the post-WPF Studio v4.0 development goals we have for the near future, including PropertyGrid for WPF and SyntaxEditor for WPF.

In this posting, I'd like to talk about some of the progress being made in those areas.

PropertyGrid for WPF

The PropertyGrid for WPF control provides nearly all the features found in modern IDE applications such as Visual Studio 2008 and Expression Blend.  If development continues as planned, we could be looking at having it out in late August.

Let's take an in-depth look as to what features the first release of this control will provide.

 PropertyGrid

The upcoming PropertyGrid for WPF product

Property Population - Manual and Automatic Options

The PropertyGrid can be populated manually using XAML or code-behind, which can be bound to any value. This
is great for scenarios where there is a known and static list of entries.

Additionally, the properties of any .NET object, or objects, can be used to automatically populate the PropertyGrid.
You can choose from simple reflection or TypeDescriptors, which supports abstract properties like attached properties, to create the entries from the specified object(s). When more than one object is specified, the properties common to all objects are "merged", just like the WinForms PropertyGrid. You can provide a custom "property factory" if you need more control over the generation of entries.

Property Editors

Property editors can be specified for properties by name/type, name, type, or base types. This means you can specify the editor to use for all enumeration types or for a specific property. The property editor can be used to customize the value cell DataTemplate, the control used to present/modify the value, and the name cell DataTemplate.  These give you total control over the appearance of each property.

Category Editors

Category editors can be used to present more complex editors that are capable of modifying more than one property
in a specified category. As seen above the FontFamily, FontSize, FontStyle, and FontWeight properties are presented using a "Font" category editor.

Data Validation

All the editors support the standard WPF data validation, as seen in the font size TextBox above. You can use Styles to apply your own ErrorTemplate.

Complex Properties

Certain "complex" properties can be expanded to show child properties.

SyntaxEditor for WPF

SyntaxEditor is under full development as well.  However this product will take more time to get an initial release out because there are several parallel goals that we're working on:

  1. Build a common document/parsing framework that can be shared among multiple related products and platforms.  This means using it for SyntaxEditor for WinForms, SyntaxEditor for WPF, CodeHighlighter for ASP.NET, and other small products we have in mind.
  2. Improve the document/parsing capabilities in general.
  3. Create better tools to help develop and maintain advanced languages.

That being said, once we get core editor functionality working, we may start some alpha testing for any WPF Studio customers who are interested.

SyntaxEditor

SyntaxEditor for WPF with some basic syntax highlighting for a C# document

Speaking of the core editing capabilities, we've been focusing a lot lately on making the common document/parsing framework.  So unfortunately that can't be displayed in screenshots.  However you'll like what you see once you get your hands on it.  Also we've been working on some basic editor features like view splitting along with some other really neat things that we'll keep quiet on for now.  Let's just say that once complete, SyntaxEditor for WPF will work like the Visual Studio code editor out-of-the-box, but will have some very nice extensibility points that weren't previously available.

If anyone has any suggestions for document/parsing or UI extensibility points, now is the time to e-mail them over.  We'd love to hear your thoughts.

Filed under: Actipro, In development, WPF