SyntaxEditor folding with custom language

3 Answers 83 Views
SyntaxEditor
Marian
Top achievements
Rank 2
Iron
Iron
Iron
Marian asked on 13 Jun 2022, 10:40 PM

Hello, I want to use SyntaxEditor for coloring and folding of my very simple custom language for defining sequence of steps. I have already made some tests and have no problem with coloring. But I have two questions to SyntaxEditor folding. My language is very simple, it's just sequence of steps, but now I have to implement if/else/endif handling.

1. If I add folding pair if/endif, it works ok, but what if I want to fold if and else branches separately? Is it possible to do folding somehow like on this screenshot? I tried similar code it in Visual Basic, VB folds whole section from if to endif, but I would like to do it like on the screenshot, if it's possible.

2. How can I customize the folding "title" (I don't know the exact terminology). I added a #region / #endregion to previous sample, and it's folding like on this screenshot:

I would like it like in Visual Studio, in case of if statement, you can see the condition, but region hides also the region directive, like on the next screenshot.

I know, C# is folding command block with braces, so it's different situation, but is it possible to do it like this also with my custom language?

I attached also my project, if it's needed for something.

Thanks.

3 Answers, 1 is accepted

Sort by
0
Accepted
Dess | Tech Support Engineer, Principal
Telerik team
answered on 16 Jun 2022, 07:41 AM

Hello, Marian, 

The provided sample project is greatly appreciated. RadSyntaxEditor offers a CSharpFoldingTagger which I believe displays the desired title for the collapsed regions. Note that you have access to the source code of the CSharpFoldingTagger and the entire Telerik source code from your account: https://docs.telerik.com/devtools/winforms/installation-and-upgrades/download-product-files
Thus, you can have a look at the default implementation and adopt it in your custom tagger.

Note that you can override the GetFoldingRegionTitle for the custom FoldingTaggerBase and return the string you want to be displayed.

As to the question about collapsing the "if"-"else" region, it may be added as a separate FoldingRegionDefinition

	public class SeqFoldingTagger : FoldingTaggerBase
	{
		public SeqFoldingTagger(RadSyntaxEditorElement editor) : base(editor)
		{
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("#region", "#endregion"));
			//FoldingRegionDefinitions.Add(new FoldingRegionDefinition("if", "endif"));
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("if", "else"));
		}
	}

However, it is important the FoldingRegionDefinition to be unique and the start/ending keywords for the folding regions to not overlap in different FoldingRegionDefinitions. In other words, if you have a "if"-"else"-"endif" code, the first part "if"-"else" forms one folding region. Hence, the "else" word is already a part of the first region and if you collapse it, the "else" word is expected to be hidden:

	public class SeqFoldingTagger : FoldingTaggerBase
	{
		public SeqFoldingTagger(RadSyntaxEditorElement editor) : base(editor)
		{
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("#region", "#endregion"));
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("else", "endif"));
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("if", "else"));
		}
	}

You can modify the folding regions a little bit so they will be strictly defined with start/end:

	public class SeqFoldingTagger : FoldingTaggerBase
	{
		public SeqFoldingTagger(RadSyntaxEditorElement editor) : base(editor)
		{
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("#region", "#endregion"));
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("else", "endelse"));
			FoldingRegionDefinitions.Add(new FoldingRegionDefinition("if", "endif")); 
		}
	}

 

I hope this information helps. If you need any further assistance please don't hesitate to contact me.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Marian
Top achievements
Rank 2
Iron
Iron
Iron
answered on 16 Jun 2022, 08:06 AM | edited on 16 Jun 2022, 08:08 AM
Hello, thanks for answer. I will look at GetFoldingRegionTitle. And with folding, I thought it will be problem to do it without changing language. I tried to add three pairs (if/endif, if/else, else/endif), but it detected always only first or last block as I expected. I can look to CSharp tagger, but I know C# is actually folding the braces blocks, not if/else itself. So I can consider if it has sense to change language just for nicer folding. If user has larger if/else blocks and wants to fold it, he can still write region inside if.
Dess | Tech Support Engineer, Principal
Telerik team
commented on 20 Jun 2022, 11:57 AM

Hi, Marian,

I believe that the previously provided information was useful for your scenario. I just wanted to pay attention again to the fact that if one word participates in different folding regions and they are consecutive or overlapping, you will be allowed to expand/collapse the first matching region since only one "+" sign is shown:


0
Marian
Top achievements
Rank 2
Iron
Iron
Iron
answered on 06 Jul 2022, 07:54 PM | edited on 06 Jul 2022, 07:55 PM

Hello,

I have one more question. I have custom WordTagger based on example in documentation. Now I have problem, it doesn't correctly color symbols with underscores, like Result_OK etc. I guess problem is in dividing string into words, that default implementation probably handles it as two words, and I should override SplitIntoWords method. Can you please help me with this? If it would be problem, I can rename that symbols to ResultOK etc, but I want to use underscores for automatically generated new symbols in future, so I would like to solve this.

Thank you very much for help, also to Dinko in second question thread, now I have a much better editor, it's great control, I have folding regions, coloring, completions, custom completion for if conditions, it's really a progress.

Dinko | Tech Support Engineer
Telerik team
commented on 11 Jul 2022, 10:17 AM

You can override the SplitIntoWords method of WordTaggerBase which will split the whole line into words with a rule that a series of equally-typed chars form a word. I am posting here the default implementation of SplitIntoWords and the function for determining the char types to get you started. What you need is to include logic for your "_" symbol - to categorize it as a letter (type 0). 

You can add the following code to the SeqWordTagger custom class.

protected int GetCharType(char c)
{
	if (c == '#')
	{
		return 3;
	}

	// return 0 for underscore
	if (c == '_')
	{
		return 0;
	}

	if (char.IsWhiteSpace(c))
	{
		return 1;
	}

	if (char.IsPunctuation(c) || char.IsSymbol(c))
	{
		return 2;
	}

	return 0;
}
protected override IList<string> SplitIntoWords(string value)
{
	List<string> words = new List<string>();
	string word;
	int lastCharType = -1;
	int startIndex = 0;
	for (int i = 0; i < value.Length; i++)
	{
		int charType = GetCharType(value[i]);
		if (charType != lastCharType)
		{
			word = value.Substring(startIndex, i - startIndex);
			words.Add(word);
			startIndex = i;
			lastCharType = charType;
		}
	}

	word = value.Substring(startIndex, value.Length - startIndex);
	words.Add(word);

	return words;
}

Also, you can include the words which include underscoring in the Keywords array.

private static readonly string[] Keywords = new string[] { "if", "else", "end_if", "Konec", "endif" };

Marian
Top achievements
Rank 2
Iron
Iron
Iron
commented on 11 Jul 2022, 05:40 PM

Thanks, it works. But you can just override GetCharType method, it's also virtual. So my code is just following:

		protected override int GetCharType(char character)
		{
			if (character == '_')
				return 0;

			return base.GetCharType(character);
		}
Dinko | Tech Support Engineer
Telerik team
commented on 12 Jul 2022, 08:59 AM

You are right. You don't need to extract the whole method, just add the additional if clause.
Tags
SyntaxEditor
Asked by
Marian
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Marian
Top achievements
Rank 2
Iron
Iron
Iron
Share this question
or