Posted 19 years ago by BTAC Developer
Avatar
I need to use a Regex to check for a literal "$" in a string. But since $ is used in Regex Patterns, I'm not sure how to do this, so that


$[any characters] is recognizable, including the '$' symbol. Any suggestions?

Comments (15)

Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Yes any regex control character can be escaped by placing a backslash in front of it so what you'd want to do is \$. This is in the Language Elements topic in the documentation. Our regex engine matches the .NET framework's engine in syntax and features applicable to an editing control.


Actipro Software Support

Posted 19 years ago by BTAC Developer
Avatar
I'm sorry, but that doesn't seem to work.
Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
I just tested it both in language definitions and in the regex find feature and it works in both places.

You have the latest 3.0 build, right?


Actipro Software Support

Posted 19 years ago by BTAC Developer
Avatar
Yes. I've fixed it. It was a matter of the location in the file. I was putting it down with the IdentifierPattern token.

Alright, so is it possible to detect when the cursor is within one of these highlighted fields since it's parsed by the lexical engine?
Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Yes, use the SelectionChanged event and check what Token the caret is in.


Actipro Software Support

Posted 19 years ago by BTAC Developer
Avatar
But how does that tell me if it's within a region parsed by the lexical engine? That is no different than the original method, which makes highlighting them with the lexical parser pretty moot and pointless.

Raised after the selection has changed.


