first commit

This commit is contained in:
2026-01-07 11:33:05 +08:00
commit fc54ffd43b
215 changed files with 31856 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor.Extensions
{
public static class ControlExtensions
{
public static EventHandlerList GetEventHandlerList(this Control c)
{
return GetEventHandlerListInternal(c);
}
public static EventHandlerList GetEventHandlerList(this Component c)
{
return GetEventHandlerListInternal(c);
}
private static EventHandlerList GetEventHandlerListInternal(object obj)
{
Type type = obj.GetType();
PropertyInfo pi = type.GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Instance);
return (EventHandlerList)pi.GetValue(obj, null);
}
}
}

View File

@@ -0,0 +1,43 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>1.2.1</Version>
<OutputType>Library</OutputType>
<TargetFrameworks>net4.6.2;net5.0-windows;net6.0-windows</TargetFrameworks>
<UseWindowsForms>true</UseWindowsForms>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<PackageId>ICSharpCode.TextEditorEx</PackageId>
<Copyright>Copyright © Stef Heyenrath, SharpDevelop, Qwertie and MysticBoy 2014-2022</Copyright>
<PackageProjectUrl>https://github.com/StefH/ICSharpCode.TextEditorEx</PackageProjectUrl>
<RepositoryUrl>https://github.com/StefH/ICSharpCode.TextEditorEx</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>TextEditor;ICSharpCode</PackageTags>
<Authors>Stef Heyenrath, SharpDevelop, Qwertie and MysticBoy</Authors>
<PackageLicenseExpression>LGPL-2.1-or-later</PackageLicenseExpression>
<RootNamespace>ICSharpCode.TextEditor</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Resources\*.*" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,13 @@
using System;
using System.Reflection;
using System.Runtime.InteropServices;
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("64fb04c7-a744-45a0-9050-13a1825a6980")]
[assembly: CLSCompliant(true)]

View File

