Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Code folding

siegi44 edited this page Mar 14, 2008 · 6 revisions

Introduction

In this section I will describe how to create a simple code folding.

For this purpose I have created a small sample application. It creates code folding for a small programming language I made up myself called VariX. For this code we will make a code folding.

`{{def function FuncName(val Name : Type) : Type return Value; enddef;

def procedure ProcName(val Name : Type) ; This is a comment enddef;`}}

That is enough for introduction. Now I will describe how this works.

Overview over the folding system

Code

`{{ using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms;

using ICSharpCode.TextEditor.Document;

namespace TextEditorTest { ///

/// This is the main class for testing the folding example. /// It is a form which simply contains a ICSharpCode.TextEditor.TextEditorControl /// public class MainForm : Form { /// /// Program entry point. /// [STAThread] private static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); }
	public MainForm()
	{
		//
		// The InitializeComponent() call is required for Windows Forms designer support.
		//
		InitializeComponent();
		
		// Initialize folding
		this.textEditorControl1.Document.FoldingManager.FoldingStrategy = new VariXFolding();
		// Update folding markers, call whenever you need to update the folding markers.
		// Especially when the text in the texteditor has been changed.
		this.textEditorControl1.Document.FoldingManager.UpdateFoldings(null, null);
	}
	
	#region FormsDesignerCode
	/// <summary>
	/// Designer variable used to keep track of non-visual components.
	/// </summary>
	private System.ComponentModel.IContainer components = null;
	
	/// <summary>
	/// Disposes resources used by the form.
	/// </summary>
	/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
	protected override void Dispose(bool disposing)
	{
		if (disposing) {
			if (components != null) {
				components.Dispose();
			}
		}
		base.Dispose(disposing);
	}
	
	/// <summary>
	/// This method is required for Windows Forms designer support.
	/// Do not change the method contents inside the source code editor. The Forms designer might
	/// not be able to load this method if it was changed manually.
	/// </summary>
	private void InitializeComponent()
	{
		this.textEditorControl1 = new ICSharpCode.TextEditor.TextEditorControl();
		this.SuspendLayout();
		// 
		// textEditorControl1
		// 
		this.textEditorControl1.Anchor = ((System.Windows.Forms.AnchorStyles)&#0040;&#0040;&#0040;&#0040;System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
								| System.Windows.Forms.AnchorStyles.Left) 
								| System.Windows.Forms.AnchorStyles.Right)));
		this.textEditorControl1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
		this.textEditorControl1.IsReadOnly = false;
		this.textEditorControl1.Location = new System.Drawing.Point(12, 12);
		this.textEditorControl1.Name = "textEditorControl1";
		this.textEditorControl1.Size = new System.Drawing.Size(268, 249);
		this.textEditorControl1.TabIndex = 0;
		this.textEditorControl1.Text = "def function FuncName(val Name : Type) : Type\r\n\treturn Value;\r\nenddef;\r\n" +
		"\r\ndef procedure ProcName(val Name : Type)\r\n\t; More lines ...\r\nenddef;";
		// 
		// MainForm
		// 
		this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
		this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
		this.ClientSize = new System.Drawing.Size(292, 273);
		this.Controls.Add(this.textEditorControl1);
		this.Name = "MainForm";
		this.Text = "TextEditorTest";
		this.ResumeLayout(false);
	}
	private ICSharpCode.TextEditor.TextEditorControl textEditorControl1;
	#endregion

}

/// <summary>
/// The class to generate the foldings, it implements ICSharpCode.TextEditor.Document.IFolding
/// </summary>
public class VariXFolding : IFoldingStrategy
{
	/// <summary>
	/// Generates the foldings for our document.
	/// </summary>
	/// <param name="document">The current document.</param>
	/// <param name="fileName">The filename of the document.</param>
	/// <param name="parseInformation">Extra parse information, not used in this sample.</param>
	/// <returns>A list of FoldMarkers.</returns>
	public List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
	{
		List<FoldMarker> list = new List<FoldMarker>();
		
		int start = 0;
		
		// Create foldmarkers for the whole document, enumerate through every line.
		for (int i = 0; i < document.TotalNumberOfLines; i++)
		{
			// Get the text of current line.
			string text = document.GetText(document.GetLineSegment(i));
			
			if (text.StartsWith("def")) // Look for method starts
				start = i;
			if (text.StartsWith("enddef;")) // Look for method endings
				// Add a new FoldMarker to the list.
				// document = the current document
				// start = the start line for the FoldMarker
				// document.GetLineSegment(start).Length = the ending of the current line = the start column of our foldmarker.
				// i = The current line = end line of the FoldMarker.
				// 7 = The end column
				list.Add(new FoldMarker(document, start, document.GetLineSegment(start).Length, i, 7));
		}
		
		return list;
	}
}

} `}}

Clone this wiki locally