first commit
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
13
ICSharpCode.TextEditor/Project/Properties/AssemblyInfo.cs
Normal 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)]
|
||||
193
ICSharpCode.TextEditor/Project/Properties/Resources.Designer.cs
generated
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
160
ICSharpCode.TextEditor/Project/Properties/Resources.resx
Normal 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>
|
||||
3
ICSharpCode.TextEditor/Project/Readme.txt
Normal 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
|
||||
17
ICSharpCode.TextEditor/Project/Resources/ASPX.xshd
Normal 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"><%</Begin>
|
||||
<End color="Black" bgcolor="Yellow">%></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>
|
||||
32
ICSharpCode.TextEditor/Project/Resources/BAT-Mode.xshd
Normal 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>
|
||||
303
ICSharpCode.TextEditor/Project/Resources/Boo.xshd
Normal 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>&<>~!@$%^*()-+=|\#/{}[]:;"' , .?</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="<"/>
|
||||
<Key word=">"/>
|
||||
<Key word="^"/>
|
||||
<Key word="="/>
|
||||
<Key word="~"/>
|
||||
<Key word="!"/>
|
||||
<Key word="|"/>
|
||||
<Key word="&"/>
|
||||
</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>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</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>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</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>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
|
||||
|
||||
<Span name="Formatting" stopateol="false" bold="false" italic="false" color="#993366" >
|
||||
<Begin >${</Begin>
|
||||
<End >}</End>
|
||||
</Span>
|
||||
|
||||
</RuleSet>
|
||||
|
||||
</RuleSets>
|
||||
|
||||
</SyntaxDefinition>
|
||||
|
||||
206
ICSharpCode.TextEditor/Project/Resources/CPP-Mode.xshd
Normal 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>~!%^*()-+=|\#/{}[]:;"'<> , .?</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>'</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 = "*" />
|
||||
<Key word = "<" />
|
||||
<Key word = ">" />
|
||||
<Key word = "^" />
|
||||
<Key word = "=" />
|
||||
<Key word = "~" />
|
||||
<Key word = "!" />
|
||||
<Key word = "|" />
|
||||
<Key word = "&" />
|
||||
</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>
|
||||
|
||||
339
ICSharpCode.TextEditor/Project/Resources/CSharp-Mode.xshd
Normal 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>&<>~!%^*()-+=|\#/{}[]:;"' , .?</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>'</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 = "*" />
|
||||
<Key word = "<" />
|
||||
<Key word = ">" />
|
||||
<Key word = "^" />
|
||||
<Key word = "=" />
|
||||
<Key word = "~" />
|
||||
<Key word = "!" />
|
||||
<Key word = "|" />
|
||||
<Key word = "&" />
|
||||
</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><>~!@%^*()-+=|\#/{}[]:;"' , .?</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><>~!@%^*()-+=|\#/{}[]:;"' , .?</Delimiters>
|
||||
|
||||
<Span name = "XmlTag" rule = "XmlDocSet" bold = "false" italic = "false" color = "Gray" stopateol = "true">
|
||||
<Begin><</Begin>
|
||||
<End>></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>&<>~!%^*()-+=|\#/{}[]:;"' , .?</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><>~!@%^*()-+=|\#/{}[]:;"' , .?</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>
|
||||
|
||||
97
ICSharpCode.TextEditor/Project/Resources/Coco-Mode.xshd
Normal 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>&<>~!@%^*()-+=|\#/{}[]:;"' , .?</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" ><</Begin>
|
||||
<End bold="true" color = "Black" >></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>
|
||||
|
||||
385
ICSharpCode.TextEditor/Project/Resources/HTML-Mode.xshd
Normal 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><!--</Begin>
|
||||
<End>--></End>
|
||||
</Span>
|
||||
<Span name="ScriptTag" rule="JavaScriptSet" bold="false" italic="false" color="SpringGreen" stopateol="false">
|
||||
<Begin><script></Begin>
|
||||
<End></script></End>
|
||||
</Span>
|
||||
<Span name="JavaScriptTag" rule="JavaScriptSet" bold="false" italic="false" color="SpringGreen" stopateol="false">
|
||||
<Begin><script lang="JavaScript"></Begin>
|
||||
<End></script></End>
|
||||
</Span>
|
||||
<Span name="JScriptTag" bold="false" italic="false" color="SpringGreen" stopateol="false">
|
||||
<Begin><script lang="JScript"></Begin>
|
||||
<End></script></End>
|
||||
</Span>
|
||||
<Span name="VBScriptTag" bold="false" italic="false" color="SpringGreen" stopateol="false">
|
||||
<Begin><script lang="VBScript"></Begin>
|
||||
<End></script></End>
|
||||
</Span>
|
||||
<Span name="UnknownScriptTag" bold="false" italic="false" color="SpringGreen" stopateol="false">
|
||||
<Begin><script@C</Begin>
|
||||
<End></script></End>
|
||||
</Span>
|
||||
<Span name="HtmlTag" rule="HtmlTagSet" bold="false" italic="false" color="DarkMagenta" stopateol="false">
|
||||
<Begin><</Begin>
|
||||
<End>></End>
|
||||
</Span>
|
||||
|
||||
<Span name="EntityReference" rule="EntityReferenceSet" bold="false" italic="false" color="Blue" stopateol="true">
|
||||
<Begin>&</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>"</Begin>
|
||||
<End>"</End>
|
||||
</Span>
|
||||
|
||||
<Span name="Char" bold="false" italic="false" color="Blue" stopateol="true">
|
||||
<Begin>'</Begin>
|
||||
<End>'</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>
|
||||
66
ICSharpCode.TextEditor/Project/Resources/JSON.xshd
Normal 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>&<>~%^*()-+=!|\/{}[]:;"' , ?</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>
|
||||
180
ICSharpCode.TextEditor/Project/Resources/Java-Mode.xshd
Normal 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>~!%^*()-+=|\#/{}[]:;"'<> , .?</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 = "<" />
|
||||
<Key word = ">" />
|
||||
<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>~!%^*()-+=|\#/{}[]:;"'<> , .?</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>
|
||||
136
ICSharpCode.TextEditor/Project/Resources/JavaScript-Mode.xshd
Normal 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>=!><+-/*%&|^~.}{,;][?:</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>"</Begin>
|
||||
<End>"</End>
|
||||
</Span>
|
||||
|
||||
<Span name = "Character" bold = "false" italic = "false" color = "Sienna" stopateol = "true" escapecharacter="\">
|
||||
<Begin>'</Begin>
|
||||
<End>'</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>
|
||||
|
||||
101
ICSharpCode.TextEditor/Project/Resources/Lua-Mode.xshd
Normal 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>~@$%^&*()+=|\[]{};"'<> ,#: </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 = "<" />
|
||||
<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 = "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>
|
||||
296
ICSharpCode.TextEditor/Project/Resources/Mode.xsd
Normal 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>
|
||||
198
ICSharpCode.TextEditor/Project/Resources/PHP-Mode.xshd
Normal 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>~!%^*()-+=|\#/{}[]:;"'<> , .?</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 = "<" />
|
||||
<Key word = ">" />
|
||||
<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>~!@%^*()-+=|\#/{}[]:;"'<> , .?</Delimiters>
|
||||
<KeyWords name ="Testword" bold="true" italic = "true" color = "Red">
|
||||
<Key word = "TODO" />
|
||||
</KeyWords>
|
||||
</RuleSet>
|
||||
|
||||
<RuleSet name ="DocumentSet" ignorecase = "false">
|
||||
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'<> , .?</Delimiters>
|
||||
|
||||
<Span name ="XMLTAG" rule = "XMLDocuSet" bold ="false" italic ="true" color ="Gray" stopateol ="true">
|
||||
<Begin><</Begin>
|
||||
<End>></End>
|
||||
</Span>
|
||||
|
||||
<KeyWords name ="Testword" bold="true" italic = "true" color = "Red">
|
||||
<Key word = "TODO" />
|
||||
</KeyWords>
|
||||
</RuleSet>
|
||||
|
||||
<RuleSet name ="XMLDocuSet" ignorecase = "false">
|
||||
<Delimiters>~!@%^*()-+=|\#/{}[]:;"'<> , .?</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>
|
||||
|
||||
37
ICSharpCode.TextEditor/Project/Resources/Patch-Mode.xshd
Normal 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>~!%^*()-+=|\#/{}[]:;"'<> , .?</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>
|
||||
|
||||
BIN
ICSharpCode.TextEditor/Project/Resources/RightArrow.cur
Normal file
|
After Width: | Height: | Size: 326 B |
200
ICSharpCode.TextEditor/Project/Resources/SQL-Mode.xshd
Normal 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>&<>~!%^*()-+=|\#/{}[]:;"' , .?</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>
|
||||
61
ICSharpCode.TextEditor/Project/Resources/SyntaxModes.xml
Normal 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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
108
ICSharpCode.TextEditor/Project/Resources/Tex-Mode.xshd
Normal 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>&~!@%^*()-+=|\#/{}[]:;"'<> , .?</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 = ">" />
|
||||
<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 = "`" />
|
||||
</KeyWords>
|
||||
</RuleSet>
|
||||
|
||||
<RuleSet name = "MathMode" ignorecase = "false">
|
||||
<Delimiters>&~!@%^*()-+=|\#/{}[]:;"'<> , .?</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 = ">" />
|
||||
<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 = "`" />
|
||||
</KeyWords>
|
||||
</RuleSet>
|
||||
</RuleSets>
|
||||
|
||||
</SyntaxDefinition>
|
||||
|
||||
BIN
ICSharpCode.TextEditor/Project/Resources/TextEditorControl.bmp
Normal file
|
After Width: | Height: | Size: 824 B |
265
ICSharpCode.TextEditor/Project/Resources/VBNET-Mode.xshd
Normal 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>~!@%^*()-+=|\#/{}[]:;"'<>,.?</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>~!@%^*()-+=|\#/{}[]:;"'<>,.?</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>
|
||||
60
ICSharpCode.TextEditor/Project/Resources/XML-Mode.xshd
Normal 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="<!--"/>
|
||||
<Property name="BlockCommentEnd" value="-->"/>
|
||||
</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><!--</Begin>
|
||||
<End>--></End>
|
||||
</Span>
|
||||
<Span name="CDataSection" bold="false" italic="false" color="Blue" stopateol="false">
|
||||
<Begin><![CDATA[</Begin>
|
||||
<End>]]></End>
|
||||
</Span>
|
||||
<Span name="DocTypeSection" bold="false" italic="false" color="Blue" stopateol="false">
|
||||
<Begin><!DOCTYPE</Begin>
|
||||
<End>></End>
|
||||
</Span>
|
||||
<Span name="XmlDecl" bold="false" italic="false" color="Blue" stopateol="false">
|
||||
<Begin><?</Begin>
|
||||
<End>?></End>
|
||||
</Span>
|
||||
<Span name="XmlTag" rule="XmlTagSet" bold="false" italic="false" color="DarkMagenta" stopateol="false">
|
||||
<Begin><</Begin>
|
||||
<End>></End>
|
||||
</Span>
|
||||
<Span name="EntityReference" bold="false" italic="false" color="Blue" stopateol="true">
|
||||
<Begin>&</Begin>
|
||||
<End>;</End>
|
||||
</Span>
|
||||
</RuleSet>
|
||||
|
||||
<RuleSet name="XmlTagSet" ignorecase="false">
|
||||
<Delimiters>/=</Delimiters>
|
||||
<Span name="String" bold="false" italic="false" color="Blue" stopateol="true">
|
||||
<Begin>"</Begin>
|
||||
<End>"</End>
|
||||
</Span>
|
||||
<Span name="Char" bold="false" italic="false" color="Blue" stopateol="true">
|
||||
<Begin>'</Begin>
|
||||
<End>'</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>
|
||||
BIN
ICSharpCode.TextEditor/Project/Resources/cut.png
Normal file
|
After Width: | Height: | Size: 648 B |
BIN
ICSharpCode.TextEditor/Project/Resources/htmlpage.png
Normal file
|
After Width: | Height: | Size: 614 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_cancel.png
Normal file
|
After Width: | Height: | Size: 510 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_copy.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_cut.png
Normal file
|
After Width: | Height: | Size: 802 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_linearrowend.png
Normal file
|
After Width: | Height: | Size: 539 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_paste.png
Normal file
|
After Width: | Height: | Size: 793 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_redo.png
Normal file
|
After Width: | Height: | Size: 894 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_searchdialog.png
Normal file
|
After Width: | Height: | Size: 680 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_selectall.png
Normal file
|
After Width: | Height: | Size: 595 B |
BIN
ICSharpCode.TextEditor/Project/Resources/sc_undo.png
Normal file
|
After Width: | Height: | Size: 888 B |
BIN
ICSharpCode.TextEditor/Project/Resources/splitdocument.png
Normal file
|
After Width: | Height: | Size: 614 B |
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
203
ICSharpCode.TextEditor/Project/Src/Actions/CaretActions.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
68
ICSharpCode.TextEditor/Project/Src/Actions/FoldActions.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
219
ICSharpCode.TextEditor/Project/Src/Actions/FormatActions.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
ICSharpCode.TextEditor/Project/Src/Actions/HomeEndActions.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
ICSharpCode.TextEditor/Project/Src/Actions/IEditAction.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
902
ICSharpCode.TextEditor/Project/Src/Actions/MiscActions.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
176
ICSharpCode.TextEditor/Project/Src/Actions/SelectionActions.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 < 0 and bookmarks > 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
457
ICSharpCode.TextEditor/Project/Src/Document/DefaultDocument.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
ICSharpCode.TextEditor/Project/Src/Document/DocumentEventArgs.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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("&", "&");
|
||||
encodedValue.Replace("<", "<");
|
||||
encodedValue.Replace(">", ">");
|
||||
|
||||
if (quoteChar == '"')
|
||||
{
|
||||
encodedValue.Replace("\"", """);
|
||||
}
|
||||
else
|
||||
{
|
||||
encodedValue.Replace("'", "'");
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Span>, 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
315
ICSharpCode.TextEditor/Project/Src/Document/IDocument.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
32
ICSharpCode.TextEditor/Project/Src/Document/ISegment.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||