@@ -0,0 +1,193 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace ICSharpCode.TextEditor.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ICSharpCode.TextEditor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap cut {
get {
object obj = ResourceManager.GetObject("cut", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap htmlpage {
get {
object obj = ResourceManager.GetObject("htmlpage", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Byte[] 类型的本地化资源。
/// </summary>
internal static byte[] RightArrow {
get {
object obj = ResourceManager.GetObject("RightArrow", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_cancel {
get {
object obj = ResourceManager.GetObject("sc_cancel", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_copy {
get {
object obj = ResourceManager.GetObject("sc_copy", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_cut {
get {
object obj = ResourceManager.GetObject("sc_cut", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_linearrowend {
get {
object obj = ResourceManager.GetObject("sc_linearrowend", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_paste {
get {
object obj = ResourceManager.GetObject("sc_paste", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_redo {
get {
object obj = ResourceManager.GetObject("sc_redo", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_searchdialog {
get {
object obj = ResourceManager.GetObject("sc_searchdialog", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_selectall {
get {
object obj = ResourceManager.GetObject("sc_selectall", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap sc_undo {
get {
object obj = ResourceManager.GetObject("sc_undo", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap splitdocument {
get {
object obj = ResourceManager.GetObject("splitdocument", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="cut" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\cut.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="htmlpage" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\htmlpage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="RightArrow" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\rightarrow.cur;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="sc_cancel" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_cancel.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_copy" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_cut" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_cut.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_linearrowend" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_linearrowend.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_paste" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_paste.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_redo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_redo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_searchdialog" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_searchdialog.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_selectall" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_selectall.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="sc_undo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\sc_undo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="splitdocument" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\splitdocument.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@@ -0,0 +1,3 @@
Based on http://www.codeproject.com/Articles/30936/Using-ICSharpCode-TextEditor
ContextMenu : MysticBoy at https://github.com/maikebing/ICSharpCode.TextEditorEx

View File

@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<SyntaxDefinition name = "ASP/XHTML" extensions = ".asp;.aspx;.asax;.asmx" extends = "HTML">
<RuleSets>
<RuleSet ignorecase = "true">
<Span name = "ASPCode" rule = "ASP" bold = "false" italic = "false" color = "Black" bgcolor = "#F7F2E3" stopateol = "false">
<Begin color="Black" bgcolor="Yellow">&lt;%</Begin>
<End color="Black" bgcolor="Yellow">%&gt;</End>
</Span>
</RuleSet>
<RuleSet name="ASP" ignorecase = "false">
<Span name = "COMMENT" bold = "false" italic = "false" color = "Green" bgcolor = "#F7F2E3" stopateol = "true">
<Begin>//</Begin>
</Span>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for BAT 2000 by Mike Krueger -->
<SyntaxDefinition name = "BAT" extensions = ".bat">
<Environment>
<Default color = "Yellow" bgcolor = "Black"/>
<Selection color = "White" bgcolor = "Purple"/>
<VRuler color = "Green"/>
<InvalidLines color = "Red"/>
<CaretMarker color = "Yellow"/>
<LineNumbers color = "Gray" bgcolor = "Black"/>
<FoldLine color = "Cyan" bgcolor = "Black"/>
<FoldMarker color = "Cyan" bgcolor = "White"/>
<SelectedFoldLine color = "Green" bgcolor="Black"/>
<EOLMarkers color = "#E0E0E5"/>
<SpaceMarkers color = "#E0E0E5"/>
<TabMarkers color = "#E0E0E5"/>
</Environment>
<Digits name = "Digits" bold = "false" italic = "false" color = "Yellow"/>
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters> </Delimiters>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,303 @@
<?xml version="1.0"?>
<SyntaxDefinition name="Boo" extensions=".boo">
<Environment>
<Custom name="LocalVariableCreation" bold="false" italic="false" color="#04ABAB" />
</Environment>
<Properties>
<Property name="LineComment" value="#"/>
</Properties>
<Digits name="Digits" bold="false" italic="false" color="DarkBlue" />
<RuleSets>
<RuleSet ignorecase="false" >
<Delimiters>&amp;&lt;&gt;~!@$%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name="DocLineComment" stopateol="false" bold="false" italic="false" color="Green">
<Begin >"""</Begin>
<End >"""</End>
</Span>
<Span name="LineComment" stopateol="true" bold="false" italic="false" color="Gray" >
<Begin >#</Begin>
</Span>
<Span name="LineComment2" stopateol="true" bold="false" italic="false" color="#999999" >
<Begin >//</Begin>
</Span>
<Span name="BlockComment" rule="comments set" stopateol="false" bold="false" italic="false" color="Green" >
<Begin >/*</Begin>
<End >*/</End>
</Span>
<Span name="String" rule="str formatting" stopateol="true" bold="false" italic="false" color="Blue" escapecharacter="\">
<Begin >"</Begin>
<End >"</End>
</Span>
<Span name="MultiLineString" rule="str formatting" stopateol="false" bold="false" italic="false" color="Blue" >
<Begin >"""</Begin>
<End >"""</End>
</Span>
<Span name="Char" stopateol="true" bold="false" italic="false" color="Blue" escapecharacter="\">
<Begin >'</Begin>
<End >'</End>
</Span>
<Span name="MultiLineRegEx" stopateol="false" bold="false" italic="false" color="#FF6600">
<Begin>@@/</Begin>
<End>/</End>
</Span>
<Span name="RegEx" stopateol="true" bold="false" italic="false" color="#FF6600">
<Begin>/@! @@!/@</Begin>
<End>/</End>
</Span>
<MarkPrevious bold="false" italic="false" color="MidnightBlue" >(</MarkPrevious>
<KeyWords name="Punctuation" bold="false" italic="false" color="DarkGreen" >
<Key word="?"/>
<Key word=","/>
<Key word="."/>
<Key word=";"/>
<Key word="("/>
<Key word=")"/>
<Key word="["/>
<Key word="]"/>
<Key word="{"/>
<Key word="}"/>
<Key word="+"/>
<Key word="-"/>
<Key word="/"/>
<Key word="%"/>
<Key word="*"/>
<Key word="&lt;"/>
<Key word="&gt;"/>
<Key word="^"/>
<Key word="="/>
<Key word="~"/>
<Key word="!"/>
<Key word="|"/>
<Key word="&amp;"/>
</KeyWords>
<KeyWords name="AccessKeywords" bold="true" italic="false" color="Black" >
<Key word="self"/>
<Key word="super"/>
</KeyWords>
<KeyWords name="OperatorKeywords" bold="true" italic="false" color="DarkCyan" >
<Key word="is"/>
<Key word="isa"/>
<Key word="and"/>
<Key word="or"/>
<Key word="not"/>
</KeyWords>
<KeyWords name="SelectionStatements" bold="true" italic="false" color="Blue" >
<Key word="else"/>
<Key word="elif"/>
<Key word="if"/>
<Key word="match"/>
<Key word="case"/>
<Key word="unless"/>
<Key word="otherwise"/>
</KeyWords>
<KeyWords name="IterationStatements" bold="true" italic="false" color="Blue" >
<Key word="for"/>
<Key word="in"/>
<Key word="while"/>
</KeyWords>
<KeyWords name="JumpStatements" bold="false" italic="false" color="Navy" >
<Key word="break"/>
<Key word="continue"/>
<Key word="return"/>
<Key word="yield"/>
<Key word="goto" />
</KeyWords>
<KeyWords name="ExceptionHandlingStatements" bold="true" italic="false" color="Teal" >
<Key word="try"/>
<Key word="raise"/>
<Key word="ensure"/>
<Key word="except"/>
<Key word="retry"/>
<Key word="success"/>
</KeyWords>
<KeyWords name="CheckedUncheckedStatements" bold="true" italic="false" color="DarkGray" >
<Key word="checked"/>
<Key word="unchecked"/>
</KeyWords>
<KeyWords name="UnsafeFixedStatements" bold="false" italic="false" color="Olive" >
<Key word="fixed"/>
<Key word="unsafe"/>
</KeyWords>
<KeyWords name="ValueTypes" bold="true" italic="false" color="Purple" >
<Key word="bool"/>
<Key word="double"/>
<Key word="single"/>
<Key word="byte"/>
<Key word="sbyte"/>
<Key word="short"/>
<Key word="ushort"/>
<Key word="int"/>
<Key word="uint"/>
<Key word="long"/>
<Key word="ulong"/>
<Key word="date"/>
<Key word="timespan" />
<Key word="decimal" />
<Key word="char" />
</KeyWords>
<KeyWords name="ReferenceTypes" bold="true" italic="false" color="Purple" >
<Key word="object"/>
<Key word="duck"/>
<Key word="string"/>
<Key word="regex"/>
</KeyWords>
<KeyWords name="Void" bold="false" italic="false" color="Red" >
<Key word="void"/>
</KeyWords>
<KeyWords name="ConversionKeyWords" bold="true" italic="false" color="Blue" >
<Key word="cast"/>
<Key word="as"/>
</KeyWords>
<KeyWords name="Modifiers" bold="false" italic="false" color="Brown" >
<Key word="override"/>
<Key word="static"/>
<Key word="virtual"/>
<Key word="abstract"/>
<Key word="final"/>
<Key word="transient"/>
<Key word="partial"/>
</KeyWords>
<KeyWords name="AccessModifiers" bold="true" italic="false" color="Blue" >
<Key word="public"/>
<Key word="protected"/>
<Key word="private"/>
<Key word="internal"/>
</KeyWords>
<KeyWords name="NameSpaces" bold="true" italic="false" color="Green" >
<Key word="namespace"/>
<Key word="import"/>
<Key word="from"/>
</KeyWords>
<KeyWords name="GetSet" bold="false" italic="false" color="SaddleBrown" >
<Key word="get"/>
<Key word="set"/>
</KeyWords>
<KeyWords name="Literals" bold="true" italic="false" color="Black" >
<Key word="null"/>
<Key word="value"/>
<Key word="true"/>
<Key word="false"/>
<Key word="ast" />
</KeyWords>
<KeyWords name="DefaultMacros" bold="false" italic="false" color="Maroon" >
<Key word="using"/>
<Key word="unchecked"/>
<Key word="checked"/>
<Key word="lock"/>
<Key word="getter"/>
<Key word="required"/>
<Key word="rawArrayIndexing"/>
<Key word="normalArrayIndexing"/>
<Key word="yieldAll" />
</KeyWords>
<KeyWords name="Builtins" bold="false" italic="false" color="Purple" >
<Key word="assert"/>
<Key word="array"/>
<Key word="matrix" />
<Key word="print"/>
<Key word="gets"/>
<Key word="prompt"/>
<Key word="enumerate"/>
<Key word="zip"/>
<Key word="filter"/>
<Key word="map"/>
<Key word="cat"/>
<Key word="__eval__" />
<Key word="__switch__" />
</KeyWords>
<KeyWords name="Methods" bold="true" italic="false" color="Blue" >
<Key word="constructor"/>
<Key word="destructor"/>
<Key word="def"/>
<Key word="include"/>
<Key word="event" />
<Key word="ref"/>
</KeyWords>
<KeyWords name="Pass" bold="false" italic="false" color="Gray" >
<Key word="pass"/>
</KeyWords>
<KeyWords name="TypesDef" bold="true" italic="false" color="Blue" >
<Key word="enum"/>
<Key word="class"/>
<Key word="struct" />
<Key word="interface"/>
<Key word="mixin"/>
<Key word="callable"/>
<Key word="do" />
<Key word="of" />
</KeyWords>
</RuleSet>
<RuleSet ignorecase="false" name="comments set" >
<Delimiters>&amp;&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name="BlockComment" rule="comment set 2" stopateol="false" bold="false" italic="false" color="#339966" >
<Begin >/*</Begin>
<End >*/</End>
</Span>
</RuleSet>
<RuleSet ignorecase="false" name="comment set 2" >
<Delimiters>&amp;&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name="BlockComment" rule="comments set" stopateol="false" bold="false" italic="false" color="Teal" >
<Begin >/*</Begin>
<End >*/</End>
</Span>
</RuleSet>
<RuleSet ignorecase="false" name="str formatting" >
<Delimiters>&amp;&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name="Formatting" stopateol="false" bold="false" italic="false" color="#993366" >
<Begin >${</Begin>
<End >}</End>
</Span>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,206 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for C/C++ 2001 by Andrea Paatz and Mike Krueger -->
<SyntaxDefinition name = "C++.NET" extensions = ".c;.h;.cc;.C;.cpp;.hpp">
<Properties>
<Property name="LineComment" value="//"/>
</Properties>
<Digits name = "Digits" bold = "false" italic = "false" color = "DarkBlue"/>
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>~!%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name = "PreprocessorDirectives" bold="false" italic="false" color="Green" stopateol = "true">
<Begin>#</Begin>
</Span>
<Span name = "LineComment" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>//</Begin>
</Span>
<Span name = "BlockComment" bold = "false" italic = "false" color = "Green" stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name = "String" bold = "false" italic = "false" color = "Magenta" stopateol = "true" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span>
<Span name = "Char" bold = "false" italic = "false" color = "Magenta" stopateol = "true" escapecharacter="\">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span>
<MarkPrevious bold = "true" italic = "false" color = "MidnightBlue">(</MarkPrevious>
<KeyWords name = "Punctuation" bold = "false" italic = "false" color = "DarkGreen">
<Key word = "?" />
<Key word = "," />
<Key word = "." />
<Key word = ";" />
<Key word = "(" />
<Key word = ")" />
<Key word = "[" />
<Key word = "]" />
<Key word = "{" />
<Key word = "}" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "%" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "^" />
<Key word = "=" />
<Key word = "~" />
<Key word = "!" />
<Key word = "|" />
<Key word = "&amp;" />
</KeyWords>
<KeyWords name = "ManagedKeyWords" bold="true" italic="false" color="Black">
<Key word = "__abstract" />
<Key word = "__box" />
<Key word = "__delegate" />
<Key word = "__gc" />
<Key word = "__identifier" />
<Key word = "__nogc" />
<Key word = "__pin" />
<Key word = "__property" />
<Key word = "__sealed" />
<Key word = "__try_cast" />
<Key word = "__typeof" />
<Key word = "__value" />
<Key word = "__event" />
<Key word = "__hook" />
<Key word = "__raise" />
<Key word = "__unhook" />
<Key word = "__interface" />
</KeyWords>
<KeyWords name = "AccessKeywords" bold="true" italic="false" color="Black">
<Key word = "this" />
</KeyWords>
<KeyWords name = "OperatorKeywords" bold="true" italic="false" color="DarkCyan">
<Key word = "and" />
<Key word = "and_eq" />
<Key word = "bitand" />
<Key word = "bitor" />
<Key word = "new" />
<Key word = "not" />
<Key word = "not_eq" />
<Key word = "or" />
<Key word = "or_eq" />
<Key word = "xor" />
<Key word = "xor_eq" />
</KeyWords>
<KeyWords name = "NameSpaces" bold="true" italic="false" color="Green">
<Key word = "using" />
<Key word = "namespace" />
</KeyWords>
<KeyWords name = "Friends" bold="false" italic="false" color="Brown">
<Key word = "friend" />
</KeyWords>
<KeyWords name = "AccessModifiers" bold="true" italic="false" color="Blue">
<Key word = "private" />
<Key word = "protected" />
<Key word = "public" />
<Key word = "const" />
<Key word = "volatile" />
<Key word = "static" />
</KeyWords>
<KeyWords name = "Types" bold="false" italic="false" color="Red">
<Key word = "bool" />
<Key word = "char" />
<Key word = "unsigned" />
<Key word = "union" />
<Key word = "virtual" />
<Key word = "double" />
<Key word = "float" />
<Key word = "short" />
<Key word = "signed" />
<Key word = "void" />
<Key word = "class" />
<Key word = "enum" />
<Key word = "struct" />
</KeyWords>
<KeyWords name = "Literals" bold="true" italic="false" color="Black">
<Key word = "false" />
<Key word = "true" />
</KeyWords>
<KeyWords name = "IterationStatements" bold="true" italic="false" color="Blue">
<Key word = "do" />
<Key word = "for" />
<Key word = "while" />
</KeyWords>
<KeyWords name = "JumpStatements" bold="false" italic="false" color="Navy">
<Key word = "break" />
<Key word = "continue" />
<Key word = "goto" />
<Key word = "return" />
</KeyWords>
<KeyWords name = "ExceptionHandlingStatements" bold="true" italic="false" color="Teal">
<Key word = "catch" />
<Key word = "throw" />
<Key word = "try" />
</KeyWords>
<KeyWords name = "SelectionStatements" bold="true" italic="false" color="Blue">
<Key word = "case" />
<Key word = "else" />
<Key word = "if" />
<Key word = "switch" />
<Key word = "default" />
</KeyWords>
<KeyWords name = "KEYWORD1" bold="true" italic="false" color="Blue">
<Key word = "asm" />
<Key word = "auto" />
<Key word = "compl" />
<Key word = "mutable" />
<Key word = "const_cast" />
<Key word = "delete" />
<Key word = "dynamic_cast" />
<Key word = "explicit" />
<Key word = "export" />
<Key word = "extern" />
<Key word = "inline" />
<Key word = "int" />
<Key word = "long" />
<Key word = "operator" />
<Key word = "register" />
<Key word = "reinterpret_cast" />
<Key word = "sizeof" />
<Key word = "static_cast" />
<Key word = "template" />
<Key word = "typedef" />
<Key word = "typeid" />
<Key word = "typename" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,339 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for C# 2000 by Mike Krueger -->
<SyntaxDefinition name = "C#" extensions = ".cs">
<Environment>
<Custom name="TypeReference" bold="false" italic="false" color="#04ABAB" />
<Custom name="UnknownEntity" bold="false" italic="false" color="#AB0404" />
</Environment>
<Properties>
<Property name="LineComment" value="//"/>
</Properties>
<Digits name = "Digits" bold = "false" italic = "false" color = "DarkBlue"/>
<RuleSets>
<RuleSet ignorecase="false">
<Delimiters>&amp;&lt;&gt;~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name = "PreprocessorDirectives" rule = "PreprocessorSet" bold="false" italic="false" color="Green" stopateol = "true">
<Begin>#</Begin>
</Span>
<Span name = "DocLineComment" rule = "DocCommentSet" bold = "false" italic = "false" color = "Green" stopateol = "true" noescapesequences="true">
<Begin bold = "false" italic = "false" color = "Gray">///@!/@</Begin>
</Span>
<Span name = "LineComment" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>//@!/@</Begin>
</Span>
<Span name = "LineComment2" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>////</Begin>
</Span>
<Span name = "BlockComment" rule = "CommentMarkerSet" bold = "false" italic = "false" color = "Green" stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name = "String" bold = "false" italic = "false" color = "Blue" stopateol = "true" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span>
<Span name = "MultiLineString" bold = "false" italic = "false" color = "Blue" stopateol = "false" escapecharacter='"'>
<Begin>@@"</Begin>
<End>"</End>
</Span>
<Span name = "Char" bold = "false" italic = "false" color = "Magenta" stopateol = "true" escapecharacter="\">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span>
<MarkPrevious bold = "true" italic = "false" color = "MidnightBlue">(</MarkPrevious>
<KeyWords name = "Punctuation" bold = "false" italic = "false" color = "DarkGreen">
<Key word = "?" />
<Key word = "," />
<Key word = "." />
<Key word = ";" />
<Key word = "(" />
<Key word = ")" />
<Key word = "[" />
<Key word = "]" />
<Key word = "{" />
<Key word = "}" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "%" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "^" />
<Key word = "=" />
<Key word = "~" />
<Key word = "!" />
<Key word = "|" />
<Key word = "&amp;" />
</KeyWords>
<KeyWords name = "AccessKeywords" bold="true" italic="false" color="Black">
<Key word = "this" />
<Key word = "base" />
</KeyWords>
<KeyWords name = "OperatorKeywords" bold="true" italic="false" color="DarkCyan">
<Key word = "as" />
<Key word = "is" />
<Key word = "new" />
<Key word = "sizeof" />
<Key word = "typeof" />
<Key word = "true" />
<Key word = "false" />
<Key word = "stackalloc" />
</KeyWords>
<KeyWords name = "SelectionStatements" bold="true" italic="false" color="Blue">
<Key word = "else" />
<Key word = "if" />
<Key word = "switch" />
<Key word = "case" />
<Key word = "default" />
</KeyWords>
<KeyWords name = "IterationStatements" bold="true" italic="false" color="Blue">
<Key word = "do" />
<Key word = "for" />
<Key word = "foreach" />
<Key word = "in" />
<Key word = "while" />
</KeyWords>
<KeyWords name = "JumpStatements" bold="false" italic="false" color="Navy">
<Key word = "break" />
<Key word = "continue" />
<Key word = "goto" />
<Key word = "return" />
</KeyWords>
<KeyWords name = "ContextKeywords" bold="false" italic="false" color="Navy">
<Key word = "yield" />
<Key word = "partial" />
<Key word = "global" />
<Key word = "where" />
<Key word = "select" />
<Key word = "group" />
<Key word = "by" />
<Key word = "into" />
<Key word = "from" />
<Key word = "ascending" />
<Key word = "descending" />
<Key word = "orderby" />
<Key word = "let" />
<Key word = "join" />
<Key word = "on" />
<Key word = "equals" />
<Key word = "var" />
</KeyWords>
<KeyWords name = "ExceptionHandlingStatements" bold="true" italic="false" color="Teal">
<Key word = "try" />
<Key word = "throw" />
<Key word = "catch" />
<Key word = "finally" />
</KeyWords>
<KeyWords name = "CheckedUncheckedStatements" bold="true" italic="false" color="DarkGray">
<Key word = "checked" />
<Key word = "unchecked" />
</KeyWords>
<KeyWords name = "UnsafeFixedStatements" bold="false" italic="false" color="Olive">
<Key word = "fixed" />
<Key word = "unsafe" />
</KeyWords>
<KeyWords name = "ValueTypes" bold="true" italic="false" color="Red">
<Key word = "bool" />
<Key word = "byte" />
<Key word = "char" />
<Key word = "decimal" />
<Key word = "double" />
<Key word = "enum" />
<Key word = "float" />
<Key word = "int" />
<Key word = "long" />
<Key word = "sbyte" />
<Key word = "short" />
<Key word = "struct" />
<Key word = "uint" />
<Key word = "ushort" />
<Key word = "ulong" />
</KeyWords>
<KeyWords name = "ReferenceTypes" bold="false" italic="false" color="Red">
<Key word = "class" />
<Key word = "interface" />
<Key word = "delegate" />
<Key word = "object" />
<Key word = "string" />
</KeyWords>
<KeyWords name = "Void" bold="false" italic="false" color="Red">
<Key word = "void" />
</KeyWords>
<KeyWords name = "ConversionKeyWords" bold="true" italic="false" color="Pink">
<Key word = "explicit" />
<Key word = "implicit" />
<Key word = "operator" />
</KeyWords>
<KeyWords name = "MethodParameters" bold="true" italic="false" color="DeepPink">
<Key word = "params" />
<Key word = "ref" />
<Key word = "out" />
</KeyWords>
<KeyWords name = "Modifiers" bold="false" italic="false" color="Brown">
<Key word = "abstract" />
<Key word = "const" />
<Key word = "event" />
<Key word = "extern" />
<Key word = "override" />
<Key word = "readonly" />
<Key word = "sealed" />
<Key word = "static" />
<Key word = "virtual" />
<Key word = "volatile" />
</KeyWords>
<KeyWords name = "AccessModifiers" bold="true" italic="false" color="Blue">
<Key word = "public" />
<Key word = "protected" />
<Key word = "private" />
<Key word = "internal" />
</KeyWords>
<KeyWords name = "NameSpaces" bold="true" italic="false" color="Green">
<Key word = "namespace" />
<Key word = "using" />
</KeyWords>
<KeyWords name = "LockKeyWord" bold="false" italic="false" color="DarkViolet">
<Key word = "lock" />
</KeyWords>
<KeyWords name = "GetSet" bold="false" italic="false" color="SaddleBrown">
<Key word = "get" />
<Key word = "set" />
<Key word = "add" />
<Key word = "remove" />
</KeyWords>
<KeyWords name = "Literals" bold="true" italic="false" color="Black">
<Key word = "null" />
<Key word = "value" />
</KeyWords>
</RuleSet>
<RuleSet name = "CommentMarkerSet" ignorecase = "false">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<KeyWords name = "ErrorWords" bold="true" italic="false" color="Red">
<Key word = "TODO" />
<Key word = "FIXME" />
</KeyWords>
<KeyWords name = "WarningWords" bold="true" italic="false" color="#EEE0E000">
<Key word = "HACK" />
<Key word = "UNDONE" />
</KeyWords>
</RuleSet>
<RuleSet name = "DocCommentSet" ignorecase = "false">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name = "XmlTag" rule = "XmlDocSet" bold = "false" italic = "false" color = "Gray" stopateol = "true">
<Begin>&lt;</Begin>
<End>&gt;</End>
</Span>
<KeyWords name = "ErrorWords" bold="true" italic="false" color="Red">
<Key word = "TODO" />
<Key word = "FIXME" />
</KeyWords>
<KeyWords name = "WarningWords" bold="true" italic="false" color="#EEE0E000">
<Key word = "HACK" />
<Key word = "UNDONE" />
</KeyWords>
</RuleSet>
<RuleSet name = "PreprocessorSet" ignorecase="false">
<Delimiters>&amp;&lt;&gt;~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<KeyWords name = "PreprocessorDirectives" bold="true" italic="false" color="Green">
<Key word = "if" />
<Key word = "else" />
<Key word = "elif" />
<Key word = "endif" />
<Key word = "define" />
<Key word = "undef" />
<Key word = "warning" />
<Key word = "error" />
<Key word = "line" />
<Key word = "region" />
<Key word = "endregion" />
<Key word = "pragma" />
</KeyWords>
</RuleSet>
<RuleSet name = "XmlDocSet" ignorecase = "false">
<Delimiters>&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name = "String" bold = "true" italic = "false" color = "Silver" stopateol = "true">
<Begin>"</Begin>
<End>"</End>
</Span>
<KeyWords name = "Punctuation" bold = "true" italic = "false" color = "Gray">
<Key word = "/" />
<Key word = "|" />
<Key word = "=" />
</KeyWords>
<KeyWords name = "SpecialComment" bold="true" italic="false" color="Gray">
<Key word = "c" />
<Key word = "code" />
<Key word = "example" />
<Key word = "exception" />
<Key word = "list" />
<Key word = "para" />
<Key word = "param" />
<Key word = "paramref" />
<Key word = "permission" />
<Key word = "remarks" />
<Key word = "returns" />
<Key word = "see" />
<Key word = "seealso" />
<Key word = "summary" />
<Key word = "value" />
<Key word = "inheritdoc" />
<Key word = "type" />
<Key word = "name" />
<Key word = "cref" />
<Key word = "item" />
<Key word = "term" />
<Key word = "description" />
<Key word = "listheader" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" ?>
<!-- syntaxdefinition for Coco/R 2003 by Mike Krueger -->
<SyntaxDefinition name="Coco" extensions=".atg">
<Digits name="Digits" bold="false" italic="false" color="DarkBlue" />
<RuleSets>
<RuleSet ignorecase="false">
<Delimiters>&amp;&lt;&gt;~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name = "LINECOMMENT" bold = "false" italic = "true" color = "Gray" stopateol = "true">
<Begin>//</Begin>
</Span>
<Span name = "BLOCKCOMMENT" bold = "false" italic = "true" color = "Gray" stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name="CSharpCode2" rule="CSharp" bold="false" italic="false" color="Black" stopateol="false">
<Begin bold = "true" color = "Blue">COMPILER</Begin>
<End bold = "true" color = "Blue">TOKENNAMES</End>
</Span>
<Span name = "STRING" bold = "false" italic = "false" color = "DarkGreen" stopateol = "true">
<Begin>"</Begin>
<End>"</End>
</Span>
<Span name = "CHAR" bold = "false" italic = "false" color = "DarkGreen" stopateol = "true">
<Begin>'</Begin>
<End>'</End>
</Span>
<Span name = "paramlist" rule="ParamList" bold = "false" italic = "false" color = "Black" stopateol = "true">
<Begin bold="true" color = "Black" >&lt;</Begin>
<End bold="true" color = "Black" >&gt;</End>
</Span>
<Span name="CSharpCode" rule="CSharp" bold="false" italic="false" color="DarkSlateGray" stopateol="false">
<Begin bold = "true" italic="true" color = "Green">(.</Begin>
<End bold = "true" italic="true" color = "Green">.)</End>
</Span>
<KeyWords name = "Punctuation" bold = "true" italic = "false" color = "Black">
<Key word = "{"/>
<Key word = "}"/>
<Key word = "("/>
<Key word = ")"/>
<Key word = "["/>
<Key word = "]"/>
<Key word = "|"/>
<Key word = "+"/>
<Key word = "-"/>
<Key word = "="/>
<Key word = "."/>
</KeyWords>
<KeyWords name = "KeyWords" bold = "true" italic = "false" color = "Blue">
<Key word = "ANY"/>
<Key word = "CHARACTERS"/>
<Key word = "COMMENTS"/>
<Key word = "COMPILER"/>
<Key word = "CONTEXT"/>
<Key word = "END"/>
<Key word = "FROM"/>
<Key word = "IF"/>
<Key word = "IGNORE"/>
<Key word = "NAMESPACE"/>
<Key word = "NESTED"/>
<Key word = "PRAGMAS"/>
<Key word = "PRODUCTIONS"/>
<Key word = "SYNC"/>
<Key word = "TO"/>
<Key word = "TOKENS"/>
<Key word = "TOKENNAMES"/>
<Key word = "WEAK"/>
<Key word = "using"/>
</KeyWords>
</RuleSet>
<RuleSet name="CSharp" reference = "C#" ignorecase="false">
</RuleSet>
<RuleSet name="ParamList" reference = "C#" ignorecase="false">
</RuleSet>
<RuleSet name="RuleDefinition" ignorecase="false">
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,385 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for HTML 2000 by Mike Krueger -->
<SyntaxDefinition name = "HTML" extensions = ".htm;.html">
<Digits name = "Digits" bold = "false" italic = "false" color = "DarkBlue"/>
<RuleSets>
<RuleSet ignorecase = "true">
<!-- It is not necessary to define span-delimiting characters as delimiters -->
<Delimiters></Delimiters>
<Span name="Comment" bold="false" italic="false" color="DarkSlateGray" stopateol="false">
<Begin>&lt;!--</Begin>
<End>--&gt;</End>
</Span>
<Span name="ScriptTag" rule="JavaScriptSet" bold="false" italic="false" color="SpringGreen" stopateol="false">
<Begin>&lt;script&gt;</Begin>
<End>&lt;/script&gt;</End>
</Span>
<Span name="JavaScriptTag" rule="JavaScriptSet" bold="false" italic="false" color="SpringGreen" stopateol="false">
<Begin>&lt;script lang="JavaScript"&gt;</Begin>
<End>&lt;/script&gt;</End>
</Span>
<Span name="JScriptTag" bold="false" italic="false" color="SpringGreen" stopateol="false">
<Begin>&lt;script lang="JScript"&gt;</Begin>
<End>&lt;/script&gt;</End>
</Span>
<Span name="VBScriptTag" bold="false" italic="false" color="SpringGreen" stopateol="false">
<Begin>&lt;script lang="VBScript"&gt;</Begin>
<End>&lt;/script&gt;</End>
</Span>
<Span name="UnknownScriptTag" bold="false" italic="false" color="SpringGreen" stopateol="false">
<Begin>&lt;script@C</Begin>
<End>&lt;/script&gt;</End>
</Span>
<Span name="HtmlTag" rule="HtmlTagSet" bold="false" italic="false" color="DarkMagenta" stopateol="false">
<Begin>&lt;</Begin>
<End>&gt;</End>
</Span>
<Span name="EntityReference" rule="EntityReferenceSet" bold="false" italic="false" color="Blue" stopateol="true">
<Begin>&amp;</Begin>
<End>;</End>
</Span>
</RuleSet>
<RuleSet name="JavaScriptSet" reference="JavaScript" />
<RuleSet name="EntityReferenceSet" ignorecase="false">
<KeyWords name = "Entities" bold="false" italic="false" color="Green">
<Key word = "aacute" />
<Key word = "agrave" />
<Key word = "acirc" />
<Key word = "amp" />
<Key word = "atilde" />
<Key word = "aring" />
<Key word = "auml" />
<Key word = "aelig" />
<Key word = "ccedil" />
<Key word = "copy" />
<Key word = "eacute" />
<Key word = "egrave" />
<Key word = "ecirc" />
<Key word = "euml" />
<Key word = "iacute" />
<Key word = "igrave" />
<Key word = "icirc" />
<Key word = "iuml" />
<Key word = "eth" />
<Key word = "gt" />
<Key word = "lt" />
<Key word = "nbsp" />
<Key word = "ntilde" />
<Key word = "oacute" />
<Key word = "ograve" />
<Key word = "ocirc" />
<Key word = "otilde" />
<Key word = "ouml" />
<Key word = "oslash" />
<Key word = "quot" />
<Key word = "reg" />
<Key word = "szlig" />
<Key word = "uacute" />
<Key word = "ugrave" />
<Key word = "ucirc" />
<Key word = "uuml" />
<Key word = "yacute" />
<Key word = "thorn" />
<Key word = "trade" />
<Key word = "yuml" />
</KeyWords>
</RuleSet>
<RuleSet name="HtmlTagSet" ignorecase="false">
<Delimiters>/=</Delimiters>
<Span name="String" bold="false" italic="false" color="Blue" stopateol="true">
<Begin>&quot;</Begin>
<End>&quot;</End>
</Span>
<Span name="Char" bold="false" italic="false" color="Blue" stopateol="true">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span>
<MarkPrevious bold="false" italic="false" color="Red">=</MarkPrevious>
<KeyWords name="Slash" bold="false" italic="false" color="DarkMagenta">
<Key word="/" />
</KeyWords>
<KeyWords name="Assignment" bold="false" italic="false" color="Blue">
<Key word="=" />
</KeyWords>
<KeyWords name = "Tags" bold="false" italic="false" color="DarkMagenta">
<Key word = "!DOCTYPE" />
<Key word = "A" />
<Key word = "ABBR" />
<Key word = "ACRONYM" />
<Key word = "ADDRESS" />
<Key word = "APPLET" />
<Key word = "AREA" />
<Key word = "B" />
<Key word = "BASE" />
<Key word = "BASEFONT" />
<Key word = "BGSOUND" />
<Key word = "BDO" />
<Key word = "BIG" />
<Key word = "BLINK" />
<Key word = "BLOCKQUOTE" />
<Key word = "BODY" />
<Key word = "BR" />
<Key word = "BUTTON" />
<Key word = "CAPTION" />
<Key word = "CENTER" />
<Key word = "CITE" />
<Key word = "CODE" />
<Key word = "COL" />
<Key word = "COLGROUP" />
<Key word = "COMMENT" />
<Key word = "DD" />
<Key word = "DEL" />
<Key word = "DFN" />
<Key word = "DIR" />
<Key word = "DIV" />
<Key word = "DL" />
<Key word = "DT" />
<Key word = "EM" />
<Key word = "EMBED" />
<Key word = "FIELDSET" />
<Key word = "FONT" />
<Key word = "FORM" />
<Key word = "FRAME" />
<Key word = "FRAMESET" />
<Key word = "H" />
<Key word = "H1" />
<Key word = "H2" />
<Key word = "H3" />
<Key word = "H4" />
<Key word = "H5" />
<Key word = "H6" />
<Key word = "HEAD" />
<Key word = "HR" />
<Key word = "HTA:APPLICATION" />
<Key word = "HTML" />
<Key word = "I" />
<Key word = "IFRAME" />
<Key word = "IMG" />
<Key word = "INPUT" />
<Key word = "INS" />
<Key word = "ISINDEX" />
<Key word = "KBD" />
<Key word = "LABEL" />
<Key word = "LEGEnd" />
<Key word = "LI" />
<Key word = "LINK" />
<Key word = "LISTING" />
<Key word = "MAP" />
<Key word = "MARQUEE" />
<Key word = "MENU" />
<Key word = "META" />
<Key word = "MULTICOL" />
<Key word = "NEXTID" />
<Key word = "NOBR" />
<Key word = "NOFRAMES" />
<Key word = "NOSCRIPT" />
<Key word = "OBJECT" />
<Key word = "OL" />
<Key word = "OPTGROUP" />
<Key word = "OPTION" />
<Key word = "P" />
<Key word = "PARAM" />
<Key word = "PLAINTEXT" />
<Key word = "PRE" />
<Key word = "Q" />
<Key word = "S" />
<Key word = "SAMP" />
<Key word = "SCRIPT" />
<Key word = "SELECT" />
<Key word = "SERVER" />
<Key word = "SMALL" />
<Key word = "SOUND" />
<Key word = "SPACER" />
<Key word = "Span" />
<Key word = "STRONG" />
<Key word = "STYLE" />
<Key word = "SUB" />
<Key word = "SUP" />
<Key word = "TABLE" />
<Key word = "TBODY" />
<Key word = "TD" />
<Key word = "TEXTAREA" />
<Key word = "TEXTFLOW" />
<Key word = "TFOOT" />
<Key word = "TH" />
<Key word = "THEAD" />
<Key word = "TITLE" />
<Key word = "TR" />
<Key word = "TT" />
<Key word = "U" />
<Key word = "VAR" />
<Key word = "WBR" />
<Key word = "XMP" />
</KeyWords>
<KeyWords name = "Attributes" bold="false" italic="false" color="Red">
<Key word = "abbr" />
<Key word = "accept-charset" />
<Key word = "accept" />
<Key word = "accesskey" />
<Key word = "action" />
<Key word = "align" />
<Key word = "alink" />
<Key word = "alt" />
<Key word = "applicationname" />
<Key word = "archive" />
<Key word = "axis" />
<Key word = "background" />
<Key word = "behavior" />
<Key word = "bgcolor" />
<Key word = "bgproperties" />
<Key word = "border" />
<Key word = "bordercolor" />
<Key word = "bordercolordark" />
<Key word = "bordercolorligh" />
<Key word = "borderstyle" />
<Key word = "caption" />
<Key word = "cellpadding" />
<Key word = "cellspacing" />
<Key word = "char" />
<Key word = "charoff" />
<Key word = "charset" />
<Key word = "checked" />
<Key word = "cite" />
<Key word = "class" />
<Key word = "classid" />
<Key word = "clear" />
<Key word = "code" />
<Key word = "codetype" />
<Key word = "color" />
<Key word = "cols" />
<Key word = "colspan" />
<Key word = "compact" />
<Key word = "content" />
<Key word = "coords" />
<Key word = "data" />
<Key word = "datetime" />
<Key word = "declare" />
<Key word = "defer" />
<Key word = "dir" />
<Key word = "direction" />
<Key word = "disabled" />
<Key word = "dynsrc" />
<Key word = "enctype" />
<Key word = "face" />
<Key word = "for" />
<Key word = "frame" />
<Key word = "frameborder" />
<Key word = "framespacing" />
<Key word = "gutter" />
<Key word = "headers" />
<Key word = "height" />
<Key word = "href" />
<Key word = "hreflang" />
<Key word = "hspace" />
<Key word = "http-equiv" />
<Key word = "icon" />
<Key word = "id" />
<Key word = "ismap" />
<Key word = "label" />
<Key word = "language" />
<Key word = "leftmargin" />
<Key word = "link" />
<Key word = "longdesc" />
<Key word = "loop" />
<Key word = "lowsrc" />
<Key word = "marginheight" />
<Key word = "marginwidth" />
<Key word = "maximizebutton" />
<Key word = "maxlength" />
<Key word = "media" />
<Key word = "method" />
<Key word = "methods" />
<Key word = "minimizebutton" />
<Key word = "multiple" />
<Key word = "name" />
<Key word = "nohref" />
<Key word = "noresize" />
<Key word = "noshade" />
<Key word = "nowrap" />
<Key word = "object" />
<Key word = "onabort" />
<Key word = "onblur" />
<Key word = "onchange" />
<Key word = "onclick" />
<Key word = "ondblclick" />
<Key word = "onerror" />
<Key word = "onfocus" />
<Key word = "onkeydown" />
<Key word = "onkeypress" />
<Key word = "onkeyup" />
<Key word = "onload" />
<Key word = "onmousedown" />
<Key word = "onmousemove" />
<Key word = "onmouseout" />
<Key word = "onmouseover" />
<Key word = "onmouseup" />
<Key word = "onreset" />
<Key word = "onselect" />
<Key word = "onsubmit" />
<Key word = "onunload" />
<Key word = "profile" />
<Key word = "prompt" />
<Key word = "readonly" />
<Key word = "rel" />
<Key word = "rev" />
<Key word = "rows" />
<Key word = "rowspan" />
<Key word = "rules" />
<Key word = "runat" />
<Key word = "scheme" />
<Key word = "scope" />
<Key word = "scrollamount" />
<Key word = "scrolldelay" />
<Key word = "scrolling" />
<Key word = "selected" />
<Key word = "shape" />
<Key word = "showintaskbar" />
<Key word = "singleinstance" />
<Key word = "size" />
<Key word = "span" />
<Key word = "src" />
<Key word = "standby" />
<Key word = "start" />
<Key word = "style" />
<Key word = "summary" />
<Key word = "sysmenu" />
<Key word = "tabindex" />
<Key word = "target" />
<Key word = "text" />
<Key word = "title" />
<Key word = "topmargin" />
<Key word = "type" />
<Key word = "urn" />
<Key word = "usemap" />
<Key word = "valign" />
<Key word = "value" />
<Key word = "valuetype" />
<Key word = "version" />
<Key word = "vlink" />
<Key word = "vrml" />
<Key word = "vspace" />
<Key word = "width" />
<Key word = "windowstate" />
<Key word = "wrap" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
JSON syntax highlighting
Written by Ezra Altahan
Created 07/06/2016 | Updated 16/10/2016
Version 1.0
hello@exr.be
https://github.com/ei
-->
<SyntaxDefinition name="JSON" extensions=".json">
<Environment>
<Default color="Black" bgcolor="#FFFFFF"/>
<Selection color="Black" bgcolor="#C3C3FF"/>
<LineNumbers color="Gray" bgcolor="#FFFFFF"/>
<CaretMarker color="#F0F0F1"/>
<VRuler color="#E0E0E5"/>
<FoldLine color="#A0A0A0" bgcolor="#FFFFFF"/>
<FoldMarker color="Black" bgcolor="#FFFFFF"/>
<SelectedFoldLine color="Black" bgcolor="#FFFFFF"/>
<EOLMarkers color="#CACAD2"/>
<SpaceMarkers color="#B6B6C0"/>
<TabMarkers color="#B6B6C0"/>
<InvalidLines color="#B6B6C0"/>
</Environment>
<Properties>
<Property name="LineComment" value="//"/>
<Property name="BlockCommentBegin" value="/*"/>
<Property name="BlockCommentEnd" value="*/"/>
</Properties>
<Digits name="Digits" color="#4C9CDA"/>
<RuleSets>
<RuleSet ignorecase="false">
<Delimiters>&amp;&lt;&gt;~%^*()-+=!|\/{}[]:;"' , ?</Delimiters>
<Span name="LineComment" stopateol="true" color="Green" bold="false" italic="false">
<Begin>//</Begin>
</Span>
<Span name="BlockComment" stopateol="false" color="Green" bold="false" italic="false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name="String" stopateol="false" color="#945DAA" bold="false" italic="false" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span>
<KeyWords name="Keywords1" color="#CC7832" bold="false">
<Key word="null"/>
<Key word="true"/>
<Key word="false"/>
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,180 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for Java 2001 by Jonathan Pierce & Mike Krueger -->
<SyntaxDefinition name = "Java" extensions = ".java">
<Properties>
<Property name="LineComment" value="//"/>
</Properties>
<Digits name = "Digits" bold = "false" italic = "false" color = "DarkBlue"/>
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>~!%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name = "LINECOMMENT" rule = "TestSet" bold = "false" italic = "true" color = "SlateGray" stopateol = "true">
<Begin>//</Begin>
</Span>
<Span name = "BLOCKCOMMENT" rule = "TestSet" bold = "false" italic = "true" color = "SlateGray" stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name = "STRING" bold = "false" italic = "false" color = "Magenta" stopateol = "true" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span>
<Span name = "CHAR" bold = "false" italic = "false" color = "Magenta" stopateol = "true" escapecharacter="\">
<Begin>'</Begin>
<End>'</End>
</Span>
<MarkPrevious bold = "true" italic = "false" color = "MidnightBlue">(</MarkPrevious>
<KeyWords name = "Punctuation" bold = "false" italic = "false" color = "DarkGreen">
<Key word = "?" />
<Key word = "," />
<Key word = "." />
<Key word = "(" />
<Key word = ")" />
<Key word = "[" />
<Key word = "]" />
<Key word = "{" />
<Key word = "}" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "%" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "^" />
<Key word = "!" />
<Key word = "|" />
</KeyWords>
<KeyWords name = "AccessKeywords" bold="true" italic="false" color="Black">
<Key word = "this" />
<Key word = "super" />
</KeyWords>
<KeyWords name = "OperatorKeywords" bold="true" italic="false" color="DarkCyan">
<Key word = "new" />
<Key word = "instanceof" />
<Key word = "true" />
<Key word = "false" />
</KeyWords>
<KeyWords name = "SelectionStatements" bold="true" italic="false" color="Blue">
<Key word = "else" />
<Key word = "if" />
<Key word = "switch" />
<Key word = "case" />
</KeyWords>
<KeyWords name = "IterationStatements" bold="true" italic="false" color="Blue">
<Key word = "do" />
<Key word = "for" />
<Key word = "while" />
</KeyWords>
<KeyWords name = "JumpStatements" bold="false" italic="false" color="Navy">
<Key word = "break" />
<Key word = "continue" />
<Key word = "default" />
<Key word = "goto" />
<Key word = "return" />
</KeyWords>
<KeyWords name = "ExceptionHandlingStatements" bold="true" italic="false" color="Teal">
<Key word = "try" />
<Key word = "throw" />
<Key word = "catch" />
<Key word = "finally" />
</KeyWords>
<KeyWords name = "ValueTypes" bold="true" italic="false" color="Red">
<Key word = "boolean" />
<Key word = "double" />
<Key word = "int" />
<Key word = "short" />
<Key word = "long" />
<Key word = "float" />
<Key word = "byte" />
<Key word = "char" />
</KeyWords>
<KeyWords name = "ReferenceTypes" bold="false" italic="false" color="Red">
<Key word = "class" />
<Key word = "interface" />
<Key word = "object" />
</KeyWords>
<KeyWords name = "Void" bold="false" italic="false" color="Red">
<Key word = "void" />
</KeyWords>
<KeyWords name = "Modifiers" bold="false" italic="false" color="Brown">
<Key word = "abstract" />
<Key word = "const" />
<Key word = "static" />
<Key word = "final" />
<Key word = "native" />
<Key word = "extends" />
<Key word = "implements" />
<Key word = "volatile" />
<Key word = "transient" />
<Key word = "throws" />
<Key word = "strictfp" />
<Key word = "synchronized" />
</KeyWords>
<KeyWords name = "AccessModifiers" bold="true" italic="false" color="Blue">
<Key word = "public" />
<Key word = "protected" />
<Key word = "private" />
</KeyWords>
<KeyWords name = "NameSpaces" bold="true" italic="false" color="Green">
<Key word = "package" />
<Key word = "import" />
</KeyWords>
<KeyWords name = "Literals" bold="true" italic="false" color="Black">
<Key word = "null" />
</KeyWords>
</RuleSet>
<RuleSet name = "TestSet" ignorecase = "true">
<Delimiters>~!%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<KeyWords name = "Todoword" bold="true" italic="true" color="Red">
<Key word = "TODO" />
</KeyWords>
<KeyWords name = "JAVADOC comments" bold="true" italic="true" color="DarkGray">
<Key word = "@author" />
<Key word = "@version" />
<Key word = "@param" />
<Key word = "@return" />
<Key word = "@exception" />
<Key word = "@throws" />
<Key word = "@see" />
<Key word = "@since" />
<Key word = "@serial" />
<Key word = "@serialField" />
<Key word = "@serialData" />
<Key word = "@deprecated" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for JavaScript 2.0 by Svante Lidman -->
<SyntaxDefinition name ="JavaScript" extensions = ".js">
<Properties>
<Property name="LineComment" value="//"/>
</Properties>
<Digits name ="Digits" bold ="false" italic ="false" color ="DarkBlue"/>
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>=!&gt;&lt;+-/*%&amp;|^~.}{,;][?:</Delimiters>
<Span name ="LineComment" bold ="false" italic ="false" color ="DarkSlateGray" stopateol ="true">
<Begin>//</Begin>
</Span>
<Span name ="BlockComment" bold ="false" italic ="false" color ="DarkSlateGray" stopateol ="false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name ="String" bold ="false" italic ="false" color ="Sienna" stopateol ="false" escapecharacter="\">
<Begin>&quot;</Begin>
<End>&quot;</End>
</Span>
<Span name = "Character" bold = "false" italic = "false" color = "Sienna" stopateol = "true" escapecharacter="\">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span>
<KeyWords name ="JavaScriptKeyWords" bold="false" italic = "false" color = "Blue">
<Key word = "break" />
<Key word = "continue" />
<Key word = "delete" />
<Key word = "else" />
<Key word = "for" />
<Key word = "function" />
<Key word = "if" />
<Key word = "in" />
<Key word = "new" />
<Key word = "return" />
<Key word = "this" />
<Key word = "typeof" />
<Key word = "var" />
<Key word = "void" />
<Key word = "while" />
<Key word = "with" />
<!--ECMAScript keywords-->
<!-- Reserved for future use
(some are already used in some Javascript Engines)
-->
<Key word = "abstract" />
<Key word = "boolean" />
<Key word = "byte" />
<Key word = "case" />
<Key word = "catch" />
<Key word = "char" />
<Key word = "class" />
<Key word = "const" />
<Key word = "debugger" />
<Key word = "default" />
<Key word = "do" />
<Key word = "double" />
<Key word = "enum" />
<Key word = "export" />
<Key word = "extends" />
<Key word = "final" />
<Key word = "finally" />
<Key word = "float" />
<Key word = "goto" />
<Key word = "implements" />
<Key word = "import" />
<Key word = "instanceof" />
<Key word = "int" />
<Key word = "interface" />
<Key word = "long" />
<Key word = "native" />
<Key word = "package" />
<Key word = "private" />
<Key word = "protected" />
<Key word = "public" />
<Key word = "short" />
<Key word = "static" />
<Key word = "super" />
<Key word = "switch" />
<Key word = "synchronized" />
<Key word = "throw" />
<Key word = "throws" />
<Key word = "transient" />
<Key word = "try" />
<Key word = "volatile" />
</KeyWords>
<KeyWords name ="JavaScriptIntrinsics" bold="false" italic = "false" color = "Blue">
<Key word = "Array" />
<Key word = "Boolean" />
<Key word = "Date" />
<Key word = "Function" />
<Key word = "Global" />
<Key word = "Math" />
<Key word = "Number" />
<Key word = "Object" />
<Key word = "RegExp" />
<Key word = "String" />
</KeyWords>
<KeyWords name ="JavaScriptLiterals" bold="false" italic = "false" color = "Blue">
<Key word = "false" />
<Key word = "null" />
<Key word = "true" />
<Key word = "NaN" />
<Key word = "Infinity" />
</KeyWords>
<KeyWords name ="JavaScriptLiterals" bold="false" italic = "false" color = "Blue">
<Key word = "" />
</KeyWords>
<KeyWords name ="JavaScriptGlobalFunctions" bold="false" italic = "false" color = "Blue">
<Key word = "eval" />
<Key word = "parseInt" />
<Key word = "parseFloat" />
<Key word = "escape" />
<Key word = "unescape" />
<Key word = "isNaN" />
<Key word = "isFinite" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,101 @@
<?xml version="1.0"?>
<SyntaxDefinition name = "Lua"
extensions = ".lua">
<Properties>
<Property name="LineComment"
value="--"/>
</Properties>
<Digits name = "Digits"
bold = "false"
italic = "false"
color = "Blue"/>
<RuleSets>
<RuleSet ignorecase="false">
<Delimiters>~@$%^&amp;*()+=|\[]{};"'&lt;&gt; ,#: </Delimiters>
<Span name = "BlockComment"
bold = "false"
italic = "false"
color = "Green"
stopateol = "false">
<Begin>--[[</Begin>
<End>]]</End>
</Span>
<Span name = "LineComment"
bold = "false"
italic = "false"
color = "Green"
stopateol = "true">
<Begin>--</Begin>
</Span>
<Span name = "String"
bold = "false"
italic = "false"
color = "Red"
stopateol = "true">
<Begin>"</Begin>
<End>"</End>
</Span>
<KeyWords name = "Punctuation"
bold = "false"
italic = "false"
color = "DarkGreen">
<Key word = "?" />
<Key word = "," />
<Key word = "." />
<Key word = ";" />
<Key word = "(" />
<Key word = ")" />
<Key word = "[" />
<Key word = "]" />
<Key word = "{" />
<Key word = "}" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "%" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "^" />
<Key word = "=" />
<Key word = "~" />
<Key word = "!" />
<Key word = "|" />
<Key word = "&amp;" />
</KeyWords>
<KeyWords name = "Keywords"
bold="true"
italic="false"
color="Blue">
<Key word = "and" />
<Key word = "break" />
<Key word = "do" />
<Key word = "else" />
<Key word = "elseif" />
<Key word = "end" />
<Key word = "false" />
<Key word = "for" />
<Key word = "function" />
<Key word = "if" />
<Key word = "in" />
<Key word = "local" />
<Key word = "nil" />
<Key word = "not" />
<Key word = "or" />
<Key word = "repeat" />
<Key word = "return" />
<Key word = "then" />
<Key word = "true" />
<Key word = "until" />
<Key word = "while" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,296 @@
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<xsd:annotation>
<xsd:documentation>
This schema defines the syntax for mode definitions in SharpDevelop.
The schema can be simplified quite a bit but it does the job as is.
If you are using this file as a reference it is probably easiest to scroll to
the botton to find the definition of the root element called SyntaxDefinition and
then unwind the different type definitions and refernces.
Note on coloring:
Many tags define how some symbol should be colored. If a specific symbol
can not be matched onto either a Span definition, Keyword, or a Digit/Number it
will be rendered in the current default color. Which is the default color of the
current span or the default color of the mode as a whole if no span has been entered.
</xsd:documentation>
</xsd:annotation>
<!-- Defines the default rendering of the mode -->
<xsd:complexType name="EnvironmentEntry">
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="CustomEnvironmentEntry">
<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:complexType>
<!-- The environment tag defines the coloring of various attributes in SharpDevelop -->
<xsd:complexType name="Environment">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="Default" type="EnvironmentEntry" minOccurs="0" maxOccurs="1" />
<xsd:element name="Selection" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="VRuler" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="InvalidLines" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="CaretMarker" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="CaretLine" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="LineNumbers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="FoldLine" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="FoldMarker" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="SelectedFoldLine" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="EOLMarkers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="SpaceMarkers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="TabMarkers" type="EnvironmentEntry" minOccurs="0" maxOccurs="1"/>
<xsd:element name="Custom" type="CustomEnvironmentEntry" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="Properties">
<xsd:sequence>
<xsd:element name="Property" type="Property" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Property">
<!-- The actual KeyWord, typically reserved words or symbols in a programming language -->
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="value" type="xsd:string" />
</xsd:complexType>
<!-- The Digits tag defines the color for rendering Digits-->
<xsd:complexType name="Digits">
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:complexType>
<!-- Defines the delimiting characters of the syntax, e.g., the characters that, "break up" a line
into separate symbols, typically key words. It is not necessary, or desirable to include the
characters that denot the start or end of a span. Space and Tab are implicitly defined as delimeters
and they don't need to be includeded explicitly (this will probably be changed at some future time).-->
<xsd:complexType name="Delimiters">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!-- The beginning symbol of a Span -->
<xsd:complexType name="Begin">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="singleword" type="xsd:boolean" />
<xsd:attribute name="startofline" type="xsd:boolean" />
<!-- The default rendering style for the Begin symbol. If not specified
the defaul rendering style for the span will be used. -->
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!-- The end symbol of a Span -->
<xsd:complexType name="End">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="singleword" type="xsd:boolean" />
<!-- The default rendering style for the End symbol. If not specified
the defaul rendering style for the span will be used. -->
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="Span">
<xsd:sequence>
<!-- Defines the symbol that indicates the beginning of the span. -->
<xsd:element name="Begin" type="Begin" />
<!-- Defines the symbol that indicates the end of the span. May be omitted for
one-line spans. -->
<xsd:element name="End" minOccurs="0" type="End" />
</xsd:sequence>
<!-- The name of the span definition -->
<xsd:attribute name="name" type="xsd:string" use="required" />
<!-- Defines the rule set that is applicable in the Span. May be omitted. -->
<xsd:attribute name="rule" type="xsd:string" />
<!-- Defines wether the Span should terminate automatically at the end of line. Typical examples
include one-line comments such as // in C++ or REM in Windows .Bat files. -->
<xsd:attribute name="stopateol" type="xsd:boolean" />
<!-- OBSOLUTE: Defines whether C-style escape sequences using \ are applicable or not in the span. -->
<xsd:attribute name="noescapesequences" type="xsd:boolean" />
<!-- defines the escape character -->
<xsd:attribute name="escapecharacter" type="xsd:string" />
<!-- The default rendering style for the span -->
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="MarkPrevious">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<!-- Svante Lidman, looking in the code it is a bit unclear what the intent is here... -->
<xsd:attribute name="markmarker" type="xsd:boolean" />
<!-- The rendering style to be used -->
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<!-- Allows you to define the coloring of the symbol that follows a specified symbol -->
<xsd:complexType name="MarkFollowing">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<!-- Svante Lidman, looking in the code it is a bit unclear what the intent is here... -->
<xsd:attribute name="markmarker" type="xsd:boolean" />
<!-- The rendering style to be used -->
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="Key">
<!-- The actual KeyWord, typically reserved words or symbols in a programming language -->
<xsd:attribute name="word" type="xsd:string" />
</xsd:complexType>
<!-- A grouping of keywords that sholuld be colored the same way -->
<xsd:complexType name="KeyWords">
<xsd:sequence>
<!-- allow groups with 0 keywords: this simplifies the syntax highlighting editor -->
<!-- A KeyWord -->
<xsd:element name="Key" type="Key" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
</xsd:sequence>
<!-- The name of the KeyWord group -->
<xsd:attribute name="name" type="xsd:string" />
<!-- The rendering style of the KeyWord group -->
<xsd:attribute name="bold" type="xsd:boolean" />
<xsd:attribute name="italic" type="xsd:boolean" />
<xsd:attribute name="color" type="xsd:string" />
<xsd:attribute name="bgcolor" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="RuleSet">
<xsd:sequence>
<!-- Defines the delimiting characters of the syntax, e.g., the characters that, "break up" a line
into separate symbols, typically key words. It is not necessary, or desirable to include the
characters that denot the start or end of a span. Space and Tab are implicitly defined as delimeters
and they don't need to be includeded explicitly (this will probably be changed at some future time).-->
<xsd:element name="Delimiters" type="Delimiters" minOccurs="0" maxOccurs="1">
</xsd:element>
<!-- A Span tag defines a scope, or what can be seen as a separate parsing context where a different set of
highlighting rules are applicable compared to the text where the span is found.
Examples of spans include:
- A string in a language as C
- A <script> tag in Html
- The internals of a tag in XML (between < and >).
A span can have a rule set associated with it that defines the highlighting rules that are applicable
in the span. -->
<xsd:element name="Span" type="Span" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
<!-- The MarkPrevious tag allows you to define the coloring of the item that preceeds a specific
symbol. An example of where this comes in handy is when coloring the contents of an XML-tag,
in particular the attributes and attribute names. The following definition:
<MarkPrevious bold="false" italic="false" color="Red">=</MarkPrevious>
will make teh highlighter color words that are followed by an = to be colored in Red.
You can see this in this file if you view it with the default XML-mode in SharpDevelop. -->
<xsd:element name="MarkPrevious" type="MarkPrevious" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
<!-- The MarkFollowing tag works similarly as the MarkPrevious tag but relates to the coloring
of the symbol that follows the specified symbol. -->
<xsd:element name="MarkFollowing" type="MarkFollowing" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
<!-- Defines a group of keywords that should be colored the same way -->
<xsd:element name="KeyWords" type="KeyWords" minOccurs="0" maxOccurs="unbounded">
</xsd:element>
</xsd:sequence>
<!-- The name of the RuleSet. Used when you refer to the RuleSet in the rule attribute of a Span tag.
Each mode file should have a rule definition without a defined name. This denotes the default rule
set for the mode. -->
<xsd:attribute name="name" type="xsd:string" />
<!-- Allows you to use another mode, defined in another file as a RuleSet. For an example see the
use of the JavaScript mode from the HTML-mode. -->
<xsd:attribute name="reference" type="xsd:string" />
<!-- Defines whether case is significant for matching keywords in the mode. -->
<xsd:attribute name="ignorecase" type="xsd:boolean" />
<!-- OBSOLETE: noescapesequences -->
<xsd:attribute name="noescapesequences" type="xsd:boolean" />
<!-- defines the escape character -->
<xsd:attribute name="escapecharacter" type="xsd:string" />
</xsd:complexType>
<!-- The RuleSets tag is just a grouping of the set of RuleSets for a mode. -->
<xsd:complexType name="RuleSets">
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<!-- Any number of RuleSet tag can be defined in a mode -->
<xsd:element name="RuleSet" type="RuleSet" minOccurs="1" maxOccurs="unbounded">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<!-- SyntaxDefinition is the root-element in a mode definition file -->
<xsd:element name="SyntaxDefinition">
<xsd:complexType>
<xsd:sequence>
<!-- The Environment tag defines colors, for various standard elements in the SharpDevelop GUI, if
not given the default values are used. -->
<xsd:element name="Environment" type="Environment" minOccurs="0" maxOccurs="1"/>
<!-- The Properties section defines properties which are bound to the highlighting -->
<xsd:element name="Properties" type="Properties" minOccurs="0" maxOccurs="1" />
<!-- The Digits tag defines the color for rendering Digits-->
<xsd:element name="Digits" type="Digits" minOccurs="0" maxOccurs="1"/>
<!-- The RuleSets tag defines the rule sets that are used in the mode. Note that all modes are defined in
a flat structture even if they are used recursively. For an example of a mode that uses
multiple rule sets see the XML-mode. There is a top level rule-set and and another rule-set
that handles highligting within a tag, i.e., between < and >. -->
<xsd:element name="RuleSets" type="RuleSets" />
</xsd:sequence>
<!-- The name of the mode. This is used when you, in the defintion of a RuleSet refers to another
mode. I.e., one that is defined in an external file. For an example of this see the HTML-Mode that
uses the JavaScript-mode this way. -->
<xsd:attribute name="name" type="xsd:string" />
<!-- The file extensions that the mode is applicable for. Extensions must be written with lower case and
should include the ., as in .txt. If several extensions are applicable they should be separeated with | -->
<xsd:attribute name="extensions" type="xsd:string" />
<!-- Name of a syntax mode where rulesets, spans, keywords and other settings are imported from -->
<xsd:attribute name="extends" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -0,0 +1,198 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for PHP 2001 by Chad Smith & Mike Krueger -->
<SyntaxDefinition name ="PHP" extensions = ".php">
<Digits name ="Digits" bold ="false" italic ="false" color ="DarkBlue"/>
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>~!%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name ="PreprocessorDirectives" bold="false" italic = "false" color = "Green" stopateol ="true">
<Begin>#</Begin>
</Span>
<Span name ="LINECOMMENT" rule = "DocumentSet" bold ="false" italic ="true" color ="SlateGray" stopateol ="true">
<Begin>///</Begin>
</Span>
<Span name ="LINECOMMENT" rule = "TestSet" bold ="false" italic ="true" color ="SlateGray" stopateol ="true">
<Begin>//@!/@</Begin>
</Span>
<Span name ="BLOCKCOMMENT" rule = "TestSet" bold ="false" italic ="true" color ="SlateGray" stopateol ="false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<Span name ="STRING" bold ="false" italic ="false" color ="Magenta" stopateol ="true" escapecharacter="\">
<Begin>"</Begin>
<End>"</End>
</Span>
<Span name ="MORELINEDSTRING" bold ="false" italic ="false" color ="Magenta" stopateol ="false" escapecharacter="\">
<Begin>@@"</Begin>
<End>"</End>
</Span>
<Span name ="CHAR" bold ="false" italic ="false" color ="Magenta" stopateol ="true" escapecharacter="\">
<Begin>'</Begin>
<End>'</End>
</Span>
<MarkPrevious bold ="true" italic ="false" color ="MidnightBlue">(</MarkPrevious>
<KeyWords name ="Punctuation" bold ="false" italic ="false" color ="DarkGreen">
<Key word = "?" />
<Key word = "," />
<Key word = "." />
<Key word = "(" />
<Key word = ")" />
<Key word = "[" />
<Key word = "]" />
<Key word = "{" />
<Key word = "}" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "%" />
<Key word = "*" />
<Key word = "&lt;" />
<Key word = "&gt;" />
<Key word = "^" />
<Key word = "!" />
<Key word = "|" />
</KeyWords>
<KeyWords name ="AccessKeywords" bold="true" italic = "false" color = "Black">
<Key word = "global" />
<Key word = "my" />
</KeyWords>
<KeyWords name ="OperatorKeywords" bold="true" italic = "false" color = "DarkCyan">
<Key word = "and" />
<Key word = "or" />
<Key word = "new" />
<Key word = "xor" />
<Key word = "true" />
<Key word = "false" />
</KeyWords>
<KeyWords name ="SelectionStatements" bold="true" italic = "false" color = "Blue">
<Key word = "else" />
<Key word = "if" />
<Key word = "switch" />
<Key word = "case" />
<Key word = "endif" />
<Key word = "elseif" />
</KeyWords>
<KeyWords name ="IterationStatements" bold="true" italic = "false" color = "Blue">
<Key word = "do" />
<Key word = "for" />
<Key word = "foreach" />
<Key word = "while" />
<Key word = "endwhile" />
<Key word = "exit" />
</KeyWords>
<KeyWords name ="JumpStatements" bold="false" italic = "false" color = "Navy">
<Key word = "break" />
<Key word = "continue" />
<Key word = "default" />
<Key word = "goto" />
<Key word = "return" />
</KeyWords>
<KeyWords name ="ExceptionHandlingStatements" bold="true" italic = "false" color = "Teal">
<Key word = "require" />
<Key word = "include" />
<Key word = "function" />
<Key word = "return" />
<Key word = "old_function" />
</KeyWords>
<KeyWords name ="ValueTypes" bold="true" italic = "false" color = "Red">
<Key word = "int" />
<Key word = "integer" />
<Key word = "real" />
<Key word = "double" />
<Key word = "float" />
<Key word = "string" />
<Key word = "array" />
<Key word = "object" />
</KeyWords>
<KeyWords name ="ReferenceTypes" bold="false" italic = "false" color = "Red">
<Key word = "class" />
<Key word = "new" />
</KeyWords>
<KeyWords name ="Void" bold="false" italic = "false" color = "Red">
<Key word = "void" />
</KeyWords>
<KeyWords name ="AccessModifiers" bold="true" italic = "false" color = "Blue">
<Key word = "public" />
<Key word = "private" />
</KeyWords>
<KeyWords name ="GetSet" bold="false" italic = "false" color = "SaddleBrown">
<Key word = "get" />
<Key word = "set" />
</KeyWords>
<KeyWords name ="Literals" bold="true" italic = "false" color = "Black">
<Key word = "null" />
<Key word = "value" />
</KeyWords>
<KeyWords name ="Statements" bold="true" italic = "false" color = "DarkBlue">
<Key word = "var" />
<Key word = "extends" />
<Key word = "list" />
<Key word = "each" />
<Key word = "PHP_SELF" />
</KeyWords>
</RuleSet>
<RuleSet name ="TestSet" ignorecase = "true">
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<KeyWords name ="Testword" bold="true" italic = "true" color = "Red">
<Key word = "TODO" />
</KeyWords>
</RuleSet>
<RuleSet name ="DocumentSet" ignorecase = "false">
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name ="XMLTAG" rule = "XMLDocuSet" bold ="false" italic ="true" color ="Gray" stopateol ="true">
<Begin>&lt;</Begin>
<End>&gt;</End>
</Span>
<KeyWords name ="Testword" bold="true" italic = "true" color = "Red">
<Key word = "TODO" />
</KeyWords>
</RuleSet>
<RuleSet name ="XMLDocuSet" ignorecase = "false">
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name ="STRING" bold ="true" italic ="true" color ="Silver" stopateol ="true">
<Begin>"</Begin>
<End>"</End>
</Span>
<KeyWords name ="Punctuation" bold ="true" italic ="true" color ="Gray">
<Key word = "/" />
<Key word = "|" />
<Key word = "=" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0"?>
<SyntaxDefinition name = "Patch" extensions = ".patch;.diff">
<!--<Digits name = "Digits" bold = "false" italic = "false" color = "DarkBlue"/>-->
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>~!%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name = "IndexLine" bold="true" italic="false" color="Green" stopateol = "true">
<Begin>Index: </Begin>
</Span>
<Span name = "IndexUnderline" bold="false" italic="false" color="DarkRed" stopateol = "true">
<Begin>==</Begin>
</Span>
<Span name = "IndexOldFile" bold="false" italic="false" color="DarkRed" stopateol = "true">
<Begin>---</Begin>
</Span>
<Span name = "IndexNewFile" bold="false" italic="false" color="DarkRed" stopateol = "true">
<Begin>+++</Begin>
</Span>
<Span name = "LocationMarker" bold="false" italic="false" color="Purple" stopateol = "true">
<Begin>@@</Begin>
</Span>
<Span name = "RemovedLine" bold="false" italic="false" color="#339966" stopateol = "true">
<Begin>-</Begin>
</Span>
<Span name = "AddedLine" bold="false" italic="false" color="Navy" stopateol = "true" >
<Begin>+</Begin>
</Span>
<Span name = "NormalLine" bold="false" italic="false" color="SystemColors.WindowText" stopateol = "true" >
<Begin> </Begin>
</Span>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View File

@@ -0,0 +1,200 @@
<?xml version="1.0"?>
<!--
Copyright 2005-2009 Paul Kohler (http://pksoftware.net/MiniSqlQuery/). All rights reserved.
This source code is made available under the terms of the Microsoft Public License (Ms-PL)
http://minisqlquery.codeplex.com/license
-->
<SyntaxDefinition name = "SQL"
extensions = ".sql">
<Properties>
<Property name="LineComment"
value="--"/>
</Properties>
<Digits name = "Digits"
bold = "true"
italic = "false"
color = "Blue"/>
<RuleSets>
<RuleSet ignorecase = "true">
<Delimiters>&amp;&lt;&gt;~!%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
<Span name="String"
bold="false"
italic="false"
color="Red"
stopateol="false">
<Begin>'</Begin>
<End>'</End>
</Span>
<Span name = "LineComment"
bold = "false"
italic = "false"
color = "Green"
stopateol = "true">
<Begin>--</Begin>
</Span>
<Span name = "BlockComment"
bold = "false"
italic = "false"
color = "Green"
stopateol = "false">
<Begin>/*</Begin>
<End>*/</End>
</Span>
<KeyWords name="JoinKeywords"
bold="true"
italic="false"
color="Purple">
<Key word="INNER" />
<Key word="JOIN" />
<Key word="LEFT" />
<Key word="RIGHT" />
<Key word="OUTER" />
<Key word="UNION" />
</KeyWords>
<KeyWords name="AliasKeywords"
bold="false"
italic="false"
color="Maroon">
<Key word="AS" />
</KeyWords>
<KeyWords name="ComparisonKeywords"
bold="true"
italic="false"
color="Navy">
<Key word="AND" />
<Key word="OR" />
<Key word="LIKE" />
</KeyWords>
<KeyWords name="SpecializedKeywords"
bold="true"
italic="false"
color="Gray">
<Key word="TOP" />
<Key word="LIMIT" />
<Key word="OPENDATASOURCE" />
<Key word="GO" />
</KeyWords>
<KeyWords name="DestructiveKeywords"
bold="true"
italic="false"
color="Red">
<Key word="DROP" />
<Key word="DELETE" />
<Key word="TRUNCATE" />
</KeyWords>
<KeyWords name="SqlKeywordsBold"
bold="true"
italic="false"
color="Blue">
<Key word="BEGIN" />
<Key word="END" />
<Key word="EXEC" />
<Key word="CREATE" />
<Key word="COMMIT" />
<Key word="RAISERROR" />
<Key word="ROLLBACK" />
<Key word="TRAN" />
<Key word="TRANSACTION" />
<Key word="USE" />
<Key word="USER" />
<Key word="VIEW" />
</KeyWords>
<KeyWords name="SqlKeywordsNormal"
bold="false"
italic="false"
color="Blue">
<Key word="ADD" />
<Key word="ALL" />
<Key word="ANY" />
<Key word="ASC" />
<Key word="BETWEEN" />
<Key word="BREAK" />
<Key word="BY" />
<Key word="CASCADE" />
<Key word="CASE" />
<Key word="CHECK" />
<Key word="CHECKPOINT" />
<Key word="CLOSE" />
<Key word="COALESCE" />
<Key word="COLLATE" />
<Key word="COLUMN" />
<Key word="COMPUTE" />
<Key word="CONSTRAINT" />
<Key word="CONTAINS" />
<Key word="CONTINUE" />
<Key word="CONVERT" />
<Key word="CROSS" />
<Key word="CURSOR" />
<Key word="DECLARE" />
<Key word="DEFAULT" />
<Key word="DESC" />
<Key word="DISTINCT" />
<Key word="DOUBLE" />
<Key word="ELSE" />
<Key word="ESCAPE" />
<Key word="EXCEPT" />
<Key word="EXECUTE" />
<Key word="EXISTS" />
<Key word="EXIT" />
<Key word="FETCH" />
<Key word="FOR" />
<Key word="FROM" />
<Key word="FULL" />
<Key word="FUNCTION" />
<Key word="GOTO" />
<Key word="GROUP" />
<Key word="HAVING" />
<Key word="IDENTITY" />
<Key word="IDENTITY_INSERT" />
<Key word="IDENTITYCOL" />
<Key word="IF" />
<Key word="IN" />
<Key word="INSERT" />
<Key word="INTO" />
<Key word="IS" />
<Key word="KEY" />
<Key word="NOCHECK" />
<Key word="NOT" />
<Key word="NULL" />
<Key word="NULLIF" />
<Key word="OF" />
<Key word="OFF" />
<Key word="OFFSETS" />
<Key word="ON" />
<Key word="OPEN" />
<Key word="ORDER" />
<Key word="OVER" />
<Key word="PRECISION" />
<Key word="PROC" />
<Key word="PROCEDURE" />
<Key word="PUBLIC" />
<Key word="READ" />
<Key word="READTEXT" />
<Key word="REFERENCES" />
<Key word="RESTORE" />
<Key word="RESTRICT" />
<Key word="RETURN" />
<Key word="ROWCOUNT" />
<Key word="RULE" />
<Key word="SAVE" />
<Key word="SELECT" />
<Key word="SET" />
<Key word="SETUSER" />
<Key word="SOME" />
<Key word="TABLE" />
<Key word="THEN" />
<Key word="TO" />
<Key word="TRIGGER" />
<Key word="UNIQUE" />
<Key word="UPDATE" />
<Key word="VALUES" />
<Key word="VARYING" />
<Key word="WAITFOR" />
<Key word="WHEN" />
<Key word="WHERE" />
<Key word="WHILE" />
<Key word="WITH" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,61 @@
<SyntaxModes version="1.0">
<Mode file = "ASPX.xshd"
name = "ASP/XHTML"
extensions = ".asp;.aspx;.asax;.asmx"/>
<Mode file = "BAT-Mode.xshd"
name = "BAT"
extensions = ".bat"/>
<Mode file = "Boo.xshd"
name = "Boo"
extensions = ".boo"/>
<Mode file = "Coco-Mode.xshd"
name = "Coco"
extensions = ".atg"/>
<Mode file = "CPP-Mode.xshd"
name = "C++.NET"
extensions = ".c;.h;.cc;.C;.cpp;.hpp"/>
<Mode file = "CSharp-Mode.xshd"
name = "C#"
extensions = ".cs"/>
<Mode file = "HTML-Mode.xshd"
name = "HTML"
extensions = ".htm;.html"/>
<Mode file = "Java-Mode.xshd"
name = "Java"
extensions = ".java"/>
<Mode file = "JavaScript-Mode.xshd"
name = "JavaScript"
extensions = ".js"/>
<Mode file = "JSON.xshd"
name = "JSON"
extensions = ".json"/>
<Mode file = "Patch-Mode.xshd"
name = "Patch"
extensions = ".patch;.diff"/>
<Mode file = "PHP-Mode.xshd"
name = "PHP"
extensions = ".php"/>
<Mode file = "Tex-Mode.xshd"
name = "TeX"
extensions = ".tex"/>
<Mode file = "VBNET-Mode.xshd"
name = "VBNET"
extensions = ".vb"/>
<Mode file = "XML-Mode.xshd"
name = "XML"
extensions = ".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco"/>
</SyntaxModes>

View File

@@ -0,0 +1,20 @@
Lua syntax highlighting based on http://github.com/nano-byte/ICSharpCode.TextEditor
SQL syntax highlighting based on http://www.codeproject.com/Articles/111969/Extending-ICSharpCode-TextEditor-Syntax-Highlighti
All supported:
ASP/XHTML
BAT
Boo
Coco
C++.NET
C#
HTML
Java
JavaScript
Patch
PHP
TeX
VBNET
XML
Lua
SQL

View File

@@ -0,0 +1,8 @@
<SyntaxModes version="1.0">
<Mode file = "Lua-Mode.xshd"
name = "Lua"
extensions = ".lua"/>
<Mode file = "SQL-Mode.xshd"
name = "SQL"
extensions = ".sql"/>
</SyntaxModes>

View File

@@ -0,0 +1,108 @@
<?xml version="1.0"?>
<!-- syntaxdefinition for TeX document 2001 by Mike Krueger (gleaned from Jedit) -->
<SyntaxDefinition name = "TeX" extensions = ".tex">
<Digits name = "Digits" bold = "false" italic = "false" color = "Black"/>
<RuleSets>
<RuleSet ignorecase = "false">
<Delimiters>&amp;~!@%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name = "LineComment" bold = "false" italic = "true" color = "SlateGray" stopateol = "true">
<Begin>%</Begin>
</Span>
<Span name = "MathMode" rule = "MathMode" bold = "false" italic = "false" color = "Black" stopateol = "false">
<Begin>$$</Begin>
<End>$$</End>
</Span>
<Span name = "LatexMathMode" rule = "MathMode" bold = "false" italic = "false" color = "Black" stopateol = "false">
<Begin>\[</Begin>
<End>\]</End>
</Span>
<!-- \... commands -->
<MarkFollowing markmarker ="true" bold = "true" italic = "false" color = "MidnightBlue">\</MarkFollowing>
<!-- some commands must be handled specially -->
<KeyWords name = "Keyword1" bold = "false" italic = "false" color = "Blue">
<Key word = "\$" />
<Key word = "\\" />
<Key word = "\%" />
</KeyWords>
<KeyWords name = "KeyWords2" bold="true" italic="false" color="Green">
<Key word = ")" />
<Key word = ")" />
<Key word = "{" />
<Key word = "}" />
<Key word = "[" />
<Key word = "]" />
<Key word = "=" />
<Key word = "!" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "*" />
<Key word = "&gt;" />
<Key word = "&lt;" />
<Key word = "&amp;" />
<Key word = "|" />
<Key word = "^" />
<Key word = "~" />
<Key word = "." />
<Key word = "," />
<Key word = ";" />
<Key word = "?" />
<Key word = ":" />
<Key word = "'" />
<!-- <Key word = """ />-->
<Key word = "`" />
</KeyWords>
</RuleSet>
<RuleSet name = "MathMode" ignorecase = "false">
<Delimiters>&amp;~!@%^*()-+=|\#/{}[]:;"'&lt;&gt; , .?</Delimiters>
<Span name = "LineComment" bold = "false" italic = "true" color = "SlateGray" stopateol = "true">
<Begin>%</Begin>
</Span>
<!-- \... commands -->
<MarkFollowing markmarker ="true" bold = "true" italic = "false" color = "MidnightBlue">\</MarkFollowing>
<KeyWords name = "KeyWords2" bold="true" italic="false" color="Green">
<Key word = ")" />
<Key word = ")" />
<Key word = "{" />
<Key word = "}" />
<Key word = "[" />
<Key word = "]" />
<Key word = "=" />
<Key word = "!" />
<Key word = "+" />
<Key word = "-" />
<Key word = "/" />
<Key word = "*" />
<Key word = "&gt;" />
<Key word = "&lt;" />
<Key word = "&amp;" />
<Key word = "|" />
<Key word = "^" />
<Key word = "~" />
<Key word = "." />
<Key word = "," />
<Key word = ";" />
<Key word = "?" />
<Key word = ":" />
<Key word = "'" />
<!-- <Key word = """ />-->
<Key word = "`" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

View File

@@ -0,0 +1,265 @@
<?xml version="1.0"?>
<!-- Syntaxdefinition for VB.NET, v0.1 Rev 1 by Christian Holm -->
<!-- Updated 2005 by Daniel Grunwald for VB.NET 2.0 -->
<SyntaxDefinition name = "VBNET" extensions = ".vb">
<Properties>
<Property name="LineComment" value="'"/>
</Properties>
<Digits name = "Digits" bold = "false" italic = "false" color = "Black"/>
<RuleSets>
<RuleSet ignorecase = "true">
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'&lt;&gt;,.?</Delimiters>
<Span name = "STRING" bold = "false" italic = "false" color = "Black" stopateol = "true" escapecharacter='"'>
<Begin>"</Begin>
<End>"</End>
</Span>
<!--
<Span name = "LINECOMMENT" rule = "DocumentSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>'</Begin>
</Span>
<Span name = "LINECOMMENT" rule = "DocumentSet" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>REM</Begin>
</Span>
-->
<Span name = "PREPROCESSORDIRECTIVE" rule = "PreprocessorSet" bold = "false" italic = "false" color = "Maroon" stopateol = "true">
<Begin startofline="true">#</Begin>
</Span>
<Span name = "DATELITERAL" bold = "false" italic = "false" color = "Blue" stopateol = "true">
<Begin startofline="false">#</Begin>
<End>#</End>
</Span>
<Span name = "LINECOMMENT" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin>'</Begin>
</Span>
<Span name = "LINECOMMENT" bold = "false" italic = "false" color = "Green" stopateol = "true">
<Begin singleword="true">REM@C</Begin>
</Span>
<KeyWords name = "DataTypes" bold="false" italic="false" color="#6F002F">
<Key word = "Boolean" />
<Key word = "Byte" />
<Key word = "Char" />
<Key word = "Date" />
<Key word = "Decimal" />
<Key word = "Double" />
<Key word = "Integer" />
<Key word = "Long" />
<Key word = "Object" />
<Key word = "SByte" />
<Key word = "Short" />
<Key word = "Single" />
<Key word = "String" />
<Key word = "UInteger" />
<Key word = "ULong" />
<Key word = "UShort" />
<Key word = "Variant" />
</KeyWords>
<KeyWords name = "Operators" bold="false" italic="false" color="#8515EA">
<Key word = "AddressOf" />
<Key word = "And" />
<Key word = "AndAlso" />
<Key word = "Is" />
<Key word = "IsNot" />
<Key word = "Like" />
<Key word = "Mod" />
<Key word = "New" />
<Key word = "Not" />
<Key word = "Or" />
<Key word = "OrElse" />
<Key word = "Xor" />
</KeyWords>
<KeyWords name = "Constants" bold="false" italic="false" color="Blue">
<Key word = "False" />
<Key word = "Me" />
<Key word = "MyBase" />
<Key word = "MyClass" />
<Key word = "Nothing" />
<Key word = "True" />
</KeyWords>
<KeyWords name = "CommonKeywords" bold="false" italic="false" color="Blue">
<Key word = "As" />
<Key word = "Of" />
<Key word = "New" />
<Key word = "End" />
</KeyWords>
<KeyWords name = "FunctionKeywords" bold="false" italic="false" color="Blue">
<Key word = "CBool" />
<Key word = "CByte" />
<Key word = "CChar" />
<Key word = "CDate" />
<Key word = "CDec" />
<Key word = "CDbl" />
<Key word = "CInt" />
<Key word = "CLng" />
<Key word = "CObj" />
<Key word = "CSByte" />
<Key word = "CShort" />
<Key word = "CSng" />
<Key word = "CStr" />
<Key word = "CType" />
<Key word = "CUInt" />
<Key word = "CULng" />
<Key word = "CUShort" />
<Key word = "DirectCast" />
<Key word = "GetType" />
<Key word = "TryCast" />
<Key word = "TypeOf" />
</KeyWords>
<KeyWords name = "ParamModifiers" bold="false" italic="false" color="Blue">
<Key word = "ByRef" />
<Key word = "ByVal" />
<Key word = "Optional" />
<Key word = "ParamArray" />
</KeyWords>
<KeyWords name = "AccessModifiers" bold="false" italic="false" color="Blue">
<Key word = "Friend" />
<Key word = "Private" />
<Key word = "Protected" />
<Key word = "Public" />
</KeyWords>
<KeyWords name = "OtherModifiers" bold="false" italic="false" color="Blue">
<Key word = "Const" />
<Key word = "Custom" />
<Key word = "Default" />
<Key word = "Global" />
<Key word = "MustInherit" />
<Key word = "MustOverride" />
<Key word = "Narrowing" />
<Key word = "NotInheritable" />
<Key word = "NotOverridable" />
<Key word = "Overloads" />
<Key word = "Overridable" />
<Key word = "Overrides" />
<Key word = "Partial" />
<Key word = "ReadOnly" />
<Key word = "Shadows" />
<Key word = "Shared" />
<Key word = "Static" />
<Key word = "Widening" />
<Key word = "WithEvents" />
<Key word = "WriteOnly" />
</KeyWords>
<KeyWords name = "Statements" bold="false" italic="false" color="Blue">
<Key word = "Throw" />
<Key word = "Stop" />
<Key word = "Return" />
<Key word = "Resume" />
<Key word = "AddHandler" />
<Key word = "RemoveHandler" />
<Key word = "RaiseEvent" />
<Key word = "Option" />
<Key word = "Let" />
<Key word = "GoTo" />
<Key word = "GoSub" />
<Key word = "Call" />
<Key word = "Continue" />
<Key word = "Dim" />
<Key word = "ReDim" />
<Key word = "Erase" />
<Key word = "On" />
<Key word = "Error" />
<Key word = "Exit" />
</KeyWords>
<KeyWords name = "GlobalConstructs" bold="false" italic="false" color="Blue">
<Key word = "Namespace" />
<Key word = "Class" />
<Key word = "Imports" />
<Key word = "Implements" />
<Key word = "Inherits" />
<Key word = "Interface" />
<Key word = "Delegate" />
<Key word = "Module" />
<Key word = "Structure" />
<Key word = "Enum" />
</KeyWords>
<KeyWords name = "TypeLevelConstructs" bold="false" italic="false" color="Blue">
<Key word = "Sub" />
<Key word = "Function" />
<Key word = "Handles" />
<Key word = "Declare" />
<Key word = "Lib" />
<Key word = "Alias" />
<Key word = "Get" />
<Key word = "Set" />
<Key word = "Property" />
<Key word = "Operator" />
<Key word = "Event" />
</KeyWords>
<KeyWords name = "Constructs" bold="false" italic="false" color="Blue">
<Key word = "SyncLock" />
<Key word = "Using" />
<Key word = "With" />
<Key word = "Do" />
<Key word = "While" />
<Key word = "Loop" />
<Key word = "Wend" />
<Key word = "Try" />
<Key word = "Catch" />
<Key word = "When" />
<Key word = "Finally" />
<Key word = "If" />
<Key word = "Then" />
<Key word = "Else" />
<Key word = "ElseIf" />
<Key word = "EndIf" />
<Key word = "For" />
<Key word = "To" />
<Key word = "Step" />
<Key word = "Each" />
<Key word = "In" />
<Key word = "Next" />
<Key word = "Select" />
<Key word = "Case" />
</KeyWords>
<KeyWords name = "ContextKeywords" bold="false" italic="false" color="Blue">
<Key word = "Ansi" />
<Key word = "Auto" />
<Key word = "Unicode" />
<Key word = "Preserve" />
<Key word = "Until" />
</KeyWords>
</RuleSet>
<RuleSet name = "PreprocessorSet" ignorecase = "true">
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'&lt;&gt;,.?</Delimiters>
<KeyWords name = "PreProcessor" bold="true" italic="false" color="Maroon">
<Key word = "Const" />
<Key word = "If" />
<Key word = "ElseIf" />
<Key word = "Else" />
<Key word = "End" />
<Key word = "ExternalSource" />
<Key word = "Region" />
<Key word = "ExternalChecksum" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" ?>
<!-- syntaxdefinition for XML 2000 by Mike Krueger -->
<SyntaxDefinition name="XML" extensions=".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco">
<Properties>
<Property name="BlockCommentBegin" value="&lt;!--"/>
<Property name="BlockCommentEnd" value="--&gt;"/>
</Properties>
<Digits name="Digits" bold="false" italic="false" color="DarkBlue" />
<RuleSets>
<RuleSet ignorecase="false">
<!-- It is not necessary to define span-delimiting characters as delimiters -->
<Delimiters></Delimiters>
<Span name="Comment" bold="false" italic="false" color="Green" stopateol="false">
<Begin>&lt;!--</Begin>
<End>--&gt;</End>
</Span>
<Span name="CDataSection" bold="false" italic="false" color="Blue" stopateol="false">
<Begin>&lt;![CDATA[</Begin>
<End>]]&gt;</End>
</Span>
<Span name="DocTypeSection" bold="false" italic="false" color="Blue" stopateol="false">
<Begin>&lt;!DOCTYPE</Begin>
<End>&gt;</End>
</Span>
<Span name="XmlDecl" bold="false" italic="false" color="Blue" stopateol="false">
<Begin>&lt;?</Begin>
<End>?&gt;</End>
</Span>
<Span name="XmlTag" rule="XmlTagSet" bold="false" italic="false" color="DarkMagenta" stopateol="false">
<Begin>&lt;</Begin>
<End>&gt;</End>
</Span>
<Span name="EntityReference" bold="false" italic="false" color="Blue" stopateol="true">
<Begin>&amp;</Begin>
<End>;</End>
</Span>
</RuleSet>
<RuleSet name="XmlTagSet" ignorecase="false">
<Delimiters>/=</Delimiters>
<Span name="String" bold="false" italic="false" color="Blue" stopateol="true">
<Begin>&quot;</Begin>
<End>&quot;</End>
</Span>
<Span name="Char" bold="false" italic="false" color="Blue" stopateol="true">
<Begin>&apos;</Begin>
<End>&apos;</End>
</Span>
<MarkPrevious bold="false" italic="false" color="Red">=</MarkPrevious>
<KeyWords name="Slash" bold="false" italic="false" color="DarkMagenta">
<Key word="/" />
</KeyWords>
<KeyWords name="Assignment" bold="false" italic="false" color="Blue">
<Key word="=" />
</KeyWords>
</RuleSet>
</RuleSets>
</SyntaxDefinition>

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

View File

@@ -0,0 +1,80 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class ToggleBookmark : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.Document.BookmarkManager.ToggleMarkAt(textArea.Caret.Position);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, textArea.Caret.Line));
textArea.Document.CommitUpdate();
}
}
public class GotoPrevBookmark : AbstractEditAction
{
Predicate<Bookmark> predicate = null;
public GotoPrevBookmark(Predicate<Bookmark> predicate)
{
this.predicate = predicate;
}
public override void Execute(TextArea textArea)
{
Bookmark mark = textArea.Document.BookmarkManager.GetPrevMark(textArea.Caret.Line, predicate);
if (mark != null) {
textArea.Caret.Position = mark.Location;
textArea.SelectionManager.ClearSelection();
textArea.SetDesiredColumn();
}
}
}
public class GotoNextBookmark : AbstractEditAction
{
Predicate<Bookmark> predicate = null;
public GotoNextBookmark(Predicate<Bookmark> predicate)
{
this.predicate = predicate;
}
public override void Execute(TextArea textArea)
{
Bookmark mark = textArea.Document.BookmarkManager.GetNextMark(textArea.Caret.Line, predicate);
if (mark != null) {
textArea.Caret.Position = mark.Location;
textArea.SelectionManager.ClearSelection();
textArea.SetDesiredColumn();
}
}
}
public class ClearAllBookmarks : AbstractEditAction
{
Predicate<Bookmark> predicate = null;
public ClearAllBookmarks(Predicate<Bookmark> predicate)
{
this.predicate = predicate;
}
public override void Execute(TextArea textArea)
{
textArea.Document.BookmarkManager.RemoveMarks(predicate);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
textArea.Document.CommitUpdate();
}
}
}

View File

@@ -0,0 +1,203 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class CaretLeft : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation position = textArea.Caret.Position;
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldedFoldingsWithEnd(position.Y);
FoldMarker justBeforeCaret = null;
foreach (FoldMarker fm in foldings) {
if (fm.EndColumn == position.X) {
justBeforeCaret = fm;
break; // the first folding found is the folding with the smallest Startposition
}
}
if (justBeforeCaret != null) {
position.Y = justBeforeCaret.StartLine;
position.X = justBeforeCaret.StartColumn;
} else {
if (position.X > 0) {
--position.X;
} else if (position.Y > 0) {
LineSegment lineAbove = textArea.Document.GetLineSegment(position.Y - 1);
position = new TextLocation(lineAbove.Length, position.Y - 1);
}
}
textArea.Caret.Position = position;
textArea.SetDesiredColumn();
}
}
public class CaretRight : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
LineSegment curLine = textArea.Document.GetLineSegment(textArea.Caret.Line);
TextLocation position = textArea.Caret.Position;
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldedFoldingsWithStart(position.Y);
FoldMarker justBehindCaret = null;
foreach (FoldMarker fm in foldings) {
if (fm.StartColumn == position.X) {
justBehindCaret = fm;
break;
}
}
if (justBehindCaret != null) {
position.Y = justBehindCaret.EndLine;
position.X = justBehindCaret.EndColumn;
} else { // no folding is interesting
if (position.X < curLine.Length || textArea.TextEditorProperties.AllowCaretBeyondEOL) {
++position.X;
} else if (position.Y + 1 < textArea.Document.TotalNumberOfLines) {
++position.Y;
position.X = 0;
}
}
textArea.Caret.Position = position;
textArea.SetDesiredColumn();
}
}
public class CaretUp : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation position = textArea.Caret.Position;
int lineNr = position.Y;
int visualLine = textArea.Document.GetVisibleLine(lineNr);
if (visualLine > 0) {
Point pos = new Point(textArea.TextView.GetDrawingXPos(lineNr, position.X),
textArea.TextView.DrawingPosition.Y + (visualLine - 1) * textArea.TextView.FontHeight - textArea.TextView.TextArea.VirtualTop.Y);
textArea.Caret.Position = textArea.TextView.GetLogicalPosition(pos);
textArea.SetCaretToDesiredColumn();
}
// if (textArea.Caret.Line > 0) {
// textArea.SetCaretToDesiredColumn(textArea.Caret.Line - 1);
// }
}
}
public class CaretDown : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation position = textArea.Caret.Position;
int lineNr = position.Y;
int visualLine = textArea.Document.GetVisibleLine(lineNr);
if (visualLine < textArea.Document.GetVisibleLine(textArea.Document.TotalNumberOfLines)) {
Point pos = new Point(textArea.TextView.GetDrawingXPos(lineNr, position.X),
textArea.TextView.DrawingPosition.Y
+ (visualLine + 1) * textArea.TextView.FontHeight
- textArea.TextView.TextArea.VirtualTop.Y);
textArea.Caret.Position = textArea.TextView.GetLogicalPosition(pos);
textArea.SetCaretToDesiredColumn();
}
// if (textArea.Caret.Line + 1 < textArea.Document.TotalNumberOfLines) {
// textArea.SetCaretToDesiredColumn(textArea.Caret.Line + 1);
// }
}
}
public class WordRight : CaretRight
{
public override void Execute(TextArea textArea)
{
LineSegment line = textArea.Document.GetLineSegment(textArea.Caret.Position.Y);
TextLocation oldPos = textArea.Caret.Position;
TextLocation newPos;
if (textArea.Caret.Column >= line.Length) {
newPos = new TextLocation(0, textArea.Caret.Line + 1);
} else {
int nextWordStart = TextUtilities.FindNextWordStart(textArea.Document, textArea.Caret.Offset);
newPos = textArea.Document.OffsetToPosition(nextWordStart);
}
// handle fold markers
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
foreach (FoldMarker marker in foldings) {
if (marker.IsFolded) {
if (oldPos.X == marker.StartColumn && oldPos.Y == marker.StartLine) {
newPos = new TextLocation(marker.EndColumn, marker.EndLine);
} else {
newPos = new TextLocation(marker.StartColumn, marker.StartLine);
}
break;
}
}
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
public class WordLeft : CaretLeft
{
public override void Execute(TextArea textArea)
{
TextLocation oldPos = textArea.Caret.Position;
if (textArea.Caret.Column == 0) {
base.Execute(textArea);
} else {
LineSegment line = textArea.Document.GetLineSegment(textArea.Caret.Position.Y);
int prevWordStart = TextUtilities.FindPrevWordStart(textArea.Document, textArea.Caret.Offset);
TextLocation newPos = textArea.Document.OffsetToPosition(prevWordStart);
// handle fold markers
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
foreach (FoldMarker marker in foldings) {
if (marker.IsFolded) {
if (oldPos.X == marker.EndColumn && oldPos.Y == marker.EndLine) {
newPos = new TextLocation(marker.StartColumn, marker.StartLine);
} else {
newPos = new TextLocation(marker.EndColumn, marker.EndLine);
}
break;
}
}
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
}
public class ScrollLineUp : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
textArea.MotherTextAreaControl.VScrollBar.Value = Math.Max(textArea.MotherTextAreaControl.VScrollBar.Minimum,
textArea.VirtualTop.Y - textArea.TextView.FontHeight);
}
}
public class ScrollLineDown : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
textArea.MotherTextAreaControl.VScrollBar.Value = Math.Min(textArea.MotherTextAreaControl.VScrollBar.Maximum,
textArea.VirtualTop.Y + textArea.TextView.FontHeight);
}
}
}

View File

@@ -0,0 +1,42 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Actions
{
public class Cut : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.ClipboardHandler.Cut(null, null);
}
}
public class Copy : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
textArea.ClipboardHandler.Copy(null, null);
}
}
public class Paste : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.ClipboardHandler.Paste(null, null);
}
}
}

View File

@@ -0,0 +1,69 @@
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.UserControls;
namespace ICSharpCode.TextEditor.Src.Actions
{
abstract class FindAndReplaceFormActions : AbstractEditAction
{
protected readonly TextEditorControlEx Control;
protected readonly FindAndReplaceForm FindForm;
protected FindAndReplaceFormActions(FindAndReplaceForm findForm, TextEditorControlEx control)
{
FindForm = findForm;
Control = control;
}
}
class FindAgainReverseAction : FindAndReplaceFormActions
{
public FindAgainReverseAction(FindAndReplaceForm findForm, TextEditorControlEx control)
: base(findForm, control)
{
}
public override void Execute(TextArea textArea)
{
FindForm.FindNext(true, true, string.Format("Search text «{0}» not found.", FindForm.LookFor));
}
}
class FindAgainAction : FindAndReplaceFormActions
{
public FindAgainAction(FindAndReplaceForm findForm, TextEditorControlEx control)
: base(findForm, control)
{
}
public override void Execute(TextArea textArea)
{
FindForm.FindNext(true, false, string.Format("Search text «{0}» not found.", FindForm.LookFor));
}
}
class EditReplaceAction : FindAndReplaceFormActions
{
public EditReplaceAction(FindAndReplaceForm findForm, TextEditorControlEx control)
: base(findForm, control)
{
}
public override void Execute(TextArea textArea)
{
FindForm.ShowFor(Control, true);
}
}
class EditFindAction : FindAndReplaceFormActions
{
public EditFindAction(FindAndReplaceForm findForm, TextEditorControlEx control)
: base(findForm, control)
{
}
public override void Execute(TextArea textArea)
{
FindForm.ShowFor(Control, false);
}
}
}

View File

@@ -0,0 +1,68 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class ToggleFolding : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
List<FoldMarker> foldMarkers = textArea.Document.FoldingManager.GetFoldingsWithStart(textArea.Caret.Line);
if (foldMarkers.Count != 0) {
foreach (FoldMarker fm in foldMarkers)
fm.IsFolded = !fm.IsFolded;
} else {
foldMarkers = textArea.Document.FoldingManager.GetFoldingsContainsLineNumber(textArea.Caret.Line);
if (foldMarkers.Count != 0) {
FoldMarker innerMost = foldMarkers[0];
for (int i = 1; i < foldMarkers.Count; i++) {
if (new TextLocation(foldMarkers[i].StartColumn, foldMarkers[i].StartLine) >
new TextLocation(innerMost.StartColumn, innerMost.StartLine))
{
innerMost = foldMarkers[i];
}
}
innerMost.IsFolded = !innerMost.IsFolded;
}
}
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
}
}
public class ToggleAllFoldings : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
bool doFold = true;
foreach (FoldMarker fm in textArea.Document.FoldingManager.FoldMarker) {
if (fm.IsFolded) {
doFold = false;
break;
}
}
foreach (FoldMarker fm in textArea.Document.FoldingManager.FoldMarker) {
fm.IsFolded = doFold;
}
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
}
}
public class ShowDefinitionsOnly : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
foreach (FoldMarker fm in textArea.Document.FoldingManager.FoldMarker) {
fm.IsFolded = fm.FoldType == FoldType.MemberBody || fm.FoldType == FoldType.Region;
}
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
}
}
}

View File

@@ -0,0 +1,219 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public abstract class AbstractLineFormatAction : AbstractEditAction
{
protected TextArea textArea;
abstract protected void Convert(IDocument document, int startLine, int endLine);
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.SelectionIsReadonly) {
return;
}
this.textArea = textArea;
textArea.BeginUpdate();
textArea.Document.UndoStack.StartUndoGroup();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
Convert(textArea.Document, selection.StartPosition.Y, selection.EndPosition.Y);
}
} else {
Convert(textArea.Document, 0, textArea.Document.TotalNumberOfLines - 1);
}
textArea.Document.UndoStack.EndUndoGroup();
textArea.Caret.ValidateCaretPos();
textArea.EndUpdate();
textArea.Refresh();
}
}
public abstract class AbstractSelectionFormatAction : AbstractEditAction
{
protected TextArea textArea;
abstract protected void Convert(IDocument document, int offset, int length);
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.SelectionIsReadonly) {
return;
}
this.textArea = textArea;
textArea.BeginUpdate();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
Convert(textArea.Document, selection.Offset, selection.Length);
}
} else {
Convert(textArea.Document, 0, textArea.Document.TextLength);
}
textArea.Caret.ValidateCaretPos();
textArea.EndUpdate();
textArea.Refresh();
}
}
public class RemoveLeadingWS : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y1; i < y2; ++i) {
LineSegment line = document.GetLineSegment(i);
int removeNumber = 0;
for (int x = line.Offset; x < line.Offset + line.Length && char.IsWhiteSpace(document.GetCharAt(x)); ++x) {
++removeNumber;
}
if (removeNumber > 0) {
document.Remove(line.Offset, removeNumber);
}
}
}
}
public class RemoveTrailingWS : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y2 - 1; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
int removeNumber = 0;
for (int x = line.Offset + line.Length - 1; x >= line.Offset && char.IsWhiteSpace(document.GetCharAt(x)); --x) {
++removeNumber;
}
if (removeNumber > 0) {
document.Remove(line.Offset + line.Length - removeNumber, removeNumber);
}
}
}
}
public class ToUpperCase : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length).ToUpper();
document.Replace(startOffset, length, what);
}
}
public class ToLowerCase : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length).ToLower();
document.Replace(startOffset, length, what);
}
}
public class InvertCaseAction : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
StringBuilder what = new StringBuilder(document.GetText(startOffset, length));
for (int i = 0; i < what.Length; ++i) {
what[i] = char.IsUpper(what[i]) ? char.ToLower(what[i]) : char.ToUpper(what[i]);
}
document.Replace(startOffset, length, what.ToString());
}
}
public class CapitalizeAction : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
StringBuilder what = new StringBuilder(document.GetText(startOffset, length));
for (int i = 0; i < what.Length; ++i) {
if (!char.IsLetter(what[i]) && i < what.Length - 1) {
what[i + 1] = char.ToUpper(what[i + 1]);
}
}
document.Replace(startOffset, length, what.ToString());
}
}
public class ConvertTabsToSpaces : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length);
string spaces = new string(' ', document.TextEditorProperties.TabIndent);
document.Replace(startOffset, length, what.Replace("\t", spaces));
}
}
public class ConvertSpacesToTabs : AbstractSelectionFormatAction
{
protected override void Convert(IDocument document, int startOffset, int length)
{
string what = document.GetText(startOffset, length);
string spaces = new string(' ', document.TextEditorProperties.TabIndent);
document.Replace(startOffset, length, what.Replace(spaces, "\t"));
}
}
public class ConvertLeadingTabsToSpaces : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if(line.Length > 0) {
// count how many whitespace characters there are at the start
int whiteSpace = 0;
for(whiteSpace = 0; whiteSpace < line.Length && char.IsWhiteSpace(document.GetCharAt(line.Offset + whiteSpace)); whiteSpace++) {
// deliberately empty
}
if(whiteSpace > 0) {
string newLine = document.GetText(line.Offset,whiteSpace);
string newPrefix = newLine.Replace("\t",new string(' ', document.TextEditorProperties.TabIndent));
document.Replace(line.Offset,whiteSpace,newPrefix);
}
}
}
}
}
public class ConvertLeadingSpacesToTabs : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int y1, int y2)
{
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if(line.Length > 0) {
// note: some users may prefer a more radical ConvertLeadingSpacesToTabs that
// means there can be no spaces before the first character even if the spaces
// didn't add up to a whole number of tabs
string newLine = TextUtilities.LeadingWhiteSpaceToTabs(document.GetText(line.Offset,line.Length), document.TextEditorProperties.TabIndent);
document.Replace(line.Offset,line.Length,newLine);
}
}
}
}
/// <summary>
/// This is a sample editaction plugin, it indents the selected area.
/// </summary>
public class IndentSelection : AbstractLineFormatAction
{
protected override void Convert(IDocument document, int startLine, int endLine)
{
document.FormattingStrategy.IndentLines(textArea, startLine, endLine);
}
}
}

