Для Linux-версии исправлен DockContent, редактор (показ всплывающего окна)
Сделан новый проект VisualPABCLinux И пришлось склонировать PluginsSupport, поскольку он вносит зависимость по редактору Компоненты WeifenLuo для Linux надо после перекомпиляции скопировать в Libraries - подшить их к основному проекту просто не получилось
This commit is contained in:
parent
45a8d6fd6d
commit
3072383106
|
|
@ -15,7 +15,7 @@ internal static class RevisionClass
|
|||
public const string Major = "3";
|
||||
public const string Minor = "8";
|
||||
public const string Build = "3";
|
||||
public const string Revision = "3129";
|
||||
public const string Revision = "3134";
|
||||
|
||||
public const string MainVersion = Major + "." + Minor;
|
||||
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%MINOR%=8
|
||||
%REVISION%=3129
|
||||
%COREVERSION%=3
|
||||
%REVISION%=3134
|
||||
%MINOR%=8
|
||||
%MAJOR%=3
|
||||
|
|
|
|||
19
ICSharpCode.TextEditorLinux/Configuration/AssemblyInfo.cs
Normal file
19
ICSharpCode.TextEditorLinux/Configuration/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1618 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
[assembly: StringFreezing()]
|
||||
|
||||
[assembly: AssemblyTitle("ICSharpCode.TextEditor")]
|
||||
[assembly: AssemblyDescription("A .NET text editor control")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
259
ICSharpCode.TextEditorLinux/ICSharpCode.TextEditorLinux.csproj
Normal file
259
ICSharpCode.TextEditorLinux/ICSharpCode.TextEditorLinux.csproj
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2D18BE89-D210-49EB-A9DD-2246FBB3DF6D}</ProjectGuid>
|
||||
<AssemblyName>ICSharpCode.TextEditorLinux</AssemblyName>
|
||||
<OutputTarget>Library</OutputTarget>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<NoStdLib>False</NoStdLib>
|
||||
<NoConfig>False</NoConfig>
|
||||
<RunPostBuildEvent>OnSuccessfulBuild</RunPostBuildEvent>
|
||||
<OutputType>Library</OutputType>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Resources\ICSharpCode.TextEditor.snk</AssemblyOriginatorKeyFile>
|
||||
<RootNamespace>ICSharpCode.TextEditor</RootNamespace>
|
||||
<RegisterForComInterop>False</RegisterForComInterop>
|
||||
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
|
||||
<BaseAddress>98041856</BaseAddress>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<FileAlignment>4096</FileAlignment>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<Optimize>False</Optimize>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<CodeAnalysisRules>-Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Design#CA1062;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1303;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA1304;-Microsoft.Globalization#CA1305;-Microsoft.Globalization#CA1300;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1718;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1705;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1706;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1807;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1816;-Microsoft.Performance#CA1817;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1818;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2100;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2110;-Microsoft.Security#CA2120;-Microsoft.Security#CA2101;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Usage#CA2209;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2215;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA2202;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2241;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230</CodeAnalysisRules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<Optimize>True</Optimize>
|
||||
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
<OutputPath>..\bin\</OutputPath>
|
||||
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DebugType>Full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DebugType>None</DebugType>
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.XML" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Src\Document\DefaultDocument.cs" />
|
||||
<Compile Include="Src\Document\DocumentEventArgs.cs" />
|
||||
<Compile Include="Src\Document\DocumentFactory.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightingDefinitionInvalidException.cs" />
|
||||
<Compile Include="Src\Document\IDocument.cs" />
|
||||
<Compile Include="Src\Document\ISegment.cs" />
|
||||
<Compile Include="Src\Document\LineManager\LineSegmentTree.cs" />
|
||||
<Compile Include="Src\Document\TextAnchor.cs" />
|
||||
<Compile Include="Src\Document\TextLocation.cs" />
|
||||
<Compile Include="Src\Document\TextUtilities.cs" />
|
||||
<Compile Include="Src\Document\BookmarkManager\BookmarkManager.cs" />
|
||||
<Compile Include="Src\Document\CustomLineManager\CustomLineManager.cs" />
|
||||
<Compile Include="Src\Document\CustomLineManager\ICustomLineManager.cs" />
|
||||
<Compile Include="Src\Document\BookmarkManager\BookmarkManagerMemento.cs" />
|
||||
<Compile Include="Src\Document\FormattingStrategy\DefaultFormattingStrategy.cs" />
|
||||
<Compile Include="Src\Document\FormattingStrategy\IFormattingStrategy.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\DefaultHighlightingStrategy.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\FontContainer.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightBackground.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightColor.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightInfo.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightingColorNotFoundException.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightingDefinitionParser.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightingManager.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightingStrategyFactory.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\HighlightRuleSet.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\IHighlightingStrategy.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\NextMarker.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\PrevMarker.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\Span.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\TextWord.cs" />
|
||||
<Compile Include="Src\Document\LineManager\LineManager.cs" />
|
||||
<Compile Include="Src\Document\LineManager\LineSegment.cs" />
|
||||
<Compile Include="Src\Document\LineManager\LineManagerEventArgs.cs" />
|
||||
<Compile Include="Src\Document\TextBufferStrategy\GapTextBufferStrategy.cs" />
|
||||
<Compile Include="Src\Document\TextBufferStrategy\ITextBufferStrategy.cs" />
|
||||
<Compile Include="Src\Document\TextBufferStrategy\StringTextBufferStrategy.cs" />
|
||||
<Compile Include="Src\Util\AugmentableRedBlackTree.cs" />
|
||||
<Compile Include="Src\Util\LookupTable.cs" />
|
||||
<Compile Include="Src\Util\RedBlackTreeIterator.cs" />
|
||||
<Compile Include="Src\Util\TextUtility.cs" />
|
||||
<Compile Include="Src\Undo\UndoableDelete.cs" />
|
||||
<Compile Include="Src\Undo\UndoableInsert.cs" />
|
||||
<Compile Include="Src\Undo\UndoableReplace.cs" />
|
||||
<Compile Include="Src\Actions\ClipBoardActions.cs" />
|
||||
<Compile Include="Src\Actions\CaretActions.cs" />
|
||||
<Compile Include="Src\Actions\HomeEndActions.cs" />
|
||||
<Compile Include="Src\Actions\IEditAction.cs" />
|
||||
<Compile Include="Src\Actions\MiscActions.cs" />
|
||||
<Compile Include="Src\Actions\SelectionActions.cs" />
|
||||
<Compile Include="Src\Document\Selection\ISelection.cs" />
|
||||
<Compile Include="Src\Document\Selection\DefaultSelection.cs" />
|
||||
<Compile Include="Src\Document\FoldingStrategy\IFoldingStrategy.cs" />
|
||||
<Compile Include="Src\Document\FoldingStrategy\IndentFoldingStrategy.cs" />
|
||||
<Compile Include="Src\Gui\Ime.cs" />
|
||||
<Compile Include="Src\Gui\TextAreaUpdate.cs" />
|
||||
<Compile Include="Src\Document\Selection\SelectionManager.cs" />
|
||||
<Compile Include="Src\Gui\CompletionWindow\ICompletionData.cs" />
|
||||
<Compile Include="Src\Gui\CompletionWindow\ICompletionDataProvider.cs" />
|
||||
<Compile Include="Src\Gui\CompletionWindow\CodeCompletionWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\CompletionWindow\DeclarationViewWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\InsightWindow\IInsightDataProvider.cs" />
|
||||
<Compile Include="Src\Gui\InsightWindow\InsightWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Util\RtfWriter.cs" />
|
||||
<Compile Include="Src\Document\FoldingStrategy\FoldingManager.cs" />
|
||||
<Compile Include="Src\Document\AbstractSegment.cs" />
|
||||
<Compile Include="Src\Document\FoldingStrategy\FoldMarker.cs" />
|
||||
<Compile Include="Src\Util\TipPainter.cs" />
|
||||
<Compile Include="Src\Util\TipSection.cs" />
|
||||
<Compile Include="Src\Util\TipText.cs" />
|
||||
<Compile Include="Src\Util\TipSplitter.cs" />
|
||||
<Compile Include="Src\Util\TipSpacer.cs" />
|
||||
<Compile Include="Src\Util\TipPainterTools.cs" />
|
||||
<Compile Include="Src\Document\ITextEditorProperties.cs" />
|
||||
<Compile Include="Src\Gui\Caret.cs" />
|
||||
<Compile Include="Src\Gui\TextArea.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\TextEditorControl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\TextEditorControlBase.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\TextAreaClipboardHandler.cs" />
|
||||
<Compile Include="Src\Gui\TextView.cs" />
|
||||
<Compile Include="Src\Gui\GutterMargin.cs" />
|
||||
<Compile Include="Src\Gui\AbstractMargin.cs" />
|
||||
<Compile Include="Src\Undo\IUndoableOperation.cs" />
|
||||
<Compile Include="Src\Undo\UndoQueue.cs" />
|
||||
<Compile Include="Src\Undo\UndoStack.cs" />
|
||||
<Compile Include="Src\Gui\TextAreaControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\TextAreaMouseHandler.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\SyntaxModes\ISyntaxModeFileProvider.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\SyntaxModes\SyntaxMode.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\SyntaxModes\ResourceSyntaxModeProvider.cs" />
|
||||
<Compile Include="Src\Gui\IconBarMargin.cs" />
|
||||
<Compile Include="Src\Gui\FoldMargin.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\SyntaxModes\FileSyntaxModeProvider.cs" />
|
||||
<Compile Include="Src\Document\Selection\ColumnRange.cs" />
|
||||
<Compile Include="Src\Gui\TextAreaDragDropHandler.cs" />
|
||||
<Compile Include="Src\Gui\BracketHighlighter.cs" />
|
||||
<Compile Include="Src\Actions\BookmarkActions.cs" />
|
||||
<Compile Include="Src\Actions\FoldActions.cs" />
|
||||
<Compile Include="Src\Actions\FormatActions.cs" />
|
||||
<Compile Include="Src\Document\DefaultTextEditorProperties.cs" />
|
||||
<Compile Include="Src\Document\MarkerStrategy\MarkerStrategy.cs" />
|
||||
<Compile Include="Src\Document\MarkerStrategy\TextMarker.cs" />
|
||||
<Compile Include="Src\Gui\CompletionWindow\AbstractCompletionWindow.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\CompletionWindow\CodeCompletionListView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Gui\BrushRegistry.cs" />
|
||||
<Compile Include="Src\Gui\HRuler.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Src\Document\BookmarkManager\Bookmark.cs" />
|
||||
<Compile Include="Src\Document\BookmarkManager\BookmarkEventHandler.cs" />
|
||||
<Compile Include="Configuration\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Resources\ASPX.xshd" />
|
||||
<EmbeddedResource Include="Resources\BAT-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\CPP-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\Coco-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\CSharp-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\HTML-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\Breakpoint.png" />
|
||||
<EmbeddedResource Include="Resources\Breakpoint32x32.png" />
|
||||
<EmbeddedResource Include="Resources\Breakpoint24x24.png" />
|
||||
<EmbeddedResource Include="Resources\ConditionBreakpoint24x24.png" />
|
||||
<None Include="Resources\ICSharpCode.TextEditor.snk" />
|
||||
<EmbeddedResource Include="Resources\TextEditorControl.bmp" />
|
||||
<EmbeddedResource Include="Resources\Java-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\JavaScript-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\Mode.xsd" />
|
||||
<EmbeddedResource Include="Resources\PHP-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\RightArrow.cur" />
|
||||
<EmbeddedResource Include="Resources\SyntaxModes.xml" />
|
||||
<EmbeddedResource Include="Resources\Tex-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\VBNET-Mode.xshd" />
|
||||
<EmbeddedResource Include="Resources\XML-Mode.xshd" />
|
||||
<Compile Include="Src\Util\FileReader.cs" />
|
||||
<EmbeddedResource Include="Resources\Boo.xshd" />
|
||||
<Compile Include="Src\Gui\DrawableLine.cs" />
|
||||
<Compile Include="Src\Gui\ToolTipRequestEventArgs.cs" />
|
||||
<Compile Include="Src\Document\HighlightingStrategy\SpanStack.cs" />
|
||||
<Compile Include="Src\Util\WeakCollection.cs" />
|
||||
<EmbeddedResource Include="Resources\Patch-Mode.xshd" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
17
ICSharpCode.TextEditorLinux/Resources/ASPX.xshd
Normal file
17
ICSharpCode.TextEditorLinux/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.TextEditorLinux/Resources/BAT-Mode.xshd
Normal file
32
ICSharpCode.TextEditorLinux/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>
|
||||
314
ICSharpCode.TextEditorLinux/Resources/Boo.xshd
Normal file
314
ICSharpCode.TextEditorLinux/Resources/Boo.xshd
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<SyntaxDefinition name="Boo" extensions=".boo">
|
||||
|
||||
<Environment>
|
||||
<Default bold="false" italic="false" color="SystemColors.WindowText" bgcolor="SystemColors.Window" />
|
||||
<Selection bold="false" italic="false" color="SystemColors.HighlightText" bgcolor="SystemColors.Highlight" />
|
||||
<VRuler bold="false" italic="false" color="SystemColors.ControlLight" />
|
||||
<InvalidLines bold="false" italic="false" color="Red" />
|
||||
<CaretMarker bold="false" italic="false" color="Yellow" />
|
||||
<LineNumbers bold="false" italic="false" color="SystemColors.ControlDark" bgcolor="SystemColors.Window" />
|
||||
<FoldLine bold="false" italic="false" color="Gray" bgcolor="Black" />
|
||||
<FoldMarker bold="false" italic="false" color="Gray" bgcolor="White" />
|
||||
<EOLMarkers bold="false" italic="false" color="#E0E0E5" />
|
||||
<SpaceMarkers bold="false" italic="false" color="#E0E0E5" />
|
||||
<TabMarkers bold="false" italic="false" color="#E0E0E5" />
|
||||
<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="given"/>
|
||||
<Key word="when"/>
|
||||
<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>
|
||||
|
||||
BIN
ICSharpCode.TextEditorLinux/Resources/Breakpoint.png
Normal file
BIN
ICSharpCode.TextEditorLinux/Resources/Breakpoint.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 858 B |
BIN
ICSharpCode.TextEditorLinux/Resources/Breakpoint24x24.png
Normal file
BIN
ICSharpCode.TextEditorLinux/Resources/Breakpoint24x24.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
ICSharpCode.TextEditorLinux/Resources/Breakpoint32x32.png
Normal file
BIN
ICSharpCode.TextEditorLinux/Resources/Breakpoint32x32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
206
ICSharpCode.TextEditorLinux/Resources/CPP-Mode.xshd
Normal file
206
ICSharpCode.TextEditorLinux/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>
|
||||
|
||||
338
ICSharpCode.TextEditorLinux/Resources/CSharp-Mode.xshd
Normal file
338
ICSharpCode.TextEditorLinux/Resources/CSharp-Mode.xshd
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
<?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 = "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.TextEditorLinux/Resources/Coco-Mode.xshd
Normal file
97
ICSharpCode.TextEditorLinux/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>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
385
ICSharpCode.TextEditorLinux/Resources/HTML-Mode.xshd
Normal file
385
ICSharpCode.TextEditorLinux/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>
|
||||
BIN
ICSharpCode.TextEditorLinux/Resources/ICSharpCode.TextEditor.snk
Normal file
BIN
ICSharpCode.TextEditorLinux/Resources/ICSharpCode.TextEditor.snk
Normal file
Binary file not shown.
180
ICSharpCode.TextEditorLinux/Resources/Java-Mode.xshd
Normal file
180
ICSharpCode.TextEditorLinux/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.TextEditorLinux/Resources/JavaScript-Mode.xshd
Normal file
136
ICSharpCode.TextEditorLinux/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>
|
||||
|
||||
295
ICSharpCode.TextEditorLinux/Resources/Mode.xsd
Normal file
295
ICSharpCode.TextEditorLinux/Resources/Mode.xsd
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
<?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="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.TextEditorLinux/Resources/PHP-Mode.xshd
Normal file
198
ICSharpCode.TextEditorLinux/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.TextEditorLinux/Resources/Patch-Mode.xshd
Normal file
37
ICSharpCode.TextEditorLinux/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.TextEditorLinux/Resources/RightArrow.cur
Normal file
BIN
ICSharpCode.TextEditorLinux/Resources/RightArrow.cur
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 326 B |
57
ICSharpCode.TextEditorLinux/Resources/SyntaxModes.xml
Normal file
57
ICSharpCode.TextEditorLinux/Resources/SyntaxModes.xml
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<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 = "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>
|
||||
108
ICSharpCode.TextEditorLinux/Resources/Tex-Mode.xshd
Normal file
108
ICSharpCode.TextEditorLinux/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.TextEditorLinux/Resources/TextEditorControl.bmp
Normal file
BIN
ICSharpCode.TextEditorLinux/Resources/TextEditorControl.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 824 B |
265
ICSharpCode.TextEditorLinux/Resources/VBNET-Mode.xshd
Normal file
265
ICSharpCode.TextEditorLinux/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.TextEditorLinux/Resources/XML-Mode.xshd
Normal file
60
ICSharpCode.TextEditorLinux/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>
|
||||
78
ICSharpCode.TextEditorLinux/Src/Actions/BookmarkActions.cs
Normal file
78
ICSharpCode.TextEditorLinux/Src/Actions/BookmarkActions.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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.Line);
|
||||
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.Line = mark.LineNumber;
|
||||
textArea.SelectionManager.ClearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.Line = mark.LineNumber;
|
||||
textArea.SelectionManager.ClearSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.TextEditorLinux/Src/Actions/CaretActions.cs
Normal file
203
ICSharpCode.TextEditorLinux/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: 2681 $</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);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
ICSharpCode.TextEditorLinux/Src/Actions/ClipBoardActions.cs
Normal file
42
ICSharpCode.TextEditorLinux/Src/Actions/ClipBoardActions.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
ICSharpCode.TextEditorLinux/Src/Actions/FoldActions.cs
Normal file
54
ICSharpCode.TextEditorLinux/Src/Actions/FoldActions.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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);
|
||||
foreach (FoldMarker fm in foldMarkers) {
|
||||
fm.IsFolded = !fm.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
213
ICSharpCode.TextEditorLinux/Src/Actions/FormatActions.cs
Normal file
213
ICSharpCode.TextEditorLinux/Src/Actions/FormatActions.cs
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2640 $</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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 FormatBuffer : AbstractLineFormatAction
|
||||
{
|
||||
protected override void Convert(IDocument document, int startLine, int endLine)
|
||||
{
|
||||
document.FormattingStrategy.IndentLines(textArea, startLine, endLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
114
ICSharpCode.TextEditorLinux/Src/Actions/HomeEndActions.cs
Normal file
114
ICSharpCode.TextEditorLinux/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: 2659 $</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.TextEditorLinux/Src/Actions/IEditAction.cs
Normal file
58
ICSharpCode.TextEditorLinux/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: 1965 $</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);
|
||||
}
|
||||
}
|
||||
926
ICSharpCode.TextEditorLinux/Src/Actions/MiscActions.cs
Normal file
926
ICSharpCode.TextEditorLinux/Src/Actions/MiscActions.cs
Normal file
|
|
@ -0,0 +1,926 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2659 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
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.Document.ReadOnly) {
|
||||
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.UpdateQueue.Clear();
|
||||
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 bool Equals(object obj)
|
||||
{
|
||||
BlockCommentRegion commentRegion = obj as BlockCommentRegion;
|
||||
if (commentRegion != null) {
|
||||
if (commentRegion.commentStart == commentStart &&
|
||||
commentRegion.commentEnd == commentEnd &&
|
||||
commentRegion.startOffset == startOffset &&
|
||||
commentRegion.endOffset == endOffset) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return commentStart.GetHashCode() & commentEnd.GetHashCode() & startOffset.GetHashCode() & endOffset.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public class IndentSelection : 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;
|
||||
}
|
||||
textArea.BeginUpdate();
|
||||
if (textArea.SelectionManager.HasSomethingSelected) {
|
||||
foreach (ISelection selection in textArea.SelectionManager.SelectionCollection) {
|
||||
textArea.Document.FormattingStrategy.IndentLines(textArea, selection.StartPosition.Y, selection.EndPosition.Y);
|
||||
}
|
||||
} else {
|
||||
textArea.Document.FormattingStrategy.IndentLines(textArea, 0, textArea.Document.TotalNumberOfLines - 1);
|
||||
}
|
||||
textArea.EndUpdate();
|
||||
textArea.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
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.Document.ReadOnly) {
|
||||
return;
|
||||
}
|
||||
if (textArea.SelectionManager.HasSomethingSelected) {
|
||||
textArea.BeginUpdate();
|
||||
textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
|
||||
textArea.SelectionManager.RemoveSelectedText();
|
||||
textArea.ScrollToCaret();
|
||||
textArea.EndUpdate();
|
||||
} else {
|
||||
if (textArea.Caret.Offset > 0) {
|
||||
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)));
|
||||
textArea.EndUpdate();
|
||||
} 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
|
||||
{
|
||||
/// <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.SelectionManager.HasSomethingSelected) {
|
||||
textArea.BeginUpdate();
|
||||
textArea.Caret.Position = textArea.SelectionManager.SelectionCollection[0].StartPosition;
|
||||
textArea.SelectionManager.RemoveSelectedText();
|
||||
textArea.ScrollToCaret();
|
||||
textArea.EndUpdate();
|
||||
} else {
|
||||
|
||||
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(textArea.Caret.DesiredColumn, requestedLineNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(textArea.Caret.DesiredColumn, requestedLineNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
public class Return : 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;
|
||||
}
|
||||
textArea.BeginUpdate();
|
||||
textArea.Document.UndoStack.StartUndoGroup();
|
||||
try {
|
||||
if (textArea.HandleKeyPress('\n'))
|
||||
{
|
||||
textArea.Document.UndoStack.EndUndoGroup();
|
||||
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
|
||||
textArea.BeginUpdate();
|
||||
if (textArea.SelectionManager.HasSomethingSelected) {
|
||||
textArea.SelectionManager.RemoveSelectedText();
|
||||
textArea.ScrollToCaret();
|
||||
}
|
||||
// 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) {
|
||||
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;
|
||||
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 anything is selected we will just delete it first
|
||||
textArea.BeginUpdate();
|
||||
if (textArea.SelectionManager.HasSomethingSelected) {
|
||||
textArea.SelectionManager.RemoveSelectedText();
|
||||
textArea.ScrollToCaret();
|
||||
}
|
||||
// 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) {
|
||||
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);
|
||||
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.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.TextEditorLinux/Src/Actions/SelectionActions.cs
Normal file
176
ICSharpCode.TextEditorLinux/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: 2659 $</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();
|
||||
}
|
||||
}
|
||||
}
|
||||
52
ICSharpCode.TextEditorLinux/Src/Document/AbstractSegment.cs
Normal file
52
ICSharpCode.TextEditorLinux/Src/Document/AbstractSegment.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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,137 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</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;
|
||||
LineSegment line;
|
||||
int lineNumber;
|
||||
bool isEnabled = true;
|
||||
|
||||
public IDocument Document {
|
||||
get {
|
||||
return document;
|
||||
}
|
||||
set {
|
||||
if (document != value) {
|
||||
if (line != null) {
|
||||
lineNumber = line.LineNumber;
|
||||
line = null;
|
||||
}
|
||||
document = value;
|
||||
if (document != null) {
|
||||
line = document.GetLineSegment(Math.Min(lineNumber, document.TotalNumberOfLines-1));
|
||||
}
|
||||
OnDocumentChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the line the bookmark belongs to.
|
||||
/// Is null if the bookmark is not connected to a document.
|
||||
/// </summary>
|
||||
public LineSegment Line {
|
||||
get { return line; }
|
||||
}
|
||||
|
||||
public int LineNumber {
|
||||
get {
|
||||
if (line != null)
|
||||
return line.LineNumber;
|
||||
else
|
||||
return lineNumber;
|
||||
}
|
||||
set {
|
||||
if (value < 0)
|
||||
throw new ArgumentOutOfRangeException("value", value, "line number must be >= 0");
|
||||
if (document == null) {
|
||||
lineNumber = value;
|
||||
} else {
|
||||
line = document.GetLineSegment(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <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, int lineNumber) : this(document, lineNumber, true)
|
||||
{
|
||||
}
|
||||
|
||||
public Bookmark(IDocument document, int lineNumber, bool isEnabled)
|
||||
{
|
||||
this.document = document;
|
||||
this.isEnabled = isEnabled;
|
||||
this.LineNumber = lineNumber;
|
||||
}
|
||||
|
||||
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: 915 $</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,254 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
public interface IBookmarkFactory
|
||||
{
|
||||
Bookmark CreateBookmark(IDocument document, int lineNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class handles the bookmarks for a buffer
|
||||
/// </summary>
|
||||
public class BookmarkManager
|
||||
{
|
||||
IDocument document;
|
||||
List<Bookmark> bookmark = new List<Bookmark>();
|
||||
|
||||
/// <value>
|
||||
/// Contains all bookmarks
|
||||
/// </value>
|
||||
public List<Bookmark> Marks {
|
||||
get {
|
||||
return 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;
|
||||
lineTracker.LineDeleted += delegate(object sender, LineEventArgs e) {
|
||||
for (int i = 0; i < bookmark.Count; i++) {
|
||||
Bookmark b = bookmark[i];
|
||||
if (b.Line == e.LineSegment) {
|
||||
bookmark.RemoveAt(i--);
|
||||
OnRemoved(new BookmarkEventArgs(b));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
IBookmarkFactory factory;
|
||||
|
||||
public IBookmarkFactory Factory {
|
||||
get {
|
||||
return factory;
|
||||
}
|
||||
set {
|
||||
factory = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the mark at the line <code>lineNr</code> if it is not set, if the
|
||||
/// line is already marked the mark is cleared.
|
||||
/// </summary>
|
||||
public void ToggleMarkAt(int lineNr)
|
||||
{
|
||||
Bookmark newMark;
|
||||
if (factory != null)
|
||||
newMark = factory.CreateBookmark(document, lineNr);
|
||||
else
|
||||
newMark = new Bookmark(document, lineNr);
|
||||
|
||||
Type newMarkType = newMark.GetType();
|
||||
|
||||
for (int i = 0; i < bookmark.Count; ++i) {
|
||||
Bookmark mark = bookmark[i];
|
||||
|
||||
if (mark.LineNumber == lineNr && 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: 915 $</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(Int32.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Ivo Kovacka" email="ivok@internet.sk"/>
|
||||
// <version>$Revision: 2691 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to store a pair of lineNr and its color
|
||||
/// </summary>
|
||||
public class CustomLine
|
||||
{
|
||||
public int StartLineNr;
|
||||
public int EndLineNr;
|
||||
public Color Color;
|
||||
public bool ReadOnly;
|
||||
|
||||
public CustomLine(int lineNr, Color customColor, bool readOnly)
|
||||
{
|
||||
this.StartLineNr = this.EndLineNr = lineNr;
|
||||
this.Color = customColor;
|
||||
this.ReadOnly = readOnly;
|
||||
}
|
||||
|
||||
public CustomLine(int startLineNr, int endLineNr, Color customColor, bool readOnly)
|
||||
{
|
||||
this.StartLineNr = startLineNr;
|
||||
this.EndLineNr = endLineNr;
|
||||
this.Color = customColor;
|
||||
this.ReadOnly = readOnly;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class handles the bookmarks for a buffer
|
||||
/// </summary>
|
||||
public class CustomLineManager : ICustomLineManager
|
||||
{
|
||||
List<CustomLine> lines = new List<CustomLine>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="CustomLineManager"/>
|
||||
/// </summary>
|
||||
internal CustomLineManager(LineManager lineTracker)
|
||||
{
|
||||
lineTracker.LineCountChanged += MoveIndices;
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Contains all custom lines
|
||||
/// </value>
|
||||
public List<CustomLine> CustomLines {
|
||||
get {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns the Color if the line <code>lineNr</code> has custom bg color
|
||||
/// otherwise returns <code>defaultColor</code>
|
||||
/// </remarks>
|
||||
public Color GetCustomColor(int lineNr, Color defaultColor)
|
||||
{
|
||||
foreach(CustomLine line in lines)
|
||||
if (line.StartLineNr <= lineNr && line.EndLineNr >= lineNr)
|
||||
return line.Color;
|
||||
return defaultColor;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns the ReadOnly if the line <code>lineNr</code> is custom
|
||||
/// otherwise returns <code>default</code>
|
||||
/// </remarks>
|
||||
public bool IsReadOnly(int lineNr, bool defaultReadOnly)
|
||||
{
|
||||
foreach(CustomLine line in lines)
|
||||
if (line.StartLineNr <= lineNr && line.EndLineNr >= lineNr)
|
||||
return line.ReadOnly;
|
||||
return defaultReadOnly;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns true if <code>selection</code> is read only
|
||||
/// </remarks>
|
||||
public bool IsReadOnly(ISelection selection, bool defaultReadOnly)
|
||||
{
|
||||
int startLine = selection.StartPosition.Y;
|
||||
int endLine = selection.EndPosition.Y;
|
||||
foreach (CustomLine customLine in lines) {
|
||||
if (customLine.ReadOnly == false)
|
||||
continue;
|
||||
if (startLine < customLine.StartLineNr && endLine < customLine.StartLineNr)
|
||||
continue;
|
||||
if (startLine > customLine.EndLineNr && endLine > customLine.EndLineNr)
|
||||
continue;
|
||||
return true;
|
||||
}
|
||||
return defaultReadOnly;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Clears all custom lines
|
||||
/// </remarks>
|
||||
public void Clear()
|
||||
{
|
||||
OnBeforeChanged();
|
||||
lines.Clear();
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Is fired before the change
|
||||
/// </remarks>
|
||||
public event EventHandler BeforeChanged;
|
||||
|
||||
/// <remarks>
|
||||
/// Is fired after the change
|
||||
/// </remarks>
|
||||
public event EventHandler Changed;
|
||||
|
||||
|
||||
|
||||
void OnChanged()
|
||||
{
|
||||
if (Changed != null) {
|
||||
Changed(this, null);
|
||||
}
|
||||
}
|
||||
void OnBeforeChanged()
|
||||
{
|
||||
if (BeforeChanged != null) {
|
||||
BeforeChanged(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Set Custom Line at the line <code>lineNr</code>
|
||||
/// </remarks>
|
||||
public void AddCustomLine(int lineNr, Color customColor, bool readOnly)
|
||||
{
|
||||
OnBeforeChanged();
|
||||
lines.Add(new CustomLine(lineNr, customColor, readOnly));
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Add Custom Lines from the line <code>startLineNr</code> to the line <code>endLineNr</code>
|
||||
/// </remarks>
|
||||
public void AddCustomLine(int startLineNr, int endLineNr, Color customColor, bool readOnly)
|
||||
{
|
||||
OnBeforeChanged();
|
||||
lines.Add(new CustomLine(startLineNr, endLineNr, customColor, readOnly));
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Remove Custom Line at the line <code>lineNr</code>
|
||||
/// </remarks>
|
||||
public void RemoveCustomLine(int lineNr)
|
||||
{
|
||||
for (int i = 0; i < lines.Count; ++i) {
|
||||
if (((CustomLine)lines[i]).StartLineNr <= lineNr && ((CustomLine)lines[i]).EndLineNr >= lineNr) {
|
||||
OnBeforeChanged();
|
||||
lines.RemoveAt(i);
|
||||
OnChanged();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method moves all indices from index upward count lines
|
||||
/// (useful for deletion/insertion of text)
|
||||
/// </summary>
|
||||
void MoveIndices(object sender, LineCountChangeEventArgs e)
|
||||
{
|
||||
bool changed = false;
|
||||
OnBeforeChanged();
|
||||
for (int i = 0; i < lines.Count; ++i) {
|
||||
int startLineNr = ((CustomLine)lines[i]).StartLineNr;
|
||||
int endLineNr = ((CustomLine)lines[i]).EndLineNr;
|
||||
if (e.LineStart >= startLineNr && e.LineStart < endLineNr) {
|
||||
changed = true;
|
||||
((CustomLine)lines[i]).EndLineNr += e.LinesMoved;
|
||||
}
|
||||
else if (e.LineStart < startLineNr) {
|
||||
((CustomLine)lines[i]).StartLineNr += e.LinesMoved;
|
||||
((CustomLine)lines[i]).EndLineNr += e.LinesMoved;
|
||||
}
|
||||
else {
|
||||
}
|
||||
/*
|
||||
if (e.LinesMoved < 0 && lineNr == e.LineStart) {
|
||||
lines.RemoveAt(i);
|
||||
--i;
|
||||
changed = true;
|
||||
} else if (lineNr > e.LineStart + 1 || (e.LinesMoved < 0 && lineNr > e.LineStart)) {
|
||||
changed = true;
|
||||
((CustomLine)lines[i]).StartLineNr += e.LinesMoved;
|
||||
((CustomLine)lines[i]).EndLineNr += e.LinesMoved;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
OnChanged();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Ivo Kovacka" email="ivok@internet.sk"/>
|
||||
// <version>$Revision: 1959 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// This class handles the custom lines for a buffer
|
||||
/// </summary>
|
||||
public interface ICustomLineManager
|
||||
{
|
||||
/// <value>
|
||||
/// Contains all custom lines
|
||||
/// </value>
|
||||
List<CustomLine> CustomLines {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns the Color if the line <code>lineNr</code> has custom bg color
|
||||
/// otherwise returns <code>defaultColor</code>
|
||||
/// </remarks>
|
||||
Color GetCustomColor(int lineNr, Color defaultColor);
|
||||
|
||||
/// <remarks>
|
||||
/// Returns true if the line <code>lineNr</code> is read only
|
||||
/// </remarks>
|
||||
bool IsReadOnly(int lineNr, bool defaultReadOnly);
|
||||
|
||||
/// <remarks>
|
||||
/// Returns true if <code>selection</code> is read only
|
||||
/// </remarks>
|
||||
bool IsReadOnly(ISelection selection, bool defaultReadOnly);
|
||||
|
||||
/// <remarks>
|
||||
/// Add Custom Line at the line <code>lineNr</code>
|
||||
/// </remarks>
|
||||
void AddCustomLine(int lineNr, Color customColor, bool readOnly);
|
||||
|
||||
/// <remarks>
|
||||
/// Add Custom Lines from the line <code>startLineNr</code> to the line <code>endLineNr</code>
|
||||
/// </remarks>
|
||||
void AddCustomLine(int startLineNr, int endLineNr, Color customColor, bool readOnly);
|
||||
|
||||
/// <remarks>
|
||||
/// Remove Custom Line at the line <code>lineNr</code>
|
||||
/// </remarks>
|
||||
void RemoveCustomLine(int lineNr);
|
||||
|
||||
/// <remarks>
|
||||
/// Clears all custom color lines
|
||||
/// </remarks>
|
||||
void Clear();
|
||||
|
||||
/// <remarks>
|
||||
/// Is fired before the change
|
||||
/// </remarks>
|
||||
event EventHandler BeforeChanged;
|
||||
|
||||
/// <remarks>
|
||||
/// Is fired after the change
|
||||
/// </remarks>
|
||||
event EventHandler Changed;
|
||||
}
|
||||
}
|
||||
460
ICSharpCode.TextEditorLinux/Src/Document/DefaultDocument.cs
Normal file
460
ICSharpCode.TextEditorLinux/Src/Document/DefaultDocument.cs
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</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;
|
||||
ICustomLineManager customLineManager;
|
||||
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 ICustomLineManager CustomLineManager {
|
||||
get {
|
||||
return customLineManager;
|
||||
}
|
||||
set {
|
||||
customLineManager = 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
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i) {
|
||||
ISegment fm = list[i];
|
||||
|
||||
if (e.Offset <= fm.Offset && fm.Offset <= e.Offset + e.Length ||
|
||||
e.Offset <= fm.Offset + fm.Length && fm.Offset + fm.Length <= e.Offset + e.Length) {
|
||||
list.RemoveAt(i);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fm.Offset <= e.Offset && e.Offset <= fm.Offset + fm.Length) {
|
||||
if (e.Text != null) {
|
||||
fm.Length += e.Text.Length;
|
||||
}
|
||||
if (e.Length > 0) {
|
||||
fm.Length -= e.Length;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fm.Offset >= e.Offset) {
|
||||
if (e.Text != null) {
|
||||
fm.Offset += e.Text.Length;
|
||||
}
|
||||
if (e.Length > 0) {
|
||||
fm.Offset -= e.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,316 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="none" email=""/>
|
||||
// <version>$Revision: 2683 $</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 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 createBackupCopy = false;
|
||||
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 useCustomLine = 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 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 CreateBackupCopy {
|
||||
get {
|
||||
return createBackupCopy;
|
||||
}
|
||||
set {
|
||||
createBackupCopy = 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 UseCustomLine {
|
||||
get {
|
||||
return useCustomLine;
|
||||
}
|
||||
set {
|
||||
useCustomLine = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
ICSharpCode.TextEditorLinux/Src/Document/DocumentEventArgs.cs
Normal file
103
ICSharpCode.TextEditorLinux/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: 915 $</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);
|
||||
}
|
||||
}
|
||||
}
|
||||
58
ICSharpCode.TextEditorLinux/Src/Document/DocumentFactory.cs
Normal file
58
ICSharpCode.TextEditorLinux/Src/Document/DocumentFactory.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: 2691 $</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);
|
||||
doc.CustomLineManager = new CustomLineManager(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,179 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2063 $</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 void SetFoldText(string text)
|
||||
{
|
||||
foldText = text;
|
||||
}
|
||||
|
||||
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,333 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</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>();
|
||||
IFoldingStrategy foldingStrategy = null;
|
||||
IDocument document;
|
||||
|
||||
public IList<FoldMarker> FoldMarker {
|
||||
get {
|
||||
return foldMarker.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
public IFoldingStrategy FoldingStrategy {
|
||||
get {
|
||||
return foldingStrategy;
|
||||
}
|
||||
set {
|
||||
foldingStrategy = value;
|
||||
}
|
||||
}
|
||||
|
||||
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 = Int32.Parse(lines[i]);
|
||||
int length = Int32.Parse(lines[i + 1]);
|
||||
string text = lines[i + 2];
|
||||
bool isFolded = Boolean.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) {
|
||||
}
|
||||
}
|
||||
|
||||
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: 1965 $</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,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: 915 $</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,180 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2643 $</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);
|
||||
textArea.Document.Replace(oldLine.Offset, oldLine.Length, newLineText);
|
||||
}
|
||||
return indentation.Length;
|
||||
}
|
||||
|
||||
/// <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
|
||||
bool kavs = false;
|
||||
for (int i = offset; i >= 0; --i) {
|
||||
char ch = document.GetCharAt(i);
|
||||
if (ch == openBracket) {
|
||||
if (!kavs || ch == '{')
|
||||
++brackets;
|
||||
if (brackets == 0) return i;
|
||||
} else if (ch == closingBracket) {
|
||||
if (!kavs || ch == '}')
|
||||
--brackets;
|
||||
}
|
||||
else if (ch == '"')
|
||||
{
|
||||
break;
|
||||
} else if (ch == '\'') {
|
||||
kavs = !kavs;
|
||||
} 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;
|
||||
bool kavs = false;
|
||||
// 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) {
|
||||
if (!kavs || ch == '{')
|
||||
++brackets;
|
||||
} else if (ch == closingBracket) {
|
||||
if (!kavs || ch == '}')
|
||||
--brackets;
|
||||
if (brackets == 0) return i;
|
||||
} else if (ch == '"') {
|
||||
break;
|
||||
} else if (ch == '\'') {
|
||||
kavs = !kavs;
|
||||
} 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: 2640 $</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,949 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2683 $</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 : IHighlightingStrategy
|
||||
{
|
||||
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["LineNumbers"] = new HighlightBackground("ControlDark", "Window", false, false);
|
||||
|
||||
environmentColors["FoldLine"] = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.Black, false, false);
|
||||
environmentColors["FoldMarker"] = new HighlightColor(Color.FromArgb(0x80, 0x80, 0x80), Color.White, false, false);
|
||||
environmentColors["SelectedFoldLine"] = new HighlightColor(Color.Black, 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) {
|
||||
if (ruleSet.Reference != null) {
|
||||
IHighlightingStrategy highlighter = HighlightingManager.Manager.FindHighlighter (ruleSet.Reference);
|
||||
|
||||
if (highlighter != null) {
|
||||
ruleSet.Highlighter = highlighter;
|
||||
} else {
|
||||
ruleSet.Highlighter = this;
|
||||
throw new HighlightingDefinitionInvalidException("The mode defintion " + ruleSet.Reference + " which is refered from the " + this.Name + " mode definition could not be found");
|
||||
}
|
||||
} else {
|
||||
ruleSet.Highlighter = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
// SSM 21/02/2022 - пробую исправить step
|
||||
var fi = words.FindIndex(tw => string.Compare(tw.Word,"for",true)==0);
|
||||
if (fi >= 0)
|
||||
{
|
||||
var toi = words.FindIndex(fi,tw => string.Compare(tw.Word, "to", true) == 0);
|
||||
if (toi >= 0)
|
||||
{
|
||||
var stepi = words.FindIndex(toi,tw => string.Compare(tw.Word, "step", true) == 0);
|
||||
if (stepi >= 0)
|
||||
{
|
||||
var doi = words.FindIndex(stepi, tw => string.Compare(tw.Word, "do", true) == 0);
|
||||
if (doi >= 0)
|
||||
{
|
||||
var f = words[fi];
|
||||
var w = words[stepi];
|
||||
w.SyntaxColor = f.SyntaxColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var fe = words.FindIndex(tw => string.Compare(tw.Word, "foreach", true) == 0);
|
||||
if (fe >= 0)
|
||||
{
|
||||
var index = words.FindIndex(tw => string.Compare(tw.Word, "index", true) == 0);
|
||||
if (index >= 0)
|
||||
{
|
||||
var f = words[fe];
|
||||
var ind = words[index];
|
||||
ind.SyntaxColor = f.SyntaxColor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
//processedLines[lineToProcess] = 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;
|
||||
|
||||
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 < currentLine.Length; ++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, currentLineOffset))
|
||||
{
|
||||
PushCurWord(document, ref markNext, words);
|
||||
string regex = GetRegString(currentLine, activeSpan.End, i, document, currentLineOffset);
|
||||
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, currentLineOffset))
|
||||
{
|
||||
|
||||
PushCurWord(document, ref markNext, words);
|
||||
|
||||
string regex = GetRegString(currentLine, span.Begin, i, document, currentLineOffset);
|
||||
|
||||
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);
|
||||
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));
|
||||
} else {
|
||||
words.Add(new TextWord(document, currentLine, currentOffset, currentLength, c, 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 currentLineOffset)
|
||||
{
|
||||
int j = 0;
|
||||
StringBuilder regexpr = new StringBuilder();
|
||||
int offset = currentLineOffset;
|
||||
int length = lineSegment.Length;
|
||||
for (int i = 0; i < expr.Length; ++i, ++j) {
|
||||
if (index + j >= length)
|
||||
break;
|
||||
|
||||
switch (expr[i]) {
|
||||
case '@': // "special" meaning
|
||||
++i;
|
||||
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(offset + index + j));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (expr[i] != document.GetCharAt(offset + index + j)) {
|
||||
return regexpr.ToString();
|
||||
}
|
||||
regexpr.Append(document.GetCharAt(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, int currentLineOffset)
|
||||
{
|
||||
int offset = currentLineOffset;
|
||||
int length = lineSegment.Length;
|
||||
for (int i = 0, j = 0; i < expr.Length; ++i, ++j) {
|
||||
|
||||
switch (expr[i]) {
|
||||
case '@': // "special" meaning
|
||||
++i;
|
||||
if (i < expr.Length) {
|
||||
switch (expr[i]) {
|
||||
case 'C': // match whitespace or punctuation
|
||||
if (index + j == offset || index + j >= offset + length) {
|
||||
// nothing (EOL or SOL)
|
||||
} else {
|
||||
char ch = document.GetCharAt(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 (offset + index + j + whatmatch.Length < document.TextLength) {
|
||||
int k = 0;
|
||||
for (; k < whatmatch.Length; ++k) {
|
||||
char docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(offset + index + j + k)) : document.GetCharAt(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(offset + index - whatmatch.Length + k)) : document.GetCharAt(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 >= length || '@' != document.GetCharAt(offset + index + j)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (index + j >= length) {
|
||||
return false;
|
||||
}
|
||||
char docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(offset + index + j)) : document.GetCharAt(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: 2313 $</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
|
||||
int pixelSize = (int)(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], Single.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: 1965 $</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,280 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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
|
||||
{
|
||||
bool systemColor = false;
|
||||
string systemColorName = null;
|
||||
|
||||
bool systemBgColor = false;
|
||||
string systemBgColorName = null;
|
||||
|
||||
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 {
|
||||
if (!systemBgColor) {
|
||||
return backgroundcolor;
|
||||
}
|
||||
return ParseColorString(systemBgColorName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The foreground color used
|
||||
/// </value>
|
||||
public Color Color {
|
||||
get {
|
||||
if (!systemColor) {
|
||||
return color;
|
||||
}
|
||||
return ParseColorString(systemColorName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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 = Boolean.Parse(el.Attributes["bold"].InnerText);
|
||||
}
|
||||
|
||||
if (el.Attributes["italic"] != null) {
|
||||
italic = Boolean.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.")) {
|
||||
systemColor = true;
|
||||
systemColorName = 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.")) {
|
||||
systemBgColor = true;
|
||||
systemBgColorName = 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 = Boolean.Parse(el.Attributes["bold"].InnerText);
|
||||
} else {
|
||||
bold = defaultColor.Bold;
|
||||
}
|
||||
|
||||
if (el.Attributes["italic"] != null) {
|
||||
italic = Boolean.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.")) {
|
||||
systemColor = true;
|
||||
systemColorName = 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.")) {
|
||||
systemBgColor = true;
|
||||
systemBgColorName = 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.systemColor = true;
|
||||
systemColorName = systemColor;
|
||||
|
||||
systemBgColor = true;
|
||||
systemBgColorName = systemBackgroundColor;
|
||||
|
||||
this.bold = bold;
|
||||
this.italic = italic;
|
||||
}
|
||||
|
||||
static Color ParseColor(string c)
|
||||
{
|
||||
int a = 255;
|
||||
int offset = 0;
|
||||
if (c.Length > 7) {
|
||||
offset = 2;
|
||||
a = Int32.Parse(c.Substring(1,2), NumberStyles.HexNumber);
|
||||
}
|
||||
|
||||
int r = Int32.Parse(c.Substring(1 + offset,2), NumberStyles.HexNumber);
|
||||
int g = Int32.Parse(c.Substring(3 + offset,2), NumberStyles.HexNumber);
|
||||
int b = Int32.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: 1965 $</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,190 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2115 $</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;
|
||||
IHighlightingStrategy highlighter = null;
|
||||
char escapeCharacter;
|
||||
|
||||
bool ignoreCase = false;
|
||||
string name = null;
|
||||
|
||||
bool[] delimiters = new bool[256];
|
||||
|
||||
string reference = null;
|
||||
|
||||
public ArrayList Spans {
|
||||
get {
|
||||
return spans;
|
||||
}
|
||||
}
|
||||
|
||||
internal IHighlightingStrategy Highlighter {
|
||||
get {
|
||||
return highlighter;
|
||||
}
|
||||
set {
|
||||
highlighter = value;
|
||||
}
|
||||
}
|
||||
|
||||
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 = Boolean.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: 1624 $</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: 2533 $</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: 2533 $</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,163 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2533 $</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 {
|
||||
highlightingStrategy = HighlightingDefinitionParser.Parse(syntaxMode, syntaxModeFileProvider.GetSyntaxModeFile(syntaxMode));
|
||||
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,38 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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,65 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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 {
|
||||
set;
|
||||
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>
|
||||
HighlightRuleSet GetRuleSet(Span span);
|
||||
|
||||
/// <remarks>
|
||||
/// Used internally, do not call
|
||||
/// </remarks>
|
||||
HighlightColor GetColor(IDocument document, LineSegment keyWord, int index, int length);
|
||||
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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: 1965 $</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 = Boolean.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: 1965 $</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 = Boolean.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: 2115 $</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 = Boolean.Parse(span.GetAttribute("stopateol"));
|
||||
}
|
||||
|
||||
begin = span["Begin"].InnerText.ToCharArray();
|
||||
beginColor = new HighlightColor(span["Begin"], color);
|
||||
|
||||
if (span["Begin"].HasAttribute("singleword")) {
|
||||
this.isBeginSingleWord = Boolean.Parse(span["Begin"].GetAttribute("singleword"));
|
||||
}
|
||||
if (span["Begin"].HasAttribute("startofline")) {
|
||||
this.isBeginStartOfLine = Boolean.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 = Boolean.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: 1471 $</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: 2533 $</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: 1301 $</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: 1965 $</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,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: 2533 $</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,236 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</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;
|
||||
}
|
||||
}
|
||||
|
||||
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 + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
322
ICSharpCode.TextEditorLinux/Src/Document/IDocument.cs
Normal file
322
ICSharpCode.TextEditorLinux/Src/Document/IDocument.cs
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ICustomColorLineManager"/> attached to the <see cref="IDocument"/> instance
|
||||
/// </summary>
|
||||
ICustomLineManager CustomLineManager {
|
||||
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.TextEditorLinux/Src/Document/ISegment.cs
Normal file
32
ICSharpCode.TextEditorLinux/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: 1966 $</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,171 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="none" email=""/>
|
||||
// <version>$Revision: 2644 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
public interface ITextEditorProperties
|
||||
{
|
||||
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 UseCustomLine {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</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)
|
||||
{
|
||||
// Console.WriteLine("Replace offset="+offset+" length="+length+" text.Length="+text.Length);
|
||||
int lineStart = GetLineNumberForOffset(offset);
|
||||
int oldNumberOfLines = this.TotalNumberOfLines;
|
||||
List<LineSegment> removedLines = RemoveInternal(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
|
||||
RunHighlighter(lineStart, 1 + Math.Max(0, this.TotalNumberOfLines - numberOfLinesAfterRemoving));
|
||||
if (removedLines != null) {
|
||||
foreach (LineSegment ls in removedLines)
|
||||
OnLineDeleted(new LineEventArgs(document, ls));
|
||||
}
|
||||
if (this.TotalNumberOfLines != oldNumberOfLines) {
|
||||
OnLineCountChanged(new LineCountChangeEventArgs(document, lineStart, this.TotalNumberOfLines - oldNumberOfLines));
|
||||
}
|
||||
}
|
||||
|
||||
List<LineSegment> RemoveInternal(int offset, int length)
|
||||
{
|
||||
Debug.Assert(length >= 0);
|
||||
if (length == 0) return null;
|
||||
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(offset - startSegmentOffset, length);
|
||||
SetSegmentLength(startSegment, startSegment.TotalLength - length);
|
||||
return null;
|
||||
}
|
||||
// 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(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 null;
|
||||
}
|
||||
int endSegmentOffset = endSegment.Offset;
|
||||
int charactersLeftInEndLine = endSegmentOffset + endSegment.TotalLength - (offset + length);
|
||||
endSegment.RemovedLinePart(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();
|
||||
List<LineSegment> removedLines = new List<LineSegment>();
|
||||
LineSegment segmentToRemove;
|
||||
do {
|
||||
segmentToRemove = it.Current;
|
||||
it.MoveNext();
|
||||
lineCollection.RemoveSegment(segmentToRemove);
|
||||
removedLines.Add(segmentToRemove);
|
||||
segmentToRemove.Deleted();
|
||||
} while (segmentToRemove != endSegment);
|
||||
return removedLines;
|
||||
}
|
||||
|
||||
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>(lineCount);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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: 2691 $</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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2691 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
public sealed class LineSegment : ISegment
|
||||
{
|
||||
internal LineSegmentTree.Enumerator treeEntry;
|
||||
int totalLength, delimiterLength;
|
||||
|
||||
List<TextWord> words;
|
||||
SpanStack highlightSpanStack;
|
||||
|
||||
public TextWord GetWord(int column)
|
||||
{
|
||||
int curColumn = 0;
|
||||
foreach (TextWord word in words) {
|
||||
if (column < curColumn + word.Length) {
|
||||
return word;
|
||||
}
|
||||
curColumn += word.Length;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsDeleted {
|
||||
get { return !treeEntry.IsValid; }
|
||||
}
|
||||
|
||||
public int LineNumber {
|
||||
get { return treeEntry.CurrentIndex; }
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
get { return treeEntry.CurrentOffset; }
|
||||
}
|
||||
|
||||
public int Length {
|
||||
get { return totalLength - delimiterLength; }
|
||||
}
|
||||
|
||||
int ISegment.Offset {
|
||||
get { return this.Offset; }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
int ISegment.Length {
|
||||
get { return this.Length; }
|
||||
set { throw new NotSupportedException(); }
|
||||
}
|
||||
|
||||
public int TotalLength {
|
||||
get { return totalLength; }
|
||||
internal set { totalLength = value; }
|
||||
}
|
||||
|
||||
public int DelimiterLength {
|
||||
get { return delimiterLength; }
|
||||
internal set { delimiterLength = value; }
|
||||
}
|
||||
|
||||
// highlighting information
|
||||
public List<TextWord> Words {
|
||||
get {
|
||||
return words;
|
||||
}
|
||||
set {
|
||||
words = value;
|
||||
}
|
||||
}
|
||||
|
||||
public HighlightColor GetColorForPosition(int x)
|
||||
{
|
||||
if (Words != null) {
|
||||
int xPos = 0;
|
||||
foreach (TextWord word in Words) {
|
||||
if (x < xPos + word.Length) {
|
||||
return word.SyntaxColor;
|
||||
}
|
||||
xPos += word.Length;
|
||||
}
|
||||
}
|
||||
return new HighlightColor(Color.Black, false, false);
|
||||
}
|
||||
|
||||
public SpanStack HighlightSpanStack {
|
||||
get {
|
||||
return highlightSpanStack;
|
||||
}
|
||||
set {
|
||||
highlightSpanStack = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="LineSegment"/> instance to string (for debug purposes)
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsDeleted)
|
||||
return "[LineSegment: (deleted) Length = " + Length + ", TotalLength = " + TotalLength + ", DelimiterLength = " + delimiterLength + "]";
|
||||
else
|
||||
return "[LineSegment: LineNumber=" + LineNumber + ", Offset = "+ Offset +", Length = " + Length + ", TotalLength = " + TotalLength + ", DelimiterLength = " + delimiterLength + "]";
|
||||
}
|
||||
|
||||
#region Anchor management
|
||||
Util.WeakCollection<TextAnchor> anchors;
|
||||
|
||||
public TextAnchor CreateAnchor(int column)
|
||||
{
|
||||
TextAnchor anchor = new TextAnchor(this, column);
|
||||
AddAnchor(anchor);
|
||||
return anchor;
|
||||
}
|
||||
|
||||
void AddAnchor(TextAnchor anchor)
|
||||
{
|
||||
Debug.Assert(anchor.Line == this);
|
||||
|
||||
if (anchors == null)
|
||||
anchors = new Util.WeakCollection<TextAnchor>();
|
||||
|
||||
anchors.Add(anchor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called when the LineSegment is deleted.
|
||||
/// </summary>
|
||||
internal void Deleted()
|
||||
{
|
||||
//Console.WriteLine("Deleted");
|
||||
treeEntry = LineSegmentTree.Enumerator.Invalid;
|
||||
if (anchors != null) {
|
||||
foreach (TextAnchor a in anchors) {
|
||||
a.Deleted();
|
||||
}
|
||||
anchors = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called when a part of the line is removed.
|
||||
/// </summary>
|
||||
internal void RemovedLinePart(int startColumn, int length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
Debug.Assert(length > 0);
|
||||
|
||||
//Console.WriteLine("RemovedLinePart " + startColumn + ", " + length);
|
||||
if (anchors != null) {
|
||||
List<TextAnchor> deletedAnchors = null;
|
||||
foreach (TextAnchor a in anchors) {
|
||||
if (a.ColumnNumber > startColumn) {
|
||||
if (a.ColumnNumber >= startColumn + length) {
|
||||
a.ColumnNumber -= length;
|
||||
} else {
|
||||
if (deletedAnchors == null)
|
||||
deletedAnchors = new List<TextAnchor>();
|
||||
a.Deleted();
|
||||
deletedAnchors.Add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (deletedAnchors != null) {
|
||||
foreach (TextAnchor a in deletedAnchors) {
|
||||
anchors.Remove(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called when a part of the line is inserted.
|
||||
/// </summary>
|
||||
internal void InsertedLinePart(int startColumn, int length)
|
||||
{
|
||||
if (length == 0)
|
||||
return;
|
||||
Debug.Assert(length > 0);
|
||||
|
||||
//Console.WriteLine("InsertedLinePart " + startColumn + ", " + length);
|
||||
if (anchors != null) {
|
||||
foreach (TextAnchor a in anchors) {
|
||||
if (a.ColumnNumber >= startColumn) {
|
||||
a.ColumnNumber += length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called after another line's content is appended to this line because the newline in between
|
||||
/// was deleted.
|
||||
/// The DefaultLineManager will call Deleted() on the deletedLine after the MergedWith call.
|
||||
///
|
||||
/// firstLineLength: the length of the line before the merge.
|
||||
/// </summary>
|
||||
internal void MergedWith(LineSegment deletedLine, int firstLineLength)
|
||||
{
|
||||
//Console.WriteLine("MergedWith");
|
||||
|
||||
if (deletedLine.anchors != null) {
|
||||
foreach (TextAnchor a in deletedLine.anchors) {
|
||||
a.Line = this;
|
||||
AddAnchor(a);
|
||||
a.ColumnNumber += firstLineLength;
|
||||
}
|
||||
deletedLine.anchors = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is called after a newline was inserted into this line, splitting it into this and followingLine.
|
||||
/// </summary>
|
||||
internal void SplitTo(LineSegment followingLine)
|
||||
{
|
||||
//Console.WriteLine("SplitTo");
|
||||
|
||||
if (anchors != null) {
|
||||
List<TextAnchor> movedAnchors = null;
|
||||
foreach (TextAnchor a in anchors) {
|
||||
if (a.ColumnNumber > this.Length) {
|
||||
a.Line = followingLine;
|
||||
followingLine.AddAnchor(a);
|
||||
a.ColumnNumber -= this.Length;
|
||||
|
||||
if (movedAnchors == null)
|
||||
movedAnchors = new List<TextAnchor>();
|
||||
movedAnchors.Add(a);
|
||||
}
|
||||
}
|
||||
if (movedAnchors != null) {
|
||||
foreach (TextAnchor a in movedAnchors) {
|
||||
anchors.Remove(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,478 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2683 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using ICSharpCode.TextEditor.Util;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// Data structure for efficient management of the line segments (most operations are O(lg n)).
|
||||
/// This implements an augmented red-black tree where each node has fields for the number of
|
||||
/// nodes in its subtree (like an order statistics tree) for access by index(=line number).
|
||||
/// Additionally, each node knows the total length of all segments in its subtree.
|
||||
/// This means we can find nodes by offset in O(lg n) time. Since the offset itself is not stored in
|
||||
/// the line segment but computed from the lengths stored in the tree, we adjusting the offsets when
|
||||
/// text is inserted in one line means we just have to increment the totalLength of the affected line and
|
||||
/// its parent nodes - an O(lg n) operation.
|
||||
/// However this means getting the line number or offset from a LineSegment is not a constant time
|
||||
/// operation, but takes O(lg n).
|
||||
///
|
||||
/// NOTE: The tree is never empty, Clear() causes it to contain an empty segment.
|
||||
/// </summary>
|
||||
sealed class LineSegmentTree : IList<LineSegment>
|
||||
{
|
||||
internal struct RBNode
|
||||
{
|
||||
internal LineSegment lineSegment;
|
||||
internal int count;
|
||||
internal int totalLength;
|
||||
|
||||
public RBNode(LineSegment lineSegment)
|
||||
{
|
||||
this.lineSegment = lineSegment;
|
||||
this.count = 1;
|
||||
this.totalLength = lineSegment.TotalLength;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "[RBNode count=" + count + " totalLength="+totalLength
|
||||
+ " lineSegment.LineNumber=" + lineSegment.LineNumber
|
||||
+ " lineSegment.Offset=" + lineSegment.Offset
|
||||
+ " lineSegment.TotalLength=" + lineSegment.TotalLength
|
||||
+ " lineSegment.DelimiterLength=" + lineSegment.DelimiterLength + "]";
|
||||
}
|
||||
}
|
||||
|
||||
struct MyHost : IRedBlackTreeHost<RBNode>
|
||||
{
|
||||
public int Compare(RBNode x, RBNode y)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Equals(RBNode a, RBNode b)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UpdateAfterChildrenChange(RedBlackTreeNode<RBNode> node)
|
||||
{
|
||||
int count = 1;
|
||||
int totalLength = node.val.lineSegment.TotalLength;
|
||||
if (node.left != null) {
|
||||
count += node.left.val.count;
|
||||
totalLength += node.left.val.totalLength;
|
||||
}
|
||||
if (node.right != null) {
|
||||
count += node.right.val.count;
|
||||
totalLength += node.right.val.totalLength;
|
||||
}
|
||||
if (count != node.val.count || totalLength != node.val.totalLength) {
|
||||
node.val.count = count;
|
||||
node.val.totalLength = totalLength;
|
||||
if (node.parent != null) UpdateAfterChildrenChange(node.parent);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAfterRotateLeft(RedBlackTreeNode<RBNode> node)
|
||||
{
|
||||
UpdateAfterChildrenChange(node);
|
||||
UpdateAfterChildrenChange(node.parent);
|
||||
}
|
||||
|
||||
public void UpdateAfterRotateRight(RedBlackTreeNode<RBNode> node)
|
||||
{
|
||||
UpdateAfterChildrenChange(node);
|
||||
UpdateAfterChildrenChange(node.parent);
|
||||
}
|
||||
}
|
||||
|
||||
readonly AugmentableRedBlackTree<RBNode, MyHost> tree = new AugmentableRedBlackTree<RBNode, MyHost>(new MyHost());
|
||||
|
||||
RedBlackTreeNode<RBNode> GetNode(int index)
|
||||
{
|
||||
if (index < 0 || index >= tree.Count)
|
||||
return tree.root;
|
||||
//throw new ArgumentOutOfRangeException("index", index, "index should be between 0 and " + (tree.Count-1));
|
||||
RedBlackTreeNode<RBNode> node = tree.root;
|
||||
while (true) {
|
||||
if (node.left != null && index < node.left.val.count) {
|
||||
node = node.left;
|
||||
} else {
|
||||
if (node.left != null) {
|
||||
index -= node.left.val.count;
|
||||
}
|
||||
if (index == 0)
|
||||
return node;
|
||||
index--;
|
||||
node = node.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int GetIndexFromNode(RedBlackTreeNode<RBNode> node)
|
||||
{
|
||||
int index = (node.left != null) ? node.left.val.count : 0;
|
||||
while (node.parent != null) {
|
||||
if (node == node.parent.right) {
|
||||
if (node.parent.left != null)
|
||||
index += node.parent.left.val.count;
|
||||
index++;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
RedBlackTreeNode<RBNode> GetNodeByOffset(int offset)
|
||||
{
|
||||
if (offset < 0 || offset > this.TotalLength)
|
||||
throw new ArgumentOutOfRangeException("offset", offset, "offset should be between 0 and " + this.TotalLength);
|
||||
if (offset == this.TotalLength) {
|
||||
if (tree.root == null)
|
||||
throw new InvalidOperationException("Cannot call GetNodeByOffset while tree is empty.");
|
||||
return tree.root.RightMost;
|
||||
}
|
||||
RedBlackTreeNode<RBNode> node = tree.root;
|
||||
while (true) {
|
||||
if (node.left != null && offset < node.left.val.totalLength) {
|
||||
node = node.left;
|
||||
} else {
|
||||
if (node.left != null) {
|
||||
offset -= node.left.val.totalLength;
|
||||
}
|
||||
offset -= node.val.lineSegment.TotalLength;
|
||||
if (offset < 0)
|
||||
return node;
|
||||
node = node.right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int GetOffsetFromNode(RedBlackTreeNode<RBNode> node)
|
||||
{
|
||||
int offset = (node.left != null) ? node.left.val.totalLength : 0;
|
||||
while (node.parent != null) {
|
||||
if (node == node.parent.right) {
|
||||
if (node.parent.left != null)
|
||||
offset += node.parent.left.val.totalLength;
|
||||
offset += node.parent.val.lineSegment.TotalLength;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public LineSegment GetByOffset(int offset)
|
||||
{
|
||||
return GetNodeByOffset(offset).val.lineSegment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total length of all line segments. Runs in O(1).
|
||||
/// </summary>
|
||||
public int TotalLength {
|
||||
get {
|
||||
if (tree.root == null)
|
||||
return 0;
|
||||
else
|
||||
return tree.root.val.totalLength;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the length of a line segment. Runs in O(lg n).
|
||||
/// </summary>
|
||||
public void SetSegmentLength(LineSegment segment, int newTotalLength)
|
||||
{
|
||||
if (segment == null)
|
||||
throw new ArgumentNullException("segment");
|
||||
RedBlackTreeNode<RBNode> node = segment.treeEntry.it.node;
|
||||
segment.TotalLength = newTotalLength;
|
||||
default(MyHost).UpdateAfterChildrenChange(node);
|
||||
#if DEBUG
|
||||
CheckProperties();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void RemoveSegment(LineSegment segment)
|
||||
{
|
||||
tree.RemoveAt(segment.treeEntry.it);
|
||||
#if DEBUG
|
||||
CheckProperties();
|
||||
#endif
|
||||
}
|
||||
|
||||
public LineSegment InsertSegmentAfter(LineSegment segment, int length)
|
||||
{
|
||||
LineSegment newSegment = new LineSegment();
|
||||
newSegment.TotalLength = length;
|
||||
newSegment.DelimiterLength = segment.DelimiterLength;
|
||||
|
||||
newSegment.treeEntry = InsertAfter(segment.treeEntry.it.node, newSegment);
|
||||
return newSegment;
|
||||
}
|
||||
|
||||
Enumerator InsertAfter(RedBlackTreeNode<RBNode> node, LineSegment newSegment)
|
||||
{
|
||||
RedBlackTreeNode<RBNode> newNode = new RedBlackTreeNode<RBNode>(new RBNode(newSegment));
|
||||
if (node.right == null) {
|
||||
tree.InsertAsRight(node, newNode);
|
||||
} else {
|
||||
tree.InsertAsLeft(node.right.LeftMost, newNode);
|
||||
}
|
||||
#if DEBUG
|
||||
CheckProperties();
|
||||
#endif
|
||||
return new Enumerator(new RedBlackTreeIterator<RBNode>(newNode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of items in the collections. Runs in O(1).
|
||||
/// </summary>
|
||||
public int Count {
|
||||
get { return tree.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an item by index. Runs in O(lg n).
|
||||
/// </summary>
|
||||
public LineSegment this[int index] {
|
||||
get {
|
||||
return GetNode(index).val.lineSegment;
|
||||
}
|
||||
set {
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
bool ICollection<LineSegment>.IsReadOnly {
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of an item. Runs in O(lg n).
|
||||
/// </summary>
|
||||
public int IndexOf(LineSegment item)
|
||||
{
|
||||
int index = item.LineNumber;
|
||||
if (index < 0 || index >= this.Count)
|
||||
return -1;
|
||||
if (item != this[index])
|
||||
return -1;
|
||||
return index;
|
||||
}
|
||||
|
||||
void IList<LineSegment>.RemoveAt(int index)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
[Conditional("DATACONSISTENCYTEST")]
|
||||
void CheckProperties()
|
||||
{
|
||||
if (tree.root == null) {
|
||||
Debug.Assert(this.Count == 0);
|
||||
} else {
|
||||
Debug.Assert(tree.root.val.count == this.Count);
|
||||
CheckProperties(tree.root);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckProperties(RedBlackTreeNode<RBNode> node)
|
||||
{
|
||||
int count = 1;
|
||||
int totalLength = node.val.lineSegment.TotalLength;
|
||||
if (node.left != null) {
|
||||
CheckProperties(node.left);
|
||||
count += node.left.val.count;
|
||||
totalLength += node.left.val.totalLength;
|
||||
}
|
||||
if (node.right != null) {
|
||||
CheckProperties(node.right);
|
||||
count += node.right.val.count;
|
||||
totalLength += node.right.val.totalLength;
|
||||
}
|
||||
Debug.Assert(node.val.count == count);
|
||||
Debug.Assert(node.val.totalLength == totalLength);
|
||||
}
|
||||
|
||||
public string GetTreeAsString()
|
||||
{
|
||||
return tree.GetTreeAsString();
|
||||
}
|
||||
#endif
|
||||
|
||||
public LineSegmentTree()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the list. Runs in O(1).
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
tree.Clear();
|
||||
LineSegment emptySegment = new LineSegment();
|
||||
emptySegment.TotalLength = 0;
|
||||
emptySegment.DelimiterLength = 0;
|
||||
tree.Add(new RBNode(emptySegment));
|
||||
emptySegment.treeEntry = GetEnumeratorForIndex(0);
|
||||
#if DEBUG
|
||||
CheckProperties();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether an item is in the list. Runs in O(n).
|
||||
/// </summary>
|
||||
public bool Contains(LineSegment item)
|
||||
{
|
||||
return IndexOf(item) >= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies all elements from the list to the array.
|
||||
/// </summary>
|
||||
public void CopyTo(LineSegment[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null) throw new ArgumentNullException("array");
|
||||
foreach (LineSegment val in this)
|
||||
array[arrayIndex++] = val;
|
||||
}
|
||||
|
||||
IEnumerator<LineSegment> IEnumerable<LineSegment>.GetEnumerator()
|
||||
{
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(tree.GetEnumerator());
|
||||
}
|
||||
|
||||
public Enumerator GetEnumeratorForIndex(int index)
|
||||
{
|
||||
return new Enumerator(new RedBlackTreeIterator<RBNode>(GetNode(index)));
|
||||
}
|
||||
|
||||
public Enumerator GetEnumeratorForOffset(int offset)
|
||||
{
|
||||
return new Enumerator(new RedBlackTreeIterator<RBNode>(GetNodeByOffset(offset)));
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<LineSegment>
|
||||
{
|
||||
/// <summary>
|
||||
/// An invalid enumerator value. Calling MoveNext on the invalid enumerator
|
||||
/// will always return false, accessing Current will throw an exception.
|
||||
/// </summary>
|
||||
public static readonly Enumerator Invalid = default(Enumerator);
|
||||
|
||||
internal RedBlackTreeIterator<RBNode> it;
|
||||
|
||||
internal Enumerator(RedBlackTreeIterator<RBNode> it)
|
||||
{
|
||||
this.it = it;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value. Runs in O(1).
|
||||
/// </summary>
|
||||
public LineSegment Current {
|
||||
get {
|
||||
return it.Current.lineSegment;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid {
|
||||
get {
|
||||
return it.IsValid;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the current value. Runs in O(lg n).
|
||||
/// </summary>
|
||||
public int CurrentIndex {
|
||||
get {
|
||||
if (it.node == null)
|
||||
throw new InvalidOperationException();
|
||||
return GetIndexFromNode(it.node);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the offset of the current value. Runs in O(lg n).
|
||||
/// </summary>
|
||||
public int CurrentOffset {
|
||||
get {
|
||||
if (it.node == null)
|
||||
throw new InvalidOperationException();
|
||||
return GetOffsetFromNode(it.node);
|
||||
}
|
||||
}
|
||||
|
||||
object System.Collections.IEnumerator.Current {
|
||||
get {
|
||||
return it.Current.lineSegment;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves to the next index. Runs in O(lg n), but for k calls, the combined time is only O(k+lg n).
|
||||
/// </summary>
|
||||
public bool MoveNext()
|
||||
{
|
||||
return it.MoveNext();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves to the previous index. Runs in O(lg n), but for k calls, the combined time is only O(k+lg n).
|
||||
/// </summary>
|
||||
public bool MoveBack()
|
||||
{
|
||||
return it.MoveBack();
|
||||
}
|
||||
|
||||
void System.Collections.IEnumerator.Reset()
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
void IList<LineSegment>.Insert(int index, LineSegment item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
void ICollection<LineSegment>.Add(LineSegment item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
bool ICollection<LineSegment>.Remove(LineSegment item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2659 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the list of markers and provides ways to retrieve markers for specific positions.
|
||||
/// </summary>
|
||||
public sealed class MarkerStrategy
|
||||
{
|
||||
List<TextMarker> textMarker = new List<TextMarker>();
|
||||
IDocument document;
|
||||
|
||||
public IDocument Document {
|
||||
get {
|
||||
return document;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<TextMarker> TextMarker {
|
||||
get {
|
||||
return textMarker.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddMarker(TextMarker item)
|
||||
{
|
||||
markersTable.Clear();
|
||||
textMarker.Add(item);
|
||||
}
|
||||
|
||||
public void InsertMarker(int index, TextMarker item)
|
||||
{
|
||||
markersTable.Clear();
|
||||
textMarker.Insert(index, item);
|
||||
}
|
||||
|
||||
public void RemoveMarker(TextMarker item)
|
||||
{
|
||||
markersTable.Clear();
|
||||
textMarker.Remove(item);
|
||||
}
|
||||
|
||||
public void RemoveAll(Predicate<TextMarker> match)
|
||||
{
|
||||
markersTable.Clear();
|
||||
textMarker.RemoveAll(match);
|
||||
}
|
||||
|
||||
public MarkerStrategy(IDocument document)
|
||||
{
|
||||
this.document = document;
|
||||
document.DocumentChanged += new DocumentEventHandler(DocumentChanged);
|
||||
}
|
||||
|
||||
Dictionary<int, List<TextMarker>> markersTable = new Dictionary<int, List<TextMarker>>();
|
||||
|
||||
public List<TextMarker> GetMarkers(int offset)
|
||||
{
|
||||
if (!markersTable.ContainsKey(offset)) {
|
||||
List<TextMarker> markers = new List<TextMarker>();
|
||||
for (int i = 0; i < textMarker.Count; ++i) {
|
||||
TextMarker marker = (TextMarker)textMarker[i];
|
||||
if (marker.Offset <= offset && offset <= marker.EndOffset) {
|
||||
markers.Add(marker);
|
||||
}
|
||||
}
|
||||
markersTable[offset] = markers;
|
||||
}
|
||||
return markersTable[offset];
|
||||
}
|
||||
|
||||
public List<TextMarker> GetMarkers(int offset, int length)
|
||||
{
|
||||
int endOffset = offset + length - 1;
|
||||
List<TextMarker> markers = new List<TextMarker>();
|
||||
for (int i = 0; i < textMarker.Count; ++i) {
|
||||
TextMarker marker = (TextMarker)textMarker[i];
|
||||
if (// start in marker region
|
||||
marker.Offset <= offset && offset <= marker.EndOffset ||
|
||||
// end in marker region
|
||||
marker.Offset <= endOffset && endOffset <= marker.EndOffset ||
|
||||
// marker start in region
|
||||
offset <= marker.Offset && marker.Offset <= endOffset ||
|
||||
// marker end in region
|
||||
offset <= marker.EndOffset && marker.EndOffset <= endOffset
|
||||
)
|
||||
{
|
||||
markers.Add(marker);
|
||||
}
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
public List<TextMarker> GetMarkers(TextLocation position)
|
||||
{
|
||||
if (position.Y >= document.TotalNumberOfLines || position.Y < 0) {
|
||||
return new List<TextMarker>();
|
||||
}
|
||||
LineSegment segment = document.GetLineSegment(position.Y);
|
||||
return GetMarkers(segment.Offset + position.X);
|
||||
}
|
||||
|
||||
void DocumentChanged(object sender, DocumentEventArgs e)
|
||||
{
|
||||
// reset markers table
|
||||
markersTable.Clear();
|
||||
document.UpdateSegmentListOnDocumentChange(textMarker, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2140 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
public enum TextMarkerType
|
||||
{
|
||||
SolidBlock,
|
||||
Underlined,
|
||||
WaveLine,
|
||||
Cant
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks a part of a document.
|
||||
/// </summary>
|
||||
public class TextMarker : AbstractSegment
|
||||
{
|
||||
TextMarkerType textMarkerType;
|
||||
Color color;
|
||||
Color foreColor;
|
||||
string toolTip = null;
|
||||
bool overrideForeColor = false;
|
||||
bool wholeLine = false;
|
||||
public TextMarkerType TextMarkerType {
|
||||
get {
|
||||
return textMarkerType;
|
||||
}
|
||||
}
|
||||
|
||||
public bool WholeLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return WholeLine;
|
||||
}
|
||||
set
|
||||
{
|
||||
wholeLine = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Color Color {
|
||||
get {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
public Color ForeColor {
|
||||
get {
|
||||
return foreColor;
|
||||
}
|
||||
}
|
||||
|
||||
public bool OverrideForeColor {
|
||||
get {
|
||||
return overrideForeColor;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToolTip {
|
||||
get {
|
||||
return toolTip;
|
||||
}
|
||||
set {
|
||||
toolTip = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last offset that is inside the marker region.
|
||||
/// </summary>
|
||||
public int EndOffset {
|
||||
get {
|
||||
return Offset + Length - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public TextMarker(int offset, int length, TextMarkerType textMarkerType) : this(offset, length, textMarkerType, Color.Red)
|
||||
{
|
||||
}
|
||||
|
||||
public TextMarker(int offset, int length, TextMarkerType textMarkerType, Color color)
|
||||
{
|
||||
if (length < 1) length = 1;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
this.textMarkerType = textMarkerType;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public TextMarker(int offset, int length, TextMarkerType textMarkerType, Color color, Color foreColor)
|
||||
{
|
||||
if (length < 1) length = 1;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
this.textMarkerType = textMarkerType;
|
||||
this.color = color;
|
||||
this.foreColor = foreColor;
|
||||
this.overrideForeColor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
public class ColumnRange
|
||||
{
|
||||
public static readonly ColumnRange NoColumn = new ColumnRange(-2, -2);
|
||||
public static readonly ColumnRange WholeColumn = new ColumnRange(-1, -1);
|
||||
|
||||
int startColumn;
|
||||
int endColumn;
|
||||
|
||||
public int StartColumn {
|
||||
get {
|
||||
return startColumn;
|
||||
}
|
||||
set {
|
||||
startColumn = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int EndColumn {
|
||||
get {
|
||||
return endColumn;
|
||||
}
|
||||
set {
|
||||
endColumn = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ColumnRange(int startColumn, int endColumn)
|
||||
{
|
||||
this.startColumn = startColumn;
|
||||
this.endColumn = endColumn;
|
||||
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return startColumn + (endColumn << 16);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ColumnRange) {
|
||||
return ((ColumnRange)obj).startColumn == startColumn &&
|
||||
((ColumnRange)obj).endColumn == endColumn;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[ColumnRange: StartColumn={0}, EndColumn={1}]", startColumn, endColumn);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2679 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of the <see cref="ICSharpCode.TextEditor.Document.ISelection"/> interface.
|
||||
/// </summary>
|
||||
public class DefaultSelection : ISelection
|
||||
{
|
||||
IDocument document;
|
||||
bool isRectangularSelection;
|
||||
TextLocation startPosition;
|
||||
TextLocation endPosition;
|
||||
|
||||
public TextLocation StartPosition {
|
||||
get {
|
||||
return startPosition;
|
||||
}
|
||||
set {
|
||||
DefaultDocument.ValidatePosition(document, value);
|
||||
startPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TextLocation EndPosition {
|
||||
get {
|
||||
return endPosition;
|
||||
}
|
||||
set {
|
||||
DefaultDocument.ValidatePosition(document, value);
|
||||
endPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
get {
|
||||
return document.PositionToOffset(startPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public int EndOffset {
|
||||
get {
|
||||
return document.PositionToOffset(endPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public int Length {
|
||||
get {
|
||||
return EndOffset - Offset;
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Returns true, if the selection is empty
|
||||
/// </value>
|
||||
public bool IsEmpty {
|
||||
get {
|
||||
return startPosition == endPosition;
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Returns true, if the selection is rectangular
|
||||
/// </value>
|
||||
// TODO : make this unused property used.
|
||||
public bool IsRectangularSelection {
|
||||
get {
|
||||
return isRectangularSelection;
|
||||
}
|
||||
set {
|
||||
isRectangularSelection = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The text which is selected by this selection.
|
||||
/// </value>
|
||||
public string SelectedText {
|
||||
get {
|
||||
if (document != null) {
|
||||
if (Length < 0) {
|
||||
return null;
|
||||
}
|
||||
return document.GetText(Offset, Length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="DefaultSelection"/>
|
||||
/// </summary>
|
||||
public DefaultSelection(IDocument document, TextLocation startPosition, TextLocation endPosition)
|
||||
{
|
||||
DefaultDocument.ValidatePosition(document, startPosition);
|
||||
DefaultDocument.ValidatePosition(document, endPosition);
|
||||
Debug.Assert(startPosition <= endPosition);
|
||||
this.document = document;
|
||||
this.startPosition = startPosition;
|
||||
this.endPosition = endPosition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="DefaultSelection"/> instance to string (for debug purposes)
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("[DefaultSelection : StartPosition={0}, EndPosition={1}]", startPosition, endPosition);
|
||||
}
|
||||
public bool ContainsPosition(TextLocation position)
|
||||
{
|
||||
if (this.IsEmpty)
|
||||
return false;
|
||||
return startPosition.Y < position.Y && position.Y < endPosition.Y ||
|
||||
startPosition.Y == position.Y && startPosition.X <= position.X && (startPosition.Y != endPosition.Y || position.X <= endPosition.X) ||
|
||||
endPosition.Y == position.Y && startPosition.Y != endPosition.Y && position.X <= endPosition.X;
|
||||
}
|
||||
|
||||
public bool ContainsOffset(int offset)
|
||||
{
|
||||
return Offset <= offset && offset <= EndOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2659 $</version>
|
||||
// </file>
|
||||
|
||||
using System.Drawing;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface representing a portion of the current selection.
|
||||
/// </summary>
|
||||
public interface ISelection
|
||||
{
|
||||
TextLocation StartPosition {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
TextLocation EndPosition {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
int Offset {
|
||||
get;
|
||||
}
|
||||
|
||||
int EndOffset {
|
||||
get;
|
||||
}
|
||||
|
||||
int Length {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Returns true, if the selection is rectangular
|
||||
/// </value>
|
||||
bool IsRectangularSelection {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Returns true, if the selection is empty
|
||||
/// </value>
|
||||
bool IsEmpty {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The text which is selected by this selection.
|
||||
/// </value>
|
||||
string SelectedText {
|
||||
get;
|
||||
}
|
||||
|
||||
bool ContainsOffset(int offset);
|
||||
|
||||
bool ContainsPosition(TextLocation position);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,456 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2679 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// This class manages the selections in a document.
|
||||
/// </summary>
|
||||
public class SelectionManager : IDisposable
|
||||
{
|
||||
TextLocation selectionStart;
|
||||
|
||||
internal TextLocation SelectionStart {
|
||||
get { return selectionStart; }
|
||||
set {
|
||||
DefaultDocument.ValidatePosition(document, value);
|
||||
selectionStart = value;
|
||||
}
|
||||
}
|
||||
IDocument document;
|
||||
TextArea textArea;
|
||||
internal SelectFrom selectFrom = new SelectFrom();
|
||||
|
||||
internal List<ISelection> selectionCollection = new List<ISelection>();
|
||||
|
||||
/// <value>
|
||||
/// A collection containing all selections.
|
||||
/// </value>
|
||||
public List<ISelection> SelectionCollection {
|
||||
get {
|
||||
return selectionCollection;
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// true if the <see cref="SelectionCollection"/> is not empty, false otherwise.
|
||||
/// </value>
|
||||
public bool HasSomethingSelected {
|
||||
get {
|
||||
return selectionCollection.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SelectionIsReadonly {
|
||||
get {
|
||||
if (document.ReadOnly)
|
||||
return true;
|
||||
if (document.TextEditorProperties.UseCustomLine) {
|
||||
foreach (ISelection sel in selectionCollection) {
|
||||
if (document.CustomLineManager.IsReadOnly(sel, false))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The text that is currently selected.
|
||||
/// </value>
|
||||
public string SelectedText {
|
||||
get {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
// PriorityQueue queue = new PriorityQueue();
|
||||
|
||||
foreach (ISelection s in selectionCollection) {
|
||||
builder.Append(s.SelectedText);
|
||||
// queue.Insert(-s.Offset, s);
|
||||
}
|
||||
|
||||
// while (queue.Count > 0) {
|
||||
// ISelection s = ((ISelection)queue.Remove());
|
||||
// builder.Append(s.SelectedText);
|
||||
// }
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="SelectionManager"/>
|
||||
/// </summary>
|
||||
public SelectionManager(IDocument document)
|
||||
{
|
||||
this.document = document;
|
||||
document.DocumentChanged += new DocumentEventHandler(DocumentChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="SelectionManager"/>
|
||||
/// </summary>
|
||||
public SelectionManager(IDocument document, TextArea textArea)
|
||||
{
|
||||
this.document = document;
|
||||
this.textArea = textArea;
|
||||
document.DocumentChanged += new DocumentEventHandler(DocumentChanged);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.document != null) {
|
||||
document.DocumentChanged -= new DocumentEventHandler(DocumentChanged);
|
||||
this.document = null;
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentChanged(object sender, DocumentEventArgs e)
|
||||
{
|
||||
if (e.Text == null) {
|
||||
Remove(e.Offset, e.Length);
|
||||
} else {
|
||||
if (e.Length < 0) {
|
||||
Insert(e.Offset, e.Text);
|
||||
} else {
|
||||
Replace(e.Offset, e.Length, e.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Clears the selection and sets a new selection
|
||||
/// using the given <see cref="ISelection"/> object.
|
||||
/// </remarks>
|
||||
public void SetSelection(ISelection selection)
|
||||
{
|
||||
// autoClearSelection = false;
|
||||
if (selection != null) {
|
||||
if (SelectionCollection.Count == 1 &&
|
||||
selection.StartPosition == SelectionCollection[0].StartPosition &&
|
||||
selection.EndPosition == SelectionCollection[0].EndPosition ) {
|
||||
return;
|
||||
}
|
||||
ClearWithoutUpdate();
|
||||
selectionCollection.Add(selection);
|
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, selection.StartPosition.Y, selection.EndPosition.Y));
|
||||
document.CommitUpdate();
|
||||
OnSelectionChanged(EventArgs.Empty);
|
||||
} else {
|
||||
ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSelection(TextLocation startPosition, TextLocation endPosition)
|
||||
{
|
||||
SetSelection(new DefaultSelection(document, startPosition, endPosition));
|
||||
}
|
||||
|
||||
public bool GreaterEqPos(TextLocation p1, TextLocation p2)
|
||||
{
|
||||
return p1.Y > p2.Y || p1.Y == p2.Y && p1.X >= p2.X;
|
||||
}
|
||||
|
||||
public void ExtendSelection(TextLocation oldPosition, TextLocation newPosition)
|
||||
{
|
||||
// where oldposition is where the cursor was,
|
||||
// and newposition is where it has ended up from a click (both zero based)
|
||||
|
||||
if (oldPosition == newPosition)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TextLocation min;
|
||||
TextLocation max;
|
||||
int oldnewX = newPosition.X;
|
||||
bool oldIsGreater = GreaterEqPos(oldPosition, newPosition);
|
||||
if (oldIsGreater) {
|
||||
min = newPosition;
|
||||
max = oldPosition;
|
||||
} else {
|
||||
min = oldPosition;
|
||||
max = newPosition;
|
||||
}
|
||||
|
||||
if (min == max) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasSomethingSelected)
|
||||
{
|
||||
SetSelection(new DefaultSelection(document, min, max));
|
||||
// initialise selectFrom for a cursor selection
|
||||
if (selectFrom.where == WhereFrom.None)
|
||||
SelectionStart = oldPosition; //textArea.Caret.Position;
|
||||
return;
|
||||
}
|
||||
|
||||
ISelection selection = this.selectionCollection[0];
|
||||
|
||||
if (min == max) {
|
||||
//selection.StartPosition = newPosition;
|
||||
return;
|
||||
} else {
|
||||
// changed selection via gutter
|
||||
if (selectFrom.where == WhereFrom.Gutter)
|
||||
{
|
||||
// selection new position is always at the left edge for gutter selections
|
||||
newPosition.X = 0;
|
||||
}
|
||||
|
||||
if (GreaterEqPos(newPosition, SelectionStart)) // selecting forward
|
||||
{
|
||||
selection.StartPosition = SelectionStart;
|
||||
// this handles last line selection
|
||||
if (selectFrom.where == WhereFrom.Gutter ) //&& newPosition.Y != oldPosition.Y)
|
||||
selection.EndPosition = new TextLocation(textArea.Caret.Column, textArea.Caret.Line);
|
||||
else {
|
||||
newPosition.X = oldnewX;
|
||||
selection.EndPosition = newPosition;
|
||||
}
|
||||
} else { // selecting back
|
||||
if (selectFrom.where == WhereFrom.Gutter && selectFrom.first == WhereFrom.Gutter)
|
||||
{ // gutter selection
|
||||
selection.EndPosition = NextValidPosition(SelectionStart.Y);
|
||||
} else { // internal text selection
|
||||
selection.EndPosition = SelectionStart; //selection.StartPosition;
|
||||
}
|
||||
selection.StartPosition = newPosition;
|
||||
}
|
||||
}
|
||||
|
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, min.Y, max.Y));
|
||||
document.CommitUpdate();
|
||||
OnSelectionChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
// retrieve the next available line
|
||||
// - checks that there are more lines available after the current one
|
||||
// - if there are then the next line is returned
|
||||
// - if there are NOT then the last position on the given line is returned
|
||||
public TextLocation NextValidPosition(int line)
|
||||
{
|
||||
if (line < document.TotalNumberOfLines - 1)
|
||||
return new TextLocation(0, line + 1);
|
||||
else
|
||||
return new TextLocation(document.GetLineSegment(document.TotalNumberOfLines - 1).Length + 1, line);
|
||||
}
|
||||
|
||||
void ClearWithoutUpdate()
|
||||
{
|
||||
while (selectionCollection.Count > 0) {
|
||||
ISelection selection = selectionCollection[selectionCollection.Count - 1];
|
||||
selectionCollection.RemoveAt(selectionCollection.Count - 1);
|
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.LinesBetween, selection.StartPosition.Y, selection.EndPosition.Y));
|
||||
OnSelectionChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
/// <remarks>
|
||||
/// Clears the selection.
|
||||
/// </remarks>
|
||||
public void ClearSelection()
|
||||
{
|
||||
Point mousepos;
|
||||
mousepos = textArea.mousepos;
|
||||
// this is the most logical place to reset selection starting
|
||||
// positions because it is always called before a new selection
|
||||
selectFrom.first = selectFrom.where;
|
||||
TextLocation newSelectionStart = textArea.TextView.GetLogicalPosition(mousepos.X - textArea.TextView.DrawingPosition.X, mousepos.Y - textArea.TextView.DrawingPosition.Y);
|
||||
if (selectFrom.where == WhereFrom.Gutter) {
|
||||
newSelectionStart.X = 0;
|
||||
// selectionStart.Y = -1;
|
||||
}
|
||||
if (newSelectionStart.Line >= document.TotalNumberOfLines) {
|
||||
newSelectionStart.Line = document.TotalNumberOfLines-1;
|
||||
newSelectionStart.Column = document.GetLineSegment(document.TotalNumberOfLines-1).Length;
|
||||
}
|
||||
this.SelectionStart = newSelectionStart;
|
||||
|
||||
ClearWithoutUpdate();
|
||||
document.CommitUpdate();
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Removes the selected text from the buffer and clears
|
||||
/// the selection.
|
||||
/// </remarks>
|
||||
public void RemoveSelectedText()
|
||||
{
|
||||
List<int> lines = new List<int>();
|
||||
int offset = -1;
|
||||
bool oneLine = true;
|
||||
// PriorityQueue queue = new PriorityQueue();
|
||||
foreach (ISelection s in selectionCollection) {
|
||||
// ISelection s = ((ISelection)queue.Remove());
|
||||
if (oneLine) {
|
||||
int lineBegin = s.StartPosition.Y;
|
||||
if (lineBegin != s.EndPosition.Y) {
|
||||
oneLine = false;
|
||||
} else {
|
||||
lines.Add(lineBegin);
|
||||
}
|
||||
}
|
||||
offset = s.Offset;
|
||||
document.Remove(s.Offset, s.Length);
|
||||
|
||||
// queue.Insert(-s.Offset, s);
|
||||
}
|
||||
ClearSelection();
|
||||
if (offset >= 0) {
|
||||
// TODO:
|
||||
// document.Caret.Offset = offset;
|
||||
}
|
||||
if (offset != -1) {
|
||||
if (oneLine) {
|
||||
foreach (int i in lines) {
|
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, i));
|
||||
}
|
||||
} else {
|
||||
document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
|
||||
}
|
||||
document.CommitUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SelectionsOverlap(ISelection s1, ISelection s2)
|
||||
{
|
||||
return (s1.Offset <= s2.Offset && s2.Offset <= s1.Offset + s1.Length) ||
|
||||
(s1.Offset <= s2.Offset + s2.Length && s2.Offset + s2.Length <= s1.Offset + s1.Length) ||
|
||||
(s1.Offset >= s2.Offset && s1.Offset + s1.Length <= s2.Offset + s2.Length);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns true if the given offset points to a section which is
|
||||
/// selected.
|
||||
/// </remarks>
|
||||
public bool IsSelected(int offset)
|
||||
{
|
||||
return GetSelectionAt(offset) != null;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns a <see cref="ISelection"/> object giving the selection in which
|
||||
/// the offset points to.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// <code>null</code> if the offset doesn't point to a selection
|
||||
/// </returns>
|
||||
public ISelection GetSelectionAt(int offset)
|
||||
{
|
||||
foreach (ISelection s in selectionCollection) {
|
||||
if (s.ContainsOffset(offset)) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Used internally, do not call.
|
||||
/// </remarks>
|
||||
internal void Insert(int offset, string text)
|
||||
{
|
||||
// foreach (ISelection selection in SelectionCollection) {
|
||||
// if (selection.Offset > offset) {
|
||||
// selection.Offset += text.Length;
|
||||
// } else if (selection.Offset + selection.Length > offset) {
|
||||
// selection.Length += text.Length;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Used internally, do not call.
|
||||
/// </remarks>
|
||||
internal void Remove(int offset, int length)
|
||||
{
|
||||
// foreach (ISelection selection in selectionCollection) {
|
||||
// if (selection.Offset > offset) {
|
||||
// selection.Offset -= length;
|
||||
// } else if (selection.Offset + selection.Length > offset) {
|
||||
// selection.Length -= length;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Used internally, do not call.
|
||||
/// </remarks>
|
||||
internal void Replace(int offset, int length, string text)
|
||||
{
|
||||
// foreach (ISelection selection in selectionCollection) {
|
||||
// if (selection.Offset > offset) {
|
||||
// selection.Offset = selection.Offset - length + text.Length;
|
||||
// } else if (selection.Offset + selection.Length > offset) {
|
||||
// selection.Length = selection.Length - length + text.Length;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public ColumnRange GetSelectionAtLine(int lineNumber)
|
||||
{
|
||||
foreach (ISelection selection in selectionCollection) {
|
||||
int startLine = selection.StartPosition.Y;
|
||||
int endLine = selection.EndPosition.Y;
|
||||
if (startLine < lineNumber && lineNumber < endLine) {
|
||||
return ColumnRange.WholeColumn;
|
||||
}
|
||||
|
||||
if (startLine == lineNumber) {
|
||||
LineSegment line = document.GetLineSegment(startLine);
|
||||
int startColumn = selection.StartPosition.X;
|
||||
int endColumn = endLine == lineNumber ? selection.EndPosition.X : line.Length + 1;
|
||||
return new ColumnRange(startColumn, endColumn);
|
||||
}
|
||||
|
||||
if (endLine == lineNumber) {
|
||||
int endColumn = selection.EndPosition.X;
|
||||
return new ColumnRange(0, endColumn);
|
||||
}
|
||||
}
|
||||
|
||||
return ColumnRange.NoColumn;
|
||||
}
|
||||
|
||||
public void FireSelectionChanged()
|
||||
{
|
||||
OnSelectionChanged(EventArgs.Empty);
|
||||
}
|
||||
protected virtual void OnSelectionChanged(EventArgs e)
|
||||
{
|
||||
if (SelectionChanged != null) {
|
||||
SelectionChanged(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler SelectionChanged;
|
||||
}
|
||||
|
||||
// selection initiated from...
|
||||
internal class SelectFrom {
|
||||
public int where = WhereFrom.None; // last selection initiator
|
||||
public int first = WhereFrom.None; // first selection initiator
|
||||
|
||||
public SelectFrom()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// selection initiated from type...
|
||||
internal class WhereFrom {
|
||||
public const int None = 0;
|
||||
public const int Gutter = 1;
|
||||
public const int TArea = 2;
|
||||
}
|
||||
}
|
||||
88
ICSharpCode.TextEditorLinux/Src/Document/TextAnchor.cs
Normal file
88
ICSharpCode.TextEditorLinux/Src/Document/TextAnchor.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2683 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of TextAnchor.
|
||||
/// </summary>
|
||||
public sealed class TextAnchor
|
||||
{
|
||||
static Exception AnchorDeletedError()
|
||||
{
|
||||
return new InvalidOperationException("The text containing the anchor was deleted");
|
||||
}
|
||||
|
||||
LineSegment lineSegment;
|
||||
int columnNumber;
|
||||
|
||||
public LineSegment Line {
|
||||
get {
|
||||
if (lineSegment == null) throw AnchorDeletedError();
|
||||
return lineSegment;
|
||||
}
|
||||
internal set {
|
||||
lineSegment = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDeleted {
|
||||
get {
|
||||
return lineSegment == null;
|
||||
}
|
||||
}
|
||||
|
||||
public int LineNumber {
|
||||
get {
|
||||
return this.Line.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
public int ColumnNumber {
|
||||
get {
|
||||
if (lineSegment == null) throw AnchorDeletedError();
|
||||
return columnNumber;
|
||||
}
|
||||
internal set {
|
||||
columnNumber = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TextLocation Location {
|
||||
get {
|
||||
return new TextLocation(this.ColumnNumber, this.LineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
get {
|
||||
return this.Line.Offset + columnNumber;
|
||||
}
|
||||
}
|
||||
|
||||
internal void Deleted()
|
||||
{
|
||||
lineSegment = null;
|
||||
}
|
||||
|
||||
internal TextAnchor(LineSegment lineSegment, int columnNumber)
|
||||
{
|
||||
this.lineSegment = lineSegment;
|
||||
this.columnNumber = columnNumber;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.IsDeleted)
|
||||
return "[TextAnchor (deleted)]";
|
||||
else
|
||||
return "[TextAnchor " + this.Location.ToString() + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2667 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
public class GapTextBufferStrategy : ITextBufferStrategy
|
||||
{
|
||||
#if DEBUG
|
||||
int creatorThread = System.Threading.Thread.CurrentThread.ManagedThreadId;
|
||||
|
||||
void CheckThread()
|
||||
{
|
||||
//if (System.Threading.Thread.CurrentThread.ManagedThreadId != creatorThread)
|
||||
// throw new InvalidOperationException("GapTextBufferStategy is not thread-safe!");
|
||||
}
|
||||
#endif
|
||||
|
||||
char[] buffer = new char[0];
|
||||
|
||||
int gapBeginOffset = 0;
|
||||
int gapEndOffset = 0;
|
||||
int gapLength = 0; // gapLength == gapEndOffset - gapBeginOffset
|
||||
|
||||
const int minGapLength = 128;
|
||||
const int maxGapLength = 2048;
|
||||
|
||||
public int Length {
|
||||
get {
|
||||
return buffer.Length - gapLength;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetContent(string text)
|
||||
{
|
||||
if (text == null) {
|
||||
text = String.Empty;
|
||||
}
|
||||
buffer = text.ToCharArray();
|
||||
gapBeginOffset = gapEndOffset = gapLength = 0;
|
||||
}
|
||||
|
||||
public char GetCharAt(int offset)
|
||||
{
|
||||
#if DEBUG
|
||||
CheckThread();
|
||||
#endif
|
||||
|
||||
if (offset < 0 || offset >= Length) {
|
||||
throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset < " + Length.ToString());
|
||||
}
|
||||
|
||||
return offset < gapBeginOffset ? buffer[offset] : buffer[offset + gapLength];
|
||||
}
|
||||
|
||||
public string GetText(int offset, int length)
|
||||
{
|
||||
#if DEBUG
|
||||
CheckThread();
|
||||
#endif
|
||||
|
||||
if (offset < 0 || offset > Length) {
|
||||
throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + Length.ToString());
|
||||
}
|
||||
if (length < 0 || offset + length > Length) {
|
||||
throw new ArgumentOutOfRangeException("length", length, "0 <= length, offset(" + offset + ")+length <= " + Length.ToString());
|
||||
}
|
||||
|
||||
int end = offset + length;
|
||||
|
||||
if (end < gapBeginOffset) {
|
||||
return new string(buffer, offset, length);
|
||||
}
|
||||
|
||||
if (offset > gapBeginOffset) {
|
||||
return new string(buffer, offset + gapLength, length);
|
||||
}
|
||||
|
||||
int block1Size = gapBeginOffset - offset;
|
||||
int block2Size = end - gapBeginOffset;
|
||||
|
||||
StringBuilder buf = new StringBuilder(block1Size + block2Size);
|
||||
buf.Append(buffer, offset, block1Size);
|
||||
buf.Append(buffer, gapEndOffset, block2Size);
|
||||
return buf.ToString();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (text == null) {
|
||||
text = String.Empty;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
CheckThread();
|
||||
#endif
|
||||
|
||||
if (offset < 0 || offset > Length) {
|
||||
throw new ArgumentOutOfRangeException("offset", offset, "0 <= offset <= " + Length.ToString());
|
||||
}
|
||||
if (length < 0 || offset + length > Length) {
|
||||
throw new ArgumentOutOfRangeException("length", length, "0 <= length, offset+length <= " + Length.ToString());
|
||||
}
|
||||
|
||||
// Math.Max is used so that if we need to resize the array
|
||||
// the new array has enough space for all old chars
|
||||
PlaceGap(offset, text.Length - length);
|
||||
gapEndOffset += length; // delete removed text
|
||||
text.CopyTo(0, buffer, gapBeginOffset, text.Length);
|
||||
gapBeginOffset += text.Length;
|
||||
gapLength = gapEndOffset - gapBeginOffset;
|
||||
if (gapLength > maxGapLength) {
|
||||
MakeNewBuffer(gapBeginOffset, minGapLength);
|
||||
}
|
||||
}
|
||||
|
||||
void PlaceGap(int newGapOffset, int minRequiredGapLength)
|
||||
{
|
||||
if (gapLength < minRequiredGapLength) {
|
||||
// enlarge gap
|
||||
MakeNewBuffer(newGapOffset, minRequiredGapLength);
|
||||
} else {
|
||||
while (newGapOffset < gapBeginOffset) {
|
||||
buffer[--gapEndOffset] = buffer[--gapBeginOffset];
|
||||
}
|
||||
while (newGapOffset > gapBeginOffset) {
|
||||
buffer[gapBeginOffset++] = buffer[gapEndOffset++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MakeNewBuffer(int newGapOffset, int newGapLength)
|
||||
{
|
||||
if (newGapLength < minGapLength) newGapLength = minGapLength;
|
||||
|
||||
char[] newBuffer = new char[Length + newGapLength];
|
||||
if (newGapOffset < gapBeginOffset) {
|
||||
// gap is moving backwards
|
||||
|
||||
// first part:
|
||||
Array.Copy(buffer, 0, newBuffer, 0, newGapOffset);
|
||||
// moving middle part:
|
||||
Array.Copy(buffer, newGapOffset, newBuffer, newGapOffset + newGapLength, gapBeginOffset - newGapOffset);
|
||||
// last part:
|
||||
Array.Copy(buffer, gapEndOffset, newBuffer, newBuffer.Length - (buffer.Length - gapEndOffset), buffer.Length - gapEndOffset);
|
||||
} else {
|
||||
// gap is moving forwards
|
||||
// first part:
|
||||
Array.Copy(buffer, 0, newBuffer, 0, gapBeginOffset);
|
||||
// moving middle part:
|
||||
Array.Copy(buffer, gapEndOffset, newBuffer, gapBeginOffset, newGapOffset - gapBeginOffset);
|
||||
// last part:
|
||||
int lastPartLength = newBuffer.Length - (newGapOffset + newGapLength);
|
||||
Array.Copy(buffer, buffer.Length - lastPartLength, newBuffer, newGapOffset + newGapLength, lastPartLength);
|
||||
}
|
||||
|
||||
gapBeginOffset = newGapOffset;
|
||||
gapEndOffset = newGapOffset + newGapLength;
|
||||
gapLength = newGapLength;
|
||||
buffer = newBuffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1966 $</version>
|
||||
// </file>
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface to describe a sequence of characters that can be edited.
|
||||
/// </summary>
|
||||
public interface ITextBufferStrategy
|
||||
{
|
||||
/// <value>
|
||||
/// The current length of the sequence of characters that can be edited.
|
||||
/// </value>
|
||||
int Length {
|
||||
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>
|
||||
/// 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);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a specific char of the sequence.
|
||||
/// </summary>
|
||||
/// <param name="offset">
|
||||
/// Offset of the char to get.
|
||||
/// </param>
|
||||
char GetCharAt(int offset);
|
||||
|
||||
/// <summary>
|
||||
/// This method sets the stored content.
|
||||
/// </summary>
|
||||
/// <param name="text">
|
||||
/// The string that represents the character sequence.
|
||||
/// </param>
|
||||
void SetContent(string text);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2682 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple implementation of the ITextBuffer interface implemented using a
|
||||
/// string.
|
||||
/// Only for fall-back purposes.
|
||||
/// </summary>
|
||||
public class StringTextBufferStrategy : ITextBufferStrategy
|
||||
{
|
||||
string storedText = "";
|
||||
|
||||
public int Length {
|
||||
get {
|
||||
return storedText.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public void Insert(int offset, string text)
|
||||
{
|
||||
if (text != null) {
|
||||
storedText = storedText.Insert(offset, text);
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove(int offset, int length)
|
||||
{
|
||||
storedText = storedText.Remove(offset, length);
|
||||
}
|
||||
|
||||
public void Replace(int offset, int length, string text)
|
||||
{
|
||||
Remove(offset, length);
|
||||
Insert(offset, text);
|
||||
}
|
||||
|
||||
public string GetText(int offset, int length)
|
||||
{
|
||||
if (length == 0) {
|
||||
return "";
|
||||
}
|
||||
if (offset == 0 && length >= storedText.Length) {
|
||||
return storedText;
|
||||
}
|
||||
return storedText.Substring(offset, Math.Min(length, storedText.Length - offset));
|
||||
}
|
||||
|
||||
public char GetCharAt(int offset)
|
||||
{
|
||||
if (offset == Length) {
|
||||
return '\0';
|
||||
}
|
||||
return storedText[offset];
|
||||
}
|
||||
|
||||
public void SetContent(string text)
|
||||
{
|
||||
storedText = text;
|
||||
}
|
||||
|
||||
public StringTextBufferStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
public static ITextBufferStrategy CreateTextBufferFromFile(string fileName)
|
||||
{
|
||||
if (!File.Exists(fileName)) {
|
||||
throw new System.IO.FileNotFoundException(fileName);
|
||||
}
|
||||
StringTextBufferStrategy s = new StringTextBufferStrategy();
|
||||
s.SetContent(Util.FileReader.ReadFileContent(fileName, Encoding.Default));
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
128
ICSharpCode.TextEditorLinux/Src/Document/TextLocation.cs
Normal file
128
ICSharpCode.TextEditorLinux/Src/Document/TextLocation.cs
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision: 2658$</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
|
||||
namespace ICSharpCode.TextEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// A line/column position.
|
||||
/// Text editor lines/columns are counting from zero.
|
||||
/// </summary>
|
||||
public struct TextLocation : IComparable<TextLocation>, IEquatable<TextLocation>
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents no text location (-1, -1).
|
||||
/// </summary>
|
||||
public static readonly TextLocation Empty = new TextLocation(-1, -1);
|
||||
|
||||
public TextLocation(int column, int line)
|
||||
{
|
||||
x = column;
|
||||
y = line;
|
||||
}
|
||||
|
||||
int x, y;
|
||||
|
||||
public int X {
|
||||
get { return x; }
|
||||
set { x = value; }
|
||||
}
|
||||
|
||||
public int Y {
|
||||
get { return y; }
|
||||
set { y = value; }
|
||||
}
|
||||
|
||||
public int Line {
|
||||
get { return y; }
|
||||
set { y = value; }
|
||||
}
|
||||
|
||||
public int Column {
|
||||
get { return x; }
|
||||
set { x = value; }
|
||||
}
|
||||
|
||||
public bool IsEmpty {
|
||||
get {
|
||||
return x <= 0 && y <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("(Line {1}, Col {0})", this.x, this.y);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return unchecked (87 * x.GetHashCode() ^ y.GetHashCode());
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is TextLocation)) return false;
|
||||
return (TextLocation)obj == this;
|
||||
}
|
||||
|
||||
public bool Equals(TextLocation other)
|
||||
{
|
||||
return this == other;
|
||||
}
|
||||
|
||||
public static bool operator ==(TextLocation a, TextLocation b)
|
||||
{
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
public static bool operator !=(TextLocation a, TextLocation b)
|
||||
{
|
||||
return a.x != b.x || a.y != b.y;
|
||||
}
|
||||
|
||||
public static bool operator <(TextLocation a, TextLocation b)
|
||||
{
|
||||
if (a.y < b.y)
|
||||
return true;
|
||||
else if (a.y == b.y)
|
||||
return a.x < b.x;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator >(TextLocation a, TextLocation b)
|
||||
{
|
||||
if (a.y > b.y)
|
||||
return true;
|
||||
else if (a.y == b.y)
|
||||
return a.x > b.x;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator <=(TextLocation a, TextLocation b)
|
||||
{
|
||||
return !(a > b);
|
||||
}
|
||||
|
||||
public static bool operator >=(TextLocation a, TextLocation b)
|
||||
{
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
public int CompareTo(TextLocation other)
|
||||
{
|
||||
if (this == other)
|
||||
return 0;
|
||||
if (this < other)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
313
ICSharpCode.TextEditorLinux/Src/Document/TextUtilities.cs
Normal file
313
ICSharpCode.TextEditorLinux/Src/Document/TextUtilities.cs
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2533 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Document
|
||||
{
|
||||
|
||||
public sealed class TextUtilities
|
||||
{
|
||||
/// <remarks>
|
||||
/// This function takes a string and converts the whitespace in front of
|
||||
/// it to tabs. If the length of the whitespace at the start of the string
|
||||
/// was not a whole number of tabs then there will still be some spaces just
|
||||
/// before the text starts.
|
||||
/// the output string will be of the form:
|
||||
/// 1. zero or more tabs
|
||||
/// 2. zero or more spaces (less than tabIndent)
|
||||
/// 3. the rest of the line
|
||||
/// </remarks>
|
||||
public static string LeadingWhiteSpaceToTabs(string line, int tabIndent) {
|
||||
StringBuilder sb = new StringBuilder(line.Length);
|
||||
int consecutiveSpaces = 0;
|
||||
int i = 0;
|
||||
for(i = 0; i < line.Length; i++) {
|
||||
if(line[i] == ' ') {
|
||||
consecutiveSpaces++;
|
||||
if(consecutiveSpaces == tabIndent) {
|
||||
sb.Append('\t');
|
||||
consecutiveSpaces = 0;
|
||||
}
|
||||
}
|
||||
else if(line[i] == '\t') {
|
||||
sb.Append('\t');
|
||||
// if we had say 3 spaces then a tab and tabIndent was 4 then
|
||||
// we would want to simply replace all of that with 1 tab
|
||||
consecutiveSpaces = 0;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i < line.Length) {
|
||||
sb.Append(line.Substring(i-consecutiveSpaces));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static bool IsLetterDigitOrUnderscore(char c)
|
||||
{
|
||||
if(!Char.IsLetterOrDigit(c)) {
|
||||
return c == '_';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public enum CharacterType {
|
||||
LetterDigitOrUnderscore,
|
||||
WhiteSpace,
|
||||
Other
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// This method returns the expression before a specified offset.
|
||||
/// That method is used in code completion to determine the expression given
|
||||
/// to the parser for type resolve.
|
||||
/// </remarks>
|
||||
public static string GetExpressionBeforeOffset(TextArea textArea, int initialOffset)
|
||||
{
|
||||
IDocument document = textArea.Document;
|
||||
int offset = initialOffset;
|
||||
while (offset - 1 > 0) {
|
||||
switch (document.GetCharAt(offset - 1)) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '}':
|
||||
goto done;
|
||||
// offset = SearchBracketBackward(document, offset - 2, '{','}');
|
||||
// break;
|
||||
case ']':
|
||||
offset = SearchBracketBackward(document, offset - 2, '[',']');
|
||||
break;
|
||||
case ')':
|
||||
offset = SearchBracketBackward(document, offset - 2, '(',')');
|
||||
break;
|
||||
case '.':
|
||||
--offset;
|
||||
break;
|
||||
case '"':
|
||||
if (offset < initialOffset - 1) {
|
||||
return null;
|
||||
}
|
||||
return "\"\"";
|
||||
case '\'':
|
||||
if (offset < initialOffset - 1) {
|
||||
return null;
|
||||
}
|
||||
return "'a'";
|
||||
case '>':
|
||||
if (document.GetCharAt(offset - 2) == '-') {
|
||||
offset -= 2;
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
default:
|
||||
if (Char.IsWhiteSpace(document.GetCharAt(offset - 1))) {
|
||||
--offset;
|
||||
break;
|
||||
}
|
||||
int start = offset - 1;
|
||||
if (!IsLetterDigitOrUnderscore(document.GetCharAt(start))) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (start > 0 && IsLetterDigitOrUnderscore(document.GetCharAt(start - 1))) {
|
||||
--start;
|
||||
}
|
||||
string word = document.GetText(start, offset - start).Trim();
|
||||
switch (word) {
|
||||
case "ref":
|
||||
case "out":
|
||||
case "in":
|
||||
case "return":
|
||||
case "throw":
|
||||
case "case":
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (word.Length > 0 && !IsLetterDigitOrUnderscore(word[0])) {
|
||||
goto done;
|
||||
}
|
||||
offset = start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
//// simple exit fails when : is inside comment line or any other character
|
||||
//// we have to check if we got several ids in resulting line, which usually happens when
|
||||
//// id. is typed on next line after comment one
|
||||
//// Would be better if lexer would parse properly such expressions. However this will cause
|
||||
//// modifications in this area too - to get full comment line and remove it afterwards
|
||||
if (offset < 0)
|
||||
return string.Empty;
|
||||
|
||||
string resText=document.GetText(offset, textArea.Caret.Offset - offset ).Trim();
|
||||
int pos=resText.LastIndexOf('\n');
|
||||
if (pos>=0) {
|
||||
offset+=pos+1;
|
||||
//// whitespaces and tabs, which might be inside, will be skipped by trim below
|
||||
}
|
||||
string expression = document.GetText(offset, textArea.Caret.Offset - offset ).Trim();
|
||||
return expression;
|
||||
}
|
||||
|
||||
|
||||
public static CharacterType GetCharacterType(char c)
|
||||
{
|
||||
if(IsLetterDigitOrUnderscore(c))
|
||||
return CharacterType.LetterDigitOrUnderscore;
|
||||
if(Char.IsWhiteSpace(c))
|
||||
return CharacterType.WhiteSpace;
|
||||
return CharacterType.Other;
|
||||
}
|
||||
|
||||
public static int GetFirstNonWSChar(IDocument document, int offset)
|
||||
{
|
||||
while (offset < document.TextLength && Char.IsWhiteSpace(document.GetCharAt(offset))) {
|
||||
++offset;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static int FindWordEnd(IDocument document, int offset)
|
||||
{
|
||||
LineSegment line = document.GetLineSegmentForOffset(offset);
|
||||
int endPos = line.Offset + line.Length;
|
||||
while (offset < endPos && IsLetterDigitOrUnderscore(document.GetCharAt(offset))) {
|
||||
++offset;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static int FindWordStart(IDocument document, int offset)
|
||||
{
|
||||
LineSegment line = document.GetLineSegmentForOffset(offset);
|
||||
|
||||
while (offset > line.Offset && !IsLetterDigitOrUnderscore(document.GetCharAt(offset - 1))) {
|
||||
--offset;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// go forward to the start of the next word
|
||||
// if the cursor is at the start or in the middle of a word we move to the end of the word
|
||||
// and then past any whitespace that follows it
|
||||
// if the cursor is at the start or in the middle of some whitespace we move to the start of the
|
||||
// next word
|
||||
public static int FindNextWordStart(IDocument document, int offset)
|
||||
{
|
||||
int originalOffset = offset;
|
||||
LineSegment line = document.GetLineSegmentForOffset(offset);
|
||||
int endPos = line.Offset + line.Length;
|
||||
// lets go to the end of the word, whitespace or operator
|
||||
CharacterType t = GetCharacterType(document.GetCharAt(offset));
|
||||
while (offset < endPos && GetCharacterType(document.GetCharAt(offset)) == t) {
|
||||
++offset;
|
||||
}
|
||||
|
||||
// now we're at the end of the word, lets find the start of the next one by skipping whitespace
|
||||
while (offset < endPos && GetCharacterType(document.GetCharAt(offset)) == CharacterType.WhiteSpace) {
|
||||
++offset;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
// go back to the start of the word we are on
|
||||
// if we are already at the start of a word or if we are in whitespace, then go back
|
||||
// to the start of the previous word
|
||||
public static int FindPrevWordStart(IDocument document, int offset)
|
||||
{
|
||||
int originalOffset = offset;
|
||||
if (offset > 0) {
|
||||
LineSegment line = document.GetLineSegmentForOffset(offset);
|
||||
CharacterType t = GetCharacterType(document.GetCharAt(offset - 1));
|
||||
while (offset > line.Offset && GetCharacterType(document.GetCharAt(offset - 1)) == t) {
|
||||
--offset;
|
||||
}
|
||||
|
||||
// if we were in whitespace, and now we're at the end of a word or operator, go back to the beginning of it
|
||||
if(t == CharacterType.WhiteSpace && offset > line.Offset) {
|
||||
t = GetCharacterType(document.GetCharAt(offset - 1));
|
||||
while (offset > line.Offset && GetCharacterType(document.GetCharAt(offset - 1)) == t) {
|
||||
--offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static string GetLineAsString(IDocument document, int lineNumber)
|
||||
{
|
||||
LineSegment line = document.GetLineSegment(lineNumber);
|
||||
return document.GetText(line.Offset, line.Length);
|
||||
}
|
||||
|
||||
public static int SearchBracketBackward(IDocument document, int offset, char openBracket, char closingBracket)
|
||||
{
|
||||
return document.FormattingStrategy.SearchBracketBackward(document, offset, openBracket, closingBracket);
|
||||
}
|
||||
|
||||
public static int SearchBracketForward(IDocument document, int offset, char openBracket, char closingBracket)
|
||||
{
|
||||
return document.FormattingStrategy.SearchBracketForward(document, offset, openBracket, closingBracket);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns true, if the line lineNumber is empty or filled with whitespaces.
|
||||
/// </remarks>
|
||||
public static bool IsEmptyLine(IDocument document, int lineNumber)
|
||||
{
|
||||
return IsEmptyLine(document, document.GetLineSegment(lineNumber));
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Returns true, if the line lineNumber is empty or filled with whitespaces.
|
||||
/// </remarks>
|
||||
public static bool IsEmptyLine(IDocument document, LineSegment line)
|
||||
{
|
||||
for (int i = line.Offset; i < line.Offset + line.Length; ++i) {
|
||||
char ch = document.GetCharAt(i);
|
||||
if (!Char.IsWhiteSpace(ch)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsWordPart(char ch)
|
||||
{
|
||||
return IsLetterDigitOrUnderscore(ch) || ch == '.';
|
||||
}
|
||||
|
||||
public static string GetWordAt(IDocument document, int offset)
|
||||
{
|
||||
if (offset < 0 || offset >= document.TextLength - 1 || !IsWordPart(document.GetCharAt(offset))) {
|
||||
return String.Empty;
|
||||
}
|
||||
int startOffset = offset;
|
||||
int endOffset = offset;
|
||||
while (startOffset > 0 && IsWordPart(document.GetCharAt(startOffset - 1))) {
|
||||
--startOffset;
|
||||
}
|
||||
|
||||
while (endOffset < document.TextLength - 1 && IsWordPart(document.GetCharAt(endOffset + 1))) {
|
||||
++endOffset;
|
||||
}
|
||||
|
||||
Debug.Assert(endOffset >= startOffset);
|
||||
return document.GetText(startOffset, endOffset - startOffset + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
115
ICSharpCode.TextEditorLinux/Src/Gui/AbstractMargin.cs
Normal file
115
ICSharpCode.TextEditorLinux/Src/Gui/AbstractMargin.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using ICSharpCode.TextEditor.Document;
|
||||
|
||||
namespace ICSharpCode.TextEditor
|
||||
{
|
||||
public delegate void MarginMouseEventHandler(AbstractMargin sender, Point mousepos, MouseButtons mouseButtons);
|
||||
public delegate void MarginPaintEventHandler(AbstractMargin sender, Graphics g, Rectangle rect);
|
||||
|
||||
/// <summary>
|
||||
/// This class views the line numbers and folding markers.
|
||||
/// </summary>
|
||||
public abstract class AbstractMargin
|
||||
{
|
||||
Cursor cursor = Cursors.Default;
|
||||
|
||||
[CLSCompliant(false)]
|
||||
protected Rectangle drawingPosition = new Rectangle(0, 0, 0, 0);
|
||||
[CLSCompliant(false)]
|
||||
protected TextArea textArea;
|
||||
|
||||
public Rectangle DrawingPosition {
|
||||
get {
|
||||
return drawingPosition;
|
||||
}
|
||||
set {
|
||||
drawingPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TextArea TextArea {
|
||||
get {
|
||||
return textArea;
|
||||
}
|
||||
}
|
||||
|
||||
public IDocument Document {
|
||||
get {
|
||||
return textArea.Document;
|
||||
}
|
||||
}
|
||||
|
||||
public ITextEditorProperties TextEditorProperties {
|
||||
get {
|
||||
return textArea.Document.TextEditorProperties;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Cursor Cursor {
|
||||
get {
|
||||
return cursor;
|
||||
}
|
||||
set {
|
||||
cursor = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Size Size {
|
||||
get {
|
||||
return new Size(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsVisible {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractMargin(TextArea textArea)
|
||||
{
|
||||
this.textArea = textArea;
|
||||
}
|
||||
|
||||
public virtual void HandleMouseDown(Point mousepos, MouseButtons mouseButtons)
|
||||
{
|
||||
if (MouseDown != null) {
|
||||
MouseDown(this, mousepos, mouseButtons);
|
||||
}
|
||||
}
|
||||
public virtual void HandleMouseMove(Point mousepos, MouseButtons mouseButtons)
|
||||
{
|
||||
if (MouseMove != null) {
|
||||
MouseMove(this, mousepos, mouseButtons);
|
||||
}
|
||||
}
|
||||
public virtual void HandleMouseLeave(EventArgs e)
|
||||
{
|
||||
if (MouseLeave != null) {
|
||||
MouseLeave(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Paint(Graphics g, Rectangle rect)
|
||||
{
|
||||
if (Painted != null) {
|
||||
Painted(this, g, rect);
|
||||
}
|
||||
}
|
||||
|
||||
public event MarginPaintEventHandler Painted;
|
||||
public event MarginMouseEventHandler MouseDown;
|
||||
public event MarginMouseEventHandler MouseMove;
|
||||
public event EventHandler MouseLeave;
|
||||
}
|
||||
}
|
||||
86
ICSharpCode.TextEditorLinux/Src/Gui/BracketHighlighter.cs
Normal file
86
ICSharpCode.TextEditorLinux/Src/Gui/BracketHighlighter.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2659 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using ICSharpCode.TextEditor.Document;
|
||||
|
||||
namespace ICSharpCode.TextEditor
|
||||
{
|
||||
public class Highlight
|
||||
{
|
||||
public TextLocation OpenBrace { get; set; }
|
||||
public TextLocation CloseBrace { get; set; }
|
||||
|
||||
public Highlight(TextLocation openBrace, TextLocation closeBrace)
|
||||
{
|
||||
this.OpenBrace = openBrace;
|
||||
this.CloseBrace = closeBrace;
|
||||
}
|
||||
}
|
||||
|
||||
public class BracketHighlightingSheme
|
||||
{
|
||||
char opentag;
|
||||
char closingtag;
|
||||
|
||||
public char OpenTag {
|
||||
get {
|
||||
return opentag;
|
||||
}
|
||||
set {
|
||||
opentag = value;
|
||||
}
|
||||
}
|
||||
|
||||
public char ClosingTag {
|
||||
get {
|
||||
return closingtag;
|
||||
}
|
||||
set {
|
||||
closingtag = value;
|
||||
}
|
||||
}
|
||||
|
||||
public BracketHighlightingSheme(char opentag, char closingtag)
|
||||
{
|
||||
this.opentag = opentag;
|
||||
this.closingtag = closingtag;
|
||||
}
|
||||
|
||||
public Highlight GetHighlight(IDocument document, int offset)
|
||||
{
|
||||
int searchOffset;
|
||||
if (document.TextEditorProperties.BracketMatchingStyle == BracketMatchingStyle.After) {
|
||||
searchOffset = offset;
|
||||
} else {
|
||||
searchOffset = offset + 1;
|
||||
}
|
||||
char word = document.GetCharAt(Math.Max(0, Math.Min(document.TextLength - 1, searchOffset)));
|
||||
|
||||
TextLocation endP = document.OffsetToPosition(searchOffset);
|
||||
if (word == opentag) {
|
||||
if (searchOffset < document.TextLength) {
|
||||
int bracketOffset = TextUtilities.SearchBracketForward(document, searchOffset + 1, opentag, closingtag);
|
||||
if (bracketOffset >= 0) {
|
||||
TextLocation p = document.OffsetToPosition(bracketOffset);
|
||||
return new Highlight(p, endP);
|
||||
}
|
||||
}
|
||||
} else if (word == closingtag) {
|
||||
if (searchOffset > 0) {
|
||||
int bracketOffset = TextUtilities.SearchBracketBackward(document, searchOffset - 1, opentag, closingtag);
|
||||
if (bracketOffset >= 0) {
|
||||
TextLocation p = document.OffsetToPosition(bracketOffset);
|
||||
return new Highlight(p, endP);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
ICSharpCode.TextEditorLinux/Src/Gui/BrushRegistry.cs
Normal file
61
ICSharpCode.TextEditorLinux/Src/Gui/BrushRegistry.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 1965 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace ICSharpCode.TextEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains brushes/pens for the text editor to speed up drawing. Re-Creation of brushes and pens
|
||||
/// seems too costly.
|
||||
/// </summary>
|
||||
public class BrushRegistry
|
||||
{
|
||||
static Hashtable brushes = new Hashtable();
|
||||
static Hashtable pens = new Hashtable();
|
||||
static Hashtable dotPens = new Hashtable();
|
||||
|
||||
public static Brush GetBrush(Color color)
|
||||
{
|
||||
if (!brushes.Contains(color)) {
|
||||
Brush newBrush = new SolidBrush(color);
|
||||
brushes.Add(color, newBrush);
|
||||
return newBrush;
|
||||
}
|
||||
return brushes[color] as Brush;
|
||||
}
|
||||
|
||||
public static Pen GetPen(Color color)
|
||||
{
|
||||
if (!pens.Contains(color)) {
|
||||
Pen newPen = new Pen(color);
|
||||
pens.Add(color, newPen);
|
||||
return newPen;
|
||||
}
|
||||
return pens[color] as Pen;
|
||||
}
|
||||
|
||||
public static Pen GetDotPen(Color bgColor, Color fgColor)
|
||||
{
|
||||
bool containsBgColor = dotPens.Contains(bgColor);
|
||||
if (!containsBgColor || !((Hashtable)dotPens[bgColor]).Contains(fgColor)) {
|
||||
if (!containsBgColor) {
|
||||
dotPens[bgColor] = new Hashtable();
|
||||
}
|
||||
|
||||
HatchBrush hb = new HatchBrush(HatchStyle.Percent50, bgColor, fgColor);
|
||||
Pen newPen = new Pen(hb);
|
||||
((Hashtable)dotPens[bgColor])[fgColor] = newPen;
|
||||
return newPen;
|
||||
}
|
||||
return ((Hashtable)dotPens[bgColor])[fgColor] as Pen;
|
||||
}
|
||||
}
|
||||
}
|
||||
568
ICSharpCode.TextEditorLinux/Src/Gui/Caret.cs
Normal file
568
ICSharpCode.TextEditorLinux/Src/Gui/Caret.cs
Normal file
|
|
@ -0,0 +1,568 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2683 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using ICSharpCode.TextEditor.Document;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ICSharpCode.TextEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// In this enumeration are all caret modes listed.
|
||||
/// </summary>
|
||||
public enum CaretMode {
|
||||
/// <summary>
|
||||
/// If the caret is in insert mode typed characters will be
|
||||
/// inserted at the caret position
|
||||
/// </summary>
|
||||
InsertMode,
|
||||
|
||||
/// <summary>
|
||||
/// If the caret is in overwirte mode typed characters will
|
||||
/// overwrite the character at the caret position
|
||||
/// </summary>
|
||||
OverwriteMode
|
||||
}
|
||||
|
||||
|
||||
public class Caret : System.IDisposable
|
||||
{
|
||||
int line = 0;
|
||||
int column = 0;
|
||||
int desiredXPos = 0;
|
||||
CaretMode caretMode;
|
||||
|
||||
static bool caretCreated = false;
|
||||
bool hidden = true;
|
||||
TextArea textArea;
|
||||
static TextArea staticTextArea;
|
||||
Point currentPos = new Point(-1, -1);
|
||||
Ime ime = null;
|
||||
|
||||
/// <value>
|
||||
/// The 'prefered' xPos in which the caret moves, when it is moved
|
||||
/// up/down.
|
||||
/// </value>
|
||||
public int DesiredColumn {
|
||||
get {
|
||||
return desiredXPos;
|
||||
}
|
||||
set {
|
||||
desiredXPos = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The current caret mode.
|
||||
/// </value>
|
||||
public CaretMode CaretMode {
|
||||
get {
|
||||
return caretMode;
|
||||
}
|
||||
set {
|
||||
caretMode = value;
|
||||
OnCaretModeChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public int Line {
|
||||
get {
|
||||
return line;
|
||||
}
|
||||
set {
|
||||
line = value;
|
||||
ValidateCaretPos();
|
||||
UpdateCaretPosition();
|
||||
OnPositionChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public int Column {
|
||||
get {
|
||||
return column;
|
||||
}
|
||||
set {
|
||||
column = value;
|
||||
ValidateCaretPos();
|
||||
UpdateCaretPosition();
|
||||
OnPositionChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public TextLocation Position {
|
||||
get {
|
||||
return new TextLocation(column, line);
|
||||
}
|
||||
set {
|
||||
line = value.Y;
|
||||
column = value.X;
|
||||
ValidateCaretPos();
|
||||
UpdateCaretPosition();
|
||||
OnPositionChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public int Offset {
|
||||
get {
|
||||
return textArea.Document.PositionToOffset(Position);
|
||||
}
|
||||
}
|
||||
|
||||
public Caret(TextArea textArea)
|
||||
{
|
||||
this.textArea = textArea;
|
||||
staticTextArea = textArea;
|
||||
textArea.GotFocus += new EventHandler(GotFocus);
|
||||
textArea.LostFocus += new EventHandler(LostFocus);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
textArea.GotFocus -= new EventHandler(GotFocus);
|
||||
textArea.LostFocus -= new EventHandler(LostFocus);
|
||||
textArea = null;
|
||||
staticTextArea = null;
|
||||
// DestroyCaret();
|
||||
// caretCreated = false;
|
||||
}
|
||||
|
||||
public TextLocation ValidatePosition(TextLocation pos)
|
||||
{
|
||||
int line = Math.Max(0, Math.Min(textArea.Document.TotalNumberOfLines - 1, pos.Y));
|
||||
int column = Math.Max(0, pos.X);
|
||||
|
||||
if (column == int.MaxValue || !textArea.TextEditorProperties.AllowCaretBeyondEOL) {
|
||||
LineSegment lineSegment = textArea.Document.GetLineSegment(line);
|
||||
column = Math.Min(column, lineSegment.Length);
|
||||
}
|
||||
return new TextLocation(column, line);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// If the caret position is outside the document text bounds
|
||||
/// it is set to the correct position by calling ValidateCaretPos.
|
||||
/// </remarks>
|
||||
public void ValidateCaretPos()
|
||||
{
|
||||
line = Math.Max(0, Math.Min(textArea.Document.TotalNumberOfLines - 1, line));
|
||||
column = Math.Max(0, column);
|
||||
|
||||
if (column == int.MaxValue || !textArea.TextEditorProperties.AllowCaretBeyondEOL) {
|
||||
LineSegment lineSegment = textArea.Document.GetLineSegment(line);
|
||||
column = Math.Min(column, lineSegment.Length);
|
||||
}
|
||||
}
|
||||
|
||||
void CreateCaret()
|
||||
{
|
||||
while (!caretCreated) {
|
||||
switch (caretMode) {
|
||||
case CaretMode.InsertMode:
|
||||
caretCreated = CreateCaret(textArea.Handle, 0, 2, textArea.TextView.FontHeight);
|
||||
break;
|
||||
case CaretMode.OverwriteMode:
|
||||
caretCreated = CreateCaret(textArea.Handle, 0, (int)textArea.TextView.SpaceWidth, textArea.TextView.FontHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (currentPos.X < 0) {
|
||||
ValidateCaretPos();
|
||||
currentPos = ScreenPosition;
|
||||
}
|
||||
SetCaretPos(currentPos.X, currentPos.Y);
|
||||
ShowCaret(textArea.Handle);
|
||||
}
|
||||
|
||||
public void RecreateCaret()
|
||||
{
|
||||
DisposeCaret();
|
||||
if (!hidden) {
|
||||
CreateCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void DisposeCaret()
|
||||
{
|
||||
caretCreated = false;
|
||||
//if (Environment.OSVersion.Platform != PlatformID.Unix && Environment.OSVersion.Platform != PlatformID.MacOSX)
|
||||
HideCaret(textArea.Handle);
|
||||
DestroyCaret();
|
||||
}
|
||||
|
||||
void GotFocus(object sender, EventArgs e)
|
||||
{
|
||||
hidden = false;
|
||||
if (!textArea.MotherTextEditorControl.IsInUpdate) {
|
||||
CreateCaret();
|
||||
UpdateCaretPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void LostFocus(object sender, EventArgs e)
|
||||
{
|
||||
hidden = true;
|
||||
DisposeCaret();
|
||||
}
|
||||
|
||||
public Point ScreenPosition {
|
||||
get {
|
||||
int xpos = textArea.TextView.GetDrawingXPos(this.line, this.column);
|
||||
return new Point(textArea.TextView.DrawingPosition.X + xpos,
|
||||
textArea.TextView.DrawingPosition.Y
|
||||
+ (textArea.Document.GetVisibleLine(this.line)) * textArea.TextView.FontHeight
|
||||
- textArea.TextView.TextArea.VirtualTop.Y);
|
||||
}
|
||||
}
|
||||
int oldLine = -1;
|
||||
public void UpdateCaretPosition()
|
||||
{
|
||||
//Console.WriteLine("updatecaret " + ScreenPosition.X+"-"+ScreenPosition.Y+"-"+oldLine+"-"+line);
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
if (oldLine != line)
|
||||
{
|
||||
//Console.WriteLine(oldLine + "-" + line);
|
||||
textArea.UpdateLine(oldLine);
|
||||
//textArea.UpdateLine(line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (textArea.MotherTextAreaControl.TextEditorProperties.LineViewerStyle == LineViewerStyle.FullRow && oldLine != line)
|
||||
{
|
||||
textArea.UpdateLine(oldLine);
|
||||
textArea.UpdateLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
oldLine = line;
|
||||
|
||||
|
||||
if (hidden || textArea.MotherTextEditorControl.IsInUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
//DisposeCaret();
|
||||
//Console.WriteLine("updatecaret " + ScreenPosition.X + "-" + ScreenPosition.Y + "-" + oldLine + "-" + line);
|
||||
|
||||
if (!caretCreated) {
|
||||
CreateCaret();
|
||||
}
|
||||
if (caretCreated) {
|
||||
ValidateCaretPos();
|
||||
int lineNr = this.line;
|
||||
int xpos = textArea.TextView.GetDrawingXPos(lineNr, this.column);
|
||||
//LineSegment lineSegment = textArea.Document.GetLineSegment(lineNr);
|
||||
Point pos = ScreenPosition;
|
||||
if (xpos >= 0) {
|
||||
|
||||
bool success = SetCaretPos(pos.X, pos.Y);
|
||||
if (!success)
|
||||
{
|
||||
DestroyCaret();
|
||||
caretCreated = false;
|
||||
UpdateCaretPosition();
|
||||
}
|
||||
|
||||
}
|
||||
// set the input method editor location
|
||||
/*if (ime == null) {
|
||||
ime = new Ime(textArea.Handle, textArea.Document.TextEditorProperties.Font);
|
||||
} else {
|
||||
ime.HWnd = textArea.Handle;
|
||||
ime.Font = textArea.Document.TextEditorProperties.Font;
|
||||
}
|
||||
ime.SetIMEWindowLocation(pos.X, pos.Y);*/
|
||||
|
||||
currentPos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
#region Native caret functions
|
||||
/*[DllImport("User32.dll")]
|
||||
static extern bool CreateCaret(IntPtr hWnd, int hBitmap, int nWidth, int nHeight);
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
static extern bool SetCaretPos(int x, int y);
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
static extern bool DestroyCaret();
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
static extern bool ShowCaret(IntPtr hWnd);
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
static extern bool HideCaret(IntPtr hWnd);*/
|
||||
|
||||
[DllImport("User32.dll", EntryPoint="CreateCaret")]
|
||||
static extern bool CreateCaretNative(IntPtr hWnd, int hBitmap, int nWidth, int nHeight);
|
||||
|
||||
[DllImport("User32.dll", EntryPoint="SetCaretPos")]
|
||||
static extern bool SetCaretPosNative(int x, int y);
|
||||
|
||||
[DllImport("User32.dll", EntryPoint="DestroyCaret")]
|
||||
static extern bool DestroyCaretNative();
|
||||
|
||||
[DllImport("User32.dll", EntryPoint="ShowCaret")]
|
||||
static extern bool ShowCaretNative(IntPtr hWnd);
|
||||
|
||||
[DllImport("User32.dll", EntryPoint="HideCaret")]
|
||||
static extern bool HideCaretNative(IntPtr hWnd);
|
||||
|
||||
static int caret_X;
|
||||
static int caret_Y;
|
||||
static int caret_width;
|
||||
static int caret_height;
|
||||
static int cur_line;
|
||||
static IntPtr hwnd;
|
||||
static bool visible;
|
||||
static System.Windows.Forms.Timer timer;
|
||||
|
||||
static bool CreateCaret(IntPtr hWnd, int hBitmap, int nWidth, int nHeight)
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
caret_width = nWidth;
|
||||
caret_height = nHeight;
|
||||
hwnd = hWnd;
|
||||
if (create_caret == null)
|
||||
{
|
||||
create_caret = get_xplat().GetMethod("CreateCaret", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
create_caret.Invoke(null, new object[] { hWnd, nWidth, nHeight });
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return CreateCaretNative(hWnd, hBitmap, nWidth, nHeight);
|
||||
}
|
||||
|
||||
static bool DestroyCaret()
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
/*if (timer != null && timer.Enabled)
|
||||
{
|
||||
timer.Stop();
|
||||
visible = false;
|
||||
}*/
|
||||
|
||||
if (destroy_caret == null)
|
||||
{
|
||||
destroy_caret = get_xplat().GetMethod("DestroyCaret", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
destroy_caret.Invoke(null, new object[] { hwnd });
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return DestroyCaretNative();
|
||||
}
|
||||
|
||||
static MethodInfo set_caret_pos = null;
|
||||
static MethodInfo create_caret = null;
|
||||
static MethodInfo destroy_caret = null;
|
||||
static MethodInfo caret_visible = null;
|
||||
static Type xplat = null;
|
||||
|
||||
static bool SetCaretPos(int x, int y)
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
|
||||
/*if (caret_X != x || caret_Y != y)
|
||||
{
|
||||
HideCaret(hwnd);
|
||||
caret_X = x;
|
||||
caret_Y = y;
|
||||
|
||||
ShowCaret(hwnd);
|
||||
}
|
||||
else
|
||||
ShowCaret(hwnd);
|
||||
return true;*/
|
||||
|
||||
if (set_caret_pos == null)
|
||||
{
|
||||
set_caret_pos = get_xplat().GetMethod("SetCaretPos", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
set_caret_pos.Invoke(null, new object[] { hwnd, x, y});
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return SetCaretPosNative(x, y);
|
||||
}
|
||||
|
||||
static bool ShowCaret(IntPtr hWnd)
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
|
||||
/*if (timer != null && timer.Enabled)
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
if (timer == null)
|
||||
{
|
||||
timer = new System.Windows.Forms.Timer();
|
||||
timer.Interval = 500;
|
||||
visible = false;
|
||||
_ShowCaret(hwnd);
|
||||
visible = true;
|
||||
timer.Tick += delegate { if (!visible) _ShowCaret(hwnd); else _HideCaret(hwnd); };
|
||||
}
|
||||
visible = false;
|
||||
timer.Start();*/
|
||||
if (caret_visible == null)
|
||||
{
|
||||
caret_visible = get_xplat().GetMethod("CaretVisible", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
caret_visible.Invoke(null, new object[] { hWnd, true });
|
||||
return true;
|
||||
|
||||
}
|
||||
else
|
||||
return ShowCaretNative(hWnd);
|
||||
}
|
||||
|
||||
static Type get_xplat()
|
||||
{
|
||||
if (xplat != null)
|
||||
return xplat;
|
||||
Type[] types = typeof(Form).Assembly.GetTypes();
|
||||
foreach (Type t in types)
|
||||
{
|
||||
if (t.FullName == "System.Windows.Forms.XplatUI")
|
||||
{
|
||||
xplat = t;
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool HideCaret(IntPtr hWnd)
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
/*if (timer != null && timer.Enabled)
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
visible = false;
|
||||
//if (staticTextArea != null)
|
||||
// staticTextArea.UpdateLine(staticTextArea.TextView.GetLogicalLine(caret_Y));
|
||||
Graphics gr = Graphics.FromHwnd(hWnd);
|
||||
//gr.DrawRectangle(new Pen(Color.Black,caret_width),0,0,10,10);
|
||||
gr.DrawLine(new Pen(Color.White, caret_width), caret_X, caret_Y, caret_X, caret_Y + caret_height);
|
||||
gr.Dispose();*/
|
||||
if (caret_visible == null)
|
||||
{
|
||||
|
||||
caret_visible = get_xplat().GetMethod("CaretVisible", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
|
||||
}
|
||||
caret_visible.Invoke(null, new object[] { hWnd, false });
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return HideCaretNative(hWnd);
|
||||
}
|
||||
|
||||
static void _ShowCaret(IntPtr hWnd)
|
||||
{
|
||||
visible = true;
|
||||
Graphics gr = Graphics.FromHwnd(hWnd);
|
||||
//gr.DrawRectangle(new Pen(Color.Black,caret_width),0,0,10,10);
|
||||
gr.DrawLine(new Pen(Color.Black,caret_width),caret_X,caret_Y,caret_X,caret_Y+caret_height);
|
||||
gr.Dispose();
|
||||
|
||||
}
|
||||
|
||||
static void _HideCaret(IntPtr hWnd)
|
||||
{
|
||||
/*if (timer != null && timer.Enabled)
|
||||
{
|
||||
timer.Stop();
|
||||
}*/
|
||||
visible = false;
|
||||
Graphics gr = Graphics.FromHwnd(hWnd);
|
||||
//gr.DrawRectangle(new Pen(Color.Black,caret_width),0,0,10,10);
|
||||
gr.DrawLine(new Pen(Color.White, caret_width), caret_X, caret_Y, caret_X, caret_Y + caret_height);
|
||||
gr.Dispose();
|
||||
//staticTextArea.UpdateLine(staticTextArea.TextView.GetLogicalLine(caret_Y));
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
bool firePositionChangedAfterUpdateEnd;
|
||||
|
||||
void FirePositionChangedAfterUpdateEnd(object sender, EventArgs e)
|
||||
{
|
||||
OnPositionChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
protected virtual void OnPositionChanged(EventArgs e)
|
||||
{
|
||||
if (this.textArea.MotherTextEditorControl.IsInUpdate) {
|
||||
if (firePositionChangedAfterUpdateEnd == false) {
|
||||
firePositionChangedAfterUpdateEnd = true;
|
||||
this.textArea.Document.UpdateCommited += FirePositionChangedAfterUpdateEnd;
|
||||
}
|
||||
return;
|
||||
} else if (firePositionChangedAfterUpdateEnd) {
|
||||
this.textArea.Document.UpdateCommited -= FirePositionChangedAfterUpdateEnd;
|
||||
firePositionChangedAfterUpdateEnd = false;
|
||||
}
|
||||
|
||||
List<FoldMarker> foldings = textArea.Document.FoldingManager.GetFoldingsFromPosition(line, column);
|
||||
bool shouldUpdate = false;
|
||||
foreach (FoldMarker foldMarker in foldings) {
|
||||
shouldUpdate |= foldMarker.IsFolded;
|
||||
foldMarker.IsFolded = false;
|
||||
}
|
||||
|
||||
if (shouldUpdate) {
|
||||
textArea.Document.FoldingManager.NotifyFoldingsChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
if (PositionChanged != null) {
|
||||
PositionChanged(this, e);
|
||||
}
|
||||
textArea.ScrollToCaret();
|
||||
}
|
||||
|
||||
protected virtual void OnCaretModeChanged(EventArgs e)
|
||||
{
|
||||
if (CaretModeChanged != null) {
|
||||
CaretModeChanged(this, e);
|
||||
}
|
||||
HideCaret(textArea.Handle);
|
||||
DestroyCaret();
|
||||
caretCreated = false;
|
||||
CreateCaret();
|
||||
ShowCaret(textArea.Handle);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// Is called each time the caret is moved.
|
||||
/// </remarks>
|
||||
public event EventHandler PositionChanged;
|
||||
|
||||
/// <remarks>
|
||||
/// Is called each time the CaretMode has changed.
|
||||
/// </remarks>
|
||||
public event EventHandler CaretModeChanged;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2681 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Gui.CompletionWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of AbstractCompletionWindow.
|
||||
/// </summary>
|
||||
public abstract class AbstractCompletionWindow : System.Windows.Forms.Form
|
||||
{
|
||||
protected TextEditorControl control;
|
||||
protected Size drawingSize;
|
||||
Rectangle workingScreen;
|
||||
Form parentForm;
|
||||
|
||||
protected AbstractCompletionWindow(Form parentForm, TextEditorControl control)
|
||||
{
|
||||
workingScreen = Screen.GetWorkingArea(parentForm);
|
||||
// SetStyle(ControlStyles.Selectable, false);
|
||||
this.parentForm = parentForm;
|
||||
this.control = control;
|
||||
|
||||
SetLocation();
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
ShowInTaskbar = false;
|
||||
MinimumSize = new Size(1, 1);
|
||||
Size = new Size(1, 1);
|
||||
}
|
||||
|
||||
protected virtual void SetLocation()
|
||||
{
|
||||
TextArea textArea = control.ActiveTextAreaControl.TextArea;
|
||||
TextLocation caretPos = textArea.Caret.Position;
|
||||
|
||||
int xpos = textArea.TextView.GetDrawingXPos(caretPos.Y, caretPos.X);
|
||||
int rulerHeight = textArea.TextEditorProperties.ShowHorizontalRuler ? textArea.TextView.FontHeight : 0;
|
||||
Point pos = new Point(textArea.TextView.DrawingPosition.X + xpos,
|
||||
textArea.TextView.DrawingPosition.Y + (textArea.Document.GetVisibleLine(caretPos.Y)) * textArea.TextView.FontHeight
|
||||
- textArea.TextView.TextArea.VirtualTop.Y + textArea.TextView.FontHeight + rulerHeight);
|
||||
|
||||
Point location = control.ActiveTextAreaControl.PointToScreen(pos);
|
||||
|
||||
// set bounds
|
||||
Rectangle bounds = new Rectangle(location, drawingSize);
|
||||
|
||||
if (!workingScreen.Contains(bounds)) {
|
||||
if (bounds.Right > workingScreen.Right) {
|
||||
bounds.X = workingScreen.Right - bounds.Width;
|
||||
}
|
||||
if (bounds.Left < workingScreen.Left) {
|
||||
bounds.X = workingScreen.Left;
|
||||
}
|
||||
if (bounds.Top < workingScreen.Top) {
|
||||
bounds.Y = workingScreen.Top;
|
||||
}
|
||||
if (bounds.Bottom > workingScreen.Bottom) {
|
||||
bounds.Y = bounds.Y - bounds.Height - control.ActiveTextAreaControl.TextArea.TextView.FontHeight;
|
||||
if (bounds.Bottom > workingScreen.Bottom) {
|
||||
bounds.Y = workingScreen.Bottom - bounds.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
Bounds = bounds;
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams {
|
||||
get {
|
||||
CreateParams p = base.CreateParams;
|
||||
AddShadowToWindow(p);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
static int shadowStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a shadow to the create params if it is supported by the operating system.
|
||||
/// </summary>
|
||||
public static void AddShadowToWindow(CreateParams createParams)
|
||||
{
|
||||
if (shadowStatus == 0) {
|
||||
// Test OS version
|
||||
shadowStatus = -1; // shadow not supported
|
||||
if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
|
||||
Version ver = Environment.OSVersion.Version;
|
||||
if (ver.Major > 5 || ver.Major == 5 && ver.Minor >= 1) {
|
||||
shadowStatus = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shadowStatus == 1 || Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
createParams.ClassStyle |= 0x00020000; // set CS_DROPSHADOW
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ShowWithoutActivation {
|
||||
get {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void ShowCompletionWindow()
|
||||
{
|
||||
//MessageBox.Show("ShowCompletionWindow");
|
||||
Owner = parentForm;
|
||||
Enabled = true;
|
||||
this.Show();
|
||||
|
||||
if (parentForm != null) {
|
||||
parentForm.LocationChanged += new EventHandler(this.ParentFormLocationChanged);
|
||||
}
|
||||
|
||||
control.ActiveTextAreaControl.VScrollBar.ValueChanged += new EventHandler(ParentFormLocationChanged);
|
||||
control.ActiveTextAreaControl.HScrollBar.ValueChanged += new EventHandler(ParentFormLocationChanged);
|
||||
control.ActiveTextAreaControl.TextArea.DoProcessDialogKey += new DialogKeyProcessor(ProcessTextAreaKey);
|
||||
control.ActiveTextAreaControl.Caret.PositionChanged += new EventHandler(CaretOffsetChanged);
|
||||
control.ActiveTextAreaControl.TextArea.LostFocus += new EventHandler(this.TextEditorLostFocus);
|
||||
control.Resize += new EventHandler(ParentFormLocationChanged);
|
||||
|
||||
foreach (Control c in Controls) {
|
||||
c.MouseMove += ControlMouseMove;
|
||||
}
|
||||
control.Focus();
|
||||
}
|
||||
|
||||
void ParentFormLocationChanged(object sender, EventArgs e)
|
||||
{
|
||||
SetLocation();
|
||||
}
|
||||
|
||||
public virtual bool ProcessKeyEvent(char ch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool ProcessTextAreaKey(Keys keyData)
|
||||
{
|
||||
if (!Visible) {
|
||||
return false;
|
||||
}
|
||||
switch (keyData) {
|
||||
case Keys.Escape:
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void CaretOffsetChanged(object sender, EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
protected void TextEditorLostFocus(object sender, EventArgs e)
|
||||
{
|
||||
if (!control.ActiveTextAreaControl.TextArea.Focused
|
||||
&& !this.ContainsFocus && Environment.OSVersion.Platform != PlatformID.Unix
|
||||
&& Environment.OSVersion.Platform != PlatformID.MacOSX
|
||||
)
|
||||
{
|
||||
//MessageBox.Show("TextEditorLostFocus.Close()");
|
||||
// SSM 22/06/22 - убрал - и в Моно стала работать
|
||||
//Close();
|
||||
}
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
{
|
||||
//MessageBox.Show("control.Focus()");
|
||||
control.Focus(); // Да, именно так!!!!!!!!!!!!!! Не удалять!!!
|
||||
//control.ActiveTextAreaControl.TextArea.Focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
|
||||
// take out the inserted methods
|
||||
parentForm.LocationChanged -= new EventHandler(ParentFormLocationChanged);
|
||||
|
||||
foreach (Control c in Controls) {
|
||||
c.MouseMove -= ControlMouseMove;
|
||||
}
|
||||
|
||||
if (control.ActiveTextAreaControl.VScrollBar != null) {
|
||||
control.ActiveTextAreaControl.VScrollBar.ValueChanged -= new EventHandler(ParentFormLocationChanged);
|
||||
}
|
||||
if (control.ActiveTextAreaControl.HScrollBar != null) {
|
||||
control.ActiveTextAreaControl.HScrollBar.ValueChanged -= new EventHandler(ParentFormLocationChanged);
|
||||
}
|
||||
|
||||
control.ActiveTextAreaControl.TextArea.LostFocus -= new EventHandler(this.TextEditorLostFocus);
|
||||
control.ActiveTextAreaControl.Caret.PositionChanged -= new EventHandler(CaretOffsetChanged);
|
||||
control.ActiveTextAreaControl.TextArea.DoProcessDialogKey -= new DialogKeyProcessor(ProcessTextAreaKey);
|
||||
control.Resize -= new EventHandler(ParentFormLocationChanged);
|
||||
Dispose();
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseMove(e);
|
||||
ControlMouseMove(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the mouse moves over this form or any child control.
|
||||
/// Shows the mouse cursor on the text area if it has been hidden.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Derived classes should attach this handler to the MouseMove event
|
||||
/// of all created controls which are not added to the Controls
|
||||
/// collection.
|
||||
/// </remarks>
|
||||
protected void ControlMouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
control.ActiveTextAreaControl.TextArea.ShowHiddenCursor(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
|
||||
// <version>$Revision: 2533 $</version>
|
||||
// </file>
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ICSharpCode.TextEditor.Gui.CompletionWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of CodeCompletionListView.
|
||||
/// </summary>
|
||||
public class CodeCompletionListView : System.Windows.Forms.UserControl
|
||||
{
|
||||
ICompletionData[] completionData;
|
||||
int firstItem = 0;
|
||||
int selectedItem = -1;
|
||||
ImageList imageList;
|
||||
|
||||
public ImageList ImageList {
|
||||
get {
|
||||
return imageList;
|
||||
}
|
||||
set {
|
||||
imageList = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int FirstItem {
|
||||
get {
|
||||
return firstItem;
|
||||
}
|
||||
set {
|
||||
if (firstItem != value) {
|
||||
firstItem = value;
|
||||
OnFirstItemChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ICompletionData SelectedCompletionData {
|
||||
get {
|
||||
if (selectedItem < 0) {
|
||||
return null;
|
||||
}
|
||||
return completionData[selectedItem];
|
||||
}
|
||||
}
|
||||
|
||||
public int ItemHeight {
|
||||
get {
|
||||
return Math.Max(imageList.ImageSize.Height, (int)(Font.Height * 1.25));
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxVisibleItem {
|
||||
get {
|
||||
return Height / ItemHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public CodeCompletionListView(ICompletionData[] completionData)
|
||||
{
|
||||
Array.Sort(completionData);
|
||||
this.completionData = completionData;
|
||||
|
||||
// this.KeyDown += new System.Windows.Forms.KeyEventHandler(OnKey);
|
||||
// SetStyle(ControlStyles.Selectable, false);
|
||||
// SetStyle(ControlStyles.UserPaint, true);
|
||||
// SetStyle(ControlStyles.DoubleBuffer, false);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (completionData != null) {
|
||||
Array.Clear(completionData, 0, completionData.Length);
|
||||
}
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public void SelectIndex(int index)
|
||||
{
|
||||
int oldSelectedItem = selectedItem;
|
||||
int oldFirstItem = firstItem;
|
||||
|
||||
index = Math.Max(0, index);
|
||||
selectedItem = Math.Max(0, Math.Min(completionData.Length - 1, index));
|
||||
if (selectedItem < firstItem) {
|
||||
FirstItem = selectedItem;
|
||||
}
|
||||
if (firstItem + MaxVisibleItem <= selectedItem) {
|
||||
FirstItem = selectedItem - MaxVisibleItem + 1;
|
||||
}
|
||||
if (oldSelectedItem != selectedItem) {
|
||||
if (firstItem != oldFirstItem) {
|
||||
Invalidate();
|
||||
} else {
|
||||
int min = Math.Min(selectedItem, oldSelectedItem) - firstItem;
|
||||
int max = Math.Max(selectedItem, oldSelectedItem) - firstItem;
|
||||
Invalidate(new Rectangle(0, 1 + min * ItemHeight, Width, (max - min + 1) * ItemHeight));
|
||||
}
|
||||
OnSelectedItemChanged(EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public void CenterViewOn(int index)
|
||||
{
|
||||
int oldFirstItem = this.FirstItem;
|
||||
int firstItem = index - MaxVisibleItem / 2;
|
||||
if (firstItem < 0)
|
||||
this.FirstItem = 0;
|
||||
else if (firstItem >= completionData.Length - MaxVisibleItem)
|
||||
this.FirstItem = completionData.Length - MaxVisibleItem;
|
||||
else
|
||||
this.FirstItem = firstItem;
|
||||
if (this.FirstItem != oldFirstItem) {
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSelection()
|
||||
{
|
||||
if (selectedItem < 0)
|
||||
return;
|
||||
int itemNum = selectedItem - firstItem;
|
||||
selectedItem = -1;
|
||||
Invalidate(new Rectangle(0, itemNum * ItemHeight, Width, (itemNum + 1) * ItemHeight + 1));
|
||||
Update();
|
||||
OnSelectedItemChanged(EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void PageDown()
|
||||
{
|
||||
SelectIndex(selectedItem + MaxVisibleItem);
|
||||
}
|
||||
|
||||
public void PageUp()
|
||||
{
|
||||
SelectIndex(selectedItem - MaxVisibleItem);
|
||||
}
|
||||
|
||||
public void SelectNextItem()
|
||||
{
|
||||
SelectIndex(selectedItem + 1);
|
||||
}
|
||||
|
||||
public void SelectPrevItem()
|
||||
{
|
||||
SelectIndex(selectedItem - 1);
|
||||
}
|
||||
|
||||
public void SelectItemWithStart(string startText)
|
||||
{
|
||||
if (startText == null || startText.Length == 0) return;
|
||||
string originalStartText = startText;
|
||||
startText = startText.ToLower();
|
||||
int bestIndex = -1;
|
||||
int bestQuality = -1;
|
||||
// Qualities: 0 = match start
|
||||
// 1 = match start case sensitive
|
||||
// 2 = full match
|
||||
// 3 = full match case sensitive
|
||||
double bestPriority = 0;
|
||||
for (int i = 0; i < completionData.Length; ++i) {
|
||||
string itemText = completionData[i].Text;
|
||||
string lowerText = itemText.ToLower();
|
||||
if (lowerText.StartsWith(startText)) {
|
||||
double priority = completionData[i].Priority;
|
||||
int quality;
|
||||
if (lowerText == startText) {
|
||||
if (itemText == originalStartText)
|
||||
quality = 3;
|
||||
else
|
||||
quality = 2;
|
||||
} else if (itemText.StartsWith(originalStartText)) {
|
||||
quality = 1;
|
||||
} else {
|
||||
quality = 0;
|
||||
}
|
||||
bool useThisItem;
|
||||
if (bestQuality < quality) {
|
||||
useThisItem = true;
|
||||
} else {
|
||||
if (bestIndex == selectedItem) {
|
||||
useThisItem = false;
|
||||
} else if (i == selectedItem) {
|
||||
useThisItem = bestQuality == quality;
|
||||
} else {
|
||||
useThisItem = bestQuality == quality && bestPriority < priority;
|
||||
}
|
||||
}
|
||||
if (useThisItem) {
|
||||
bestIndex = i;
|
||||
bestPriority = priority;
|
||||
bestQuality = quality;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestIndex < 0) {
|
||||
ClearSelection();
|
||||
} else {
|
||||
if (bestIndex < firstItem || firstItem + MaxVisibleItem <= bestIndex) {
|
||||
SelectIndex(bestIndex);
|
||||
CenterViewOn(bestIndex);
|
||||
} else {
|
||||
SelectIndex(bestIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs pe)
|
||||
{
|
||||
float yPos = 1;
|
||||
float itemHeight = ItemHeight;
|
||||
// Maintain aspect ratio
|
||||
int imageWidth = (int)(itemHeight * imageList.ImageSize.Width / imageList.ImageSize.Height);
|
||||
|
||||
int curItem = firstItem;
|
||||
Graphics g = pe.Graphics;
|
||||
while (curItem < completionData.Length && yPos < Height) {
|
||||
RectangleF drawingBackground = new RectangleF(1, yPos, Width - 2, itemHeight);
|
||||
if (drawingBackground.IntersectsWith(pe.ClipRectangle)) {
|
||||
// draw Background
|
||||
if (curItem == selectedItem) {
|
||||
g.FillRectangle(SystemBrushes.Highlight, drawingBackground);
|
||||
} else {
|
||||
g.FillRectangle(SystemBrushes.Window, drawingBackground);
|
||||
}
|
||||
|
||||
// draw Icon
|
||||
int xPos = 0;
|
||||
if (imageList != null && completionData[curItem].ImageIndex < imageList.Images.Count) {
|
||||
g.DrawImage(imageList.Images[completionData[curItem].ImageIndex], new RectangleF(1, yPos, imageWidth, itemHeight));
|
||||
xPos = imageWidth;
|
||||
}
|
||||
|
||||
// draw text
|
||||
if (curItem == selectedItem) {
|
||||
g.DrawString(completionData[curItem].Text, Font, SystemBrushes.HighlightText, xPos, yPos);
|
||||
} else {
|
||||
g.DrawString(completionData[curItem].Text, Font, SystemBrushes.WindowText, xPos, yPos);
|
||||
}
|
||||
}
|
||||
|
||||
yPos += itemHeight;
|
||||
++curItem;
|
||||
}
|
||||
g.DrawRectangle(SystemPens.Control, new Rectangle(0, 0, Width - 1, Height - 1));
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
|
||||
{
|
||||
float yPos = 1;
|
||||
int curItem = firstItem;
|
||||
float itemHeight = ItemHeight;
|
||||
|
||||
while (curItem < completionData.Length && yPos < Height) {
|
||||
RectangleF drawingBackground = new RectangleF(1, yPos, Width - 2, itemHeight);
|
||||
if (drawingBackground.Contains(e.X, e.Y)) {
|
||||
SelectIndex(curItem);
|
||||
break;
|
||||
}
|
||||
yPos += itemHeight;
|
||||
++curItem;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs pe)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnSelectedItemChanged(EventArgs e)
|
||||
{
|
||||
if (SelectedItemChanged != null) {
|
||||
SelectedItemChanged(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnFirstItemChanged(EventArgs e)
|
||||
{
|
||||
if (FirstItemChanged != null) {
|
||||
FirstItemChanged(this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler SelectedItemChanged;
|
||||
public event EventHandler FirstItemChanged;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue