Highlight Class Names

SyntaxEditor for Windows Forms Forum

Posted 19 years ago by BTAC Developer
Avatar
The default parsing information with the SyntaxEditor tutorials shows how to do quite a bit of highlighting with C# code.. but I'd like to also address the color of class names. Any ideas? Below is my "Trigger" event, it's pretty much identical to the tutorial one, except I've done some house-cleaning to it.

using System;
using System.Drawing;
using System.Windows.Forms;
using ActiproSoftware.SyntaxEditor;

namespace System.Windows.Forms
{
    public enum Language
    {
        /// <summary>
        /// Defines the Microsoft C# Language.
        /// </summary>
        CS,

        /// <summary>
        /// Defines the World Wide Web Consortium Cascading Style Sheets Language.
        /// </summary>
        CSS,

        /// <summary>
        /// Defines the World Wide Web Consortium Hypertext Markup Language.
        /// </summary>
        HTML,

        /// <summary>
        /// Defines the Sun Microsystems Java Language.
        /// </summary>
        JAVA,

        /// <summary>
        /// Defines the standard INI Condiguration File Language.
        /// </summary>
        INI,

        /// <summary>
        /// Defines the World Wide Web Consortium JavaScript Language.
        /// </summary>
        JS,

        /// <summary>
        /// Defines the Perl Language.
        /// </summary>
        PERL,

        /// <summary>
        /// Defines the Postback Hypertext Language (PHP).
        /// </summary>
        PHP,

        /// <summary>
        /// Defines the Python Language.
        /// </summary>
        PYTHON,

        /// <summary>
        /// Defines the Server Query Language (MSSQL).
        /// </summary>
        SQL,

        /// <summary>
        /// Defines the Microsoft Visual Basic .NET Language.
        /// </summary>
        VBNET,

        /// <summary>
        /// Defines the World Wide Web Consortium Extensible Markup Language (XML).
        /// </summary>
        XML,

        /// <summary>
        /// Defines the Microsoft Visual Basic Script Language.
        /// </summary>
        VBSCRIPT
    }

    /// <summary>
    /// The Syntax Editor Control is a pre-defined SyntaxEditor with
    /// methods and event handlers predefined for using within class
    /// files.
    /// </summary>
    public sealed partial class SyntaxEditorControl : UserControl
    {
        // ====================================================== //
        //                       CLASS CONSTRUCTORS                  //
        // ====================================================== //

        /// <summary>
        /// Constructs a new SyntaxEditorControl.
        /// </summary>
        public SyntaxEditorControl ( )
        {
            //
            // Required for the Windows Form Designer
            //
            InitializeComponent ( );

            //if ( !DesignMode )
            //    SelectLanguage ( Language );
        }

        // ====================================================== //
        //                        EVENT HANDLERS                      //
        // ====================================================== //