View File

@@ -0,0 +1,28 @@
using System.Windows.Forms;
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.UserControls;
namespace ICSharpCode.TextEditor.Src.Actions
{
class GoToLineNumberAction : AbstractEditAction
{
private readonly GotoForm _gotoForm;
public GoToLineNumberAction()
{
_gotoForm = new GotoForm();
}
public override void Execute(TextArea textArea)
{
_gotoForm.FirstLineNumber = 1;
_gotoForm.LastLineNumber = textArea.Document.TotalNumberOfLines;
_gotoForm.SelectedLineNumber = textArea.Caret.Line + 1;
if (DialogResult.OK == _gotoForm.ShowDialogEx() && _gotoForm.SelectedLineNumber > 0)
{
textArea.Caret.Position = new TextLocation(0, _gotoForm.SelectedLineNumber - 1);
}
}
}
}

View File

@@ -0,0 +1,114 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class Home : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
LineSegment curLine;
TextLocation newPos = textArea.Caret.Position;
bool jumpedIntoFolding = false;
do {
curLine = textArea.Document.GetLineSegment(newPos.Y);
if (TextUtilities.IsEmptyLine(textArea.Document, newPos.Y)) {
if (newPos.X != 0) {
newPos.X = 0;
} else {
newPos.X = curLine.Length;
}
} else {
int firstCharOffset = TextUtilities.GetFirstNonWSChar(textArea.Document, curLine.Offset);
int firstCharColumn = firstCharOffset - curLine.Offset;
if (newPos.X == firstCharColumn) {
newPos.X = 0;
} else {
newPos.X = firstCharColumn;
}
}
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
jumpedIntoFolding = false;
foreach (FoldMarker foldMarker in foldings) {
if (foldMarker.IsFolded) {
newPos = new TextLocation(foldMarker.StartColumn, foldMarker.StartLine);
jumpedIntoFolding = true;
break;
}
}
} while (jumpedIntoFolding);
if (newPos != textArea.Caret.Position) {
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
}
public class End : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
LineSegment curLine;
TextLocation newPos = textArea.Caret.Position;
bool jumpedIntoFolding = false;
do {
curLine = textArea.Document.GetLineSegment(newPos.Y);
newPos.X = curLine.Length;
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(newPos.Y, newPos.X);
jumpedIntoFolding = false;
foreach (FoldMarker foldMarker in foldings) {
if (foldMarker.IsFolded) {
newPos = new TextLocation(foldMarker.EndColumn, foldMarker.EndLine);
jumpedIntoFolding = true;
break;
}
}
} while (jumpedIntoFolding);
if (newPos != textArea.Caret.Position) {
textArea.Caret.Position = newPos;
textArea.SetDesiredColumn();
}
}
}
public class MoveToStart : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
if (textArea.Caret.Line != 0 || textArea.Caret.Column != 0) {
textArea.Caret.Position = new TextLocation(0, 0);
textArea.SetDesiredColumn();
}
}
}
public class MoveToEnd : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
TextLocation endPos = textArea.Document.OffsetToPosition(textArea.Document.TextLength);
if (textArea.Caret.Position != endPos) {
textArea.Caret.Position = endPos;
textArea.SetDesiredColumn();
}
}
}
}