[C#]
public event SelectionEventHandler SelectionChanged;


[Visual Basic]
Public Event SelectionChanged As SelectionEventHandler


Event Data
The event handler receives an argument of type SelectionEventArgs containing data related to this event.

Requirements
Namespace: ActiproSoftware.SyntaxEditor
Assembly: ActiproSoftware.SyntaxEditor (in actiprosoftware.syntaxeditor.dll)


That doesn't tell me very much.

[Modified at 08/08/2005 03:46 PM]
Posted 19 years ago by BTAC Developer
Avatar
Aah, I've got an idea.

I'll add the "$" as a Trigger Key, then in the Trigger event, I'll read the token and read the token to the right of it, if the token to the right is whitespace, I know I'm at the end of a word, and can recurisvely read backwards until I hit whitespace after another "$" again! Should that do it?
Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
If you're just trying to get the value of the Token then you can do stuff like:
editor.SelectedView.GetPreviousToken()

Which, depending on where the caret is will probably give you the token of the declaration. You'll have to play with it.

I hope I'm not leading you in circles on this. :) It's hard to say because we haven't really looked into how exactly to implement this yet. Just have some ideas from Boyd. We should just do it ourselves soon and get it out of the way since it is becoming more highly requested. But I can say we most likely will be using span indicators to mark the declarations when we do it ourselves.


Actipro Software Support

Posted 19 years ago by BTAC Developer
Avatar
I've already got the DOM structure for serializable snippets if you need it. :D
Posted 19 years ago by BTAC Developer
Avatar
protected override void OnSelectionChanged ( SelectionEventArgs e )
{
// Design a "Token" -- Get the Last Token in the Stream
ActiproSoftware.SyntaxEditor.Token ActiproToken =
e.Selection.View.GetPreviousToken ( );

if ( ActiproToken == null )
return;

// Construct a unique Token Name for this Indicator
String TokenName = ActiproToken.StartOffset.ToString() ;

if ( Document.FindNextSpanIndicator ( ActiproToken.StartOffset, TokenName ) != null )
Document.Indicators.Remove ( Document.FindNextSpanIndicator ( ActiproToken.StartOffset, TokenName ) );

if ( Document.FindPreviousSpanIndicator ( ActiproToken.StartOffset, TokenName ) != null )
Document.Indicators.Remove ( Document.FindPreviousSpanIndicator ( ActiproToken.StartOffset, TokenName ) );

if ( ActiproToken.HighlightingStyle.Name != "Highlight" )
return;

if ( !Document.Indicators.Contains ( TokenName ) )
Document.Indicators.Add ( new HighlightIndicator ( TokenName ), ActiproToken.StartOffset, ActiproToken.Length );
}

This is what I've got so far, but it doesn't quite work. If the user edits the contents of the token by deleting either $ character, then the Highlight Style is lost, but the Indicator is not. How can I persist the indicator to exist only when the highlight style exists?

[Modified at 08/08/2005 06:43 PM]
Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
In the SemanticParser.PostParse method, you know the range of offsets that were lexically parsed. From that you can check the Modified property of each Token to know if it was changed. Also if a Token was completely deleted on the last modification, it will be in the editor.Document.Tokens.DeletedTokens collection.


Actipro Software Support

Posted 19 years ago by BTAC Developer
Avatar
I'm not sure I follow you. Can you give me an example?
Posted 19 years ago by BTAC Developer
Avatar
Haha. I've got it! Now I just have to figure out how to tab between the different ones and modify multiple ones at a time (so that when you type in one, it changes the others that match). Any suggestions there?

/// <summary>
/// Allows for performing semantic parsing following a lexical parse.
/// </summary>
/// <param name="document">The <see cref="Document"/> to parse.</param>
/// <param name="modification">The <see cref="DocumentModification"/> that caused the parse.</param>
public override void PostParse ( Document document, DocumentModification modification )
{
// If programmatically setting the text of a document...
if ( modification.HasFlag ( DocumentModificationFlags.ProgrammaticTextParse ) )
document.Outlining.RootNode.CollapseDescendants ( "RegionPreProcessorDirective" );

if ( modification.StartOffset == 0 )
return;

foreach ( Token ActiproToken in document.Tokens )
{
if ( modification.StartOffset > ActiproToken.StartOffset )
{
// Construct a unique Token Name for this Indicator
String TokenName = ActiproToken.StartOffset.ToString ( );

if ( document.FindNextSpanIndicator ( ActiproToken.StartOffset, TokenName ) != null )
document.Indicators.Remove ( document.FindNextSpanIndicator ( ActiproToken.StartOffset, TokenName ) );

if ( document.FindPreviousSpanIndicator ( ActiproToken.StartOffset, TokenName ) != null )
document.Indicators.Remove ( document.FindPreviousSpanIndicator ( ActiproToken.StartOffset, TokenName ) );

if ( ActiproToken.HighlightingStyle.Name != "Highlight" )
return;

if ( !document.Indicators.Contains ( TokenName ) )
document.Indicators.Add ( new HighlightIndicator ( TokenName ), ActiproToken.StartOffset, ActiproToken.Length );
}
}
}

[Modified at 08/09/2005 10:26 AM]
Posted 19 years ago by BTAC Developer
Avatar
Of course, I think this might work much better..

/// <summary>
/// Allows for performing semantic parsing following a lexical parse.
/// </summary>
/// <param name="document">The <see cref="Document"/> to parse.</param>
/// <param name="modification">The <see cref="DocumentModification"/> that caused the parse.</param>
public override void PostParse ( Document document, DocumentModification modification )
{
// If programmatically setting the text of a document...
if ( modification.HasFlag ( DocumentModificationFlags.ProgrammaticTextParse ) )
document.Outlining.RootNode.CollapseDescendants ( "RegionPreProcessorDirective" );

// Clear each of the Indicators in the Document
foreach ( HighlightIndicator Highlighter in document.Indicators )
document.Indicators.Remove ( Highlighter );

// Iterate the Indicators and Add the Highlighting
foreach ( Token ActiproToken in document.Tokens )
if ( ActiproToken.HighlightingStyle.Name == "Highlight" )
document.Indicators.Add ( new HighlightIndicator ( ), ActiproToken.StartOffset, ActiproToken.Length );
}
Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
For tabbing, I'd recommend intercepting the KeyTyping event and looking for the Tab key. Then doing a search for the next declaration to jump to.

For knowing when to update other dependent declarations, maybe handle the SelectionChanged event and always keep track of the last code snippet indicator that you were in. If it changes the next time SelectionChanged is fired, then update the dependent declarations.


Actipro Software Support

The latest build of this product (v24.1.0) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.