        /// <summary>
        /// Raised whenever a keystroke is entered in the editor window.
        /// </summary>
        /// <param name="sender">Object that triggered the event.</param>
        /// <param name="e">TriggerEventArgs to handle the event.</param>
        private void KeyStroke ( object sender, ActiproSoftware.SyntaxEditor.TriggerEventArgs e )
        {
            //
            // Determine the Language Key that the Editor Uses
            //
            switch ( SyntaxEditor.Document.Language.Key )
            {
                case "C#":

                    //
                    // Determine the Key that was Pressed
                    // to provide proper intellisense and
                    // syntax controls for the mouse edit
                    //

                    switch ( e.Trigger.Key )
                    {
                        //
                        // Determine if the Key Pressed is a "MemberList" Key, which
                        // means that the key is part of the C# Language Definition.
                        //
                        case "MemberListTrigger":

                            // Construct the Full Name of the Item -- This is to test
                            // Reflection and Iteration of the DataType in a KeySteam

                            ActiproSoftware.SyntaxEditor.TokenStream ActiproTokenStream =
                                SyntaxEditor.Document.GetTokenStream
                                    (
                                // iterate the ActiproTokens of the current view -- select the currently focused ActiproToken and the
                                // ActiproToken next to it for full parsing support.
                                        SyntaxEditor.Document.Tokens.IndexOf
                                            ( SyntaxEditor.SelectedView.Selection.EndOffset - 1 )
                                    );

                            // Design a String to Hold the Full Lexical Name of the Token
                            // As well as the number of periods in the Token Stream
                            String TokenName = String.Empty; Int32 Periods = 0;

                            // Iterate the Entire Tokenized Stream from Beginning to End
                            while ( ActiproTokenStream.Position > 0 )
                            {
                                // Iterate each Token of the Stream and Assign it
                                ActiproSoftware.SyntaxEditor.Token ActiproToken =
                                    ActiproTokenStream.ReadReverse ( );

                                // Determine the Token Key
                                switch ( ActiproToken.Key )
                                {

                                    case "IdentifierToken":
                                    case "NativeTypeToken":
                                        // If the Token is an Identifier or a Native .NET Type
                                        // Then Simply Assign the Full Token Text to the TokenName
                                        TokenName = SyntaxEditor.Document.GetTokenText ( ActiproToken ) + TokenName;

                                        break;

                                    // if the ActiproToken is a punctuation mark, such as a '.', or a ',' then
                                    // it should be treated as a delimiter ActiproToken by the syntax editors.
                                    case "PunctuationToken":
                                        if ( ( ActiproToken.Length == 1 ) && ( SyntaxEditor.Document.GetTokenText ( ActiproToken ) == "." ) )
                                        {
                                            TokenName = SyntaxEditor.Document.GetTokenText ( ActiproToken ) + TokenName;
                                            // Increment the Period Count
                                            Periods++;
                                        }
                                        else
                                            // Return to the Beginning of the Stream
                                            ActiproTokenStream.Position = 0;
                                        break;

                                    default:
                                        // Return to the Beginning of the Stream
                                        ActiproTokenStream.Position = 0;
                                        break;
                                }

                            }

                            // Convert the FullText Names of Common Token Types
                            if ( ( TokenName.Length > 0 ) && ( Periods == 0 ) )
                            {
                                switch ( TokenName )
                                {
                                    case "bool":
                                        TokenName = "System.Boolean";
                                        break;
                                    case "byte":
                                        TokenName = "System.Byte";
                                        break;
                                    case "char":
                                        TokenName = "System.Char";
                                        break;
                                    case "decimal":
                                        TokenName = "System.Decimal";
                                        break;
                                    case "double":
                                        TokenName = "System.Double";
                                        break;
                                    case "short":
                                        TokenName = "System.Int16";
                                        break;
                                    case "int":
                                        TokenName = "System.Int32";
                                        break;
                                    case "long":
                                        TokenName = "System.Int64";
                                        break;
                                    case "object":
                                        TokenName = "System.Object";
                                        break;
                                    case "sbyte":
                                        TokenName = "System.SByte";
                                        break;
                                    case "float":
                                        TokenName = "System.Single";
                                        break;
                                    case "string":
                                        TokenName = "System.String";
                                        break;
                                    case "ushort":
                                        TokenName = "System.UInt16";
                                        break;
                                    case "uint":
                                        TokenName = "System.UInt32";
                                        break;
                                    case "ulong":
                                        TokenName = "System.UInt64";
                                        break;
                                    case "void":
                                        TokenName = "System.Void";
                                        break;
                                }
                            }

                            // if a full ActiproToken name is found, then there are a number of options
                            // we can do, such as display the intellisense using reflection list
                            if ( TokenName.Length > 0 )
                            {
                                // Get the MemberList for the IntelliSense ListBox
                                IntelliPromptMemberList intellisenseMemberList =
                                    SyntaxEditor.IntelliPrompt.MemberList;

                                // Specify the IntelliPrompt ImageList
                                intellisenseMemberList.ImageList = SyntaxEditor.ReflectionImageList;

                                // Clear the Existing List so that Items can be Added to it Later
                                intellisenseMemberList.Clear ( );

                                // Use Reflection to Get the Assembly Contents
                                Reflection.Assembly[ ] ReflectedAssemblies =
                                    AppDomain.CurrentDomain.GetAssemblies ( );

                                // Iterate the Reflected Assemblies
                                foreach ( Reflection.Assembly ReflectedAssemblyData in ReflectedAssemblies )
                                {
                                    // Retrieve the Assembly Type from Reflection
                                    Type AssemblyType =
                                        ReflectedAssemblyData.GetType ( TokenName, false, false );

                                    if ( AssemblyType != null )
                                    {
                                        intellisenseMemberList.AddReflectionForTypeMembers ( AssemblyType, IntelliPromptTypeMemberFlags.AllMemberTypes |
                                                IntelliPromptTypeMemberFlags.AllAccessTypes | IntelliPromptTypeMemberFlags.Static );
                                        break;
                                    }
                                }

                                // If No Assembly Type can be Found ---
                                if ( intellisenseMemberList.Count == 0 )
                                {
                                    // Then we Assume a Namespace Assembly
                                    System.Collections.Specialized.StringCollection clcNamespaces =
                                        new System.Collections.Specialized.StringCollection ( );

                                    // Append the Token Name to the Namespace Collection
                                    clcNamespaces.Add ( TokenName );

                                    // Create an Array of Flags for Assemblies -- 
                                    IntelliPromptNamespaceAndTypeFlags[ ] intelliFlags =
                                        new IntelliPromptNamespaceAndTypeFlags[ ReflectedAssemblies.Length ];

                                    // This Assumes only Public Namespaces
                                    for ( int index = 0; index < intelliFlags.Length; index++ )
                                        intelliFlags[ index ] = IntelliPromptNamespaceAndTypeFlags.NamespacesAndTypes | IntelliPromptNamespaceAndTypeFlags.Public;

                                    // Use a Reflection Helper Method
                                    intellisenseMemberList.AddReflectionForAssemblyNamespacesAndTypes ( ReflectedAssemblies, intelliFlags, clcNamespaces, null, false );

                                    // Iterate the Items and Add the Descriptions and ToolTip Data
                                    foreach ( IntelliPromptMemberListItem Item in intellisenseMemberList )
                                    {
                                        if ( Item.ImageIndex == ( int )ActiproSoftware.Products.SyntaxEditor.IconResource.Namespace )
                                            Item.Description = String.Format ( "namespace <b>{0}</b>", Item.Tag.ToString ( ) );
                                        else if ( Item.Tag is Type )
                                        {
                                            // Get the Type of Item
                                            Type ItemType = ( Type )Item.Tag;
                                            if ( ItemType.IsEnum )
                                                Item.Description = String.Format ( "enum <b>{0}</b>", ItemType.FullName );
                                            else if ( ItemType.IsInterface )
                                                Item.Description = String.Format ( "interface <b>{0}</b>", ItemType.FullName );
                                            else if ( ItemType.IsValueType )
                                                Item.Description = String.Format ( "struct <b>{0}</b>", ItemType.FullName );
                                            else if ( ItemType.IsSubclassOf ( typeof ( Delegate ) ) )
                                                Item.Description = String.Format ( "delegate <b>{0}</b>", ItemType.FullName );
                                            else
                                                Item.Description = String.Format ( "class <b>{0}</b>", ItemType.FullName );
                                        }
                                    }
                                }

                                // Show the Finalized Member List
                                if ( intellisenseMemberList.Count > 0 )
                                    intellisenseMemberList.Show ( );
                            }
                            break;

                        //
                        // Determine if the Key Pressed is an "XmlComment" Key, which
                        // means that the key belongs to those used for xml comments.
                        //
                        case "XMLCommentTagListTrigger":
                            // Retrieve the IntelliSense Member List
                            IntelliPromptMemberList intelliMemberList =
                                SyntaxEditor.IntelliPrompt.MemberList;

                            // Set IntelliPrompt ImageList
                            intelliMemberList.ImageList =
                                SyntaxEditor.ReflectionImageList;

                            // Append Items to the MemberList
                            int intImageIndex =
                                ( int )ActiproSoftware.Products.SyntaxEditor.IconResource.Keyword;

                            // Clear the Intellisense Member List
                            intelliMemberList.Clear ( );

                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "c", intImageIndex, "Indicates that text within the tag should be marked as code.  Use &lt;code&gt; to indicate multiple lines as code." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "code", intImageIndex, "Indicates multiple lines as code. Use &lt;c&gt; to indicate that text within a description should be marked as code." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "example", intImageIndex, "Specifies an example of how to use a method or other library member." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "exception", intImageIndex, "Specifies which exceptions a class can throw.", "exception cref=\"", "\"" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "include", intImageIndex, "Refers to comments in another file that describe the types and members in your source code.", "include file='", "' path='[@name=\"\"]'/>" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "list", intImageIndex, "Provides a container for list items.", "list type=\"", "\"" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "listheader", intImageIndex, "Defines the heading row of either a table or definition list." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "item", intImageIndex, "Defines an item in a table or definition list." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "term", intImageIndex, "A term to define, which will be defined in text." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "description", intImageIndex, "Either an item in a bullet or numbered list or the definition of a term." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "para", intImageIndex, "Provides a paragraph container." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "param", intImageIndex, "Describes one of the parameters for the method.", "param name=\"", "\"/>" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "paramref", intImageIndex, "Indicates that a word is a parameter.", "paramref name=\"", "\"/>" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "permission", intImageIndex, "Documents the access of a member.", "permission cref=\"", "\"" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "remarks", intImageIndex, "Specifies overview information about a class or other type." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "returns", intImageIndex, "Describes the return value for a method declaration." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "see", intImageIndex, "Specifies a link from within text.", "see cref=\"", "\"/>" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "seealso", intImageIndex, "Specifies the text that you might want to appear in a See Also section.", "seealso cref=\"", "\"/>" ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "summary", intImageIndex, "Describes a member for a type." ) );
                            intelliMemberList.Add ( new IntelliPromptMemberListItem ( "value", intImageIndex, "Describes the value for a property declaration." ) );

                            // Display the Completed Member List
                            if ( intelliMemberList.Count > 0 )
                                intelliMemberList.Show ( );
                            break;
                        default:
                            break;
                    }
                    break;
                case "HTML":