View File

@@ -0,0 +1,58 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor.Actions
{
/// <summary>
/// To define a new key for the textarea, you must write a class which
/// implements this interface.
/// </summary>
public interface IEditAction
{
/// <value>
/// An array of keys on which this edit action occurs.
/// </value>
Keys[] Keys {
get;
set;
}
/// <remarks>
/// When the key which is defined per XML is pressed, this method will be launched.
/// </remarks>
void Execute(TextArea textArea);
}
/// <summary>
/// To define a new key for the textarea, you must write a class which
/// implements this interface.
/// </summary>
public abstract class AbstractEditAction : IEditAction
{
Keys[] keys = null;
/// <value>
/// An array of keys on which this edit action occurs.
/// </value>
public Keys[] Keys {
get {
return keys;
}
set {
keys = value;
}
}
/// <remarks>
/// When the key which is defined per XML is pressed, this method will be launched.
/// </remarks>
public abstract void Execute(TextArea textArea);
}
}

View File

@@ -0,0 +1,902 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class Tab : AbstractEditAction
{
public static string GetIndentationString(IDocument document)
{
return GetIndentationString(document, null);
}
public static string GetIndentationString(IDocument document, TextArea textArea)
{
StringBuilder indent = new StringBuilder();
if (document.TextEditorProperties.ConvertTabsToSpaces) {
int tabIndent = document.TextEditorProperties.IndentationSize;
if (textArea != null) {
int column = textArea.TextView.GetVisualColumn(textArea.Caret.Line, textArea.Caret.Column);
indent.Append(new string(' ', tabIndent - column % tabIndent));
} else {
indent.Append(new string(' ', tabIndent));
}
} else {
indent.Append('\t');
}
return indent.ToString();
}
void InsertTabs(IDocument document, ISelection selection, int y1, int y2)
{
string indentationString = GetIndentationString(document);
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (i == y2 && i == selection.EndPosition.Y && selection.EndPosition.X == 0) {
continue;
}
// this bit is optional - but useful if you are using block tabbing to sort out
// a source file with a mixture of tabs and spaces
// string newLine = document.GetText(line.Offset,line.Length);
// document.Replace(line.Offset,line.Length,newLine);
document.Insert(line.Offset, indentationString);
}
}
void InsertTabAtCaretPosition(TextArea textArea)
{
switch (textArea.Caret.CaretMode) {
case CaretMode.InsertMode:
textArea.InsertString(GetIndentationString(textArea.Document, textArea));
break;
case CaretMode.OverwriteMode:
string indentStr = GetIndentationString(textArea.Document, textArea);
textArea.ReplaceChar(indentStr[0]);
if (indentStr.Length > 1) {
textArea.InsertString(indentStr.Substring(1));
}
break;
}
textArea.SetDesiredColumn();
}
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.SelectionIsReadonly) {
return;
}
textArea.Document.UndoStack.StartUndoGroup();
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
int startLine = selection.StartPosition.Y;
int endLine = selection.EndPosition.Y;
if (startLine != endLine) {
textArea.BeginUpdate();
InsertTabs(textArea.Document, selection, startLine, endLine);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, startLine, endLine));
textArea.EndUpdate();
} else {
InsertTabAtCaretPosition(textArea);
break;
}
}
textArea.Document.CommitUpdate();
textArea.AutoClearSelection = false;
} else {
InsertTabAtCaretPosition(textArea);
}
textArea.Document.UndoStack.EndUndoGroup();
}
}
public class ShiftTab : AbstractEditAction
{
void RemoveTabs(IDocument document, ISelection selection, int y1, int y2)
{
document.UndoStack.StartUndoGroup();
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (i == y2 && line.Offset == selection.EndOffset) {
continue;
}
if (line.Length > 0) {
/**** TextPad Strategy:
/// first convert leading whitespace to tabs (controversial! - not all editors work like this)
string newLine = TextUtilities.LeadingWhiteSpaceToTabs(document.GetText(line.Offset,line.Length),document.Properties.Get("TabIndent", 4));
if(newLine.Length > 0 && newLine[0] == '\t') {
document.Replace(line.Offset,line.Length,newLine.Substring(1));
++redocounter;
}
else if(newLine.Length > 0 && newLine[0] == ' ') {
/// there were just some leading spaces but less than TabIndent of them
int leadingSpaces = 1;
for(leadingSpaces = 1; leadingSpaces < newLine.Length && newLine[leadingSpaces] == ' '; leadingSpaces++) {
/// deliberately empty
}
document.Replace(line.Offset,line.Length,newLine.Substring(leadingSpaces));
++redocounter;
}
/// else
/// there were no leading tabs or spaces on this line so do nothing
/// MS Visual Studio 6 strategy:
****/
// string temp = document.GetText(line.Offset,line.Length);
if (line.Length > 0) {
int charactersToRemove = 0;
if(document.GetCharAt(line.Offset) == '\t') { // first character is a tab - just remove it
charactersToRemove = 1;
} else if(document.GetCharAt(line.Offset) == ' ') {
int leadingSpaces = 1;
int tabIndent = document.TextEditorProperties.IndentationSize;
for (leadingSpaces = 1; leadingSpaces < line.Length && document.GetCharAt(line.Offset + leadingSpaces) == ' '; leadingSpaces++) {
// deliberately empty
}
if(leadingSpaces >= tabIndent) {
// just remove tabIndent
charactersToRemove = tabIndent;
}
else if(line.Length > leadingSpaces && document.GetCharAt(line.Offset + leadingSpaces) == '\t') {
// remove the leading spaces and the following tab as they add up
// to just one tab stop
charactersToRemove = leadingSpaces+1;
}
else {
// just remove the leading spaces
charactersToRemove = leadingSpaces;
}
}
if (charactersToRemove > 0) {
document.Remove(line.Offset,charactersToRemove);
}
}
}
}
document.UndoStack.EndUndoGroup();
}
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
int startLine = selection.StartPosition.Y;
int endLine = selection.EndPosition.Y;
textArea.BeginUpdate();
RemoveTabs(textArea.Document, selection, startLine, endLine);
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, startLine, endLine));
textArea.EndUpdate();
}
textArea.AutoClearSelection = false;
} else {
// Pressing Shift-Tab with nothing selected the cursor will move back to the
// previous tab stop. It will stop at the beginning of the line. Also, the desired
// column is updated to that column.
LineSegment line = textArea.Document.GetLineSegmentForOffset(textArea.Caret.Offset);
string startOfLine = textArea.Document.GetText(line.Offset,textArea.Caret.Offset - line.Offset);
int tabIndent = textArea.Document.TextEditorProperties.IndentationSize;
int currentColumn = textArea.Caret.Column;
int remainder = currentColumn % tabIndent;
if (remainder == 0) {
textArea.Caret.DesiredColumn = Math.Max(0, currentColumn - tabIndent);
} else {
textArea.Caret.DesiredColumn = Math.Max(0, currentColumn - remainder);
}
textArea.SetCaretToDesiredColumn();
}
}
}
public class ToggleComment : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("LineComment")) {
new ToggleLineComment().Execute(textArea);
} else if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentBegin") &&
textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentBegin")) {
new ToggleBlockComment().Execute(textArea);
}
}
}
public class ToggleLineComment : AbstractEditAction
{
int firstLine;
int lastLine;
void RemoveCommentAt(IDocument document, string comment, ISelection selection, int y1, int y2)
{
firstLine = y1;
lastLine = y2;
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (selection != null && i == y2 && line.Offset == selection.Offset + selection.Length) {
--lastLine;
continue;
}
string lineText = document.GetText(line.Offset, line.Length);
if (lineText.Trim().StartsWith(comment)) {
document.Remove(line.Offset + lineText.IndexOf(comment), comment.Length);
}
}
}
void SetCommentAt(IDocument document, string comment, ISelection selection, int y1, int y2)
{
firstLine = y1;
lastLine = y2;
for (int i = y2; i >= y1; --i) {
LineSegment line = document.GetLineSegment(i);
if (selection != null && i == y2 && line.Offset == selection.Offset + selection.Length) {
--lastLine;
continue;
}
string lineText = document.GetText(line.Offset, line.Length);
document.Insert(line.Offset, comment);
}
}
bool ShouldComment(IDocument document, string comment, ISelection selection, int startLine, int endLine)
{
for (int i = endLine; i >= startLine; --i) {
LineSegment line = document.GetLineSegment(i);
if (selection != null && i == endLine && line.Offset == selection.Offset + selection.Length) {
--lastLine;
continue;
}
string lineText = document.GetText(line.Offset, line.Length);
if (!lineText.Trim().StartsWith(comment)) {
return true;
}
}
return false;
}
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
string comment = null;
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("LineComment")) {
comment = textArea.Document.HighlightingStrategy.Properties["LineComment"].ToString();
}
if (comment == null || comment.Length == 0) {
return;
}
textArea.Document.UndoStack.StartUndoGroup();
if (textArea.SelectionManager.HasSomethingSelected) {
bool shouldComment = true;
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
if (!ShouldComment(textArea.Document, comment, selection, selection.StartPosition.Y, selection.EndPosition.Y)) {
shouldComment = false;
break;
}
}
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
textArea.BeginUpdate();
if (shouldComment) {
SetCommentAt(textArea.Document, comment, selection, selection.StartPosition.Y, selection.EndPosition.Y);
} else {
RemoveCommentAt(textArea.Document, comment, selection, selection.StartPosition.Y, selection.EndPosition.Y);
}
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, firstLine, lastLine));
textArea.EndUpdate();
}
textArea.Document.CommitUpdate();
textArea.AutoClearSelection = false;
} else {
textArea.BeginUpdate();
int caretLine = textArea.Caret.Line;
if (ShouldComment(textArea.Document, comment, null, caretLine, caretLine)) {
SetCommentAt(textArea.Document, comment, null, caretLine, caretLine);
} else {
RemoveCommentAt(textArea.Document, comment, null, caretLine, caretLine);
}
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, caretLine));
textArea.EndUpdate();
}
textArea.Document.UndoStack.EndUndoGroup();
}
}
public class ToggleBlockComment : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
string commentStart = null;
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentBegin")) {
commentStart = textArea.Document.HighlightingStrategy.Properties["BlockCommentBegin"].ToString();
}
string commentEnd = null;
if (textArea.Document.HighlightingStrategy.Properties.ContainsKey("BlockCommentEnd")) {
commentEnd = textArea.Document.HighlightingStrategy.Properties["BlockCommentEnd"].ToString();
}
if (commentStart == null || commentStart.Length == 0 || commentEnd == null || commentEnd.Length == 0) {
return;
}
int selectionStartOffset;
int selectionEndOffset;
if (textArea.SelectionManager.HasSomethingSelected) {
selectionStartOffset = textArea.SelectionManager.SelectionCollection[0].Offset;
selectionEndOffset = textArea.SelectionManager.SelectionCollection[textArea.SelectionManager.SelectionCollection.Count - 1].EndOffset;
} else {
selectionStartOffset = textArea.Caret.Offset;
selectionEndOffset = selectionStartOffset;
}
BlockCommentRegion commentRegion = FindSelectedCommentRegion(textArea.Document, commentStart, commentEnd, selectionStartOffset, selectionEndOffset);
textArea.Document.UndoStack.StartUndoGroup();
if (commentRegion != null) {
RemoveComment(textArea.Document, commentRegion);
} else if (textArea.SelectionManager.HasSomethingSelected) {
SetCommentAt(textArea.Document, selectionStartOffset, selectionEndOffset, commentStart, commentEnd);
}
textArea.Document.UndoStack.EndUndoGroup();
textArea.Document.CommitUpdate();
textArea.AutoClearSelection = false;
}
public static BlockCommentRegion FindSelectedCommentRegion(IDocument document, string commentStart, string commentEnd, int selectionStartOffset, int selectionEndOffset)
{
if (document.TextLength == 0) {
return null;
}
// Find start of comment in selected text.
int commentEndOffset = -1;
string selectedText = document.GetText(selectionStartOffset, selectionEndOffset - selectionStartOffset);
int commentStartOffset = selectedText.IndexOf(commentStart);
if (commentStartOffset >= 0) {
commentStartOffset += selectionStartOffset;
}
// Find end of comment in selected text.
if (commentStartOffset >= 0) {
commentEndOffset = selectedText.IndexOf(commentEnd, commentStartOffset + commentStart.Length - selectionStartOffset);
} else {
commentEndOffset = selectedText.IndexOf(commentEnd);
}
if (commentEndOffset >= 0) {
commentEndOffset += selectionStartOffset;
}
// Find start of comment before or partially inside the
// selected text.
int commentEndBeforeStartOffset = -1;
if (commentStartOffset == -1) {
int offset = selectionEndOffset + commentStart.Length - 1;
if (offset > document.TextLength) {
offset = document.TextLength;
}
string text = document.GetText(0, offset);
commentStartOffset = text.LastIndexOf(commentStart);
if (commentStartOffset >= 0) {
// Find end of comment before comment start.
commentEndBeforeStartOffset = text.IndexOf(commentEnd, commentStartOffset, selectionStartOffset - commentStartOffset);
if (commentEndBeforeStartOffset > commentStartOffset) {
commentStartOffset = -1;
}
}
}
// Find end of comment after or partially after the
// selected text.
if (commentEndOffset == -1) {
int offset = selectionStartOffset + 1 - commentEnd.Length;
if (offset < 0) {
offset = selectionStartOffset;
}
string text = document.GetText(offset, document.TextLength - offset);
commentEndOffset = text.IndexOf(commentEnd);
if (commentEndOffset >= 0) {
commentEndOffset += offset;
}
}
if (commentStartOffset != -1 && commentEndOffset != -1) {
return new BlockCommentRegion(commentStart, commentEnd, commentStartOffset, commentEndOffset);
}
return null;
}
void SetCommentAt(IDocument document, int offsetStart, int offsetEnd, string commentStart, string commentEnd)
{
document.Insert(offsetEnd, commentEnd);
document.Insert(offsetStart, commentStart);
}
void RemoveComment(IDocument document, BlockCommentRegion commentRegion)
{
document.Remove(commentRegion.EndOffset, commentRegion.CommentEnd.Length);
document.Remove(commentRegion.StartOffset, commentRegion.CommentStart.Length);
}
}
public class BlockCommentRegion
{
string commentStart = string.Empty;
string commentEnd = string.Empty;
int startOffset = -1;
int endOffset = -1;
/// <summary>
/// The end offset is the offset where the comment end string starts from.
/// </summary>
public BlockCommentRegion(string commentStart, string commentEnd, int startOffset, int endOffset)
{
this.commentStart = commentStart;
this.commentEnd = commentEnd;
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public string CommentStart {
get {
return commentStart;
}
}
public string CommentEnd {
get {
return commentEnd;
}
}
public int StartOffset {
get {
return startOffset;
}
}
public int EndOffset {
get {
return endOffset;
}
}
public override int GetHashCode()
{
int hashCode = 0;
unchecked {
if (commentStart != null) hashCode += 1000000007 * commentStart.GetHashCode();
if (commentEnd != null) hashCode += 1000000009 * commentEnd.GetHashCode();
hashCode += 1000000021 * startOffset.GetHashCode();
hashCode += 1000000033 * endOffset.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj)
{
BlockCommentRegion other = obj as BlockCommentRegion;
if (other == null) return false;
return this.commentStart == other.commentStart && this.commentEnd == other.commentEnd && this.startOffset == other.startOffset && this.endOffset == other.endOffset;
}
}
public class Backspace : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
Delete.DeleteSelection(textArea);
} else {
if (textArea.Caret.Offset > 0 && !textArea.IsReadOnly(textArea.Caret.Offset - 1)) {
textArea.BeginUpdate();
int curLineNr = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
int curLineOffset = textArea.Document.GetLineSegment(curLineNr).Offset;
if (curLineOffset == textArea.Caret.Offset) {
LineSegment line = textArea.Document.GetLineSegment(curLineNr - 1);
bool lastLine = curLineNr == textArea.Document.TotalNumberOfLines;
int lineEndOffset = line.Offset + line.Length;
int lineLength = line.Length;
textArea.Document.Remove(lineEndOffset, curLineOffset - lineEndOffset);
textArea.Caret.Position = new TextLocation(lineLength, curLineNr - 1);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, curLineNr - 1)));
} else {
int caretOffset = textArea.Caret.Offset - 1;
textArea.Caret.Position = textArea.Document.OffsetToPosition(caretOffset);
textArea.Document.Remove(caretOffset, 1);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToLineEnd, new TextLocation(textArea.Caret.Offset - textArea.Document.GetLineSegment(curLineNr).Offset, curLineNr)));
}
textArea.EndUpdate();
}
}
}
}
public class Delete : AbstractEditAction
{
internal static void DeleteSelection(TextArea textArea)
{
Debug.Assert(textArea.SelectionManager.HasSomethingSelected);
if (textArea.SelectionManager.SelectionIsReadonly)
return;
textArea.BeginUpdate();
textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
textArea.SelectionManager.RemoveSelectedText();
textArea.ScrollToCaret();
textArea.EndUpdate();
}
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
DeleteSelection(textArea);
} else {
if (textArea.IsReadOnly(textArea.Caret.Offset))
return;
if (textArea.Caret.Offset < textArea.Document.TextLength) {
textArea.BeginUpdate();
int curLineNr = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
LineSegment curLine = textArea.Document.GetLineSegment(curLineNr);
if (curLine.Offset + curLine.Length == textArea.Caret.Offset) {
if (curLineNr + 1 < textArea.Document.TotalNumberOfLines) {
LineSegment nextLine = textArea.Document.GetLineSegment(curLineNr + 1);
textArea.Document.Remove(textArea.Caret.Offset, nextLine.Offset - textArea.Caret.Offset);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, curLineNr)));
}
} else {
textArea.Document.Remove(textArea.Caret.Offset, 1);
// textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToLineEnd, new TextLocation(textArea.Caret.Offset - textArea.Document.GetLineSegment(curLineNr).Offset, curLineNr)));
}
textArea.UpdateMatchingBracket();
textArea.EndUpdate();
}
}
}
}
public class MovePageDown : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
int curLineNr = textArea.Caret.Line;
int requestedLineNumber = Math.Min(textArea.Document.GetNextVisibleLineAbove(curLineNr, textArea.TextView.VisibleLineCount), textArea.Document.TotalNumberOfLines - 1);
if (curLineNr != requestedLineNumber) {
textArea.Caret.Position = new TextLocation(0, requestedLineNumber);
textArea.SetCaretToDesiredColumn();
}
}
}
public class MovePageUp : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
int curLineNr = textArea.Caret.Line;
int requestedLineNumber = Math.Max(textArea.Document.GetNextVisibleLineBelow(curLineNr, textArea.TextView.VisibleLineCount), 0);
if (curLineNr != requestedLineNumber) {
textArea.Caret.Position = new TextLocation(0, requestedLineNumber);
textArea.SetCaretToDesiredColumn();
}
}
}
public class Return : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="TextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
textArea.BeginUpdate();
textArea.Document.UndoStack.StartUndoGroup();
try {
if (textArea.HandleKeyPress('\n'))
return;
textArea.InsertString(Environment.NewLine);
int curLineNr = textArea.Caret.Line;
textArea.Document.FormattingStrategy.FormatLine(textArea, curLineNr, textArea.Caret.Offset, '\n');
textArea.SetDesiredColumn();
textArea.Document.UpdateQueue.Clear();
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, curLineNr - 1)));
} finally {
textArea.Document.UndoStack.EndUndoGroup();
textArea.EndUpdate();
}
}
}
public class ToggleEditMode : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.Document.ReadOnly) {
return;
}
switch (textArea.Caret.CaretMode) {
case CaretMode.InsertMode:
textArea.Caret.CaretMode = CaretMode.OverwriteMode;
break;
case CaretMode.OverwriteMode:
textArea.Caret.CaretMode = CaretMode.InsertMode;
break;
}
}
}
public class Undo : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
textArea.MotherTextEditorControl.Undo();
}
}
public class Redo : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
textArea.MotherTextEditorControl.Redo();
}
}
/// <summary>
/// handles the ctrl-backspace key
/// functionality attempts to roughly mimic MS Developer studio
/// I will implement this as deleting back to the point that ctrl-leftarrow would
/// take you to
/// </summary>
public class WordBackspace : AbstractEditAction
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
// if anything is selected we will just delete it first
if (textArea.SelectionManager.HasSomethingSelected) {
Delete.DeleteSelection(textArea);
return;
}
textArea.BeginUpdate();
// now delete from the caret to the beginning of the word
LineSegment line =
textArea.Document.GetLineSegmentForOffset(textArea.Caret.Offset);
// if we are not at the beginning of a line
if (textArea.Caret.Offset > line.Offset) {
int prevWordStart = TextUtilities.FindPrevWordStart(textArea.Document,
textArea.Caret.Offset);
if (prevWordStart < textArea.Caret.Offset) {
if (!textArea.IsReadOnly(prevWordStart, textArea.Caret.Offset - prevWordStart)) {
textArea.Document.Remove(prevWordStart,
textArea.Caret.Offset - prevWordStart);
textArea.Caret.Position = textArea.Document.OffsetToPosition(prevWordStart);
}
}
}
// if we are now at the beginning of a line
if (textArea.Caret.Offset == line.Offset) {
// if we are not on the first line
int curLineNr = textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset);
if (curLineNr > 0) {
// move to the end of the line above
LineSegment lineAbove = textArea.Document.GetLineSegment(curLineNr - 1);
int endOfLineAbove = lineAbove.Offset + lineAbove.Length;
int charsToDelete = textArea.Caret.Offset - endOfLineAbove;
if (!textArea.IsReadOnly(endOfLineAbove, charsToDelete)) {
textArea.Document.Remove(endOfLineAbove, charsToDelete);
textArea.Caret.Position = textArea.Document.OffsetToPosition(endOfLineAbove);
}
}
}
textArea.SetDesiredColumn();
textArea.EndUpdate();
// if there are now less lines, we need this or there are redraw problems
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset))));
textArea.Document.CommitUpdate();
}
}
/// <summary>
/// handles the ctrl-delete key
/// functionality attempts to mimic MS Developer studio
/// I will implement this as deleting forwardto the point that
/// ctrl-leftarrow would take you to
/// </summary>
public class DeleteWord : Delete
{
/// <remarks>
/// Executes this edit action
/// </remarks>
/// <param name="textArea">The <see cref="ItextArea"/> which is used for callback purposes</param>
public override void Execute(TextArea textArea)
{
if (textArea.SelectionManager.HasSomethingSelected) {
DeleteSelection(textArea);
return;
}
// if anything is selected we will just delete it first
textArea.BeginUpdate();
// now delete from the caret to the beginning of the word
LineSegment line = textArea.Document.GetLineSegmentForOffset(textArea.Caret.Offset);
if(textArea.Caret.Offset == line.Offset + line.Length) {
// if we are at the end of a line
base.Execute(textArea);
} else {
int nextWordStart = TextUtilities.FindNextWordStart(textArea.Document,
textArea.Caret.Offset);
if(nextWordStart > textArea.Caret.Offset) {
if (!textArea.IsReadOnly(textArea.Caret.Offset, nextWordStart - textArea.Caret.Offset)) {
textArea.Document.Remove(textArea.Caret.Offset, nextWordStart - textArea.Caret.Offset);
// cursor never moves with this command
}
}
}
textArea.UpdateMatchingBracket();
textArea.EndUpdate();
// if there are now less lines, we need this or there are redraw problems
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, textArea.Document.GetLineNumberForOffset(textArea.Caret.Offset))));
textArea.Document.CommitUpdate();
}
}
public class DeleteLine : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
int lineNr = textArea.Caret.Line;
LineSegment line = textArea.Document.GetLineSegment(lineNr);
if (textArea.IsReadOnly(line.Offset, line.Length))
return;
textArea.Document.Remove(line.Offset, line.TotalLength);
textArea.Caret.Position = textArea.Document.OffsetToPosition(line.Offset);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.PositionToEnd, new TextLocation(0, lineNr)));
textArea.UpdateMatchingBracket();
textArea.Document.CommitUpdate();
}
}
public class DeleteToLineEnd : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
int lineNr = textArea.Caret.Line;
LineSegment line = textArea.Document.GetLineSegment(lineNr);
int numRemove = (line.Offset + line.Length) - textArea.Caret.Offset;
if (numRemove > 0 && !textArea.IsReadOnly(textArea.Caret.Offset, numRemove)) {
textArea.Document.Remove(textArea.Caret.Offset, numRemove);
textArea.Document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, new TextLocation(0, lineNr)));
textArea.Document.CommitUpdate();
}
}
}
public class GotoMatchingBrace : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
Highlight highlight = textArea.FindMatchingBracketHighlight();
if (highlight != null) {
TextLocation p1 = new TextLocation(highlight.CloseBrace.X + 1, highlight.CloseBrace.Y);
TextLocation p2 = new TextLocation(highlight.OpenBrace.X + 1, highlight.OpenBrace.Y);
if (p1 == textArea.Caret.Position) {
if (textArea.Document.TextEditorProperties.BracketMatchingStyle == BracketMatchingStyle.After) {
textArea.Caret.Position = p2;
} else {
textArea.Caret.Position = new TextLocation(p2.X - 1, p2.Y);
}
} else {
if (textArea.Document.TextEditorProperties.BracketMatchingStyle == BracketMatchingStyle.After) {
textArea.Caret.Position = p1;
} else {
textArea.Caret.Position = new TextLocation(p1.X - 1, p1.Y);
}
}
textArea.SetDesiredColumn();
}
}
}
}

View File

@@ -0,0 +1,176 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Actions
{
public class ShiftCaretRight : CaretRight
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftCaretLeft : CaretLeft
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftCaretUp : CaretUp
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftCaretDown : CaretDown
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftWordRight : WordRight
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftWordLeft : WordLeft
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftHome : Home
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftEnd : End
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMoveToStart : MoveToStart
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMoveToEnd : MoveToEnd
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMovePageUp : MovePageUp
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class ShiftMovePageDown : MovePageDown
{
public override void Execute(TextArea textArea)
{
TextLocation oldCaretPos = textArea.Caret.Position;
base.Execute(textArea);
textArea.AutoClearSelection = false;
textArea.SelectionManager.ExtendSelection(oldCaretPos, textArea.Caret.Position);
}
}
public class SelectWholeDocument : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.AutoClearSelection = false;
TextLocation startPoint = new TextLocation(0, 0);
TextLocation endPoint = textArea.Document.OffsetToPosition(textArea.Document.TextLength);
if (textArea.SelectionManager.HasSomethingSelected) {
if (textArea.SelectionManager.SelectionCollection[0].StartPosition == startPoint &&
textArea.SelectionManager.SelectionCollection[0].EndPosition == endPoint) {
return;
}
}
textArea.Caret.Position = textArea.SelectionManager.NextValidPosition(endPoint.Y);
textArea.SelectionManager.ExtendSelection(startPoint, endPoint);
// after a SelectWholeDocument selection, the caret is placed correctly,
// but it is not positioned internally. The effect is when the cursor
// is moved up or down a line, the caret will take on the column that
// it was in before the SelectWholeDocument
textArea.SetDesiredColumn();
}
}
public class ClearAllSelections : AbstractEditAction
{
public override void Execute(TextArea textArea)
{
textArea.SelectionManager.ClearSelection();
}
}
}

View File

@@ -0,0 +1,52 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This interface is used to describe a span inside a text sequence
/// </summary>
public class AbstractSegment : ISegment
{
[CLSCompliant(false)]
protected int offset = -1;
[CLSCompliant(false)]
protected int length = -1;
#region ICSharpCode.TextEditor.Document.ISegment interface implementation
public virtual int Offset {
get {
return offset;
}
set {
offset = value;
}
}
public virtual int Length {
get {
return length;
}
set {
length = value;
}
}
#endregion
public override string ToString()
{
return string.Format("[AbstractSegment: Offset = {0}, Length = {1}]",
Offset,
Length);
}
}
}

View File

@@ -0,0 +1,164 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using SWF = System.Windows.Forms;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// Description of Bookmark.
/// </summary>
public class Bookmark
{
IDocument document;
TextAnchor anchor;
TextLocation location;
bool isEnabled = true;
public IDocument Document {
get {
return document;
}
set {
if (document != value) {
if (anchor != null) {
location = anchor.Location;
anchor = null;
}
document = value;
CreateAnchor();
OnDocumentChanged(EventArgs.Empty);
}
}
}
void CreateAnchor()
{
if (document != null) {
LineSegment line = document.GetLineSegment(Math.Max(0, Math.Min(location.Line, document.TotalNumberOfLines-1)));
anchor = line.CreateAnchor(Math.Max(0, Math.Min(location.Column, line.Length)));
// after insertion: keep bookmarks after the initial whitespace (see DefaultFormattingStrategy.SmartReplaceLine)
anchor.MovementType = AnchorMovementType.AfterInsertion;
anchor.Deleted += AnchorDeleted;
}
}
void AnchorDeleted(object sender, EventArgs e)
{
document.BookmarkManager.RemoveMark(this);
}
/// <summary>
/// Gets the TextAnchor used for this bookmark.
/// Is null if the bookmark is not connected to a document.
/// </summary>
public TextAnchor Anchor {
get { return anchor; }
}
public TextLocation Location {
get {
if (anchor != null)
return anchor.Location;
else
return location;
}
set {
location = value;
CreateAnchor();
}
}
public event EventHandler DocumentChanged;
protected virtual void OnDocumentChanged(EventArgs e)
{
if (DocumentChanged != null) {
DocumentChanged(this, e);
}
}
public bool IsEnabled {
get {
return isEnabled;
}
set {
if (isEnabled != value) {
isEnabled = value;
if (document != null) {
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, LineNumber));
document.CommitUpdate();
}
OnIsEnabledChanged(EventArgs.Empty);
}
}
}
public event EventHandler IsEnabledChanged;
protected virtual void OnIsEnabledChanged(EventArgs e)
{
if (IsEnabledChanged != null) {
IsEnabledChanged(this, e);
}
}
public int LineNumber {
get {
if (anchor != null)
return anchor.LineNumber;
else
return location.Line;
}
}
public int ColumnNumber {
get {
if (anchor != null)
return anchor.ColumnNumber;
else
return location.Column;
}
}
/// <summary>
/// Gets if the bookmark can be toggled off using the 'set/unset bookmark' command.
/// </summary>
public virtual bool CanToggle {
get {
return true;
}
}
public Bookmark(IDocument document, TextLocation location) : this(document, location, true)
{
}
public Bookmark(IDocument document, TextLocation location, bool isEnabled)
{
this.document = document;
this.isEnabled = isEnabled;
this.Location = location;
}
public virtual bool Click(SWF.Control parent, SWF.MouseEventArgs e)
{
if (e.Button == SWF.MouseButtons.Left && CanToggle) {
document.BookmarkManager.RemoveMark(this);
return true;
}
return false;
}
public virtual void Draw(IconBarMargin margin, Graphics g, Point p)
{
margin.DrawBookmark(g, p.Y, isEnabled);
}
}
}

View File

@@ -0,0 +1,32 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
public delegate void BookmarkEventHandler(object sender, BookmarkEventArgs e);
/// <summary>
/// Description of BookmarkEventHandler.
/// </summary>
public class BookmarkEventArgs : EventArgs
{
Bookmark bookmark;
public Bookmark Bookmark {
get {
return bookmark;
}
}
public BookmarkEventArgs(Bookmark bookmark)
{
this.bookmark = bookmark;
}
}
}

View File

@@ -0,0 +1,246 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ICSharpCode.TextEditor.Util;
namespace ICSharpCode.TextEditor.Document
{
public interface IBookmarkFactory
{
Bookmark CreateBookmark(IDocument document, TextLocation location);
}
/// <summary>
/// This class handles the bookmarks for a buffer
/// </summary>
public class BookmarkManager
{
IDocument document;
#if DEBUG
IList<Bookmark> bookmark = new CheckedList<Bookmark>();
#else
List<Bookmark> bookmark = new List<Bookmark>();
#endif
/// <value>
/// Contains all bookmarks
/// </value>
public ReadOnlyCollection<Bookmark> Marks {
get {
return new ReadOnlyCollection<Bookmark>(bookmark);
}
}
public IDocument Document {
get {
return document;
}
}
/// <summary>
/// Creates a new instance of <see cref="BookmarkManager"/>
/// </summary>
internal BookmarkManager(IDocument document, LineManager lineTracker)
{
this.document = document;
}
/// <summary>
/// Gets/Sets the bookmark factory used to create bookmarks for "ToggleMarkAt".
/// </summary>
public IBookmarkFactory Factory { get; set;}
/// <summary>
/// Sets the mark at the line <code>location.Line</code> if it is not set, if the
/// line is already marked the mark is cleared.
/// </summary>
public void ToggleMarkAt(TextLocation location)
{
Bookmark newMark;
if (Factory != null) {
newMark = Factory.CreateBookmark(document, location);
} else {
newMark = new Bookmark(document, location);
}
Type newMarkType = newMark.GetType();
for (int i = 0; i < bookmark.Count; ++i) {
Bookmark mark = bookmark[i];
if (mark.LineNumber == location.Line && mark.CanToggle && mark.GetType() == newMarkType) {
bookmark.RemoveAt(i);
OnRemoved(new BookmarkEventArgs(mark));
return;
}
}
bookmark.Add(newMark);
OnAdded(new BookmarkEventArgs(newMark));
}
public void AddMark(Bookmark mark)
{
bookmark.Add(mark);
OnAdded(new BookmarkEventArgs(mark));
}
public void RemoveMark(Bookmark mark)
{
bookmark.Remove(mark);
OnRemoved(new BookmarkEventArgs(mark));
}
public void RemoveMarks(Predicate<Bookmark> predicate)
{
for (int i = 0; i < bookmark.Count; ++i) {
Bookmark bm = bookmark[i];
if (predicate(bm)) {
bookmark.RemoveAt(i--);
OnRemoved(new BookmarkEventArgs(bm));
}
}
}
/// <returns>
/// true, if a mark at mark exists, otherwise false
/// </returns>
public bool IsMarked(int lineNr)
{
for (int i = 0; i < bookmark.Count; ++i) {
if (bookmark[i].LineNumber == lineNr) {
return true;
}
}
return false;
}
/// <remarks>
/// Clears all bookmark
/// </remarks>
public void Clear()
{
foreach (Bookmark mark in bookmark) {
OnRemoved(new BookmarkEventArgs(mark));
}
bookmark.Clear();
}
/// <value>
/// The lowest mark, if no marks exists it returns -1
/// </value>
public Bookmark GetFirstMark(Predicate<Bookmark> predicate)
{
if (bookmark.Count < 1) {
return null;
}
Bookmark first = null;
for (int i = 0; i < bookmark.Count; ++i) {
if (predicate(bookmark[i]) && bookmark[i].IsEnabled && (first == null || bookmark[i].LineNumber < first.LineNumber)) {
first = bookmark[i];
}
}
return first;
}
/// <value>
/// The highest mark, if no marks exists it returns -1
/// </value>
public Bookmark GetLastMark(Predicate<Bookmark> predicate)
{
if (bookmark.Count < 1) {
return null;
}
Bookmark last = null;
for (int i = 0; i < bookmark.Count; ++i) {
if (predicate(bookmark[i]) && bookmark[i].IsEnabled && (last == null || bookmark[i].LineNumber > last.LineNumber)) {
last = bookmark[i];
}
}
return last;
}
bool AcceptAnyMarkPredicate(Bookmark mark)
{
return true;
}
public Bookmark GetNextMark(int curLineNr)
{
return GetNextMark(curLineNr, AcceptAnyMarkPredicate);
}
/// <remarks>
/// returns first mark higher than <code>lineNr</code>
/// </remarks>
/// <returns>
/// returns the next mark > cur, if it not exists it returns FirstMark()
/// </returns>
public Bookmark GetNextMark(int curLineNr, Predicate<Bookmark> predicate)
{
if (bookmark.Count == 0) {
return null;
}
Bookmark next = GetFirstMark(predicate);
foreach (Bookmark mark in bookmark) {
if (predicate(mark) && mark.IsEnabled && mark.LineNumber > curLineNr) {
if (mark.LineNumber < next.LineNumber || next.LineNumber <= curLineNr) {
next = mark;
}
}
}
return next;
}
public Bookmark GetPrevMark(int curLineNr)
{
return GetPrevMark(curLineNr, AcceptAnyMarkPredicate);
}
/// <remarks>
/// returns first mark lower than <code>lineNr</code>
/// </remarks>
/// <returns>
/// returns the next mark lower than cur, if it not exists it returns LastMark()
/// </returns>
public Bookmark GetPrevMark(int curLineNr, Predicate<Bookmark> predicate)
{
if (bookmark.Count == 0) {
return null;
}
Bookmark prev = GetLastMark(predicate);
foreach (Bookmark mark in bookmark) {
if (predicate(mark) && mark.IsEnabled && mark.LineNumber < curLineNr) {
if (mark.LineNumber > prev.LineNumber || prev.LineNumber >= curLineNr) {
prev = mark;
}
}
}
return prev;
}
protected virtual void OnRemoved(BookmarkEventArgs e)
{
if (Removed != null) {
Removed(this, e);
}
}
protected virtual void OnAdded(BookmarkEventArgs e)
{
if (Added != null) {
Added(this, e);
}
}
public event BookmarkEventHandler Removed;
public event BookmarkEventHandler Added;
}
}

View File

@@ -0,0 +1,101 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This class is used for storing the state of a bookmark manager
/// </summary>
public class BookmarkManagerMemento
{
List<int> bookmarks = new List<int>();
/// <value>
/// Contains all bookmarks as int values
/// </value>
public List<int> Bookmarks {
get {
return bookmarks;
}
set {
bookmarks = value;
}
}
/// <summary>
/// Validates all bookmarks if they're in range of the document.
/// (removing all bookmarks &lt; 0 and bookmarks &gt; max. line number
/// </summary>
public void CheckMemento(IDocument document)
{
for (int i = 0; i < bookmarks.Count; ++i) {
int mark = (int)bookmarks[i];
if (mark < 0 || mark >= document.TotalNumberOfLines) {
bookmarks.RemoveAt(i);
--i;
}
}
}
/// <summary>
/// Creates a new instance of <see cref="BookmarkManagerMemento"/>
/// </summary>
public BookmarkManagerMemento()
{
}
/// <summary>
/// Creates a new instance of <see cref="BookmarkManagerMemento"/>
/// </summary>
public BookmarkManagerMemento(XmlElement element)
{
foreach (XmlElement el in element.ChildNodes) {
bookmarks.Add(int.Parse(el.Attributes["line"].InnerText));
}
}
/// <summary>
/// Creates a new instance of <see cref="BookmarkManagerMemento"/>
/// </summary>
public BookmarkManagerMemento(List<int> bookmarks)
{
this.bookmarks = bookmarks;
}
/// <summary>
/// Converts a xml element to a <see cref="BookmarkManagerMemento"/> object
/// </summary>
public object FromXmlElement(XmlElement element)
{
return new BookmarkManagerMemento(element);
}
/// <summary>
/// Converts this <see cref="BookmarkManagerMemento"/> to a xml element
/// </summary>
public XmlElement ToXmlElement(XmlDocument doc)
{
XmlElement bookmarknode = doc.CreateElement("Bookmarks");
foreach (int line in bookmarks) {
XmlElement markNode = doc.CreateElement("Mark");
XmlAttribute lineAttr = doc.CreateAttribute("line");
lineAttr.InnerText = line.ToString();
markNode.Attributes.Append(lineAttr);
bookmarknode.AppendChild(markNode);
}
return bookmarknode;
}
}
}

View File

@@ -0,0 +1,457 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using ICSharpCode.TextEditor.Undo;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// Describes the caret marker
/// </summary>
public enum LineViewerStyle {
/// <summary>
/// No line viewer will be displayed
/// </summary>
None,
/// <summary>
/// The row in which the caret is will be marked
/// </summary>
FullRow
}
/// <summary>
/// Describes the indent style
/// </summary>
public enum IndentStyle {
/// <summary>
/// No indentation occurs
/// </summary>
None,
/// <summary>
/// The indentation from the line above will be
/// taken to indent the curent line
/// </summary>
Auto,
/// <summary>
/// Inteligent, context sensitive indentation will occur
/// </summary>
Smart
}
/// <summary>
/// Describes the bracket highlighting style
/// </summary>
public enum BracketHighlightingStyle {
/// <summary>
/// Brackets won't be highlighted
/// </summary>
None,
/// <summary>
/// Brackets will be highlighted if the caret is on the bracket
/// </summary>
OnBracket,
/// <summary>
/// Brackets will be highlighted if the caret is after the bracket
/// </summary>
AfterBracket
}
/// <summary>
/// Describes the selection mode of the text area
/// </summary>
public enum DocumentSelectionMode {
/// <summary>
/// The 'normal' selection mode.
/// </summary>
Normal,
/// <summary>
/// Selections will be added to the current selection or new
/// ones will be created (multi-select mode)
/// </summary>
Additive
}
/// <summary>
/// The default <see cref="IDocument"/> implementation.
/// </summary>
internal sealed class DefaultDocument : IDocument
{
bool readOnly = false;
LineManager lineTrackingStrategy;
BookmarkManager bookmarkManager;
ITextBufferStrategy textBufferStrategy;
IFormattingStrategy formattingStrategy;
FoldingManager foldingManager;
UndoStack undoStack = new UndoStack();
ITextEditorProperties textEditorProperties = new DefaultTextEditorProperties();
MarkerStrategy markerStrategy;
public LineManager LineManager {
get { return lineTrackingStrategy; }
set { lineTrackingStrategy = value; }
}
public event EventHandler<LineLengthChangeEventArgs> LineLengthChanged {
add { lineTrackingStrategy.LineLengthChanged += value; }
remove { lineTrackingStrategy.LineLengthChanged -= value; }
}
public event EventHandler<LineCountChangeEventArgs> LineCountChanged {
add { lineTrackingStrategy.LineCountChanged += value; }
remove { lineTrackingStrategy.LineCountChanged -= value; }
}
public event EventHandler<LineEventArgs> LineDeleted {
add { lineTrackingStrategy.LineDeleted += value; }
remove { lineTrackingStrategy.LineDeleted -= value; }
}
public MarkerStrategy MarkerStrategy {
get { return markerStrategy; }
set { markerStrategy = value; }
}
public ITextEditorProperties TextEditorProperties {
get {
return textEditorProperties;
}
set {
textEditorProperties = value;
}
}
public UndoStack UndoStack {
get {
return undoStack;
}
}
public IList<LineSegment> LineSegmentCollection {
get {
return lineTrackingStrategy.LineSegmentCollection;
}
}
public bool ReadOnly {
get {
return readOnly;
}
set {
readOnly = value;
}
}
public ITextBufferStrategy TextBufferStrategy {
get {
return textBufferStrategy;
}
set {
textBufferStrategy = value;
}
}
public IFormattingStrategy FormattingStrategy {
get {
return formattingStrategy;
}
set {
formattingStrategy = value;
}
}
public FoldingManager FoldingManager {
get {
return foldingManager;
}
set {
foldingManager = value;
}
}
public IHighlightingStrategy HighlightingStrategy {
get {
return lineTrackingStrategy.HighlightingStrategy;
}
set {
lineTrackingStrategy.HighlightingStrategy = value;
}
}
public int TextLength {
get {
return textBufferStrategy.Length;
}
}
public BookmarkManager BookmarkManager {
get {
return bookmarkManager;
}
set {
bookmarkManager = value;
}
}
public string TextContent {
get {
return GetText(0, textBufferStrategy.Length);
}
set {
Debug.Assert(textBufferStrategy != null);
Debug.Assert(lineTrackingStrategy != null);
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, 0, 0, value));
textBufferStrategy.SetContent(value);
lineTrackingStrategy.SetContent(value);
undoStack.ClearAll();
OnDocumentChanged(new DocumentEventArgs(this, 0, 0, value));
OnTextContentChanged(EventArgs.Empty);
}
}
public void Insert(int offset, string text)
{
if (readOnly) {
return;
}
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, offset, -1, text));
textBufferStrategy.Insert(offset, text);
lineTrackingStrategy.Insert(offset, text);
undoStack.Push(new UndoableInsert(this, offset, text));
OnDocumentChanged(new DocumentEventArgs(this, offset, -1, text));
}
public void Remove(int offset, int length)
{
if (readOnly) {
return;
}
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, offset, length));
undoStack.Push(new UndoableDelete(this, offset, GetText(offset, length)));
textBufferStrategy.Remove(offset, length);
lineTrackingStrategy.Remove(offset, length);
OnDocumentChanged(new DocumentEventArgs(this, offset, length));
}
public void Replace(int offset, int length, string text)
{
if (readOnly) {
return;
}
OnDocumentAboutToBeChanged(new DocumentEventArgs(this, offset, length, text));
undoStack.Push(new UndoableReplace(this, offset, GetText(offset, length), text));
textBufferStrategy.Replace(offset, length, text);
lineTrackingStrategy.Replace(offset, length, text);
OnDocumentChanged(new DocumentEventArgs(this, offset, length, text));
}
public char GetCharAt(int offset)
{
return textBufferStrategy.GetCharAt(offset);
}
public string GetText(int offset, int length)
{
#if DEBUG
if (length < 0) throw new ArgumentOutOfRangeException("length", length, "length < 0");
#endif
return textBufferStrategy.GetText(offset, length);
}
public string GetText(ISegment segment)
{
return GetText(segment.Offset, segment.Length);
}
public int TotalNumberOfLines {
get {
return lineTrackingStrategy.TotalNumberOfLines;
}
}
public int GetLineNumberForOffset(int offset)
{
return lineTrackingStrategy.GetLineNumberForOffset(offset);
}
public LineSegment GetLineSegmentForOffset(int offset)
{
return lineTrackingStrategy.GetLineSegmentForOffset(offset);
}
public LineSegment GetLineSegment(int line)
{
return lineTrackingStrategy.GetLineSegment(line);
}
public int GetFirstLogicalLine(int lineNumber)
{
return lineTrackingStrategy.GetFirstLogicalLine(lineNumber);
}
public int GetLastLogicalLine(int lineNumber)
{
return lineTrackingStrategy.GetLastLogicalLine(lineNumber);
}
public int GetVisibleLine(int lineNumber)
{
return lineTrackingStrategy.GetVisibleLine(lineNumber);
}
// public int GetVisibleColumn(int logicalLine, int logicalColumn)
// {
// return lineTrackingStrategy.GetVisibleColumn(logicalLine, logicalColumn);
// }
//
public int GetNextVisibleLineAbove(int lineNumber, int lineCount)
{
return lineTrackingStrategy.GetNextVisibleLineAbove(lineNumber, lineCount);
}
public int GetNextVisibleLineBelow(int lineNumber, int lineCount)
{
return lineTrackingStrategy.GetNextVisibleLineBelow(lineNumber, lineCount);
}
public TextLocation OffsetToPosition(int offset)
{
int lineNr = GetLineNumberForOffset(offset);
LineSegment line = GetLineSegment(lineNr);
return new TextLocation(offset - line.Offset, lineNr);
}
public int PositionToOffset(TextLocation p)
{
if (p.Y >= this.TotalNumberOfLines) {
return 0;
}
LineSegment line = GetLineSegment(p.Y);
return Math.Min(this.TextLength, line.Offset + Math.Min(line.Length, p.X));
}
public void UpdateSegmentListOnDocumentChange<T>(List<T> list, DocumentEventArgs e) where T : ISegment
{
int removedCharacters = e.Length > 0 ? e.Length : 0;
int insertedCharacters = e.Text != null ? e.Text.Length : 0;
for (int i = 0; i < list.Count; ++i) {
ISegment s = list[i];
int segmentStart = s.Offset;
int segmentEnd = s.Offset + s.Length;
if (e.Offset <= segmentStart) {
segmentStart -= removedCharacters;
if (segmentStart < e.Offset)
segmentStart = e.Offset;
}
if (e.Offset < segmentEnd) {
segmentEnd -= removedCharacters;
if (segmentEnd < e.Offset)
segmentEnd = e.Offset;
}
Debug.Assert(segmentStart <= segmentEnd);
if (segmentStart == segmentEnd) {
list.RemoveAt(i);
--i;
continue;
}
if (e.Offset <= segmentStart)
segmentStart += insertedCharacters;
if (e.Offset < segmentEnd)
segmentEnd += insertedCharacters;
Debug.Assert(segmentStart < segmentEnd);
s.Offset = segmentStart;
s.Length = segmentEnd - segmentStart;
}
}
void OnDocumentAboutToBeChanged(DocumentEventArgs e)
{
if (DocumentAboutToBeChanged != null) {
DocumentAboutToBeChanged(this, e);
}
}
void OnDocumentChanged(DocumentEventArgs e)
{
if (DocumentChanged != null) {
DocumentChanged(this, e);
}
}
public event DocumentEventHandler DocumentAboutToBeChanged;
public event DocumentEventHandler DocumentChanged;
// UPDATE STUFF
List<TextAreaUpdate> updateQueue = new List<TextAreaUpdate>();
public List<TextAreaUpdate> UpdateQueue {
get {
return updateQueue;
}
}
public void RequestUpdate(TextAreaUpdate update)
{
if (updateQueue.Count == 1 && updateQueue[0].TextAreaUpdateType == TextAreaUpdateType.WholeTextArea) {
// if we're going to update the whole text area, we don't need to store detail updates
return;
}
if (update.TextAreaUpdateType == TextAreaUpdateType.WholeTextArea) {
// if we're going to update the whole text area, we don't need to store detail updates
updateQueue.Clear();
}
updateQueue.Add(update);
}
public void CommitUpdate()
{
if (UpdateCommited != null) {
UpdateCommited(this, EventArgs.Empty);
}
}
void OnTextContentChanged(EventArgs e)
{
if (TextContentChanged != null) {
TextContentChanged(this, e);
}
}
public event EventHandler UpdateCommited;
public event EventHandler TextContentChanged;
[Conditional("DEBUG")]
internal static void ValidatePosition(IDocument document, TextLocation position)
{
document.GetLineSegment(position.Line);
}
}
}

View File

@@ -0,0 +1,321 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="none" email=""/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public enum BracketMatchingStyle {
Before,
After
}
public class DefaultTextEditorProperties : ITextEditorProperties
{
int tabIndent = 4;
int indentationSize = 4;
IndentStyle indentStyle = IndentStyle.Smart;
DocumentSelectionMode documentSelectionMode = DocumentSelectionMode.Normal;
Encoding encoding = System.Text.Encoding.UTF8;
BracketMatchingStyle bracketMatchingStyle = BracketMatchingStyle.After;
FontContainer fontContainer;
static Font DefaultFont;
public DefaultTextEditorProperties()
{
if (DefaultFont == null) {
DefaultFont = new Font("Courier New", 10);
}
this.fontContainer = new FontContainer(DefaultFont);
}
bool allowCaretBeyondEOL = false;
bool caretLine = false;
bool showMatchingBracket = true;
bool showLineNumbers = true;
bool showSpaces = false;
bool showTabs = false;
bool showEOLMarker = false;
bool showInvalidLines = false;
bool isIconBarVisible = false;
bool enableFolding = true;
bool showHorizontalRuler = false;
bool showVerticalRuler = true;
bool convertTabsToSpaces = false;
System.Drawing.Text.TextRenderingHint textRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
bool mouseWheelScrollDown = true;
bool mouseWheelTextZoom = true;
bool hideMouseCursor = false;
bool cutCopyWholeLine = true;
int verticalRulerRow = 80;
LineViewerStyle lineViewerStyle = LineViewerStyle.None;
string lineTerminator = "\r\n";
bool autoInsertCurlyBracket = true;
bool supportReadOnlySegments = false;
public int TabIndent {
get {
return tabIndent;
}
set {
tabIndent = value;
}
}
public int IndentationSize {
get { return indentationSize; }
set { indentationSize = value; }
}
public IndentStyle IndentStyle {
get {
return indentStyle;
}
set {
indentStyle = value;
}
}
public bool CaretLine {
get
{
return caretLine;
}
set
{
caretLine = value;
}
}
public DocumentSelectionMode DocumentSelectionMode {
get {
return documentSelectionMode;
}
set {
documentSelectionMode = value;
}
}
public bool AllowCaretBeyondEOL {
get {
return allowCaretBeyondEOL;
}
set {
allowCaretBeyondEOL = value;
}
}
public bool ShowMatchingBracket {
get {
return showMatchingBracket;
}
set {
showMatchingBracket = value;
}
}
public bool ShowLineNumbers {
get {
return showLineNumbers;
}
set {
showLineNumbers = value;
}
}
public bool ShowSpaces {
get {
return showSpaces;
}
set {
showSpaces = value;
}
}
public bool ShowTabs {
get {
return showTabs;
}
set {
showTabs = value;
}
}
public bool ShowEOLMarker {
get {
return showEOLMarker;
}
set {
showEOLMarker = value;
}
}
public bool ShowInvalidLines {
get {
return showInvalidLines;
}
set {
showInvalidLines = value;
}
}
public bool IsIconBarVisible {
get {
return isIconBarVisible;
}
set {
isIconBarVisible = value;
}
}
public bool EnableFolding {
get {
return enableFolding;
}
set {
enableFolding = value;
}
}
public bool ShowHorizontalRuler {
get {
return showHorizontalRuler;
}
set {
showHorizontalRuler = value;
}
}
public bool ShowVerticalRuler {
get {
return showVerticalRuler;
}
set {
showVerticalRuler = value;
}
}
public bool ConvertTabsToSpaces {
get {
return convertTabsToSpaces;
}
set {
convertTabsToSpaces = value;
}
}
public System.Drawing.Text.TextRenderingHint TextRenderingHint {
get { return textRenderingHint; }
set { textRenderingHint = value; }
}
public bool MouseWheelScrollDown {
get {
return mouseWheelScrollDown;
}
set {
mouseWheelScrollDown = value;
}
}
public bool MouseWheelTextZoom {
get {
return mouseWheelTextZoom;
}
set {
mouseWheelTextZoom = value;
}
}
public bool HideMouseCursor {
get {
return hideMouseCursor;
}
set {
hideMouseCursor = value;
}
}
public bool CutCopyWholeLine {
get {
return cutCopyWholeLine;
}
set {
cutCopyWholeLine = value;
}
}
public Encoding Encoding {
get {
return encoding;
}
set {
encoding = value;
}
}
public int VerticalRulerRow {
get {
return verticalRulerRow;
}
set {
verticalRulerRow = value;
}
}
public LineViewerStyle LineViewerStyle {
get {
return lineViewerStyle;
}
set {
lineViewerStyle = value;
}
}
public string LineTerminator {
get {
return lineTerminator;
}
set {
lineTerminator = value;
}
}
public bool AutoInsertCurlyBracket {
get {
return autoInsertCurlyBracket;
}
set {
autoInsertCurlyBracket = value;
}
}
public Font Font {
get {
return fontContainer.DefaultFont;
}
set {
fontContainer.DefaultFont = value;
}
}
public FontContainer FontContainer {
get {
return fontContainer;
}
}
public BracketMatchingStyle BracketMatchingStyle {
get {
return bracketMatchingStyle;
}
set {
bracketMatchingStyle = value;
}
}
public bool SupportReadOnlySegments {
get {
return supportReadOnlySegments;
}
set {
supportReadOnlySegments = value;
}
}
}
}

View File

@@ -0,0 +1,103 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This delegate is used for document events.
/// </summary>
public delegate void DocumentEventHandler(object sender, DocumentEventArgs e);
/// <summary>
/// This class contains more information on a document event
/// </summary>
public class DocumentEventArgs : EventArgs
{
IDocument document;
int offset;
int length;
string text;
/// <returns>
/// always a valid Document which is related to the Event.
/// </returns>
public IDocument Document {
get {
return document;
}
}
/// <returns>
/// -1 if no offset was specified for this event
/// </returns>
public int Offset {
get {
return offset;
}
}
/// <returns>
/// null if no text was specified for this event
/// </returns>
public string Text {
get {
return text;
}
}
/// <returns>
/// -1 if no length was specified for this event
/// </returns>
public int Length {
get {
return length;
}
}
/// <summary>
/// Creates a new instance off <see cref="DocumentEventArgs"/>
/// </summary>
public DocumentEventArgs(IDocument document) : this(document, -1, -1, null)
{
}
/// <summary>
/// Creates a new instance off <see cref="DocumentEventArgs"/>
/// </summary>
public DocumentEventArgs(IDocument document, int offset) : this(document, offset, -1, null)
{
}
/// <summary>
/// Creates a new instance off <see cref="DocumentEventArgs"/>
/// </summary>
public DocumentEventArgs(IDocument document, int offset, int length) : this(document, offset, length, null)
{
}
/// <summary>
/// Creates a new instance off <see cref="DocumentEventArgs"/>
/// </summary>
public DocumentEventArgs(IDocument document, int offset, int length, string text)
{
this.document = document;
this.offset = offset;
this.length = length;
this.text = text;
}
public override string ToString()
{
return string.Format("[DocumentEventArgs: Document = {0}, Offset = {1}, Text = {2}, Length = {3}]",
Document,
Offset,
Text,
Length);
}
}
}

View File

@@ -0,0 +1,57 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This interface represents a container which holds a text sequence and
/// all necessary information about it. It is used as the base for a text editor.
/// </summary>
public class DocumentFactory
{
/// <remarks>
/// Creates a new <see cref="IDocument"/> object. Only create
/// <see cref="IDocument"/> with this method.
/// </remarks>
public IDocument CreateDocument()
{
DefaultDocument doc = new DefaultDocument();
doc.TextBufferStrategy = new GapTextBufferStrategy();
doc.FormattingStrategy = new DefaultFormattingStrategy();
doc.LineManager = new LineManager(doc, null);
doc.FoldingManager = new FoldingManager(doc, doc.LineManager);
doc.FoldingManager.FoldingStrategy = null; //new ParserFoldingStrategy();
doc.MarkerStrategy = new MarkerStrategy(doc);
doc.BookmarkManager = new BookmarkManager(doc, doc.LineManager);
return doc;
}
/// <summary>
/// Creates a new document and loads the given file
/// </summary>
public IDocument CreateFromTextBuffer(ITextBufferStrategy textBuffer)
{
DefaultDocument doc = (DefaultDocument)CreateDocument();
doc.TextContent = textBuffer.GetText(0, textBuffer.Length);
doc.TextBufferStrategy = textBuffer;
return doc;
}
/// <summary>
/// Creates a new document and loads the given file
/// </summary>
public IDocument CreateFromFile(string fileName)
{
IDocument document = CreateDocument();
document.TextContent = Util.FileReader.ReadFileContent(fileName, Encoding.Default);
return document;
}
}
}

View File

@@ -0,0 +1,107 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This file is part of CodingEditor.
// Note: This project is derived from Peter Project
// (hosted on sourceforge and codeplex)
//
// Copyright (c) 2008-2009, CE Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System.Collections.Generic;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Src.Document.FoldingStrategy
{
public class CSharpFoldingStrategy : IFoldingStrategy
{
#region Methods
/// <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)
{
var list = new List<FoldMarker>();
var startLines = new Stack<int>();
// Create foldmarkers for the whole document, enumerate through every line.
for (int i = 0; i < document.TotalNumberOfLines; i++)
{
var seg = document.GetLineSegment(i);
int offs, end = document.TextLength;
char c;
for (offs = seg.Offset; offs < end && ((c = document.GetCharAt(offs)) == ' ' || c == '\t'); offs++)
{
}
if (offs == end)
break;
int spaceCount = offs - seg.Offset;
// now offs points to the first non-whitespace char on the line
if (document.GetCharAt(offs) == '#')
{
string text = document.GetText(offs, seg.Length - spaceCount);
if (text.StartsWith("#region"))
startLines.Push(i);
if (text.StartsWith("#endregion") && startLines.Count > 0)
{
// Add a new FoldMarker to the list.
int start = startLines.Pop();
list.Add(new FoldMarker(document, start,
document.GetLineSegment(start).Length,
i, spaceCount + "#endregion".Length, FoldType.Region, "{...}"));
}
}
// { }
if (document.GetCharAt(offs) == '{')
{
int offsetOfClosingBracket = document.FormattingStrategy.SearchBracketForward(document, offs + 1, '{', '}');
if (offsetOfClosingBracket > 0)
{
int length = offsetOfClosingBracket - offs + 1;
list.Add(new FoldMarker(document, offs, length, "{...}", false));
}
}
if (document.GetCharAt(offs) == '/')
{
string text = document.GetText(offs, seg.Length - spaceCount);
if (text.StartsWith("/// <summary>"))
startLines.Push(i);
if ((text.StartsWith("/// <param") || text.StartsWith("/// <returns>") || text.StartsWith("/// </summary>"))
&& startLines.Count > 0)
{
// Add a new FoldMarker to the list.
int start = startLines.Pop();
list.Add(new FoldMarker(document, start,
document.GetLineSegment(start).Length,
i, spaceCount + "/// </summary>".Length, FoldType.TypeBody, "/// <summary>..."));
}
}
}
return list;
}
#endregion Methods
}
}

View File

@@ -0,0 +1,174 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
public enum FoldType {
Unspecified,
MemberBody,
Region,
TypeBody
}
public class FoldMarker : AbstractSegment, IComparable
{
bool isFolded = false;
string foldText = "...";
FoldType foldType = FoldType.Unspecified;
IDocument document = null;
int startLine = -1, startColumn, endLine = -1, endColumn;
static void GetPointForOffset(IDocument document, int offset, out int line, out int column)
{
if (offset > document.TextLength) {
line = document.TotalNumberOfLines + 1;
column = 1;
} else if (offset < 0) {
line = -1;
column = -1;
} else {
line = document.GetLineNumberForOffset(offset);
column = offset - document.GetLineSegment(line).Offset;
}
}
public FoldType FoldType {
get { return foldType; }
set { foldType = value; }
}
public int StartLine {
get {
if (startLine < 0) {
GetPointForOffset(document, offset, out startLine, out startColumn);
}
return startLine;
}
}
public int StartColumn {
get {
if (startLine < 0) {
GetPointForOffset(document, offset, out startLine, out startColumn);
}
return startColumn;
}
}
public int EndLine {
get {
if (endLine < 0) {
GetPointForOffset(document, offset + length, out endLine, out endColumn);
}
return endLine;
}
}
public int EndColumn {
get {
if (endLine < 0) {
GetPointForOffset(document, offset + length, out endLine, out endColumn);
}
return endColumn;
}
}
public override int Offset {
get { return base.Offset; }
set {
base.Offset = value;
startLine = -1; endLine = -1;
}
}
public override int Length {
get { return base.Length; }
set {
base.Length = value;
endLine = -1;
}
}
public bool IsFolded {
get {
return isFolded;
}
set {
isFolded = value;
}
}
public string FoldText {
get {
return foldText;
}
}
public string InnerText {
get {
return document.GetText(offset, length);
}
}
public FoldMarker(IDocument document, int offset, int length, string foldText, bool isFolded)
{
this.document = document;
this.offset = offset;
this.length = length;
this.foldText = foldText;
this.isFolded = isFolded;
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn) : this(document, startLine, startColumn, endLine, endColumn, FoldType.Unspecified)
{
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType) : this(document, startLine, startColumn, endLine, endColumn, foldType, "...")
{
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType, string foldText) : this(document, startLine, startColumn, endLine, endColumn, foldType, foldText, false)
{
}
public FoldMarker(IDocument document, int startLine, int startColumn, int endLine, int endColumn, FoldType foldType, string foldText, bool isFolded)
{
this.document = document;
startLine = Math.Min(document.TotalNumberOfLines - 1, Math.Max(startLine, 0));
ISegment startLineSegment = document.GetLineSegment(startLine);
endLine = Math.Min(document.TotalNumberOfLines - 1, Math.Max(endLine, 0));
ISegment endLineSegment = document.GetLineSegment(endLine);
// Prevent the region from completely disappearing
if (string.IsNullOrEmpty(foldText)) {
foldText = "...";
}
this.FoldType = foldType;
this.foldText = foldText;
this.offset = startLineSegment.Offset + Math.Min(startColumn, startLineSegment.Length);
this.length = (endLineSegment.Offset + Math.Min(endColumn, endLineSegment.Length)) - this.offset;
this.isFolded = isFolded;
}
public int CompareTo(object o)
{
if (!(o is FoldMarker)) {
throw new ArgumentException();
}
FoldMarker f = (FoldMarker)o;
if (offset != f.offset) {
return offset.CompareTo(f.offset);
}
return length.CompareTo(f.length);
}
}
}

View File

@@ -0,0 +1,362 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public class FoldingManager
{
List<FoldMarker> foldMarker = new List<FoldMarker>();
List<FoldMarker> foldMarkerByEnd = new List<FoldMarker>();
IDocument document;
public IList<FoldMarker> FoldMarker => foldMarker.AsReadOnly();
public IFoldingStrategy? FoldingStrategy { get; set; }
internal FoldingManager(IDocument document, LineManager lineTracker)
{
this.document = document;
document.DocumentChanged += new DocumentEventHandler(DocumentChanged);
// lineTracker.LineCountChanged += new LineManagerEventHandler(LineManagerLineCountChanged);
// lineTracker.LineLengthChanged += new LineLengthEventHandler(LineManagerLineLengthChanged);
// foldMarker.Add(new FoldMarker(0, 5, 3, 5));
//
// foldMarker.Add(new FoldMarker(5, 5, 10, 3));
// foldMarker.Add(new FoldMarker(6, 0, 8, 2));
//
// FoldMarker fm1 = new FoldMarker(10, 4, 10, 7);
// FoldMarker fm2 = new FoldMarker(10, 10, 10, 14);
//
// fm1.IsFolded = true;
// fm2.IsFolded = true;
//
// foldMarker.Add(fm1);
// foldMarker.Add(fm2);
// foldMarker.Sort();
}
void DocumentChanged(object sender, DocumentEventArgs e)
{
int oldCount = foldMarker.Count;
document.UpdateSegmentListOnDocumentChange(foldMarker, e);
if (oldCount != foldMarker.Count)
{
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
}
}
public List<FoldMarker> GetFoldingsFromPosition(int line, int column)
{
List<FoldMarker> foldings = new List<FoldMarker>();
if (foldMarker != null)
{
for (int i = 0; i < foldMarker.Count; ++i)
{
FoldMarker fm = foldMarker[i];
if ((fm.StartLine == line && column > fm.StartColumn && !(fm.EndLine == line && column >= fm.EndColumn)) ||
(fm.EndLine == line && column < fm.EndColumn && !(fm.StartLine == line && column <= fm.StartColumn)) ||
(line > fm.StartLine && line < fm.EndLine))
{
foldings.Add(fm);
}
}
}
return foldings;
}
class StartComparer : IComparer<FoldMarker>
{
public readonly static StartComparer Instance = new StartComparer();
public int Compare(FoldMarker x, FoldMarker y)
{
if (x.StartLine < y.StartLine)
return -1;
else if (x.StartLine == y.StartLine)
return x.StartColumn.CompareTo(y.StartColumn);
else
return 1;
}
}
class EndComparer : IComparer<FoldMarker>
{
public readonly static EndComparer Instance = new EndComparer();
public int Compare(FoldMarker x, FoldMarker y)
{
if (x.EndLine < y.EndLine)
return -1;
else if (x.EndLine == y.EndLine)
return x.EndColumn.CompareTo(y.EndColumn);
else
return 1;
}
}
List<FoldMarker> GetFoldingsByStartAfterColumn(int lineNumber, int column, bool forceFolded)
{
List<FoldMarker> foldings = new List<FoldMarker>();
if (foldMarker != null)
{
int index = foldMarker.BinarySearch(
new FoldMarker(document, lineNumber, column, lineNumber, column),
StartComparer.Instance);
if (index < 0) index = ~index;
for (; index < foldMarker.Count; index++)
{
FoldMarker fm = foldMarker[index];
if (fm.StartLine > lineNumber)
break;
if (fm.StartColumn <= column)
continue;
if (!forceFolded || fm.IsFolded)
foldings.Add(fm);
}
}
return foldings;
}
public List<FoldMarker> GetFoldingsWithStart(int lineNumber)
{
return GetFoldingsByStartAfterColumn(lineNumber, -1, false);
}
public List<FoldMarker> GetFoldedFoldingsWithStart(int lineNumber)
{
return GetFoldingsByStartAfterColumn(lineNumber, -1, true);
}
public List<FoldMarker> GetFoldedFoldingsWithStartAfterColumn(int lineNumber, int column)
{
return GetFoldingsByStartAfterColumn(lineNumber, column, true);
}
List<FoldMarker> GetFoldingsByEndAfterColumn(int lineNumber, int column, bool forceFolded)
{
List<FoldMarker> foldings = new List<FoldMarker>();
if (foldMarker != null)
{
int index = foldMarkerByEnd.BinarySearch(
new FoldMarker(document, lineNumber, column, lineNumber, column),
EndComparer.Instance);
if (index < 0) index = ~index;
for (; index < foldMarkerByEnd.Count; index++)
{
FoldMarker fm = foldMarkerByEnd[index];
if (fm.EndLine > lineNumber)
break;
if (fm.EndColumn <= column)
continue;
if (!forceFolded || fm.IsFolded)
foldings.Add(fm);
}
}
return foldings;
}
public List<FoldMarker> GetFoldingsWithEnd(int lineNumber)
{
return GetFoldingsByEndAfterColumn(lineNumber, -1, false);
}
public List<FoldMarker> GetFoldedFoldingsWithEnd(int lineNumber)
{
return GetFoldingsByEndAfterColumn(lineNumber, -1, true);
}
public bool IsFoldStart(int lineNumber)
{
return GetFoldingsWithStart(lineNumber).Count > 0;
}
public bool IsFoldEnd(int lineNumber)
{
return GetFoldingsWithEnd(lineNumber).Count > 0;
}
public List<FoldMarker> GetFoldingsContainsLineNumber(int lineNumber)
{
List<FoldMarker> foldings = new List<FoldMarker>();
if (foldMarker != null)
{
foreach (FoldMarker fm in foldMarker)
{
if (fm.StartLine < lineNumber && lineNumber < fm.EndLine)
{
foldings.Add(fm);
}
}
}
return foldings;
}
public bool IsBetweenFolding(int lineNumber)
{
return GetFoldingsContainsLineNumber(lineNumber).Count > 0;
}
public bool IsLineVisible(int lineNumber)
{
foreach (FoldMarker fm in GetFoldingsContainsLineNumber(lineNumber))
{
if (fm.IsFolded)
return false;
}
return true;
}
public List<FoldMarker> GetTopLevelFoldedFoldings()
{
List<FoldMarker> foldings = new List<FoldMarker>();
if (foldMarker != null)
{
Point end = new Point(0, 0);
foreach (FoldMarker fm in foldMarker)
{
if (fm.IsFolded && (fm.StartLine > end.Y || fm.StartLine == end.Y && fm.StartColumn >= end.X))
{
foldings.Add(fm);
end = new Point(fm.EndColumn, fm.EndLine);
}
}
}
return foldings;
}
public void UpdateFoldings(string fileName, object parseInfo)
{
UpdateFoldings(FoldingStrategy?.GenerateFoldMarkers(document, fileName, parseInfo));
}
public void UpdateFoldings(List<FoldMarker> newFoldings)
{
int oldFoldingsCount = foldMarker.Count;
lock (this)
{
if (newFoldings != null && newFoldings.Count != 0)
{
newFoldings.Sort();
if (foldMarker.Count == newFoldings.Count)
{
for (int i = 0; i < foldMarker.Count; ++i)
{
newFoldings[i].IsFolded = foldMarker[i].IsFolded;
}
foldMarker = newFoldings;
}
else
{
for (int i = 0, j = 0; i < foldMarker.Count && j < newFoldings.Count;)
{
int n = newFoldings[j].CompareTo(foldMarker[i]);
if (n > 0)
{
++i;
}
else
{
if (n == 0)
{
newFoldings[j].IsFolded = foldMarker[i].IsFolded;
}
++j;
}
}
}
}
if (newFoldings != null)
{
foldMarker = newFoldings;
foldMarkerByEnd = new List<FoldMarker>(newFoldings);
foldMarkerByEnd.Sort(EndComparer.Instance);
}
else
{
foldMarker.Clear();
foldMarkerByEnd.Clear();
}
}
if (oldFoldingsCount != foldMarker.Count)
{
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
document.CommitUpdate();
}
}
public string SerializeToString()
{
StringBuilder sb = new StringBuilder();
foreach (FoldMarker marker in this.foldMarker)
{
sb.Append(marker.Offset); sb.Append("\n");
sb.Append(marker.Length); sb.Append("\n");
sb.Append(marker.FoldText); sb.Append("\n");
sb.Append(marker.IsFolded); sb.Append("\n");
}
return sb.ToString();
}
public void DeserializeFromString(string str)
{
try
{
string[] lines = str.Split('\n');
for (int i = 0; i < lines.Length && lines[i].Length > 0; i += 4)
{
int offset = int.Parse(lines[i]);
int length = int.Parse(lines[i + 1]);
string text = lines[i + 2];
bool isFolded = bool.Parse(lines[i + 3]);
bool found = false;
foreach (FoldMarker marker in foldMarker)
{
if (marker.Offset == offset && marker.Length == length)
{
marker.IsFolded = isFolded;
found = true;
break;
}
}
if (!found)
{
foldMarker.Add(new FoldMarker(document, offset, length, text, isFolded));
}
}
if (lines.Length > 0)
{
NotifyFoldingsChanged(EventArgs.Empty);
}
}
catch (Exception)
{
// Empty catch
}
}
public void NotifyFoldingsChanged(EventArgs e)
{
if (FoldingsChanged != null)
{
FoldingsChanged(this, e);
}
}
public event EventHandler FoldingsChanged;
}
}