                    //
                    // Determine the Key that was Pressed
                    // to provide proper intellisense and
                    // syntax controls for the mouse edit
                    //

                    switch ( e.Trigger.Key )
                    {
                        case "TagListTrigger":
                            {
                                // HTML EDITED OUT BECAUSE IT MESSES WITH CODE PARSER //

                                // Show the list of html commands
                                if ( intellisenseMemberList.Count > 0 )
                                    intellisenseMemberList.Show ( );
                                break;
                            }
                    }
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Raised whenever the Document Language and Syntax is Modified
        /// </summary>
        /// <param name="sender">Object that raised the event.</param>
        /// <param name="e">SyntaxLanguageEventArgs to handle the event.</param>
        private void OnChangeDocumentSyntax ( object sender, ActiproSoftware.SyntaxEditor.SyntaxLanguageEventArgs e )
        {
            switch ( e.Language.Key )
            {
                case "C#":
                    // Use the C# semantic parser 
                    e.Language.SemanticParser = new SemanticCSharpParser ( );
                    break;
                case "CSS":
                    // Use the CSS semantic parser
                    e.Language.SemanticParser = new SemanticCssParser ( );
                    break;
                case "HTML":
                    // Use the HTML semantic parser 
                    e.Language.SemanticParser = new SemanticHtmlParser ( );
                    break;
                case "Java":
                    // Use the Java semantic parser 
                    e.Language.SemanticParser = new SemanticJavaParser ( );
                    break;
                case "JScript":
                    // Use the JScript semantic parser 
                    e.Language.SemanticParser = new SemanticJScriptParser ( );
                    break;
                case "SQL":
                    // Use the SQL semantic parser 
                    e.Language.SemanticParser = new SemanticSqlParser ( );
                    break;
                case "VB.NET":
                    // Use the VB.NET semantic parser 
                    e.Language.SemanticParser = new SemanticVBDotNetParser ( );
                    break;
                case "XML":
                    // Use the XML semantic parser 
                    e.Language.SemanticParser = new SemanticXmlParser ( );
                    break;
            }
        }