View File

@@ -0,0 +1,24 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This interface is used for the folding capabilities
/// of the textarea.
/// </summary>
public interface IFoldingStrategy
{
/// <remarks>
/// Calculates the fold level of a specific line.
/// </remarks>
List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation);
}
}

View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Src.Document.FoldingStrategy
{
public interface IFoldingStrategyEx : IFoldingStrategy
{
List<string> GetFoldingErrors();
}
}

View File

@@ -0,0 +1,47 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// A simple folding strategy which calculates the folding level
/// using the indent level of the line.
/// </summary>
public class IndentFoldingStrategy : IFoldingStrategy
{
public List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
{
List<FoldMarker> l = new List<FoldMarker>();
Stack<int> offsetStack = new Stack<int>();
Stack<string> textStack = new Stack<string>();
//int level = 0;
//foreach (LineSegment segment in document.LineSegmentCollection) {
//
//}
return l;
}
int GetLevel(IDocument document, int offset)
{
int level = 0;
int spaces = 0;
for (int i = offset; i < document.TextLength; ++i) {
char c = document.GetCharAt(i);
if (c == '\t' || (c == ' ' && ++spaces == 4)) {
spaces = 0;
++level;
} else {
break;
}
}
return level;
}
}
}

View File

@@ -0,0 +1,129 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This file is part of CodingEditor.
// Note: This project is derived from Peter Project
// (hosted on sourceforge and codeplex)
//
// Copyright (c) 2008-2009, CE Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Src.Document.FoldingStrategy
{
public class JSONFoldingStrategy : IFoldingStrategy
{
#region Methods
/// <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)
{
var list = new List<FoldMarker>();
var startLines = new Stack<int>();
// Create foldmarkers for the whole document, enumerate through every line.
for (int i = 0; i < document.TotalNumberOfLines; i++)
{
var seg = document.GetLineSegment(i);
int offs, end = seg.Length + seg.Offset;
char c;
for (
offs = seg.Offset;
offs < end;
offs++)
{
c = document.GetCharAt(offs);
if (seg.Words.Any(w => w.IsDelimiter && w.Offset == offs - seg.Offset && w.Word == c.ToString()))
{
if (c == '{')
{
int offsetOfClosingBracket = SearchBracketForward(document, i, offs, '{', '}');
if (offsetOfClosingBracket > 0)
{
int length = offsetOfClosingBracket - offs + 1;
list.Add(new FoldMarker(document, offs, length, "{...}", false));
}
}
if (c == '[')
{
int offsetOfClosingBracket = SearchBracketForward(document, i, offs, '[', ']');
if (offsetOfClosingBracket > 0)
{
int length = offsetOfClosingBracket - offs + 1;
list.Add(new FoldMarker(document, offs, length, "[...]", false));
}
}
}
}
}
return list;
}
private int SearchBracketForward(IDocument document, int currLine, int currOffset, char openBracket, char closingBracket)
{
// Create foldmarkers for the whole document, enumerate through every line.
int brackets = 1, spaceCount = 0;
for (int i = currLine; i < document.TotalNumberOfLines; i++)
{
var seg = document.GetLineSegment(i);
int offs, end = seg.Length + seg.Offset;
char c;
for (
offs = i == currLine ? currOffset + 1 : seg.Offset;
offs < end;
offs++)
{
c = document.GetCharAt(offs);
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') spaceCount++;
if (seg.Words.Any(w => w.IsDelimiter && w.Offset == offs - seg.Offset && w.Word == c.ToString()))
{
if (c == openBracket)
{
++brackets;
}
else if (c == closingBracket)
{
--brackets;
if (brackets == 0)
{
if (offs - spaceCount - 1 == currOffset)
{
return -1;
}
return offs;
}
}
}
}
}
return -1;
}
#endregion Methods
}
}

View File

@@ -0,0 +1,310 @@
// Copied from http://codingeditor.googlecode.com/svn/trunk/libs/ICSharpCode.TextEditor/Project/Src/Document/FoldingStrategy/
#region Header
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision: 1971 $</version>
// </file>
#endregion Header
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Src.Document.FoldingStrategy
{
/// <summary>
/// Holds information about the start of a fold in an xml string.
/// </summary>
class XmlFoldStart
{
#region Fields
readonly int _col;
string _foldText = string.Empty;
readonly int _line;
readonly string _name = string.Empty;
readonly string _prefix = string.Empty;
#endregion Fields
#region Constructors
public XmlFoldStart(string prefix, string name, int line, int col)
{
_line = line;
_col = col;
_prefix = prefix;
_name = name;
}
#endregion Constructors
#region Properties
/// <summary>
/// The column where the fold should start. Columns start from 0.
/// </summary>
public int Column
{
get
{
return _col;
}
}
/// <summary>
/// The text to be displayed when the item is folded.
/// </summary>
public string FoldText
{
get
{
return _foldText;
}
set
{
_foldText = value;
}
}
/// <summary>
/// The line where the fold should start. Lines start from 0.
/// </summary>
public int Line
{
get
{
return _line;
}
}
/// <summary>
/// The name of the xml item with its prefix if it has one.
/// </summary>
public string Name
{
get
{
return _prefix.Length > 0 ? string.Concat(_prefix, ":", _name) : _name;
}
}
#endregion Properties
}
/// <summary>
/// Determines folds for an xml string in the editor.
/// </summary>
public class XmlFoldingStrategy : IFoldingStrategyEx
{
#region Fields
/// <summary>
/// Flag indicating whether attributes should be displayed on folded elements.
/// </summary>
public bool ShowAttributesWhenFolded = false;
private List<string> _foldingErrors = new List<string>();
#endregion Fields
#region Methods
public List<string> GetFoldingErrors()
{
return _foldingErrors;
}
/// <summary>
/// Adds folds to the text editor around each start-end element pair.
/// </summary>
/// <remarks>
/// <para>If the xml is not well formed then no folds are created.</para>
/// <para>Note that the xml text reader lines and positions start
/// from 1 and the SharpDevelop text editor line information starts from 0.</para>
/// </remarks>
public List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
{
_foldingErrors = new List<string>();
//showAttributesWhenFolded = XmlEditorAddInOptions.ShowAttributesWhenFolded;
var foldMarkers = new List<FoldMarker>();
var stack = new Stack();
try
{
string xml = document.TextContent;
var reader = new XmlTextReader(new StringReader(xml));
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (!reader.IsEmptyElement)
{
XmlFoldStart newFoldStart = CreateElementFoldStart(reader);
stack.Push(newFoldStart);
}
break;
case XmlNodeType.EndElement:
var foldStart = (XmlFoldStart)stack.Pop();
CreateElementFold(document, foldMarkers, reader, foldStart);
break;
case XmlNodeType.Comment:
CreateCommentFold(document, foldMarkers, reader);
break;
}
}
}
catch (Exception ex)
{
_foldingErrors.Add(ex.Message);
// If the xml is not well formed keep the foldings that already exist in the document.
return new List<FoldMarker>(document.FoldingManager.FoldMarker);
}
return foldMarkers;
}
/// <summary>
/// Xml encode the attribute string since the string returned from
/// the XmlTextReader is the plain unencoded string and .NET
/// does not provide us with an xml encode method.
/// </summary>
static string XmlEncodeAttributeValue(string attributeValue, char quoteChar)
{
var encodedValue = new StringBuilder(attributeValue);
encodedValue.Replace("&", "&amp;");
encodedValue.Replace("<", "&lt;");
encodedValue.Replace(">", "&gt;");
if (quoteChar == '"')
{
encodedValue.Replace("\"", "&quot;");
}
else
{
encodedValue.Replace("'", "&apos;");
}
return encodedValue.ToString();
}
/// <summary>
/// Creates a comment fold if the comment spans more than one line.
/// </summary>
/// <remarks>The text displayed when the comment is folded is the first
/// line of the comment.</remarks>
void CreateCommentFold(IDocument document, List<FoldMarker> foldMarkers, XmlTextReader reader)
{
if (reader.Value != null)
{
string comment = reader.Value.Replace("\r\n", "\n");
string[] lines = comment.Split('\n');
if (lines.Length > 1)
{
// Take off 5 chars to get the actual comment start (takes
// into account the <!-- chars.
int startCol = reader.LinePosition - 5;
int startLine = reader.LineNumber - 1;
// Add 3 to the end col value to take into account the '-->'
int endCol = lines[lines.Length - 1].Length + startCol + 3;
int endLine = startLine + lines.Length - 1;
string foldText = string.Concat("<!--", lines[0], "-->");
var foldMarker = new FoldMarker(document, startLine, startCol, endLine, endCol, FoldType.TypeBody, foldText);
foldMarkers.Add(foldMarker);
}
}
}
/// <summary>
/// Create an element fold if the start and end tag are on
/// different lines.
/// </summary>
void CreateElementFold(IDocument document, List<FoldMarker> foldMarkers, XmlTextReader reader, XmlFoldStart foldStart)
{
int endLine = reader.LineNumber - 1;
if (endLine > foldStart.Line)
{
int endCol = reader.LinePosition + foldStart.Name.Length;
var foldMarker = new FoldMarker(document, foldStart.Line, foldStart.Column, endLine, endCol, FoldType.TypeBody, foldStart.FoldText);
foldMarkers.Add(foldMarker);
}
}
/// <summary>
/// Creates an XmlFoldStart for the start tag of an element.
/// </summary>
XmlFoldStart CreateElementFoldStart(XmlTextReader reader)
{
// Take off 2 from the line position returned
// from the xml since it points to the start
// of the element name and not the beginning
// tag.
var newFoldStart = new XmlFoldStart(reader.Prefix, reader.LocalName, reader.LineNumber - 1, reader.LinePosition - 2);
if (ShowAttributesWhenFolded && reader.HasAttributes)
{
newFoldStart.FoldText = string.Concat("<", newFoldStart.Name, " ", GetAttributeFoldText(reader), ">");
}
else
{
newFoldStart.FoldText = string.Concat("<", newFoldStart.Name, ">");
}
return newFoldStart;
}
/// <summary>
/// Gets the element's attributes as a string on one line that will
/// be displayed when the element is folded.
/// </summary>
/// <remarks>
/// Currently this puts all attributes from an element on the same
/// line of the start tag. It does not cater for elements where attributes
/// are not on the same line as the start tag.
/// </remarks>
string GetAttributeFoldText(XmlTextReader reader)
{
var text = new StringBuilder();
for (int i = 0; i < reader.AttributeCount; ++i)
{
reader.MoveToAttribute(i);
text.Append(reader.Name);
text.Append("=");
text.Append(reader.QuoteChar.ToString(CultureInfo.InvariantCulture));
text.Append(XmlEncodeAttributeValue(reader.Value, reader.QuoteChar));
text.Append(reader.QuoteChar.ToString(CultureInfo.InvariantCulture));
// Append a space if this is not the
// last attribute.
if (i < reader.AttributeCount - 1)
{
text.Append(" ");
}
}
return text.ToString();
}
#endregion Methods
}
}

View File

@@ -0,0 +1,218 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This class handles the auto and smart indenting in the textbuffer while
/// you type.
/// </summary>
public class DefaultFormattingStrategy : IFormattingStrategy
{
/// <summary>
/// Creates a new instance off <see cref="DefaultFormattingStrategy"/>
/// </summary>
public DefaultFormattingStrategy()
{
}
/// <summary>
/// returns the whitespaces which are before a non white space character in the line line
/// as a string.
/// </summary>
protected string GetIndentation(TextArea textArea, int lineNumber)
{
if (lineNumber < 0 || lineNumber > textArea.Document.TotalNumberOfLines) {
throw new ArgumentOutOfRangeException("lineNumber");
}
string lineText = TextUtilities.GetLineAsString(textArea.Document, lineNumber);
StringBuilder whitespaces = new StringBuilder();
foreach (char ch in lineText) {
if (char.IsWhiteSpace(ch)) {
whitespaces.Append(ch);
} else {
break;
}
}
return whitespaces.ToString();
}
/// <summary>
/// Could be overwritten to define more complex indenting.
/// </summary>
protected virtual int AutoIndentLine(TextArea textArea, int lineNumber)
{
string indentation = lineNumber != 0 ? GetIndentation(textArea, lineNumber - 1) : "";
if(indentation.Length > 0) {
string newLineText = indentation + TextUtilities.GetLineAsString(textArea.Document, lineNumber).Trim();
LineSegment oldLine = textArea.Document.GetLineSegment(lineNumber);
SmartReplaceLine(textArea.Document, oldLine, newLineText);
}
return indentation.Length;
}
static readonly char[] whitespaceChars = {' ', '\t'};
/// <summary>
/// Replaces the text in a line.
/// If only whitespace at the beginning and end of the line was changed, this method
/// only adjusts the whitespace and doesn't replace the other text.
/// </summary>
public static void SmartReplaceLine(IDocument document, LineSegment line, string newLineText)
{
if (document == null)
throw new ArgumentNullException("document");
if (line == null)
throw new ArgumentNullException("line");
if (newLineText == null)
throw new ArgumentNullException("newLineText");
string newLineTextTrim = newLineText.Trim(whitespaceChars);
string oldLineText = document.GetText(line);
if (oldLineText == newLineText)
return;
int pos = oldLineText.IndexOf(newLineTextTrim);
if (newLineTextTrim.Length > 0 && pos >= 0) {
document.UndoStack.StartUndoGroup();
try {
// find whitespace at beginning
int startWhitespaceLength = 0;
while (startWhitespaceLength < newLineText.Length) {
char c = newLineText[startWhitespaceLength];
if (c != ' ' && c != '\t')
break;
startWhitespaceLength++;
}
// find whitespace at end
int endWhitespaceLength = newLineText.Length - newLineTextTrim.Length - startWhitespaceLength;
// replace whitespace sections
int lineOffset = line.Offset;
document.Replace(lineOffset + pos + newLineTextTrim.Length, line.Length - pos - newLineTextTrim.Length, newLineText.Substring(newLineText.Length - endWhitespaceLength));
document.Replace(lineOffset, pos, newLineText.Substring(0, startWhitespaceLength));
} finally {
document.UndoStack.EndUndoGroup();
}
} else {
document.Replace(line.Offset, line.Length, newLineText);
}
}
/// <summary>
/// Could be overwritten to define more complex indenting.
/// </summary>
protected virtual int SmartIndentLine(TextArea textArea, int line)
{
return AutoIndentLine(textArea, line); // smart = autoindent in normal texts
}
/// <summary>
/// This function formats a specific line after <code>ch</code> is pressed.
/// </summary>
/// <returns>
/// the caret delta position the caret will be moved this number
/// of bytes (e.g. the number of bytes inserted before the caret, or
/// removed, if this number is negative)
/// </returns>
public virtual void FormatLine(TextArea textArea, int line, int cursorOffset, char ch)
{
if (ch == '\n') {
textArea.Caret.Column = IndentLine(textArea, line);
}
}
/// <summary>
/// This function sets the indentation level in a specific line
/// </summary>
/// <returns>
/// the number of inserted characters.
/// </returns>
public int IndentLine(TextArea textArea, int line)
{
textArea.Document.UndoStack.StartUndoGroup();
int result;
switch (textArea.Document.TextEditorProperties.IndentStyle) {
case IndentStyle.None:
result = 0;
break;
case IndentStyle.Auto:
result = AutoIndentLine(textArea, line);
break;
case IndentStyle.Smart:
result = SmartIndentLine(textArea, line);
break;
default:
throw new NotSupportedException("Unsupported value for IndentStyle: " + textArea.Document.TextEditorProperties.IndentStyle);
}
textArea.Document.UndoStack.EndUndoGroup();
return result;
}
/// <summary>
/// This function sets the indentlevel in a range of lines.
/// </summary>
public virtual void IndentLines(TextArea textArea, int begin, int end)
{
textArea.Document.UndoStack.StartUndoGroup();
for (int i = begin; i <= end; ++i) {
IndentLine(textArea, i);
}
textArea.Document.UndoStack.EndUndoGroup();
}
public virtual int SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket)
{
int brackets = -1;
// first try "quick find" - find the matching bracket if there is no string/comment in the way
for (int i = offset; i >= 0; --i) {
char ch = document.GetCharAt(i);
if (ch == openBracket) {
++brackets;
if (brackets == 0) return i;
} else if (ch == closingBracket) {
--brackets;
} else if (ch == '"') {
break;
} else if (ch == '\'') {
break;
} else if (ch == '/' && i > 0) {
if (document.GetCharAt(i - 1) == '/') break;
if (document.GetCharAt(i - 1) == '*') break;
}
}
return -1;
}
public virtual int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket)
{
int brackets = 1;
// try "quick find" - find the matching bracket if there is no string/comment in the way
for (int i = offset; i < document.TextLength; ++i) {
char ch = document.GetCharAt(i);
if (ch == openBracket) {
++brackets;
} else if (ch == closingBracket) {
--brackets;
if (brackets == 0) return i;
} else if (ch == '"') {
break;
} else if (ch == '\'') {
break;
} else if (ch == '/' && i > 0) {
if (document.GetCharAt(i - 1) == '/') break;
} else if (ch == '*' && i > 0) {
if (document.GetCharAt(i - 1) == '/') break;
}
}
return -1;
}
}
}

View File

@@ -0,0 +1,59 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This interface handles the auto and smart indenting and formating
/// in the document while you type. Language bindings could overwrite this
/// interface and define their own indentation/formating.
/// </summary>
public interface IFormattingStrategy
{
/// <summary>
/// This function formats a specific line after <code>ch</code> is pressed.
/// </summary>
void FormatLine(TextArea textArea, int line, int caretOffset, char charTyped);
/// <summary>
/// This function sets the indentation level in a specific line
/// </summary>
/// <returns>
/// The target caret position (length of new indentation).
/// </returns>
int IndentLine(TextArea textArea, int line);
/// <summary>
/// This function sets the indentlevel in a range of lines.
/// </summary>
void IndentLines(TextArea textArea, int begin, int end);
/// <summary>
/// Finds the offset of the opening bracket in the block defined by offset skipping
/// brackets in strings and comments.
/// </summary>
/// <param name="document">The document to search in.</param>
/// <param name="offset">The offset of an position in the block or the offset of the closing bracket.</param>
/// <param name="openBracket">The character for the opening bracket.</param>
/// <param name="closingBracket">The character for the closing bracket.</param>
/// <returns>Returns the offset of the opening bracket or -1 if no matching bracket was found.</returns>
int SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket);
/// <summary>
/// Finds the offset of the closing bracket in the block defined by offset skipping
/// brackets in strings and comments.
/// </summary>
/// <param name="document">The document to search in.</param>
/// <param name="offset">The offset of an position in the block or the offset of the opening bracket.</param>
/// <param name="openBracket">The character for the opening bracket.</param>
/// <param name="closingBracket">The character for the closing bracket.</param>
/// <returns>Returns the offset of the closing bracket or -1 if no matching bracket was found.</returns>
int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket);
}
}

View File

@@ -0,0 +1,917 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace ICSharpCode.TextEditor.Document
{
public class DefaultHighlightingStrategy : IHighlightingStrategyUsingRuleSets
{
string name;
List<HighlightRuleSet> rules = new List<HighlightRuleSet>();
Dictionary<string, HighlightColor> environmentColors = new Dictionary<string, HighlightColor>();
Dictionary<string, string> properties = new Dictionary<string, string>();
string[] extensions;
HighlightColor digitColor;
HighlightRuleSet defaultRuleSet = null;
public HighlightColor DigitColor {
get {
return digitColor;
}
set {
digitColor = value;
}
}
public IEnumerable<KeyValuePair<string, HighlightColor>> EnvironmentColors {
get {
return environmentColors;
}
}
protected void ImportSettingsFrom(DefaultHighlightingStrategy source)
{
if (source == null)
throw new ArgumentNullException("source");
properties = source.properties;
extensions = source.extensions;
digitColor = source.digitColor;
defaultRuleSet = source.defaultRuleSet;
name = source.name;
rules = source.rules;
environmentColors = source.environmentColors;
defaultTextColor = source.defaultTextColor;
}
public DefaultHighlightingStrategy() : this("Default")
{
}
public DefaultHighlightingStrategy(string name)
{
this.name = name;
digitColor = new HighlightColor(SystemColors.WindowText, false, false);
defaultTextColor = new HighlightColor(SystemColors.WindowText, false, false);
// set small 'default color environment'
environmentColors["Default"] = new HighlightBackground("WindowText", "Window", false, false);
environmentColors["Selection"] = new HighlightColor("HighlightText", "Highlight", false, false);
environmentColors["VRuler"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["InvalidLines"] = new HighlightColor(Color.Red, false, false);
environmentColors["CaretMarker"] = new HighlightColor(Color.Yellow, false, false);
environmentColors["CaretLine"] = new HighlightBackground("ControlLight", "Window", false, false);
environmentColors["LineNumbers"] = new HighlightBackground("ControlDark", "Window", false, false);
environmentColors["FoldLine"] = new HighlightColor("ControlDark", false, false);
environmentColors["FoldMarker"] = new HighlightColor("WindowText", "Window", false, false);
environmentColors["SelectedFoldLine"] = new HighlightColor("WindowText", false, false);
environmentColors["EOLMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["SpaceMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
environmentColors["TabMarkers"] = new HighlightColor("ControlLight", "Window", false, false);
}
public Dictionary<string, string> Properties {
get {
return properties;
}
}
public string Name
{
get {
return name;
}
}
public string[] Extensions
{
set {
extensions = value;
}
get {
return extensions;
}
}
public List<HighlightRuleSet> Rules {
get {
return rules;
}
}
public HighlightRuleSet FindHighlightRuleSet(string name)
{
foreach(HighlightRuleSet ruleSet in rules) {
if (ruleSet.Name == name) {
return ruleSet;
}
}
return null;
}
public void AddRuleSet(HighlightRuleSet aRuleSet)
{
HighlightRuleSet existing = FindHighlightRuleSet(aRuleSet.Name);
if (existing != null) {
existing.MergeFrom(aRuleSet);
} else {
rules.Add(aRuleSet);
}
}
public void ResolveReferences()
{
// Resolve references from Span definitions to RuleSets
ResolveRuleSetReferences();
// Resolve references from RuleSet defintitions to Highlighters defined in an external mode file
ResolveExternalReferences();
}
void ResolveRuleSetReferences()
{
foreach (HighlightRuleSet ruleSet in Rules) {
if (ruleSet.Name == null) {
defaultRuleSet = ruleSet;
}
foreach (Span aSpan in ruleSet.Spans) {
if (aSpan.Rule != null) {
bool found = false;
foreach (HighlightRuleSet refSet in Rules) {
if (refSet.Name == aSpan.Rule) {
found = true;
aSpan.RuleSet = refSet;
break;
}
}
if (!found) {
aSpan.RuleSet = null;
throw new HighlightingDefinitionInvalidException("The RuleSet " + aSpan.Rule + " could not be found in mode definition " + this.Name);
}
} else {
aSpan.RuleSet = null;
}
}
}
if (defaultRuleSet == null) {
throw new HighlightingDefinitionInvalidException("No default RuleSet is defined for mode definition " + this.Name);
}
}
void ResolveExternalReferences()
{
foreach (HighlightRuleSet ruleSet in Rules) {
ruleSet.Highlighter = this;
if (ruleSet.Reference != null) {
IHighlightingStrategy highlighter = HighlightingManager.Manager.FindHighlighter (ruleSet.Reference);
if (highlighter == null)
throw new HighlightingDefinitionInvalidException("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition could not be found");
if (highlighter is IHighlightingStrategyUsingRuleSets)
ruleSet.Highlighter = (IHighlightingStrategyUsingRuleSets)highlighter;
else
throw new HighlightingDefinitionInvalidException("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition does not implement IHighlightingStrategyUsingRuleSets");
}
}
}
// internal void SetDefaultColor(HighlightBackground color)
// {
// return (HighlightColor)environmentColors[name];
// defaultColor = color;
// }
HighlightColor defaultTextColor;
public HighlightColor DefaultTextColor {
get {
return defaultTextColor;
}
}
public void SetColorFor(string name, HighlightColor color)
{
if (name == "Default")
defaultTextColor = new HighlightColor(color.Color, color.Bold, color.Italic);
environmentColors[name] = color;
}
public HighlightColor GetColorFor(string name)
{
HighlightColor color;
if (environmentColors.TryGetValue(name, out color))
return color;
else
return defaultTextColor;
}
public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
{
return GetColor(defaultRuleSet, document, currentSegment, currentOffset, currentLength);
}
protected virtual HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
{
if (ruleSet != null) {
if (ruleSet.Reference != null) {
return ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength);
} else {
return (HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength];
}
}
return null;
}
public HighlightRuleSet GetRuleSet(Span aSpan)
{
if (aSpan == null) {
return this.defaultRuleSet;
} else {
if (aSpan.RuleSet != null)
{
if (aSpan.RuleSet.Reference != null) {
return aSpan.RuleSet.Highlighter.GetRuleSet(null);
} else {
return aSpan.RuleSet;
}
} else {
return null;
}
}
}
// Line state variable
protected LineSegment currentLine;
protected int currentLineNumber;
// Span stack state variable
protected SpanStack currentSpanStack;
public virtual void MarkTokens(IDocument document)
{
if (Rules.Count == 0) {
return;
}
int lineNumber = 0;
while (lineNumber < document.TotalNumberOfLines) {
LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
if (lineNumber >= document.LineSegmentCollection.Count) { // may be, if the last line ends with a delimiter
break; // then the last line is not in the collection :)
}
currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
if (currentSpanStack != null) {
while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL)
{
currentSpanStack.Pop();
}
if (currentSpanStack.IsEmpty) currentSpanStack = null;
}
currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
if (currentLine.Length == -1) { // happens when buffer is empty !
return;
}
currentLineNumber = lineNumber;
List<TextWord> words = ParseLine(document);
// Alex: clear old words
if (currentLine.Words != null) {
currentLine.Words.Clear();
}
currentLine.Words = words;
currentLine.HighlightSpanStack = (currentSpanStack==null || currentSpanStack.IsEmpty) ? null : currentSpanStack;
++lineNumber;
}
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
document.CommitUpdate();
currentLine = null;
}
bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged)
{
currentLineNumber = lineNumber;
bool processNextLine = false;
LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
if (currentSpanStack != null) {
while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL) {
currentSpanStack.Pop();
}
if (currentSpanStack.IsEmpty) {
currentSpanStack = null;
}
}
currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];
if (currentLine.Length == -1) { // happens when buffer is empty !
return false;
}
List<TextWord> words = ParseLine(document);
if (currentSpanStack != null && currentSpanStack.IsEmpty) {
currentSpanStack = null;
}
// Check if the span state has changed, if so we must re-render the next line
// This check may seem utterly complicated but I didn't want to introduce any function calls
// or allocations here for perf reasons.
if(currentLine.HighlightSpanStack != currentSpanStack) {
if (currentLine.HighlightSpanStack == null) {
processNextLine = false;
foreach (Span sp in currentSpanStack) {
if (!sp.StopEOL) {
spanChanged = true;
processNextLine = true;
break;
}
}
} else if (currentSpanStack == null) {
processNextLine = false;
foreach (Span sp in currentLine.HighlightSpanStack) {
if (!sp.StopEOL) {
spanChanged = true;
processNextLine = true;
break;
}
}
} else {
SpanStack.Enumerator e1 = currentSpanStack.GetEnumerator();
SpanStack.Enumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
bool done = false;
while (!done) {
bool blockSpanIn1 = false;
while (e1.MoveNext()) {
if (!((Span)e1.Current).StopEOL) {
blockSpanIn1 = true;
break;
}
}
bool blockSpanIn2 = false;
while (e2.MoveNext()) {
if (!((Span)e2.Current).StopEOL) {
blockSpanIn2 = true;
break;
}
}
if (blockSpanIn1 || blockSpanIn2) {
if (blockSpanIn1 && blockSpanIn2) {
if (e1.Current != e2.Current) {
done = true;
processNextLine = true;
spanChanged = true;
}
} else {
spanChanged = true;
done = true;
processNextLine = true;
}
} else {
done = true;
processNextLine = false;
}
}
}
} else {
processNextLine = false;
}
//// Alex: remove old words
if (currentLine.Words!=null) currentLine.Words.Clear();
currentLine.Words = words;
currentLine.HighlightSpanStack = (currentSpanStack != null && !currentSpanStack.IsEmpty) ? currentSpanStack : null;
return processNextLine;
}
public virtual void MarkTokens(IDocument document, List<LineSegment> inputLines)
{
if (Rules.Count == 0) {
return;
}
Dictionary<LineSegment, bool> processedLines = new Dictionary<LineSegment, bool>();
bool spanChanged = false;
int documentLineSegmentCount = document.LineSegmentCollection.Count;
foreach (LineSegment lineToProcess in inputLines) {
if (!processedLines.ContainsKey(lineToProcess)) {
int lineNumber = lineToProcess.LineNumber;
bool processNextLine = true;
if (lineNumber != -1) {
while (processNextLine && lineNumber < documentLineSegmentCount) {
processNextLine = MarkTokensInLine(document, lineNumber, ref spanChanged);
processedLines[currentLine] = true;
++lineNumber;
}
}
}
}
if (spanChanged || inputLines.Count > 20) {
// if the span was changed (more than inputLines lines had to be reevaluated)
// or if there are many lines in inputLines, it's faster to update the whole
// text area instead of many small segments
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
} else {
// document.Caret.ValidateCaretPos();
// document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, document.GetLineNumberForOffset(document.Caret.Offset)));
//
foreach (LineSegment lineToProcess in inputLines) {
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, lineToProcess.LineNumber));
}
}
document.CommitUpdate();
currentLine = null;
}
// Span state variables
protected bool inSpan;
protected Span activeSpan;
protected HighlightRuleSet activeRuleSet;
// Line scanning state variables
protected int currentOffset;
protected int currentLength;
protected bool isDelimiter = false;
void UpdateSpanStateVariables()
{
inSpan = (currentSpanStack != null && !currentSpanStack.IsEmpty);
activeSpan = inSpan ? currentSpanStack.Peek() : null;
activeRuleSet = GetRuleSet(activeSpan);
}
List<TextWord> ParseLine(IDocument document)
{
List<TextWord> words = new List<TextWord>();
HighlightColor markNext = null;
currentOffset = 0;
currentLength = 0;
UpdateSpanStateVariables();
int currentLineLength = currentLine.Length;
int currentLineOffset = currentLine.Offset;
for (int i = 0; i < currentLineLength; ++i) {
char ch = document.GetCharAt(currentLineOffset + i);
switch (ch) {
case '\n':
case '\r':
PushCurWord(document, ref markNext, words);
++currentOffset;
break;
case ' ':
PushCurWord(document, ref markNext, words);
if (activeSpan != null && activeSpan.Color.HasBackground) {
words.Add(new TextWord.SpaceTextWord(activeSpan.Color));
} else {
words.Add(TextWord.Space);
}
++currentOffset;
break;
case '\t':
PushCurWord(document, ref markNext, words);
if (activeSpan != null && activeSpan.Color.HasBackground) {
words.Add(new TextWord.TabTextWord(activeSpan.Color));
} else {
words.Add(TextWord.Tab);
}
++currentOffset;
break;
default:
{
// handle escape characters
char escapeCharacter = '\0';
if (activeSpan != null && activeSpan.EscapeCharacter != '\0') {
escapeCharacter = activeSpan.EscapeCharacter;
} else if (activeRuleSet != null) {
escapeCharacter = activeRuleSet.EscapeCharacter;
}
if (escapeCharacter != '\0' && escapeCharacter == ch) {
// we found the escape character
if (activeSpan != null && activeSpan.End != null && activeSpan.End.Length == 1
&& escapeCharacter == activeSpan.End[0])
{
// the escape character is a end-doubling escape character
// it may count as escape only when the next character is the escape, too
if (i + 1 < currentLineLength) {
if (document.GetCharAt(currentLineOffset + i + 1) == escapeCharacter) {
currentLength += 2;
PushCurWord(document, ref markNext, words);
++i;
continue;
}
}
} else {
// this is a normal \-style escape
++currentLength;
if (i + 1 < currentLineLength) {
++currentLength;
}
PushCurWord(document, ref markNext, words);
++i;
continue;
}
}
// highlight digits
if (!inSpan && (char.IsDigit(ch) || (ch == '.' && i + 1 < currentLineLength && char.IsDigit(document.GetCharAt(currentLineOffset + i + 1)))) && currentLength == 0) {
bool ishex = false;
bool isfloatingpoint = false;
if (ch == '0' && i + 1 < currentLineLength && char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'X') { // hex digits
const string hex = "0123456789ABCDEF";
++currentLength;
++i; // skip 'x'
++currentLength;
ishex = true;
while (i + 1 < currentLineLength && hex.IndexOf(char.ToUpper(document.GetCharAt(currentLineOffset + i + 1))) != -1) {
++i;
++currentLength;
}
} else {
++currentLength;
while (i + 1 < currentLineLength && char.IsDigit(document.GetCharAt(currentLineOffset + i + 1))) {
++i;
++currentLength;
}
}
if (!ishex && i + 1 < currentLineLength && document.GetCharAt(currentLineOffset + i + 1) == '.') {
isfloatingpoint = true;
++i;
++currentLength;
while (i + 1 < currentLineLength && char.IsDigit(document.GetCharAt(currentLineOffset + i + 1))) {
++i;
++currentLength;
}
}
if (i + 1 < currentLineLength && char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'E') {
isfloatingpoint = true;
++i;
++currentLength;
if (i + 1 < currentLineLength && (document.GetCharAt(currentLineOffset + i + 1) == '+' || document.GetCharAt(currentLine.Offset + i + 1) == '-')) {
++i;
++currentLength;
}
while (i + 1 < currentLine.Length && char.IsDigit(document.GetCharAt(currentLineOffset + i + 1))) {
++i;
++currentLength;
}
}
if (i + 1 < currentLine.Length) {
char nextch = char.ToUpper(document.GetCharAt(currentLineOffset + i + 1));
if (nextch == 'F' || nextch == 'M' || nextch == 'D') {
isfloatingpoint = true;
++i;
++currentLength;
}
}
if (!isfloatingpoint) {
bool isunsigned = false;
if (i + 1 < currentLineLength && char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'U') {
++i;
++currentLength;
isunsigned = true;
}
if (i + 1 < currentLineLength && char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'L') {
++i;
++currentLength;
if (!isunsigned && i + 1 < currentLineLength && char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'U') {
++i;
++currentLength;
}
}
}
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, DigitColor, false));
currentOffset += currentLength;
currentLength = 0;
continue;
}
// Check for SPAN ENDs
if (inSpan) {
if (activeSpan.End != null && activeSpan.End.Length > 0) {
if (MatchExpr(currentLine, activeSpan.End, i, document, activeSpan.IgnoreCase)) {
PushCurWord(document, ref markNext, words);
string regex = GetRegString(currentLine, activeSpan.End, i, document);
currentLength += regex.Length;
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, activeSpan.EndColor, false));
currentOffset += currentLength;
currentLength = 0;
i += regex.Length - 1;
currentSpanStack.Pop();
UpdateSpanStateVariables();
continue;
}
}
}
// check for SPAN BEGIN
if (activeRuleSet != null) {
foreach (Span span in activeRuleSet.Spans) {
if ((!span.IsBeginSingleWord || currentLength == 0)
&& (!span.IsBeginStartOfLine.HasValue || span.IsBeginStartOfLine.Value == (currentLength == 0 && words.TrueForAll(delegate(TextWord textWord) { return textWord.Type != TextWordType.Word; })))
&& MatchExpr(currentLine, span.Begin, i, document, activeRuleSet.IgnoreCase)) {
PushCurWord(document, ref markNext, words);
string regex = GetRegString(currentLine, span.Begin, i, document);
if (!OverrideSpan(regex, document, words, span, ref i)) {
currentLength += regex.Length;
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, span.BeginColor, false));
currentOffset += currentLength;
currentLength = 0;
i += regex.Length - 1;
if (currentSpanStack == null) {
currentSpanStack = new SpanStack();
}
currentSpanStack.Push(span);
span.IgnoreCase = activeRuleSet.IgnoreCase;
UpdateSpanStateVariables();
}
goto skip;
}
}
}
// check if the char is a delimiter
if (activeRuleSet != null && (int)ch < 256 && activeRuleSet.Delimiters[(int)ch]) {
PushCurWord(document, ref markNext, words);
isDelimiter = true;
if (currentOffset + currentLength +1 < currentLine.Length) {
++currentLength;
PushCurWord(document, ref markNext, words);
goto skip;
}
}
++currentLength;
skip: continue;
}
}
}
PushCurWord(document, ref markNext, words);
OnParsedLine(document, currentLine, words);
return words;
}
protected virtual void OnParsedLine(IDocument document, LineSegment currentLine, List<TextWord> words)
{
}
protected virtual bool OverrideSpan(string spanBegin, IDocument document, List<TextWord> words, Span span, ref int lineOffset)
{
return false;
}
/// <summary>
/// pushes the curWord string on the word list, with the
/// correct color.
/// </summary>
void PushCurWord(IDocument document, ref HighlightColor markNext, List<TextWord> words)
{
// Svante Lidman : Need to look through the next prev logic.
if (currentLength > 0) {
if (words.Count > 0 && activeRuleSet != null) {
TextWord prevWord = null;
int pInd = words.Count - 1;
while (pInd >= 0) {
if (!((TextWord)words[pInd]).IsWhiteSpace) {
prevWord = (TextWord)words[pInd];
if (prevWord.HasDefaultColor) {
PrevMarker marker = (PrevMarker)activeRuleSet.PrevMarkers[document, currentLine, currentOffset, currentLength];
if (marker != null) {
prevWord.SyntaxColor = marker.Color;
// document.Caret.ValidateCaretPos();
// document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, document.GetLineNumberForOffset(document.Caret.Offset)));
}
}
break;
}
pInd--;
}
}
if (inSpan) {
HighlightColor c = null;
bool hasDefaultColor = true;
if (activeSpan.Rule == null) {
c = activeSpan.Color;
} else {
c = GetColor(activeRuleSet, document, currentLine, currentOffset, currentLength);
hasDefaultColor = false;
}
if (c == null) {
c = activeSpan.Color;
if (c.Color == Color.Transparent) {
c = this.DefaultTextColor;
}
hasDefaultColor = true;
}
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, markNext != null ? markNext : c, hasDefaultColor));
} else {
HighlightColor c = markNext != null ? markNext : GetColor(activeRuleSet, document, currentLine, currentOffset, currentLength);
if (c == null) {
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, this.DefaultTextColor, true) {
IsDelimiter = isDelimiter
});
} else {
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, c, false)
{
IsDelimiter = isDelimiter
});
}
isDelimiter = false;
}
if (activeRuleSet != null) {
NextMarker nextMarker = (NextMarker)activeRuleSet.NextMarkers[document, currentLine, currentOffset, currentLength];
if (nextMarker != null) {
if (nextMarker.MarkMarker && words.Count > 0) {
TextWord prevword = ((TextWord)words[words.Count - 1]);
prevword.SyntaxColor = nextMarker.Color;
}
markNext = nextMarker.Color;
} else {
markNext = null;
}
}
currentOffset += currentLength;
currentLength = 0;
}
}
#region Matching
/// <summary>
/// get the string, which matches the regular expression expr,
/// in string s2 at index
/// </summary>
static string GetRegString(LineSegment lineSegment, char[] expr, int index, IDocument document)
{
int j = 0;
StringBuilder regexpr = new StringBuilder();
for (int i = 0; i < expr.Length; ++i, ++j) {
if (index + j >= lineSegment.Length)
break;
switch (expr[i]) {
case '@': // "special" meaning
++i;
if (i == expr.Length)
throw new HighlightingDefinitionInvalidException("Unexpected end of @ sequence, use @@ to look for a single @.");
switch (expr[i]) {
case '!': // don't match the following expression
StringBuilder whatmatch = new StringBuilder();
++i;
while (i < expr.Length && expr[i] != '@') {
whatmatch.Append(expr[i++]);
}
break;
case '@': // matches @
regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
break;
}
break;
default:
if (expr[i] != document.GetCharAt(lineSegment.Offset + index + j)) {
return regexpr.ToString();
}
regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
break;
}
}
return regexpr.ToString();
}
/// <summary>
/// returns true, if the get the string s2 at index matches the expression expr
/// </summary>
static bool MatchExpr(LineSegment lineSegment, char[] expr, int index, IDocument document, bool ignoreCase)
{
for (int i = 0, j = 0; i < expr.Length; ++i, ++j) {
switch (expr[i]) {
case '@': // "special" meaning
++i;
if (i == expr.Length)
throw new HighlightingDefinitionInvalidException("Unexpected end of @ sequence, use @@ to look for a single @.");
switch (expr[i]) {
case 'C': // match whitespace or punctuation
if (index + j == lineSegment.Offset || index + j >= lineSegment.Offset + lineSegment.Length) {
// nothing (EOL or SOL)
} else {
char ch = document.GetCharAt(lineSegment.Offset + index + j);
if (!char.IsWhiteSpace(ch) && !char.IsPunctuation(ch)) {
return false;
}
}
break;
case '!': // don't match the following expression
{
StringBuilder whatmatch = new StringBuilder();
++i;
while (i < expr.Length && expr[i] != '@') {
whatmatch.Append(expr[i++]);
}
if (lineSegment.Offset + index + j + whatmatch.Length < document.TextLength) {
int k = 0;
for (; k < whatmatch.Length; ++k) {
char docChar = ignoreCase ? char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j + k)) : document.GetCharAt(lineSegment.Offset + index + j + k);
char spanChar = ignoreCase ? char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
if (docChar != spanChar) {
break;
}
}
if (k >= whatmatch.Length) {
return false;
}
}
// --j;
break;
}
case '-': // don't match the expression before
{
StringBuilder whatmatch = new StringBuilder();
++i;
while (i < expr.Length && expr[i] != '@') {
whatmatch.Append(expr[i++]);
}
if (index - whatmatch.Length >= 0) {
int k = 0;
for (; k < whatmatch.Length; ++k) {
char docChar = ignoreCase ? char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k)) : document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k);
char spanChar = ignoreCase ? char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
if (docChar != spanChar)
break;
}
if (k >= whatmatch.Length) {
return false;
}
}
// --j;
break;
}
case '@': // matches @
if (index + j >= lineSegment.Length || '@' != document.GetCharAt(lineSegment.Offset + index + j)) {
return false;
}
break;
}
break;
default:
{
if (index + j >= lineSegment.Length) {
return false;
}
char docChar = ignoreCase ? char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j)) : document.GetCharAt(lineSegment.Offset + index + j);
char spanChar = ignoreCase ? char.ToUpperInvariant(expr[i]) : expr[i];
if (docChar != spanChar) {
return false;
}
break;
}
}
}
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,103 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This class is used to generate bold, italic and bold/italic fonts out
/// of a base font.
/// </summary>
public class FontContainer
{
Font defaultFont;
Font regularfont, boldfont, italicfont, bolditalicfont;
/// <value>
/// The scaled, regular version of the base font
/// </value>
public Font RegularFont {
get {
return regularfont;
}
}
/// <value>
/// The scaled, bold version of the base font
/// </value>
public Font BoldFont {
get {
return boldfont;
}
}
/// <value>
/// The scaled, italic version of the base font
/// </value>
public Font ItalicFont {
get {
return italicfont;
}
}
/// <value>
/// The scaled, bold/italic version of the base font
/// </value>
public Font BoldItalicFont {
get {
return bolditalicfont;
}
}
static float twipsPerPixelY;
public static float TwipsPerPixelY {
get {
if (twipsPerPixelY == 0) {
using (Bitmap bmp = new Bitmap(1,1)) {
using (Graphics g = Graphics.FromImage(bmp)) {
twipsPerPixelY = 1440 / g.DpiY;
}
}
}
return twipsPerPixelY;
}
}
/// <value>
/// The base font
/// </value>
public Font DefaultFont {
get {
return defaultFont;
}
set {
// 1440 twips is one inch
float pixelSize = (float)Math.Round(value.SizeInPoints * 20 / TwipsPerPixelY);
defaultFont = value;
regularfont = new Font(value.FontFamily, pixelSize * TwipsPerPixelY / 20f, FontStyle.Regular);
boldfont = new Font(regularfont, FontStyle.Bold);
italicfont = new Font(regularfont, FontStyle.Italic);
bolditalicfont = new Font(regularfont, FontStyle.Bold | FontStyle.Italic);
}
}
public static Font ParseFont(string font)
{
string[] descr = font.Split(new char[]{',', '='});
return new Font(descr[1], float.Parse(descr[3]));
}
public FontContainer(Font defaultFont)
{
this.DefaultFont = defaultFont;
}
}
}

View File

@@ -0,0 +1,51 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// Extens the highlighting color with a background image.
/// </summary>
public class HighlightBackground : HighlightColor
{
Image backgroundImage;
/// <value>
/// The image used as background
/// </value>
public Image BackgroundImage {
get {
return backgroundImage;
}
}
/// <summary>
/// Creates a new instance of <see cref="HighlightBackground"/>
/// </summary>
public HighlightBackground(XmlElement el) : base(el)
{
if (el.Attributes["image"] != null) {
backgroundImage = new Bitmap(el.Attributes["image"].InnerText);
}
}
/// <summary>
/// Creates a new instance of <see cref="HighlightBackground"/>
/// </summary>
public HighlightBackground(Color color, Color backgroundcolor, bool bold, bool italic) : base(color, backgroundcolor, bold, italic)
{
}
public HighlightBackground(string systemColor, string systemBackgroundColor, bool bold, bool italic) : base(systemColor, systemBackgroundColor, bold, italic)
{
}
}
}

View File

@@ -0,0 +1,274 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// A color used for highlighting
/// </summary>
public class HighlightColor
{
Color color;
Color backgroundcolor = System.Drawing.Color.WhiteSmoke;
bool bold = false;
bool italic = false;
bool hasForeground = false;
bool hasBackground = false;
public bool HasForeground {
get {
return hasForeground;
}
}
public bool HasBackground {
get {
return hasBackground;
}
}
/// <value>
/// If true the font will be displayed bold style
/// </value>
public bool Bold {
get {
return bold;
}
}
/// <value>
/// If true the font will be displayed italic style
/// </value>
public bool Italic {
get {
return italic;
}
}
/// <value>
/// The background color used
/// </value>
public Color BackgroundColor {
get {
return backgroundcolor;
}
}
/// <value>
/// The foreground color used
/// </value>
public Color Color {
get {
return color;
}
}
/// <value>
/// The font used
/// </value>
public Font GetFont(FontContainer fontContainer)
{
if (Bold) {
return Italic ? fontContainer.BoldItalicFont : fontContainer.BoldFont;
}
return Italic ? fontContainer.ItalicFont : fontContainer.RegularFont;
}
Color ParseColorString(string colorName)
{
string[] cNames = colorName.Split('*');
PropertyInfo myPropInfo = typeof(System.Drawing.SystemColors).GetProperty(cNames[0], BindingFlags.Public |
BindingFlags.Instance |
BindingFlags.Static);
Color c = (Color)myPropInfo.GetValue(null, null);
if (cNames.Length == 2) {
// hack : can't figure out how to parse doubles with '.' (culture info might set the '.' to ',')
double factor = double.Parse(cNames[1]) / 100;
c = Color.FromArgb((int)((double)c.R * factor), (int)((double)c.G * factor), (int)((double)c.B * factor));
}
return c;
}
/// <summary>
/// Creates a new instance of <see cref="HighlightColor"/>
/// </summary>
public HighlightColor(XmlElement el)
{
Debug.Assert(el != null, "ICSharpCode.TextEditor.Document.SyntaxColor(XmlElement el) : el == null");
if (el.Attributes["bold"] != null) {
bold = bool.Parse(el.Attributes["bold"].InnerText);
}
if (el.Attributes["italic"] != null) {
italic = bool.Parse(el.Attributes["italic"].InnerText);
}
if (el.Attributes["color"] != null) {
string c = el.Attributes["color"].InnerText;
if (c[0] == '#') {
color = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
color = ParseColorString(c.Substring("SystemColors.".Length));
} else {
color = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasForeground = true;
} else {
color = Color.Transparent; // to set it to the default value.
}
if (el.Attributes["bgcolor"] != null) {
string c = el.Attributes["bgcolor"].InnerText;
if (c[0] == '#') {
backgroundcolor = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
backgroundcolor = ParseColorString(c.Substring("SystemColors.".Length));
} else {
backgroundcolor = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasBackground = true;
}
}
/// <summary>
/// Creates a new instance of <see cref="HighlightColor"/>
/// </summary>
public HighlightColor(XmlElement el, HighlightColor defaultColor)
{
Debug.Assert(el != null, "ICSharpCode.TextEditor.Document.SyntaxColor(XmlElement el) : el == null");
if (el.Attributes["bold"] != null) {
bold = bool.Parse(el.Attributes["bold"].InnerText);
} else {
bold = defaultColor.Bold;
}
if (el.Attributes["italic"] != null) {
italic = bool.Parse(el.Attributes["italic"].InnerText);
} else {
italic = defaultColor.Italic;
}
if (el.Attributes["color"] != null) {
string c = el.Attributes["color"].InnerText;
if (c[0] == '#') {
color = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
color = ParseColorString(c.Substring("SystemColors.".Length));
} else {
color = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasForeground = true;
} else {
color = defaultColor.color;
}
if (el.Attributes["bgcolor"] != null) {
string c = el.Attributes["bgcolor"].InnerText;
if (c[0] == '#') {
backgroundcolor = ParseColor(c);
} else if (c.StartsWith("SystemColors.")) {
backgroundcolor = ParseColorString(c.Substring("SystemColors.".Length));
} else {
backgroundcolor = (Color)(Color.GetType()).InvokeMember(c, BindingFlags.GetProperty, null, Color, new object[0]);
}
hasBackground = true;
} else {
backgroundcolor = defaultColor.BackgroundColor;
}
}
/// <summary>
/// Creates a new instance of <see cref="HighlightColor"/>
/// </summary>
public HighlightColor(Color color, bool bold, bool italic)
{
hasForeground = true;
this.color = color;
this.bold = bold;
this.italic = italic;
}
/// <summary>
/// Creates a new instance of <see cref="HighlightColor"/>
/// </summary>
public HighlightColor(Color color, Color backgroundcolor, bool bold, bool italic)
{
hasForeground = true;
hasBackground = true;
this.color = color;
this.backgroundcolor = backgroundcolor;
this.bold = bold;
this.italic = italic;
}
/// <summary>
/// Creates a new instance of <see cref="HighlightColor"/>
/// </summary>
public HighlightColor(string systemColor, string systemBackgroundColor, bool bold, bool italic)
{
hasForeground = true;
hasBackground = true;
this.color = ParseColorString(systemColor);
this.backgroundcolor = ParseColorString(systemBackgroundColor);
this.bold = bold;
this.italic = italic;
}
/// <summary>
/// Creates a new instance of <see cref="HighlightColor"/>
/// </summary>
public HighlightColor(string systemColor, bool bold, bool italic)
{
hasForeground = true;
this.color = ParseColorString(systemColor);
this.bold = bold;
this.italic = italic;
}
static Color ParseColor(string c)
{
int a = 255;
int offset = 0;
if (c.Length > 7) {
offset = 2;
a = int.Parse(c.Substring(1,2), NumberStyles.HexNumber);
}
int r = int.Parse(c.Substring(1 + offset,2), NumberStyles.HexNumber);
int g = int.Parse(c.Substring(3 + offset,2), NumberStyles.HexNumber);
int b = int.Parse(c.Substring(5 + offset,2), NumberStyles.HexNumber);
return Color.FromArgb(a, r, g, b);
}
/// <summary>
/// Converts a <see cref="HighlightColor"/> instance to string (for debug purposes)
/// </summary>
public override string ToString()
{
return "[HighlightColor: Bold = " + Bold +
", Italic = " + Italic +
", Color = " + Color +
", BackgroundColor = " + BackgroundColor + "]";
}
}
}

View File

@@ -0,0 +1,25 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightInfo
{
public bool BlockSpanOn = false;
public bool Span = false;
public Span CurSpan = null;
public HighlightInfo(Span curSpan, bool span, bool blockSpanOn)
{
this.CurSpan = curSpan;
this.Span = span;
this.BlockSpanOn = blockSpanOn;
}
}
}

View File

@@ -0,0 +1,182 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Xml;
using ICSharpCode.TextEditor.Util;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightRuleSet
{
LookupTable keyWords;
ArrayList spans = new ArrayList();
LookupTable prevMarkers;
LookupTable nextMarkers;
char escapeCharacter;
bool ignoreCase = false;
string name = null;
bool[] delimiters = new bool[256];
string reference = null;
public ArrayList Spans {
get {
return spans;
}
}
internal IHighlightingStrategyUsingRuleSets Highlighter;
public LookupTable KeyWords {
get {
return keyWords;
}
}
public LookupTable PrevMarkers {
get {
return prevMarkers;
}
}
public LookupTable NextMarkers {
get {
return nextMarkers;
}
}
public bool[] Delimiters {
get {
return delimiters;
}
}
public char EscapeCharacter {
get {
return escapeCharacter;
}
}
public bool IgnoreCase {
get {
return ignoreCase;
}
}
public string Name {
get {
return name;
}
set {
name = value;
}
}
public string Reference {
get {
return reference;
}
}
public HighlightRuleSet()
{
keyWords = new LookupTable(false);
prevMarkers = new LookupTable(false);
nextMarkers = new LookupTable(false);
}
public HighlightRuleSet(XmlElement el)
{
XmlNodeList nodes;
if (el.Attributes["name"] != null) {
Name = el.Attributes["name"].InnerText;
}
if (el.HasAttribute("escapecharacter")) {
escapeCharacter = el.GetAttribute("escapecharacter")[0];
}
if (el.Attributes["reference"] != null) {
reference = el.Attributes["reference"].InnerText;
}
if (el.Attributes["ignorecase"] != null) {
ignoreCase = bool.Parse(el.Attributes["ignorecase"].InnerText);
}
for (int i = 0; i < Delimiters.Length; ++i) {
delimiters[i] = false;
}
if (el["Delimiters"] != null) {
string delimiterString = el["Delimiters"].InnerText;
foreach (char ch in delimiterString) {
delimiters[(int)ch] = true;
}
}
// Spans = new LookupTable(!IgnoreCase);
keyWords = new LookupTable(!IgnoreCase);
prevMarkers = new LookupTable(!IgnoreCase);
nextMarkers = new LookupTable(!IgnoreCase);
nodes = el.GetElementsByTagName("KeyWords");
foreach (XmlElement el2 in nodes) {
HighlightColor color = new HighlightColor(el2);
XmlNodeList keys = el2.GetElementsByTagName("Key");
foreach (XmlElement node in keys) {
keyWords[node.Attributes["word"].InnerText] = color;
}
}
nodes = el.GetElementsByTagName("Span");
foreach (XmlElement el2 in nodes) {
Spans.Add(new Span(el2));
/*
Span span = new Span(el2);
Spans[span.Begin] = span;*/
}
nodes = el.GetElementsByTagName("MarkPrevious");
foreach (XmlElement el2 in nodes) {
PrevMarker prev = new PrevMarker(el2);
prevMarkers[prev.What] = prev;
}
nodes = el.GetElementsByTagName("MarkFollowing");
foreach (XmlElement el2 in nodes) {
NextMarker next = new NextMarker(el2);
nextMarkers[next.What] = next;
}
}
/// <summary>
/// Merges spans etc. from the other rule set into this rule set.
/// </summary>
public void MergeFrom(HighlightRuleSet ruleSet)
{
for (int i = 0; i < delimiters.Length; i++) {
delimiters[i] |= ruleSet.delimiters[i];
}
// insert merged spans in front of old spans
ArrayList oldSpans = spans;
spans = (ArrayList)ruleSet.spans.Clone();
spans.AddRange(oldSpans);
//keyWords.MergeFrom(ruleSet.keyWords);
//prevMarkers.MergeFrom(ruleSet.prevMarkers);
//nextMarkers.MergeFrom(ruleSet.nextMarkers);
}
}
}

View File

@@ -0,0 +1,32 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Runtime.Serialization;
namespace ICSharpCode.TextEditor.Document
{
[Serializable()]
public class HighlightingColorNotFoundException : Exception
{
public HighlightingColorNotFoundException() : base()
{
}
public HighlightingColorNotFoundException(string message) : base(message)
{
}
public HighlightingColorNotFoundException(string message, Exception innerException) : base(message, innerException)
{
}
protected HighlightingColorNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

View File

@@ -0,0 +1,37 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Runtime.Serialization;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// Indicates that the highlighting definition that was tried to load was invalid.
/// You get this exception only once per highlighting definition, after that the definition
/// is replaced with the default highlighter.
/// </summary>
[Serializable()]
public class HighlightingDefinitionInvalidException : Exception
{
public HighlightingDefinitionInvalidException() : base()
{
}
public HighlightingDefinitionInvalidException(string message) : base(message)
{
}
public HighlightingDefinitionInvalidException(string message, Exception innerException) : base(message, innerException)
{
}
protected HighlightingDefinitionInvalidException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}

View File

@@ -0,0 +1,110 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Schema;
namespace ICSharpCode.TextEditor.Document
{
public static class HighlightingDefinitionParser
{
public static DefaultHighlightingStrategy Parse(SyntaxMode syntaxMode, XmlReader xmlReader)
{
return Parse(null, syntaxMode, xmlReader);
}
public static DefaultHighlightingStrategy Parse(DefaultHighlightingStrategy highlighter, SyntaxMode syntaxMode, XmlReader xmlReader)
{
if (syntaxMode == null)
throw new ArgumentNullException("syntaxMode");
if (xmlReader == null)
throw new ArgumentNullException("xmlTextReader");
try {
List<ValidationEventArgs> errors = null;
XmlReaderSettings settings = new XmlReaderSettings();
Stream shemaStream = typeof(HighlightingDefinitionParser).Assembly.GetManifestResourceStream("ICSharpCode.TextEditor.Resources.Mode.xsd");
settings.Schemas.Add("", new XmlTextReader(shemaStream));
settings.Schemas.ValidationEventHandler += delegate(object sender, ValidationEventArgs args) {
if (errors == null) {
errors = new List<ValidationEventArgs>();
}
errors.Add(args);
};
settings.ValidationType = ValidationType.Schema;
XmlReader validatingReader = XmlReader.Create(xmlReader, settings);
XmlDocument doc = new XmlDocument();
doc.Load(validatingReader);
if (highlighter == null)
highlighter = new DefaultHighlightingStrategy(doc.DocumentElement.Attributes["name"].InnerText);
if (doc.DocumentElement.HasAttribute("extends")) {
KeyValuePair<SyntaxMode, ISyntaxModeFileProvider> entry = HighlightingManager.Manager.FindHighlighterEntry(doc.DocumentElement.GetAttribute("extends"));
if (entry.Key == null) {
throw new HighlightingDefinitionInvalidException("Cannot find referenced highlighting source " + doc.DocumentElement.GetAttribute("extends"));
} else {
highlighter = Parse(highlighter, entry.Key, entry.Value.GetSyntaxModeFile(entry.Key));
if (highlighter == null) return null;
}
}
if (doc.DocumentElement.HasAttribute("extensions")) {
highlighter.Extensions = doc.DocumentElement.GetAttribute("extensions").Split(new char[] { ';', '|' });
}
XmlElement environment = doc.DocumentElement["Environment"];
if (environment != null) {
foreach (XmlNode node in environment.ChildNodes) {
if (node is XmlElement) {
XmlElement el = (XmlElement)node;
if (el.Name == "Custom") {
highlighter.SetColorFor(el.GetAttribute("name"), el.HasAttribute("bgcolor") ? new HighlightBackground(el) : new HighlightColor(el));
} else {
highlighter.SetColorFor(el.Name, el.HasAttribute("bgcolor") ? new HighlightBackground(el) : new HighlightColor(el));
}
}
}
}
// parse properties
if (doc.DocumentElement["Properties"]!= null) {
foreach (XmlElement propertyElement in doc.DocumentElement["Properties"].ChildNodes) {
highlighter.Properties[propertyElement.Attributes["name"].InnerText] = propertyElement.Attributes["value"].InnerText;
}
}
if (doc.DocumentElement["Digits"]!= null) {
highlighter.DigitColor = new HighlightColor(doc.DocumentElement["Digits"]);
}
XmlNodeList nodes = doc.DocumentElement.GetElementsByTagName("RuleSet");
foreach (XmlElement element in nodes) {
highlighter.AddRuleSet(new HighlightRuleSet(element));
}
xmlReader.Close();
if (errors != null) {
StringBuilder msg = new StringBuilder();
foreach (ValidationEventArgs args in errors) {
msg.AppendLine(args.Message);
}
throw new HighlightingDefinitionInvalidException(msg.ToString());
} else {
return highlighter;
}
} catch (Exception e) {
throw new HighlightingDefinitionInvalidException("Could not load mode definition file '" + syntaxMode.FileName + "'.\n", e);
}
}
}
}

View File

@@ -0,0 +1,166 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightingManager
{
ArrayList syntaxModeFileProviders = new ArrayList();
static HighlightingManager highlightingManager;
// hash table from extension name to highlighting definition,
// OR from extension name to Pair SyntaxMode,ISyntaxModeFileProvider
Hashtable highlightingDefs = new Hashtable();
Hashtable extensionsToName = new Hashtable();
public Hashtable HighlightingDefinitions {
get {
return highlightingDefs;
}
}
public static HighlightingManager Manager {
get {
return highlightingManager;
}
}
static HighlightingManager()
{
highlightingManager = new HighlightingManager();
highlightingManager.AddSyntaxModeFileProvider(new ResourceSyntaxModeProvider());
}
public HighlightingManager()
{
CreateDefaultHighlightingStrategy();
}
public void AddSyntaxModeFileProvider(ISyntaxModeFileProvider syntaxModeFileProvider)
{
foreach (SyntaxMode syntaxMode in syntaxModeFileProvider.SyntaxModes) {
highlightingDefs[syntaxMode.Name] = new DictionaryEntry(syntaxMode, syntaxModeFileProvider);
foreach (string extension in syntaxMode.Extensions) {
extensionsToName[extension.ToUpperInvariant()] = syntaxMode.Name;
}
}
if (!syntaxModeFileProviders.Contains(syntaxModeFileProvider)) {
syntaxModeFileProviders.Add(syntaxModeFileProvider);
}
}
public void AddHighlightingStrategy(IHighlightingStrategy highlightingStrategy)
{
highlightingDefs[highlightingStrategy.Name] = highlightingStrategy;
foreach (string extension in highlightingStrategy.Extensions)
{
extensionsToName[extension.ToUpperInvariant()] = highlightingStrategy.Name;
}
}
public void ReloadSyntaxModes()
{
highlightingDefs.Clear();
extensionsToName.Clear();
CreateDefaultHighlightingStrategy();
foreach (ISyntaxModeFileProvider provider in syntaxModeFileProviders) {
provider.UpdateSyntaxModeList();
AddSyntaxModeFileProvider(provider);
}
OnReloadSyntaxHighlighting(EventArgs.Empty);
}
void CreateDefaultHighlightingStrategy()
{
DefaultHighlightingStrategy defaultHighlightingStrategy = new DefaultHighlightingStrategy();
defaultHighlightingStrategy.Extensions = new string[] {};
defaultHighlightingStrategy.Rules.Add(new HighlightRuleSet());
highlightingDefs["Default"] = defaultHighlightingStrategy;
}
IHighlightingStrategy LoadDefinition(DictionaryEntry entry)
{
SyntaxMode syntaxMode = (SyntaxMode)entry.Key;
ISyntaxModeFileProvider syntaxModeFileProvider = (ISyntaxModeFileProvider)entry.Value;
DefaultHighlightingStrategy highlightingStrategy = null;
try {
var reader = syntaxModeFileProvider.GetSyntaxModeFile(syntaxMode);
if (reader == null)
throw new HighlightingDefinitionInvalidException("Could not get syntax mode file for " + syntaxMode.Name);
highlightingStrategy = HighlightingDefinitionParser.Parse(syntaxMode, reader);
if (highlightingStrategy.Name != syntaxMode.Name) {
throw new HighlightingDefinitionInvalidException("The name specified in the .xshd '" + highlightingStrategy.Name + "' must be equal the syntax mode name '" + syntaxMode.Name + "'");
}
} finally {
if (highlightingStrategy == null) {
highlightingStrategy = DefaultHighlighting;
}
highlightingDefs[syntaxMode.Name] = highlightingStrategy;
highlightingStrategy.ResolveReferences();
}
return highlightingStrategy;
}
public DefaultHighlightingStrategy DefaultHighlighting {
get {
return (DefaultHighlightingStrategy)highlightingDefs["Default"];
}
}
internal KeyValuePair<SyntaxMode, ISyntaxModeFileProvider> FindHighlighterEntry(string name)
{
foreach (ISyntaxModeFileProvider provider in syntaxModeFileProviders) {
foreach (SyntaxMode mode in provider.SyntaxModes) {
if (mode.Name == name) {
return new KeyValuePair<SyntaxMode, ISyntaxModeFileProvider>(mode, provider);
}
}
}
return new KeyValuePair<SyntaxMode, ISyntaxModeFileProvider>(null, null);
}
public IHighlightingStrategy FindHighlighter(string name)
{
object def = highlightingDefs[name];
if (def is DictionaryEntry) {
return LoadDefinition((DictionaryEntry)def);
}
return def == null ? DefaultHighlighting : (IHighlightingStrategy)def;
}
public IHighlightingStrategy FindHighlighterForFile(string fileName)
{
string highlighterName = (string)extensionsToName[Path.GetExtension(fileName).ToUpperInvariant()];
if (highlighterName != null) {
object def = highlightingDefs[highlighterName];
if (def is DictionaryEntry) {
return LoadDefinition((DictionaryEntry)def);
}
return def == null ? DefaultHighlighting : (IHighlightingStrategy)def;
} else {
return DefaultHighlighting;
}
}
protected virtual void OnReloadSyntaxHighlighting(EventArgs e)
{
if (ReloadSyntaxHighlighting != null) {
ReloadSyntaxHighlighting(this, e);
}
}
public event EventHandler ReloadSyntaxHighlighting;
}
}

View File

@@ -0,0 +1,40 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
public class HighlightingStrategyFactory
{
public static IHighlightingStrategy CreateHighlightingStrategy()
{
return (IHighlightingStrategy)HighlightingManager.Manager.HighlightingDefinitions["Default"];
}
public static IHighlightingStrategy CreateHighlightingStrategy(string name)
{
IHighlightingStrategy highlightingStrategy = HighlightingManager.Manager.FindHighlighter(name);
if (highlightingStrategy == null)
{
return CreateHighlightingStrategy();
}
return highlightingStrategy;
}
public static IHighlightingStrategy CreateHighlightingStrategyForFile(string fileName)
{
IHighlightingStrategy highlightingStrategy = HighlightingManager.Manager.FindHighlighterForFile(fileName);
if (highlightingStrategy == null)
{
return CreateHighlightingStrategy();
}
return highlightingStrategy;
}
}
}

View File

@@ -0,0 +1,67 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// A highlighting strategy for a buffer.
/// </summary>
public interface IHighlightingStrategy
{
/// <value>
/// The name of the highlighting strategy, must be unique
/// </value>
string Name {
get;
}
/// <value>
/// The file extenstions on which this highlighting strategy gets
/// used
/// </value>
string[] Extensions {
get;
}
Dictionary<string, string> Properties {
get;
}
// returns special color. (BackGround Color, Cursor Color and so on)
/// <remarks>
/// Gets the color of an Environment element.
/// </remarks>
HighlightColor GetColorFor(string name);
/// <remarks>
/// Used internally, do not call
/// </remarks>
void MarkTokens(IDocument document, List<LineSegment> lines);
/// <remarks>
/// Used internally, do not call
/// </remarks>
void MarkTokens(IDocument document);
}
public interface IHighlightingStrategyUsingRuleSets : IHighlightingStrategy
{
/// <remarks>
/// Used internally, do not call
/// </remarks>
HighlightRuleSet GetRuleSet(Span span);
/// <remarks>
/// Used internally, do not call
/// </remarks>
HighlightColor GetColor(IDocument document, LineSegment keyWord, int index, int length);
}
}

View File

@@ -0,0 +1,63 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// Used for mark next token
/// </summary>
public class NextMarker
{
string what;
HighlightColor color;
bool markMarker = false;
/// <value>
/// String value to indicate to mark next token
/// </value>
public string What {
get {
return what;
}
}
/// <value>
/// Color for marking next token
/// </value>
public HighlightColor Color {
get {
return color;
}
}
/// <value>
/// If true the indication text will be marked with the same color
/// too
/// </value>
public bool MarkMarker {
get {
return markMarker;
}
}
/// <summary>
/// Creates a new instance of <see cref="NextMarker"/>
/// </summary>
public NextMarker(XmlElement mark)
{
color = new HighlightColor(mark);
what = mark.InnerText;
if (mark.Attributes["markmarker"] != null) {
markMarker = bool.Parse(mark.Attributes["markmarker"].InnerText);
}
}
}
}

View File

@@ -0,0 +1,63 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// Used for mark previous token
/// </summary>
public class PrevMarker
{
string what;
HighlightColor color;
bool markMarker = false;
/// <value>
/// String value to indicate to mark previous token
/// </value>
public string What {
get {
return what;
}
}
/// <value>
/// Color for marking previous token
/// </value>
public HighlightColor Color {
get {
return color;
}
}
/// <value>
/// If true the indication text will be marked with the same color
/// too
/// </value>
public bool MarkMarker {
get {
return markMarker;
}
}
/// <summary>
/// Creates a new instance of <see cref="PrevMarker"/>
/// </summary>
public PrevMarker(XmlElement mark)
{
color = new HighlightColor(mark);
what = mark.InnerText;
if (mark.Attributes["markmarker"] != null) {
markMarker = bool.Parse(mark.Attributes["markmarker"].InnerText);
}
}
}
}

View File

@@ -0,0 +1,157 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public sealed class Span
{
bool stopEOL;
HighlightColor color;
HighlightColor beginColor;
HighlightColor endColor;
char[] begin;
char[] end;
string name;
string rule;
HighlightRuleSet ruleSet;
char escapeCharacter;
bool ignoreCase;
bool isBeginSingleWord;
bool? isBeginStartOfLine;
bool isEndSingleWord;
internal HighlightRuleSet RuleSet {
get {
return ruleSet;
}
set {
ruleSet = value;
}
}
public bool IgnoreCase {
get {
return ignoreCase;
}
set {
ignoreCase = value;
}
}
public bool StopEOL {
get {
return stopEOL;
}
}
public bool? IsBeginStartOfLine {
get {
return isBeginStartOfLine;
}
}
public bool IsBeginSingleWord {
get {
return isBeginSingleWord;
}
}
public bool IsEndSingleWord {
get {
return isEndSingleWord;
}
}
public HighlightColor Color {
get {
return color;
}
}
public HighlightColor BeginColor {
get {
if(beginColor != null) {
return beginColor;
} else {
return color;
}
}
}
public HighlightColor EndColor {
get {
return endColor!=null ? endColor : color;
}
}
public char[] Begin {
get { return begin; }
}
public char[] End {
get { return end; }
}
public string Name {
get { return name; }
}
public string Rule {
get { return rule; }
}
/// <summary>
/// Gets the escape character of the span. The escape character is a character that can be used in front
/// of the span end to make it not end the span. The escape character followed by another escape character
/// means the escape character was escaped like in @"a "" b" literals in C#.
/// The default value '\0' means no escape character is allowed.
/// </summary>
public char EscapeCharacter {
get { return escapeCharacter; }
}
public Span(XmlElement span)
{
color = new HighlightColor(span);
if (span.HasAttribute("rule")) {
rule = span.GetAttribute("rule");
}
if (span.HasAttribute("escapecharacter")) {
escapeCharacter = span.GetAttribute("escapecharacter")[0];
}
name = span.GetAttribute("name");
if (span.HasAttribute("stopateol")) {
stopEOL = bool.Parse(span.GetAttribute("stopateol"));
}
begin = span["Begin"].InnerText.ToCharArray();
beginColor = new HighlightColor(span["Begin"], color);
if (span["Begin"].HasAttribute("singleword")) {
this.isBeginSingleWord = bool.Parse(span["Begin"].GetAttribute("singleword"));
}
if (span["Begin"].HasAttribute("startofline")) {
this.isBeginStartOfLine = bool.Parse(span["Begin"].GetAttribute("startofline"));
}
if (span["End"] != null) {
end = span["End"].InnerText.ToCharArray();
endColor = new HighlightColor(span["End"], color);
if (span["End"].HasAttribute("singleword")) {
this.isEndSingleWord = bool.Parse(span["End"].GetAttribute("singleword"));
}
}
}
}
}