        /// <summary>
        /// Raised whenever indentation is performed.
        /// </summary>
        /// <param name="sender">The object that raised the event.</param>
        /// <param name="e">SmartIndentEventArgs to handle the event.</param>
        private void OnSmartIndentation ( object sender, ActiproSoftware.SyntaxEditor.SmartIndentEventArgs e )
        {
            /*
            // By Default, the SyntaxEditor will Initialize the IndentAmount
            // for block formatting.
            switch ( SyntaxEditor.Document.Language.Key )
            {
                case "C#":

                    // Obtain a Reference to the TextEditor Content
                    TextStream strTextStream =
                        SyntaxEditor.Document.GetTextStream
                            ( SyntaxEditor.SelectedView.Selection.FirstOffset );

                    Boolean blnExitLoop = false; // Raise this Value whenever the Loop needs to Exit

                    while ( strTextStream.Position > 0 )
                    {
                        // Increment the Token
                        strTextStream.GoToPreviousToken ( );

                        switch ( strTextStream.CurrentToken.Key )
                        {
                            case "WhitespaceToken":
                                // Ignore all Whitespace
                                break;
                            case "OpenCurlyBraceToken":
                                e.IndentAmount++; blnExitLoop = true;
                                break;
                            default:
                                blnExitLoop = true;
                                break;
                        }

                        if ( blnExitLoop )
                            break;
                    }
                    break;
            }
             * */
        }


        // ====================================================== //
        //                       CLASS PROPERTIES                      //
        // ====================================================== //

        /// <summary>
        /// Gets or Sets the ActiproSyntax Editor Control
        /// </summary>
        public ActiproSoftware.SyntaxEditor.SyntaxEditor SyntaxEditor
        {
            get { return m_syntaxEditor; }
            set { m_syntaxEditor = value; }
        }

        /// <summary>
        /// Gets or Sets the Programming Language
        /// </summary>
        [System.ComponentModel.Browsable ( true )]
        public Language Language
        {
            get { return _csLanguage; }
            set
            {
                // Specify the Language
                _csLanguage = value;

                if ( DesignMode )
                    return;

                // Switch the Template
                SelectLanguage ( value );
            }
        }
    }
}
[Modified at 07/30/2005 08:42 PM]

Comments (1)

Posted 19 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Right now you'd have to keep track of what identifiers are class names by parsing yourself. If you do that, then you can set the CustomHiglightingStyle property of the class tokens to use an alternative highlighting style. Your parsing should take place in the semantic parser for the language, maybe in PostParse. Eventually we hope to maintain a DOM for the document that you can navigate to help automate this sort of thing.


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.