View File

@@ -0,0 +1,118 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// A stack of Span instances. Works like Stack&lt;Span&gt;, but can be cloned quickly
/// because it is implemented as linked list.
/// </summary>
public sealed class SpanStack : ICloneable, IEnumerable<Span>
{
internal sealed class StackNode
{
public readonly StackNode Previous;
public readonly Span Data;
public StackNode(StackNode previous, Span data)
{
this.Previous = previous;
this.Data = data;
}
}
StackNode top = null;
public Span Pop()
{
Span s = top.Data;
top = top.Previous;
return s;
}
public Span Peek()
{
return top.Data;
}
public void Push(Span s)
{
top = new StackNode(top, s);
}
public bool IsEmpty {
get {
return top == null;
}
}
public SpanStack Clone()
{
SpanStack n = new SpanStack();
n.top = this.top;
return n;
}
object ICloneable.Clone()
{
return this.Clone();
}
public Enumerator GetEnumerator()
{
return new Enumerator(new StackNode(top, null));
}
IEnumerator<Span> IEnumerable<Span>.GetEnumerator()
{
return this.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public struct Enumerator : IEnumerator<Span>
{
StackNode c;
internal Enumerator(StackNode node)
{
c = node;
}
public Span Current {
get {
return c.Data;
}
}
object System.Collections.IEnumerator.Current {
get {
return c.Data;
}
}
public void Dispose()
{
c = null;
}
public bool MoveNext()
{
c = c.Previous;
return c != null;
}
public void Reset()
{
throw new NotSupportedException();
}
}
}
}

View File

@@ -0,0 +1,84 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public class FileSyntaxModeProvider : ISyntaxModeFileProvider
{
string directory;
List<SyntaxMode> syntaxModes = null;
public ICollection<SyntaxMode> SyntaxModes {
get {
return syntaxModes;
}
}
public FileSyntaxModeProvider(string directory)
{
this.directory = directory;
UpdateSyntaxModeList();
}
public void UpdateSyntaxModeList()
{
string syntaxModeFile = Path.Combine(directory, "SyntaxModes.xml");
if (File.Exists(syntaxModeFile)) {
Stream s = File.OpenRead(syntaxModeFile);
syntaxModes = SyntaxMode.GetSyntaxModes(s);
s.Close();
} else {
syntaxModes = ScanDirectory(directory);
}
}
public XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode)
{
string syntaxModeFile = Path.Combine(directory, syntaxMode.FileName);
if (!File.Exists(syntaxModeFile)) {
throw new HighlightingDefinitionInvalidException("Can't load highlighting definition " + syntaxModeFile + " (file not found)!");
}
return new XmlTextReader(File.OpenRead(syntaxModeFile));
}
List<SyntaxMode> ScanDirectory(string directory)
{
string[] files = Directory.GetFiles(directory);
List<SyntaxMode> modes = new List<SyntaxMode>();
foreach (string file in files) {
if (Path.GetExtension(file).Equals(".XSHD", StringComparison.OrdinalIgnoreCase)) {
XmlTextReader reader = new XmlTextReader(file);
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element) {
switch (reader.Name) {
case "SyntaxDefinition":
string name = reader.GetAttribute("name");
string extensions = reader.GetAttribute("extensions");
modes.Add(new SyntaxMode(Path.GetFileName(file),
name,
extensions));
goto bailout;
default:
throw new HighlightingDefinitionInvalidException("Unknown root node in syntax highlighting file :" + reader.Name);
}
}
}
bailout:
reader.Close();
}
}
return modes;
}
}
}

View File

@@ -0,0 +1,23 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public interface ISyntaxModeFileProvider
{
ICollection<SyntaxMode> SyntaxModes {
get;
}
XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode);
void UpdateSyntaxModeList();
}
}

View File

@@ -0,0 +1,48 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public class ResourceSyntaxModeProvider : ISyntaxModeFileProvider
{
List<SyntaxMode> syntaxModes = null;
public ICollection<SyntaxMode> SyntaxModes {
get {
return syntaxModes;
}
}
public ResourceSyntaxModeProvider()
{
Assembly assembly = typeof(SyntaxMode).Assembly;
Stream syntaxModeStream = assembly.GetManifestResourceStream("ICSharpCode.TextEditor.Resources.SyntaxModes.xml");
if (syntaxModeStream != null) {
syntaxModes = SyntaxMode.GetSyntaxModes(syntaxModeStream);
} else {
syntaxModes = new List<SyntaxMode>();
}
}
public XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode)
{
Assembly assembly = typeof(SyntaxMode).Assembly;
return new XmlTextReader(assembly.GetManifestResourceStream("ICSharpCode.TextEditor.Resources." + syntaxMode.FileName));
}
public void UpdateSyntaxModeList()
{
// resources don't change during runtime
}
}
}

View File

@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.TextEditor.Src.Document.HighlightingStrategy.SyntaxModes
{
public class ResourceSyntaxModeProviderEx : ISyntaxModeFileProvider
{
private const string ResourcesDir = "ICSharpCode.TextEditor.Resources.";
readonly List<SyntaxMode> _syntaxModes;
public ICollection<SyntaxMode> SyntaxModes
{
get
{
return _syntaxModes;
}
}
public ResourceSyntaxModeProviderEx()
{
var syntaxModeStream = GetSyntaxModeStream("SyntaxModesEx.xml");
_syntaxModes = syntaxModeStream != null ? SyntaxMode.GetSyntaxModes(syntaxModeStream) : new List<SyntaxMode>();
}
public XmlTextReader GetSyntaxModeFile(SyntaxMode syntaxMode)
{
var stream = GetSyntaxModeStream(syntaxMode.FileName);
return stream != null ? new XmlTextReader(stream) : null;
}
public void UpdateSyntaxModeList()
{
// resources don't change during runtime
}
private Stream GetSyntaxModeStream(string filename)
{
Assembly assembly = Assembly.GetExecutingAssembly();
return assembly.GetManifestResourceStream(string.Format("{0}{1}", ResourcesDir, filename));
}
}
}

View File

@@ -0,0 +1,96 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml;
namespace ICSharpCode.TextEditor.Document
{
public class SyntaxMode
{
string fileName;
string name;
string[] extensions;
public string FileName {
get {
return fileName;
}
set {
fileName = value;
}
}
public string Name {
get {
return name;
}
set {
name = value;
}
}
public string[] Extensions {
get {
return extensions;
}
set {
extensions = value;
}
}
public SyntaxMode(string fileName, string name, string extensions)
{
this.fileName = fileName;
this.name = name;
this.extensions = extensions.Split(';', '|', ',');
}
public SyntaxMode(string fileName, string name, string[] extensions)
{
this.fileName = fileName;
this.name = name;
this.extensions = extensions;
}
public static List<SyntaxMode> GetSyntaxModes(Stream xmlSyntaxModeStream)
{
XmlTextReader reader = new XmlTextReader(xmlSyntaxModeStream);
List<SyntaxMode> syntaxModes = new List<SyntaxMode>();
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
switch (reader.Name) {
case "SyntaxModes":
string version = reader.GetAttribute("version");
if (version != "1.0") {
throw new HighlightingDefinitionInvalidException("Unknown syntax mode file defininition with version " + version);
}
break;
case "Mode":
syntaxModes.Add(new SyntaxMode(reader.GetAttribute("file"),
reader.GetAttribute("name"),
reader.GetAttribute("extensions")));
break;
default:
throw new HighlightingDefinitionInvalidException("Unknown node in syntax mode file :" + reader.Name);
}
break;
}
}
reader.Close();
return syntaxModes;
}
public override string ToString()
{
return string.Format("[SyntaxMode: FileName={0}, Name={1}, Extensions=({2})]", fileName, name, string.Join(",", extensions));
}
}
}

View File

@@ -0,0 +1,239 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Diagnostics;
using System.Drawing;
namespace ICSharpCode.TextEditor.Document
{
public enum TextWordType {
Word,
Space,
Tab
}
/// <summary>
/// This class represents single words with color information, two special versions of a word are
/// spaces and tabs.
/// </summary>
public class TextWord
{
HighlightColor color;
LineSegment line;
IDocument document;
int offset;
int length;
public sealed class SpaceTextWord : TextWord
{
public SpaceTextWord()
{
length = 1;
}
public SpaceTextWord(HighlightColor color)
{
length = 1;
base.SyntaxColor = color;
}
public override Font GetFont(FontContainer fontContainer)
{
return null;
}
public override TextWordType Type {
get {
return TextWordType.Space;
}
}
public override bool IsWhiteSpace {
get {
return true;
}
}
}
public sealed class TabTextWord : TextWord
{
public TabTextWord()
{
length = 1;
}
public TabTextWord(HighlightColor color)
{
length = 1;
base.SyntaxColor = color;
}
public override Font GetFont(FontContainer fontContainer)
{
return null;
}
public override TextWordType Type {
get {
return TextWordType.Tab;
}
}
public override bool IsWhiteSpace {
get {
return true;
}
}
}
static TextWord spaceWord = new SpaceTextWord();
static TextWord tabWord = new TabTextWord();
bool hasDefaultColor;
public static TextWord Space {
get {
return spaceWord;
}
}
public static TextWord Tab {
get {
return tabWord;
}
}
public int Offset {
get {
return offset;
}
}
public int Length {
get {
return length;
}
}
/// <summary>
/// Splits the <paramref name="word"/> into two parts: the part before <paramref name="pos"/> is assigned to
/// the reference parameter <paramref name="word"/>, the part after <paramref name="pos"/> is returned.
/// </summary>
public static TextWord Split(ref TextWord word, int pos)
{
#if DEBUG
if (word.Type != TextWordType.Word)
throw new ArgumentException("word.Type must be Word");
if (pos <= 0)
throw new ArgumentOutOfRangeException("pos", pos, "pos must be > 0");
if (pos >= word.Length)
throw new ArgumentOutOfRangeException("pos", pos, "pos must be < word.Length");
#endif
TextWord after = new TextWord(word.document, word.line, word.offset + pos, word.length - pos, word.color, word.hasDefaultColor);
word = new TextWord(word.document, word.line, word.offset, pos, word.color, word.hasDefaultColor);
return after;
}
public bool HasDefaultColor {
get {
return hasDefaultColor;
}
}
public virtual TextWordType Type {
get {
return TextWordType.Word;
}
}
public string Word {
get {
if (document == null) {
return string.Empty;
}
return document.GetText(line.Offset + offset, length);
}
}
public virtual Font GetFont(FontContainer fontContainer)
{
return color.GetFont(fontContainer);
}
public Color Color {
get {
if (color == null)
return Color.Black;
else
return color.Color;
}
}
public bool Bold {
get {
if (color == null)
return false;
else
return color.Bold;
}
}
public bool Italic {
get {
if (color == null)
return false;
else
return color.Italic;
}
}
public HighlightColor SyntaxColor {
get {
return color;
}
set {
Debug.Assert(value != null);
color = value;
}
}
public virtual bool IsWhiteSpace {
get {
return false;
}
}
public virtual bool IsDelimiter { get; set; } = false;
protected TextWord()
{
}
// TAB
public TextWord(IDocument document, LineSegment line, int offset, int length, HighlightColor color, bool hasDefaultColor)
{
Debug.Assert(document != null);
Debug.Assert(line != null);
Debug.Assert(color != null);
this.document = document;
this.line = line;
this.offset = offset;
this.length = length;
this.color = color;
this.hasDefaultColor = hasDefaultColor;
}
/// <summary>
/// Converts a <see cref="TextWord"/> instance to string (for debug purposes)
/// </summary>
public override string ToString()
{
return "[TextWord: Word = " + Word + ", Color = " + Color + "]";
}
}
}

View File

@@ -0,0 +1,315 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using ICSharpCode.TextEditor.Undo;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This interface represents a container which holds a text sequence and
/// all necessary information about it. It is used as the base for a text editor.
/// </summary>
public interface IDocument
{
ITextEditorProperties TextEditorProperties {
get;
set;
}
UndoStack UndoStack {
get;
}
/// <value>
/// If true the document can't be altered
/// </value>
bool ReadOnly {
get;
set;
}
/// <summary>
/// The <see cref="IFormattingStrategy"/> attached to the <see cref="IDocument"/> instance
/// </summary>
IFormattingStrategy FormattingStrategy {
get;
set;
}
/// <summary>
/// The <see cref="ITextBufferStrategy"/> attached to the <see cref="IDocument"/> instance
/// </summary>
ITextBufferStrategy TextBufferStrategy {
get;
}
/// <summary>
/// The <see cref="FoldingManager"/> attached to the <see cref="IDocument"/> instance
/// </summary>
FoldingManager FoldingManager {
get;
}
/// <summary>
/// The <see cref="IHighlightingStrategy"/> attached to the <see cref="IDocument"/> instance
/// </summary>
IHighlightingStrategy HighlightingStrategy {
get;
set;
}
/// <summary>
/// The <see cref="IBookMarkManager"/> attached to the <see cref="IDocument"/> instance
/// </summary>
BookmarkManager BookmarkManager {
get;
}
MarkerStrategy MarkerStrategy {
get;
}
// /// <summary>
// /// The <see cref="SelectionManager"/> attached to the <see cref="IDocument"/> instance
// /// </summary>
// SelectionManager SelectionManager {
// get;
// }
#region ILineManager interface
/// <value>
/// A collection of all line segments
/// </value>
/// <remarks>
/// The collection should only be used if you're aware
/// of the 'last line ends with a delimiter problem'. Otherwise
/// the <see cref="GetLineSegment"/> method should be used.
/// </remarks>
IList<LineSegment> LineSegmentCollection {
get;
}
/// <value>
/// The total number of lines in the document.
/// </value>
int TotalNumberOfLines {
get;
}
/// <remarks>
/// Returns a valid line number for the given offset.
/// </remarks>
/// <param name="offset">
/// A offset which points to a character in the line which
/// line number is returned.
/// </param>
/// <returns>
/// An int which value is the line number.
/// </returns>
/// <exception cref="System.ArgumentException">If offset points not to a valid position</exception>
int GetLineNumberForOffset(int offset);
/// <remarks>
/// Returns a <see cref="LineSegment"/> for the given offset.
/// </remarks>
/// <param name="offset">
/// A offset which points to a character in the line which
/// is returned.
/// </param>
/// <returns>
/// A <see cref="LineSegment"/> object.
/// </returns>
/// <exception cref="System.ArgumentException">If offset points not to a valid position</exception>
LineSegment GetLineSegmentForOffset(int offset);
/// <remarks>
/// Returns a <see cref="LineSegment"/> for the given line number.
/// This function should be used to get a line instead of getting the
/// line using the <see cref="ArrayList"/>.
/// </remarks>
/// <param name="lineNumber">
/// The line number which is requested.
/// </param>
/// <returns>
/// A <see cref="LineSegment"/> object.
/// </returns>
/// <exception cref="System.ArgumentException">If offset points not to a valid position</exception>
LineSegment GetLineSegment(int lineNumber);
/// <remarks>
/// Get the first logical line for a given visible line.
/// example : lineNumber == 100 foldings are in the linetracker
/// between 0..1 (2 folded, invisible lines) this method returns 102
/// the 'logical' line number
/// </remarks>
int GetFirstLogicalLine(int lineNumber);
/// <remarks>
/// Get the last logical line for a given visible line.
/// example : lineNumber == 100 foldings are in the linetracker
/// between 0..1 (2 folded, invisible lines) this method returns 102
/// the 'logical' line number
/// </remarks>
int GetLastLogicalLine(int lineNumber);
/// <remarks>
/// Get the visible line for a given logical line.
/// example : lineNumber == 100 foldings are in the linetracker
/// between 0..1 (2 folded, invisible lines) this method returns 98
/// the 'visible' line number
/// </remarks>
int GetVisibleLine(int lineNumber);
// /// <remarks>
// /// Get the visible column for a given logical line and logical column.
// /// </remarks>
// int GetVisibleColumn(int logicalLine, int logicalColumn);
/// <remarks>
/// Get the next visible line after lineNumber
/// </remarks>
int GetNextVisibleLineAbove(int lineNumber, int lineCount);
/// <remarks>
/// Get the next visible line below lineNumber
/// </remarks>
int GetNextVisibleLineBelow(int lineNumber, int lineCount);
event EventHandler<LineLengthChangeEventArgs> LineLengthChanged;
event EventHandler<LineCountChangeEventArgs> LineCountChanged;
event EventHandler<LineEventArgs> LineDeleted;
#endregion
#region ITextBufferStrategy interface
/// <value>
/// Get the whole text as string.
/// When setting the text using the TextContent property, the undo stack is cleared.
/// Set TextContent only for actions such as loading a file; if you want to change the current document
/// use the Replace method instead.
/// </value>
string TextContent {
get;
set;
}
/// <value>
/// The current length of the sequence of characters that can be edited.
/// </value>
int TextLength {
get;
}
/// <summary>
/// Inserts a string of characters into the sequence.
/// </summary>
/// <param name="offset">
/// offset where to insert the string.
/// </param>
/// <param name="text">
/// text to be inserted.
/// </param>
void Insert(int offset, string text);
/// <summary>
/// Removes some portion of the sequence.
/// </summary>
/// <param name="offset">
/// offset of the remove.
/// </param>
/// <param name="length">
/// number of characters to remove.
/// </param>
void Remove(int offset, int length);
/// <summary>
/// Replace some portion of the sequence.
/// </summary>
/// <param name="offset">
/// offset.
/// </param>
/// <param name="length">
/// number of characters to replace.
/// </param>
/// <param name="text">
/// text to be replaced with.
/// </param>
void Replace(int offset, int length, string text);
/// <summary>
/// Returns a specific char of the sequence.
/// </summary>
/// <param name="offset">
/// Offset of the char to get.
/// </param>
char GetCharAt(int offset);
/// <summary>
/// Fetches a string of characters contained in the sequence.
/// </summary>
/// <param name="offset">
/// Offset into the sequence to fetch
/// </param>
/// <param name="length">
/// number of characters to copy.
/// </param>
string GetText(int offset, int length);
#endregion
string GetText(ISegment segment);
#region ITextModel interface
/// <summary>
/// returns the logical line/column position from an offset
/// </summary>
TextLocation OffsetToPosition(int offset);
/// <summary>
/// returns the offset from a logical line/column position
/// </summary>
int PositionToOffset(TextLocation p);
#endregion
/// <value>
/// A container where all TextAreaUpdate objects get stored
/// </value>
List<TextAreaUpdate> UpdateQueue {
get;
}
/// <remarks>
/// Requests an update of the textarea
/// </remarks>
void RequestUpdate(TextAreaUpdate update);
/// <remarks>
/// Commits all updates in the queue to the textarea (the
/// textarea will be painted)
/// </remarks>
void CommitUpdate();
/// <summary>
/// Moves, Resizes, Removes a list of segments on insert/remove/replace events.
/// </summary>
void UpdateSegmentListOnDocumentChange<T>(List<T> list, DocumentEventArgs e) where T : ISegment;
/// <summary>
/// Is fired when CommitUpdate is called
/// </summary>
event EventHandler UpdateCommited;
/// <summary>
/// </summary>
event DocumentEventHandler DocumentAboutToBeChanged;
/// <summary>
/// </summary>
event DocumentEventHandler DocumentChanged;
event EventHandler TextContentChanged;
}
}

View File

@@ -0,0 +1,32 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// This interface is used to describe a span inside a text sequence
/// </summary>
public interface ISegment
{
/// <value>
/// The offset where the span begins
/// </value>
int Offset {
get;
set;
}
/// <value>
/// The length of the span
/// </value>
int Length {
get;
set;
}
}
}

View File

@@ -0,0 +1,177 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="none" email=""/>
// <version>$Revision$</version>
// </file>
using System;
using System.Drawing;
using System.Text;
namespace ICSharpCode.TextEditor.Document
{
public interface ITextEditorProperties
{
bool CaretLine
{
get;
set;
}
bool AutoInsertCurlyBracket { // is wrapped in text editor control
get;
set;
}
bool HideMouseCursor { // is wrapped in text editor control
get;
set;
}
bool IsIconBarVisible { // is wrapped in text editor control
get;
set;
}
bool AllowCaretBeyondEOL {
get;
set;
}
bool ShowMatchingBracket { // is wrapped in text editor control
get;
set;
}
bool CutCopyWholeLine {
get;
set;
}
System.Drawing.Text.TextRenderingHint TextRenderingHint { // is wrapped in text editor control
get;
set;
}
bool MouseWheelScrollDown {
get;
set;
}
bool MouseWheelTextZoom {
get;
set;
}
string LineTerminator {
get;
set;
}
LineViewerStyle LineViewerStyle { // is wrapped in text editor control
get;
set;
}
bool ShowInvalidLines { // is wrapped in text editor control
get;
set;
}
int VerticalRulerRow { // is wrapped in text editor control
get;
set;
}
bool ShowSpaces { // is wrapped in text editor control
get;
set;
}
bool ShowTabs { // is wrapped in text editor control
get;
set;
}
bool ShowEOLMarker { // is wrapped in text editor control
get;
set;
}
bool ConvertTabsToSpaces { // is wrapped in text editor control
get;
set;
}
bool ShowHorizontalRuler { // is wrapped in text editor control
get;
set;
}
bool ShowVerticalRuler { // is wrapped in text editor control
get;
set;
}
Encoding Encoding {
get;
set;
}
bool EnableFolding { // is wrapped in text editor control
get;
set;
}
bool ShowLineNumbers { // is wrapped in text editor control
get;
set;
}
/// <summary>
/// The width of a tab.
/// </summary>
int TabIndent { // is wrapped in text editor control
get;
set;
}
/// <summary>
/// The amount of spaces a tab is converted to if ConvertTabsToSpaces is true.
/// </summary>
int IndentationSize {
get;
set;
}
IndentStyle IndentStyle { // is wrapped in text editor control
get;
set;
}
DocumentSelectionMode DocumentSelectionMode {
get;
set;
}
Font Font { // is wrapped in text editor control
get;
set;
}
FontContainer FontContainer {
get;
}
BracketMatchingStyle BracketMatchingStyle { // is wrapped in text editor control
get;
set;
}
bool SupportReadOnlySegments {
get;
set;
}
}
}

View File

@@ -0,0 +1,44 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
namespace ICSharpCode.TextEditor.Document
{
/// <summary>
/// A list of events that are fired after the line manager has finished working.
/// </summary>
struct DeferredEventList
{
internal List<LineSegment> removedLines;
internal List<TextAnchor> textAnchor;
public void AddRemovedLine(LineSegment line)
{
if (removedLines == null)
removedLines = new List<LineSegment>();
removedLines.Add(line);
}
public void AddDeletedAnchor(TextAnchor anchor)
{
if (textAnchor == null)
textAnchor = new List<TextAnchor>();
textAnchor.Add(anchor);
}
public void RaiseEvents()
{
// removedLines is raised by the LineManager
if (textAnchor != null) {
foreach (TextAnchor a in textAnchor) {
a.RaiseDeleted();
}
}
}
}
}

View File

@@ -0,0 +1,369 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ICSharpCode.TextEditor.Document
{
internal sealed class LineManager
{
LineSegmentTree lineCollection = new LineSegmentTree();
IDocument document;
IHighlightingStrategy highlightingStrategy;
public IList<LineSegment> LineSegmentCollection {
get {
return lineCollection;
}
}
public int TotalNumberOfLines {
get {
return lineCollection.Count;
}
}
public IHighlightingStrategy HighlightingStrategy {
get {
return highlightingStrategy;
}
set {
if (highlightingStrategy != value) {
highlightingStrategy = value;
if (highlightingStrategy != null) {
highlightingStrategy.MarkTokens(document);
}
}
}
}
public LineManager(IDocument document, IHighlightingStrategy highlightingStrategy)
{
this.document = document;
this.highlightingStrategy = highlightingStrategy;
}
public int GetLineNumberForOffset(int offset)
{
return GetLineSegmentForOffset(offset).LineNumber;
}
public LineSegment GetLineSegmentForOffset(int offset)
{
return lineCollection.GetByOffset(offset);
}
public LineSegment GetLineSegment(int lineNr)
{
return lineCollection[lineNr];
}
public void Insert(int offset, string text)
{
Replace(offset, 0, text);
}
public void Remove(int offset, int length)
{
Replace(offset, length, string.Empty);
}
public void Replace(int offset, int length, string text)
{
Debug.WriteLine("Replace offset="+offset+" length="+length+" text.Length="+text.Length);
int lineStart = GetLineNumberForOffset(offset);
int oldNumberOfLines = this.TotalNumberOfLines;
DeferredEventList deferredEventList = new DeferredEventList();
RemoveInternal(ref deferredEventList, offset, length);
int numberOfLinesAfterRemoving = this.TotalNumberOfLines;
if (!string.IsNullOrEmpty(text)) {
InsertInternal(offset, text);
}
// #if DEBUG
// Console.WriteLine("New line collection:");
// Console.WriteLine(lineCollection.GetTreeAsString());
// Console.WriteLine("New text:");
// Console.WriteLine("'" + document.TextContent + "'");
// #endif
// Only fire events after RemoveInternal+InsertInternal finished completely:
// Otherwise we would expose inconsistent state to the event handlers.
RunHighlighter(lineStart, 1 + Math.Max(0, this.TotalNumberOfLines - numberOfLinesAfterRemoving));
if (deferredEventList.removedLines != null) {
foreach (LineSegment ls in deferredEventList.removedLines)
OnLineDeleted(new LineEventArgs(document, ls));
}
deferredEventList.RaiseEvents();
if (this.TotalNumberOfLines != oldNumberOfLines) {
OnLineCountChanged(new LineCountChangeEventArgs(document, lineStart, this.TotalNumberOfLines - oldNumberOfLines));
}
}
void RemoveInternal(ref DeferredEventList deferredEventList, int offset, int length)
{
Debug.Assert(length >= 0);
if (length == 0) return;
LineSegmentTree.Enumerator it = lineCollection.GetEnumeratorForOffset(offset);
LineSegment startSegment = it.Current;
int startSegmentOffset = startSegment.Offset;
if (offset + length < startSegmentOffset + startSegment.TotalLength) {
// just removing a part of this line segment
startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, length);
SetSegmentLength(startSegment, startSegment.TotalLength - length);
return;
}
// merge startSegment with another line segment because startSegment's delimiter was deleted
// possibly remove lines in between if multiple delimiters were deleted
int charactersRemovedInStartLine = startSegmentOffset + startSegment.TotalLength - offset;
Debug.Assert(charactersRemovedInStartLine > 0);
startSegment.RemovedLinePart(ref deferredEventList, offset - startSegmentOffset, charactersRemovedInStartLine);
LineSegment endSegment = lineCollection.GetByOffset(offset + length);
if (endSegment == startSegment) {
// special case: we are removing a part of the last line up to the
// end of the document
SetSegmentLength(startSegment, startSegment.TotalLength - length);
return;
}
int endSegmentOffset = endSegment.Offset;
int charactersLeftInEndLine = endSegmentOffset + endSegment.TotalLength - (offset + length);
endSegment.RemovedLinePart(ref deferredEventList, 0, endSegment.TotalLength - charactersLeftInEndLine);
startSegment.MergedWith(endSegment, offset - startSegmentOffset);
SetSegmentLength(startSegment, startSegment.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
startSegment.DelimiterLength = endSegment.DelimiterLength;
// remove all segments between startSegment (excl.) and endSegment (incl.)
it.MoveNext();
LineSegment segmentToRemove;
do {
segmentToRemove = it.Current;
it.MoveNext();
lineCollection.RemoveSegment(segmentToRemove);
segmentToRemove.Deleted(ref deferredEventList);
} while (segmentToRemove != endSegment);
}
void InsertInternal(int offset, string text)
{
LineSegment segment = lineCollection.GetByOffset(offset);
DelimiterSegment ds = NextDelimiter(text, 0);
if (ds == null) {
// no newline is being inserted, all text is inserted in a single line
segment.InsertedLinePart(offset - segment.Offset, text.Length);
SetSegmentLength(segment, segment.TotalLength + text.Length);
return;
}
LineSegment firstLine = segment;
firstLine.InsertedLinePart(offset - firstLine.Offset, ds.Offset);
int lastDelimiterEnd = 0;
while (ds != null) {
// split line segment at line delimiter
int lineBreakOffset = offset + ds.Offset + ds.Length;
int segmentOffset = segment.Offset;
int lengthAfterInsertionPos = segmentOffset + segment.TotalLength - (offset + lastDelimiterEnd);
lineCollection.SetSegmentLength(segment, lineBreakOffset - segmentOffset);
LineSegment newSegment = lineCollection.InsertSegmentAfter(segment, lengthAfterInsertionPos);
segment.DelimiterLength = ds.Length;
segment = newSegment;
lastDelimiterEnd = ds.Offset + ds.Length;
ds = NextDelimiter(text, lastDelimiterEnd);
}
firstLine.SplitTo(segment);
// insert rest after last delimiter
if (lastDelimiterEnd != text.Length) {
segment.InsertedLinePart(0, text.Length - lastDelimiterEnd);
SetSegmentLength(segment, segment.TotalLength + text.Length - lastDelimiterEnd);
}
}
void SetSegmentLength(LineSegment segment, int newTotalLength)
{
int delta = newTotalLength - segment.TotalLength;
if (delta != 0) {
lineCollection.SetSegmentLength(segment, newTotalLength);
OnLineLengthChanged(new LineLengthChangeEventArgs(document, segment, delta));
}
}
void RunHighlighter(int firstLine, int lineCount)
{
if (highlightingStrategy != null) {
List<LineSegment> markLines = new List<LineSegment>();
LineSegmentTree.Enumerator it = lineCollection.GetEnumeratorForIndex(firstLine);
for (int i = 0; i < lineCount && it.IsValid; i++) {
markLines.Add(it.Current);
it.MoveNext();
}
highlightingStrategy.MarkTokens(document, markLines);
}
}
public void SetContent(string text)
{
lineCollection.Clear();
if (text != null) {
Replace(0, 0, text);
}
}
public int GetVisibleLine(int logicalLineNumber)
{
if (!document.TextEditorProperties.EnableFolding) {
return logicalLineNumber;
}
int visibleLine = 0;
int foldEnd = 0;
List<FoldMarker> foldings = document.FoldingManager.GetTopLevelFoldedFoldings();
foreach (FoldMarker fm in foldings) {
if (fm.StartLine >= logicalLineNumber) {
break;
}
if (fm.StartLine >= foldEnd) {
visibleLine += fm.StartLine - foldEnd;
if (fm.EndLine > logicalLineNumber) {
return visibleLine;
}
foldEnd = fm.EndLine;
}
}
// Debug.Assert(logicalLineNumber >= foldEnd);
visibleLine += logicalLineNumber - foldEnd;
return visibleLine;
}
public int GetFirstLogicalLine(int visibleLineNumber)
{
if (!document.TextEditorProperties.EnableFolding) {
return visibleLineNumber;
}
int v = 0;
int foldEnd = 0;
List<FoldMarker> foldings = document.FoldingManager.GetTopLevelFoldedFoldings();
foreach (FoldMarker fm in foldings) {
if (fm.StartLine >= foldEnd) {
if (v + fm.StartLine - foldEnd >= visibleLineNumber) {
break;
}
v += fm.StartLine - foldEnd;
foldEnd = fm.EndLine;
}
}
// help GC
foldings.Clear();
foldings = null;
return foldEnd + visibleLineNumber - v;
}
public int GetLastLogicalLine(int visibleLineNumber)
{
if (!document.TextEditorProperties.EnableFolding) {
return visibleLineNumber;
}
return GetFirstLogicalLine(visibleLineNumber + 1) - 1;
}
// TODO : speedup the next/prev visible line search
// HOW? : save the foldings in a sorted list and lookup the
// line numbers in this list
public int GetNextVisibleLineAbove(int lineNumber, int lineCount)
{
int curLineNumber = lineNumber;
if (document.TextEditorProperties.EnableFolding) {
for (int i = 0; i < lineCount && curLineNumber < TotalNumberOfLines; ++i) {
++curLineNumber;
while (curLineNumber < TotalNumberOfLines && (curLineNumber >= lineCollection.Count || !document.FoldingManager.IsLineVisible(curLineNumber))) {
++curLineNumber;
}
}
} else {
curLineNumber += lineCount;
}
return Math.Min(TotalNumberOfLines - 1, curLineNumber);
}
public int GetNextVisibleLineBelow(int lineNumber, int lineCount)
{
int curLineNumber = lineNumber;
if (document.TextEditorProperties.EnableFolding) {
for (int i = 0; i < lineCount; ++i) {
--curLineNumber;
while (curLineNumber >= 0 && !document.FoldingManager.IsLineVisible(curLineNumber)) {
--curLineNumber;
}
}
} else {
curLineNumber -= lineCount;
}
return Math.Max(0, curLineNumber);
}
// use always the same DelimiterSegment object for the NextDelimiter
DelimiterSegment delimiterSegment = new DelimiterSegment();
DelimiterSegment NextDelimiter(string text, int offset)
{
for (int i = offset; i < text.Length; i++) {
switch (text[i]) {
case '\r':
if (i + 1 < text.Length) {
if (text[i + 1] == '\n') {
delimiterSegment.Offset = i;
delimiterSegment.Length = 2;
return delimiterSegment;
}
}
#if DATACONSISTENCYTEST
Debug.Assert(false, "Found lone \\r, data consistency problems?");
#endif
goto case '\n';
case '\n':
delimiterSegment.Offset = i;
delimiterSegment.Length = 1;
return delimiterSegment;
}
}
return null;
}
void OnLineCountChanged(LineCountChangeEventArgs e)
{
if (LineCountChanged != null) {
LineCountChanged(this, e);
}
}
void OnLineLengthChanged(LineLengthChangeEventArgs e)
{
if (LineLengthChanged != null) {
LineLengthChanged(this, e);
}
}
void OnLineDeleted(LineEventArgs e)
{
if (LineDeleted != null) {
LineDeleted(this, e);
}
}
public event EventHandler<LineLengthChangeEventArgs> LineLengthChanged;
public event EventHandler<LineCountChangeEventArgs> LineCountChanged;
public event EventHandler<LineEventArgs> LineDeleted;
sealed class DelimiterSegment
{
internal int Offset;
internal int Length;
}
}
}

View File

@@ -0,0 +1,97 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.TextEditor.Document
{
public class LineCountChangeEventArgs : EventArgs
{
IDocument document;
int start;
int moved;
/// <returns>
/// always a valid Document which is related to the Event.
/// </returns>
public IDocument Document {
get {
return document;
}
}
/// <returns>
/// -1 if no offset was specified for this event
/// </returns>
public int LineStart {
get {
return start;
}
}
/// <returns>
/// -1 if no length was specified for this event
/// </returns>
public int LinesMoved {
get {
return moved;
}
}
public LineCountChangeEventArgs(IDocument document, int lineStart, int linesMoved)
{
this.document = document;
this.start = lineStart;
this.moved = linesMoved;
}
}
public class LineEventArgs : EventArgs
{
IDocument document;
LineSegment lineSegment;
public IDocument Document {
get { return document; }
}
public LineSegment LineSegment {
get { return lineSegment; }
}
public LineEventArgs(IDocument document, LineSegment lineSegment)
{
this.document = document;
this.lineSegment = lineSegment;
}
public override string ToString()
{
return string.Format("[LineEventArgs Document={0} LineSegment={1}]", this.document, this.lineSegment);
}
}
public class LineLengthChangeEventArgs : LineEventArgs
{
int lengthDelta;
public int LengthDelta {
get { return lengthDelta; }
}
public LineLengthChangeEventArgs(IDocument document, LineSegment lineSegment, int moved)
: base(document, lineSegment)
{
this.lengthDelta = moved;
}
public override string ToString()
{
return string.Format("[LineLengthEventArgs Document={0} LineSegment={1} LengthDelta={2}]", this.Document, this.LineSegment, this.lengthDelta);
}
}
}

Some files were not shown because too many files have changed in this diff Show More