Merge branch 'master' into newNR
This commit is contained in:
Коммит
fd1eff9fe6
|
@ -33,26 +33,26 @@
|
|||
</BuildLogFile>
|
||||
<FrameworkVersion>.NET 4.0.30319</FrameworkVersion>
|
||||
<HelpTitle>AvalonEdit</HelpTitle>
|
||||
<CopyrightText>Copyright 2008-2011, Daniel Grunwald</CopyrightText>
|
||||
<CopyrightText>Copyright 2008-2012, Daniel Grunwald</CopyrightText>
|
||||
<PresentationStyle>Prototype</PresentationStyle>
|
||||
<HelpFileVersion>4.1.0.0</HelpFileVersion>
|
||||
<HelpFileVersion>4.2.0.0</HelpFileVersion>
|
||||
<ComponentConfigurations>
|
||||
<ComponentConfig id="Code Block Component" enabled="True">
|
||||
<component id="Code Block Component" type="SandcastleBuilder.Components.CodeBlockComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<!-- Base path for relative filenames in source attributes
|
||||
<!-- Base path for relative filenames in source attributes
|
||||
(optional) -->
|
||||
<basePath value="{@HtmlEncProjectFolder}" />
|
||||
<!-- Connect to language filter (optional). If omitted,
|
||||
<basePath value="{@HtmlEncProjectFolder}" />
|
||||
<!-- Connect to language filter (optional). If omitted,
|
||||
language filtering is enabled by default. -->
|
||||
<languageFilter value="true" />
|
||||
<!-- Allow missing source files (Optional). If omitted,
|
||||
<languageFilter value="true" />
|
||||
<!-- Allow missing source files (Optional). If omitted,
|
||||
it will generate errors if referenced source files
|
||||
are missing. -->
|
||||
<allowMissingSource value="false" />
|
||||
<!-- Remove region markers from imported code blocks. If omitted,
|
||||
<allowMissingSource value="false" />
|
||||
<!-- Remove region markers from imported code blocks. If omitted,
|
||||
region markers in imported code blocks are left alone. -->
|
||||
<removeRegionMarkers value="false" />
|
||||
<!-- Code colorizer options (required).
|
||||
<removeRegionMarkers value="false" />
|
||||
<!-- Code colorizer options (required).
|
||||
Attributes:
|
||||
Language syntax configuration file (required)
|
||||
XSLT style file (required)
|
||||
|
@ -63,71 +63,82 @@
|
|||
Keep XML comment "see" tags within the code (optional)
|
||||
Tab size override (optional, 0 = Use syntax file setting)
|
||||
Use language name as default title (optional) -->
|
||||
<colorizer syntaxFile="{@SHFBFolder}Colorizer\highlight.xml" styleFile="{@SHFBFolder}Colorizer\highlight.xsl" copyImageUrl="../icons/CopyCode.gif" language="cs" numberLines="false" outlining="false" keepSeeTags="false" tabSize="0" defaultTitle="true" />
|
||||
</component>
|
||||
<colorizer syntaxFile="{@SHFBFolder}Colorizer\highlight.xml" styleFile="{@SHFBFolder}Colorizer\highlight.xsl" copyImageUrl="../icons/CopyCode.gif" language="cs" numberLines="false" outlining="false" keepSeeTags="false" tabSize="0" defaultTitle="true" />
|
||||
</component>
|
||||
</ComponentConfig>
|
||||
<ComponentConfig id="IntelliSense Component" enabled="True"><component id="IntelliSense Component" type="SandcastleBuilder.Components.IntelliSenseComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<!-- Output options (optional)
|
||||
<ComponentConfig id="IntelliSense Component" enabled="True">
|
||||
<component id="IntelliSense Component" type="SandcastleBuilder.Components.IntelliSenseComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<!-- Output options (optional)
|
||||
Attributes:
|
||||
Include Namespaces (false by default)
|
||||
Namespaces filename ("Namespaces" if not specified or empty)
|
||||
Directory (current folder if not specified or empty) -->
|
||||
<output includeNamespaces="false" namespacesFile="Namespaces" folder="{@OutputFolder}" />
|
||||
</component></ComponentConfig>
|
||||
<ComponentConfig id="Cached MSDN URL References" enabled="True"><component id="Cached MSDN URL References" type="SandcastleBuilder.Components.CachedResolveReferenceLinksComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll" locale="{@Locale}" linkTarget="{@SdkLinkTarget}">
|
||||
<helpOutput format="HtmlHelp1">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@HtmlSdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Local" />
|
||||
</helpOutput>
|
||||
<helpOutput format="MSHelp2">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelp2SdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Index" />
|
||||
</helpOutput>
|
||||
<helpOutput format="MSHelpViewer">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelpViewerSdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Id" />
|
||||
</helpOutput>
|
||||
<helpOutput format="Website">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@WebsiteSdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Local" />
|
||||
</helpOutput>
|
||||
</component></ComponentConfig>
|
||||
<ComponentConfig id="Post-transform Component" enabled="True"><component id="Post-transform Component" type="SandcastleBuilder.Components.PostTransformComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<!-- Code colorizer files (required).
|
||||
<output includeNamespaces="false" namespacesFile="Namespaces" folder="{@OutputFolder}" />
|
||||
</component>
|
||||
</ComponentConfig>
|
||||
<ComponentConfig id="Cached MSDN URL References" enabled="True">
|
||||
<component id="Cached MSDN URL References" type="SandcastleBuilder.Components.CachedResolveReferenceLinksComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll" locale="{@Locale}" linkTarget="{@SdkLinkTarget}">
|
||||
<helpOutput format="HtmlHelp1">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@HtmlSdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Local" />
|
||||
</helpOutput>
|
||||
<helpOutput format="MSHelp2">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelp2SdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Index" />
|
||||
</helpOutput>
|
||||
<helpOutput format="MSHelpViewer">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelpViewerSdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Id" />
|
||||
</helpOutput>
|
||||
<helpOutput format="Website">
|
||||
<cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
|
||||
<targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@WebsiteSdkLinkType}" />
|
||||
<targets files="reflection.xml" type="Local" />
|
||||
</helpOutput>
|
||||
</component>
|
||||
</ComponentConfig>
|
||||
<ComponentConfig id="Post-transform Component" enabled="True">
|
||||
<component id="Post-transform Component" type="SandcastleBuilder.Components.PostTransformComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<!-- Code colorizer files (required).
|
||||
Attributes:
|
||||
Stylesheet file (required)
|
||||
Script file (required)
|
||||
"Copy" image file (required) -->
|
||||
<colorizer stylesheet="{@SHFBFolder}Colorizer\highlight.css" scriptFile="{@SHFBFolder}Colorizer\highlight.js" copyImage="{@SHFBFolder}Colorizer\CopyCode.gif" />
|
||||
<!-- Base output paths for the files (required). These should match
|
||||
<colorizer stylesheet="{@SHFBFolder}Colorizer\highlight.css" scriptFile="{@SHFBFolder}Colorizer\highlight.js" copyImage="{@SHFBFolder}Colorizer\CopyCode.gif" />
|
||||
<!-- Base output paths for the files (required). These should match
|
||||
the parent folder of the output path of the HTML files (see
|
||||
each of the SaveComponent instances below). -->
|
||||
<outputPaths>
|
||||
<outputPaths>
|
||||
{@HelpFormatOutputPaths}
|
||||
</outputPaths>
|
||||
<!-- Logo image file (optional). Filename is required. The height,
|
||||
<!-- Logo image file (optional). Filename is required. The height,
|
||||
width, altText, placement, and alignment attributes are
|
||||
optional. -->
|
||||
<logoFile filename="" height="0" width="0" altText="" placement="left" alignment="left" />
|
||||
</component></ComponentConfig>
|
||||
<ComponentConfig id="Cached Reflection Index Data" enabled="True"><component id="Cached Reflection Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
|
||||
<cache base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" cacheFile="{@LocalDataFolder}Cache\Reflection.cache" />
|
||||
<data files="reflection.xml" />
|
||||
</index>
|
||||
<copy name="reflection" source="*" target="/document/reference" />
|
||||
</component></ComponentConfig>
|
||||
<ComponentConfig id="Cached Framework Comments Index Data" enabled="True"><component id="Cached Framework Comments Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<index name="comments" value="/doc/members/member" key="@name" cache="100">
|
||||
<logoFile filename="" height="0" width="0" altText="" placement="left" alignment="left" />
|
||||
</component>
|
||||
</ComponentConfig>
|
||||
<ComponentConfig id="Cached Reflection Index Data" enabled="True">
|
||||
<component id="Cached Reflection Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
|
||||
<cache base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" cacheFile="{@LocalDataFolder}Cache\Reflection.cache" />
|
||||
<data files="reflection.xml" />
|
||||
</index>
|
||||
<copy name="reflection" source="*" target="/document/reference" />
|
||||
</component>
|
||||
</ComponentConfig>
|
||||
<ComponentConfig id="Cached Framework Comments Index Data" enabled="True">
|
||||
<component id="Cached Framework Comments Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
|
||||
<index name="comments" value="/doc/members/member" key="@name" cache="100">
|
||||
{@CachedFrameworkCommentList}
|
||||
{@CommentFileList}
|
||||
</index>
|
||||
<copy name="comments" source="*" target="/document/comments" />
|
||||
</component></ComponentConfig></ComponentConfigurations>
|
||||
<copy name="comments" source="*" target="/document/comments" />
|
||||
</component>
|
||||
</ComponentConfig>
|
||||
</ComponentConfigurations>
|
||||
<DocumentationSources>
|
||||
<DocumentationSource sourceFile="..\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj" />
|
||||
</DocumentationSources>
|
||||
|
|
|
@ -41,13 +41,13 @@
|
|||
<section>
|
||||
<title>System requirements</title>
|
||||
<content>
|
||||
<para>AvalonEdit requires the
|
||||
<para>There are two versions of AvalonEdit - the normal one requires
|
||||
<externalLink>
|
||||
<linkText>.NET Framework 3.5 SP1</linkText>
|
||||
<linkUri>http://www.microsoft.com/downloads/details.aspx?FamilyID=ab99342f-5d1a-413d-8319-81da479ab0d7&DisplayLang=en</linkUri>
|
||||
<linkText>.NET Framework 4.0</linkText>
|
||||
<linkUri>http://msdn.microsoft.com/en-us/library/w0x726c2.aspx</linkUri>
|
||||
<linkTarget>_blank</linkTarget>
|
||||
</externalLink>.
|
||||
For compiling AvalonEdit inside Visual Studio 2008, VS08 SP1 is required.
|
||||
</externalLink> or higher; but we also offer a modified version for .NET 3.5 SP1.
|
||||
For compiling AvalonEdit, you will need a C# 4.0 compiler (SharpDevelop 4.x or Visual Studio 2010).
|
||||
</para>
|
||||
<para>AvalonEdit requires FullTrust and will not run as XBAP.</para>
|
||||
</content>
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
{
|
||||
readonly TextArea textArea;
|
||||
readonly TextView textView;
|
||||
readonly ImeSupport ime;
|
||||
readonly CaretLayer caretAdorner;
|
||||
bool visible;
|
||||
|
||||
|
@ -31,6 +32,7 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
this.textArea = textArea;
|
||||
this.textView = textArea.TextView;
|
||||
position = new TextViewPosition(1, 1, 0);
|
||||
ime = new ImeSupport(textArea);
|
||||
|
||||
caretAdorner = new CaretLayer(textView);
|
||||
textView.InsertLayer(caretAdorner, KnownLayer.Caret, LayerInsertionPosition.Replace);
|
||||
|
@ -442,6 +444,7 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
} else {
|
||||
caretAdorner.Hide();
|
||||
}
|
||||
ime.UpdateCompositionWindow();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
|
@ -41,21 +42,28 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
const ModifierKeys None = ModifierKeys.None;
|
||||
const ModifierKeys Ctrl = ModifierKeys.Control;
|
||||
const ModifierKeys Shift = ModifierKeys.Shift;
|
||||
const ModifierKeys Alt = ModifierKeys.Alt;
|
||||
|
||||
AddBinding(EditingCommands.MoveLeftByCharacter, None, Key.Left, OnMoveCaret(CaretMovementType.CharLeft));
|
||||
AddBinding(EditingCommands.SelectLeftByCharacter, Shift, Key.Left, OnMoveCaretExtendSelection(CaretMovementType.CharLeft));
|
||||
AddBinding(RectangleSelection.BoxSelectLeftByCharacter, Alt | Shift, Key.Left, OnMoveCaretBoxSelection(CaretMovementType.CharLeft));
|
||||
AddBinding(EditingCommands.MoveRightByCharacter, None, Key.Right, OnMoveCaret(CaretMovementType.CharRight));
|
||||
AddBinding(EditingCommands.SelectRightByCharacter, Shift, Key.Right, OnMoveCaretExtendSelection(CaretMovementType.CharRight));
|
||||
AddBinding(RectangleSelection.BoxSelectRightByCharacter, Alt | Shift, Key.Right, OnMoveCaretBoxSelection(CaretMovementType.CharRight));
|
||||
|
||||
AddBinding(EditingCommands.MoveLeftByWord, Ctrl, Key.Left, OnMoveCaret(CaretMovementType.WordLeft));
|
||||
AddBinding(EditingCommands.SelectLeftByWord, Ctrl | Shift, Key.Left, OnMoveCaretExtendSelection(CaretMovementType.WordLeft));
|
||||
AddBinding(RectangleSelection.BoxSelectLeftByWord, Ctrl | Alt | Shift, Key.Left, OnMoveCaretBoxSelection(CaretMovementType.WordLeft));
|
||||
AddBinding(EditingCommands.MoveRightByWord, Ctrl, Key.Right, OnMoveCaret(CaretMovementType.WordRight));
|
||||
AddBinding(EditingCommands.SelectRightByWord, Ctrl | Shift, Key.Right, OnMoveCaretExtendSelection(CaretMovementType.WordRight));
|
||||
AddBinding(RectangleSelection.BoxSelectRightByWord, Ctrl | Alt | Shift, Key.Right, OnMoveCaretBoxSelection(CaretMovementType.WordRight));
|
||||
|
||||
AddBinding(EditingCommands.MoveUpByLine, None, Key.Up, OnMoveCaret(CaretMovementType.LineUp));
|
||||
AddBinding(EditingCommands.SelectUpByLine, Shift, Key.Up, OnMoveCaretExtendSelection(CaretMovementType.LineUp));
|
||||
AddBinding(RectangleSelection.BoxSelectUpByLine, Alt | Shift, Key.Up, OnMoveCaretBoxSelection(CaretMovementType.LineUp));
|
||||
AddBinding(EditingCommands.MoveDownByLine, None, Key.Down, OnMoveCaret(CaretMovementType.LineDown));
|
||||
AddBinding(EditingCommands.SelectDownByLine, Shift, Key.Down, OnMoveCaretExtendSelection(CaretMovementType.LineDown));
|
||||
AddBinding(RectangleSelection.BoxSelectDownByLine, Alt | Shift, Key.Down, OnMoveCaretBoxSelection(CaretMovementType.LineDown));
|
||||
|
||||
AddBinding(EditingCommands.MoveDownByPage, None, Key.PageDown, OnMoveCaret(CaretMovementType.PageDown));
|
||||
AddBinding(EditingCommands.SelectDownByPage, Shift, Key.PageDown, OnMoveCaretExtendSelection(CaretMovementType.PageDown));
|
||||
|
@ -64,8 +72,10 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
|
||||
AddBinding(EditingCommands.MoveToLineStart, None, Key.Home, OnMoveCaret(CaretMovementType.LineStart));
|
||||
AddBinding(EditingCommands.SelectToLineStart, Shift, Key.Home, OnMoveCaretExtendSelection(CaretMovementType.LineStart));
|
||||
AddBinding(RectangleSelection.BoxSelectToLineStart, Alt | Shift, Key.Home, OnMoveCaretBoxSelection(CaretMovementType.LineStart));
|
||||
AddBinding(EditingCommands.MoveToLineEnd, None, Key.End, OnMoveCaret(CaretMovementType.LineEnd));
|
||||
AddBinding(EditingCommands.SelectToLineEnd, Shift, Key.End, OnMoveCaretExtendSelection(CaretMovementType.LineEnd));
|
||||
AddBinding(RectangleSelection.BoxSelectToLineEnd, Alt | Shift, Key.End, OnMoveCaretBoxSelection(CaretMovementType.LineEnd));
|
||||
|
||||
AddBinding(EditingCommands.MoveToDocumentStart, Ctrl, Key.Home, OnMoveCaret(CaretMovementType.DocumentStart));
|
||||
AddBinding(EditingCommands.SelectToDocumentStart, Ctrl | Shift, Key.Home, OnMoveCaretExtendSelection(CaretMovementType.DocumentStart));
|
||||
|
@ -135,6 +145,31 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
};
|
||||
}
|
||||
|
||||
static ExecutedRoutedEventHandler OnMoveCaretBoxSelection(CaretMovementType direction)
|
||||
{
|
||||
return (target, args) => {
|
||||
TextArea textArea = GetTextArea(target);
|
||||
if (textArea != null && textArea.Document != null) {
|
||||
args.Handled = true;
|
||||
// First, convert the selection into a rectangle selection
|
||||
// (this is required so that virtual space gets enabled for the caret movement)
|
||||
if (textArea.Options.EnableRectangularSelection && !(textArea.Selection is RectangleSelection)) {
|
||||
if (textArea.Selection.IsEmpty) {
|
||||
textArea.Selection = new RectangleSelection(textArea, textArea.Caret.Position, textArea.Caret.Position);
|
||||
} else {
|
||||
// Convert normal selection to rectangle selection
|
||||
textArea.Selection = new RectangleSelection(textArea, textArea.Selection.StartPosition, textArea.Caret.Position);
|
||||
}
|
||||
}
|
||||
// Now move the caret and extend the selection
|
||||
TextViewPosition oldPosition = textArea.Caret.Position;
|
||||
MoveCaret(textArea, direction);
|
||||
textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position);
|
||||
textArea.Caret.BringCaretToView();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#region Caret movement
|
||||
static void MoveCaret(TextArea textArea, CaretMovementType direction)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using ICSharpCode.AvalonEdit.Utils;
|
||||
using ICSharpCode.NRefactory;
|
||||
using ICSharpCode.NRefactory.Editor;
|
||||
|
||||
namespace ICSharpCode.AvalonEdit.Editing
|
||||
|
@ -22,6 +23,14 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
return this;
|
||||
}
|
||||
|
||||
public override TextViewPosition StartPosition {
|
||||
get { return new TextViewPosition(TextLocation.Empty); }
|
||||
}
|
||||
|
||||
public override TextViewPosition EndPosition {
|
||||
get { return new TextViewPosition(TextLocation.Empty); }
|
||||
}
|
||||
|
||||
public override ISegment SurroundingSegment {
|
||||
get { return null; }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
|
||||
using ICSharpCode.AvalonEdit;
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using ICSharpCode.AvalonEdit.Rendering;
|
||||
using ICSharpCode.AvalonEdit.Utils;
|
||||
using Draw = System.Drawing;
|
||||
|
||||
namespace ICSharpCode.AvalonEdit.Editing
|
||||
{
|
||||
/// <summary>
|
||||
/// Native API required for IME support.
|
||||
/// </summary>
|
||||
static class ImeNativeWrapper
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct CompositionForm
|
||||
{
|
||||
public int dwStyle;
|
||||
public POINT ptCurrentPos;
|
||||
public RECT rcArea;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct POINT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct RECT
|
||||
{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
|
||||
class LOGFONT
|
||||
{
|
||||
public int lfHeight = 0;
|
||||
public int lfWidth = 0;
|
||||
public int lfEscapement = 0;
|
||||
public int lfOrientation = 0;
|
||||
public int lfWeight = 0;
|
||||
public byte lfItalic = 0;
|
||||
public byte lfUnderline = 0;
|
||||
public byte lfStrikeOut = 0;
|
||||
public byte lfCharSet = 0;
|
||||
public byte lfOutPrecision = 0;
|
||||
public byte lfClipPrecision = 0;
|
||||
public byte lfQuality = 0;
|
||||
public byte lfPitchAndFamily = 0;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string lfFaceName = null;
|
||||
}
|
||||
|
||||
const int CPS_CANCEL = 0x4;
|
||||
const int NI_COMPOSITIONSTR = 0x15;
|
||||
const int GCS_COMPSTR = 0x0008;
|
||||
|
||||
public const int WM_IME_COMPOSITION = 0x10F;
|
||||
public const int WM_INPUTLANGCHANGE = 0x51;
|
||||
|
||||
[DllImport("imm32.dll")]
|
||||
static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);
|
||||
[DllImport("imm32.dll")]
|
||||
static extern IntPtr ImmGetContext(IntPtr hWnd);
|
||||
[DllImport("imm32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool ImmNotifyIME(IntPtr hIMC, int dwAction, int dwIndex, int dwValue = 0);
|
||||
[DllImport("imm32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hIMC);
|
||||
[DllImport("imm32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool ImmSetCompositionWindow(IntPtr hIMC, ref CompositionForm form);
|
||||
[DllImport("imm32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool ImmSetCompositionFont(IntPtr hIMC, ref LOGFONT font);
|
||||
[DllImport("imm32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool ImmGetCompositionFont(IntPtr hIMC, out LOGFONT font);
|
||||
|
||||
public static IntPtr AssociateContext(HwndSource source, IntPtr hIMC)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException("source");
|
||||
return ImmAssociateContext(source.Handle, hIMC);
|
||||
}
|
||||
|
||||
public static bool NotifyIme(IntPtr hIMC)
|
||||
{
|
||||
return ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL);
|
||||
}
|
||||
|
||||
public static IntPtr GetContext(HwndSource source)
|
||||
{
|
||||
if (source == null)
|
||||
return IntPtr.Zero;
|
||||
return ImmGetContext(source.Handle);
|
||||
}
|
||||
|
||||
public static bool ReleaseContext(HwndSource source, IntPtr hIMC)
|
||||
{
|
||||
return source != null && hIMC != IntPtr.Zero && ImmReleaseContext(source.Handle, hIMC);
|
||||
}
|
||||
|
||||
public static bool SetCompositionWindow(HwndSource source, IntPtr hIMC, TextArea textArea)
|
||||
{
|
||||
if (textArea == null)
|
||||
throw new ArgumentNullException("textArea");
|
||||
Rect textViewBounds = textArea.TextView.GetBounds();
|
||||
Rect characterBounds = textArea.TextView.GetCharacterBounds(textArea.Caret.Position, source);
|
||||
if (source != null) {
|
||||
Matrix transformToDevice = source.CompositionTarget.TransformToDevice;
|
||||
textViewBounds.Transform(transformToDevice);
|
||||
characterBounds.Transform(transformToDevice);
|
||||
}
|
||||
CompositionForm form = new CompositionForm();
|
||||
form.dwStyle = 0x0020;
|
||||
form.ptCurrentPos.x = (int)Math.Max(characterBounds.Left, textViewBounds.Left);
|
||||
form.ptCurrentPos.y = (int)Math.Max(characterBounds.Top, textViewBounds.Top);
|
||||
form.rcArea.left = (int)textViewBounds.Left;
|
||||
form.rcArea.top = (int)textViewBounds.Top;
|
||||
form.rcArea.right = (int)textViewBounds.Right;
|
||||
form.rcArea.bottom = (int)textViewBounds.Bottom;
|
||||
return ImmSetCompositionWindow(hIMC, ref form);
|
||||
}
|
||||
|
||||
public static bool SetCompositionFont(HwndSource source, IntPtr hIMC, TextArea textArea)
|
||||
{
|
||||
if (textArea == null)
|
||||
throw new ArgumentNullException("textArea");
|
||||
// LOGFONT font = new LOGFONT();
|
||||
// ImmGetCompositionFont(hIMC, out font);
|
||||
return false;
|
||||
}
|
||||
|
||||
static Rect GetBounds(this TextView textView)
|
||||
{
|
||||
Point location = textView.TranslatePoint(new Point(0,0), textView);
|
||||
return new Rect(location, new Size(textView.ActualWidth, textView.ActualHeight));
|
||||
}
|
||||
|
||||
static readonly Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
|
||||
|
||||
static Rect GetCharacterBounds(this TextView textView, TextViewPosition pos, HwndSource source)
|
||||
{
|
||||
VisualLine vl = textView.GetVisualLine(pos.Line);
|
||||
if (vl == null) return EMPTY_RECT;
|
||||
TextLine line = vl.GetTextLine(pos.VisualColumn);
|
||||
double offset = vl.GetTextLineVisualYPosition(line, VisualYPosition.LineTop) - textView.ScrollOffset.Y;
|
||||
Rect r = line.GetTextBounds(pos.VisualColumn, 1).First().Rectangle;
|
||||
r.Offset(-textView.ScrollOffset.X, offset);
|
||||
// this may happen during layout changes in AvalonDock, so we just return an empty rectangle
|
||||
// in those cases. It should be refreshed immediately.
|
||||
if (!source.RootVisual.IsAncestorOf(textView)) return EMPTY_RECT;
|
||||
Point pointOnRootVisual = textView.TransformToAncestor(source.RootVisual).Transform(r.Location);
|
||||
Point pointOnHwnd = pointOnRootVisual.TransformToDevice(source.RootVisual);
|
||||
r.Location = pointOnHwnd;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
using ICSharpCode.AvalonEdit;
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using ICSharpCode.AvalonEdit.Rendering;
|
||||
|
||||
namespace ICSharpCode.AvalonEdit.Editing
|
||||
{
|
||||
class ImeSupport : IDisposable
|
||||
{
|
||||
TextArea textArea;
|
||||
IntPtr currentContext;
|
||||
IntPtr previousContext;
|
||||
HwndSource hwndSource;
|
||||
|
||||
public ImeSupport(TextArea textArea)
|
||||
{
|
||||
if (textArea == null)
|
||||
throw new ArgumentNullException("textArea");
|
||||
this.textArea = textArea;
|
||||
InputMethod.SetIsInputMethodSuspended(this.textArea, true);
|
||||
textArea.GotKeyboardFocus += TextAreaGotKeyboardFocus;
|
||||
textArea.LostKeyboardFocus += TextAreaLostKeyboardFocus;
|
||||
textArea.OptionChanged += TextAreaOptionChanged;
|
||||
currentContext = IntPtr.Zero;
|
||||
previousContext = IntPtr.Zero;
|
||||
}
|
||||
|
||||
void TextAreaOptionChanged(object sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == "EnableImeSupport" && textArea.IsKeyboardFocusWithin) {
|
||||
CreateContext();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (textArea != null) {
|
||||
textArea.GotKeyboardFocus -= TextAreaGotKeyboardFocus;
|
||||
textArea.LostKeyboardFocus -= TextAreaLostKeyboardFocus;
|
||||
textArea = null;
|
||||
}
|
||||
ClearContext();
|
||||
}
|
||||
|
||||
void ClearContext()
|
||||
{
|
||||
if (hwndSource != null) {
|
||||
hwndSource.RemoveHook(WndProc);
|
||||
ImeNativeWrapper.AssociateContext(hwndSource, previousContext);
|
||||
previousContext = IntPtr.Zero;
|
||||
ImeNativeWrapper.ReleaseContext(hwndSource, currentContext);
|
||||
hwndSource = null;
|
||||
currentContext = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
void TextAreaGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
if (this.textArea == null)
|
||||
return;
|
||||
if (e.OriginalSource != this.textArea)
|
||||
return;
|
||||
CreateContext();
|
||||
}
|
||||
|
||||
void CreateContext()
|
||||
{
|
||||
if (this.textArea == null)
|
||||
return;
|
||||
if (!textArea.Options.EnableImeSupport)
|
||||
return;
|
||||
hwndSource = (HwndSource)PresentationSource.FromVisual(this.textArea);
|
||||
if (hwndSource != null) {
|
||||
currentContext = ImeNativeWrapper.GetContext(hwndSource);
|
||||
previousContext = ImeNativeWrapper.AssociateContext(hwndSource, currentContext);
|
||||
// ImeNativeWrapper.SetCompositionFont(hwndSource, currentContext, textArea);
|
||||
hwndSource.AddHook(WndProc);
|
||||
}
|
||||
}
|
||||
|
||||
void TextAreaLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
|
||||
{
|
||||
if (e.OriginalSource != this.textArea)
|
||||
return;
|
||||
if (currentContext != IntPtr.Zero)
|
||||
ImeNativeWrapper.NotifyIme(currentContext);
|
||||
ClearContext();
|
||||
}
|
||||
|
||||
IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
switch (msg) {
|
||||
case ImeNativeWrapper.WM_INPUTLANGCHANGE:
|
||||
ClearContext();
|
||||
CreateContext();
|
||||
break;
|
||||
case ImeNativeWrapper.WM_IME_COMPOSITION:
|
||||
UpdateCompositionWindow();
|
||||
break;
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public void UpdateCompositionWindow()
|
||||
{
|
||||
if (currentContext != IntPtr.Zero && textArea != null) {
|
||||
ImeNativeWrapper.SetCompositionWindow(hwndSource, currentContext, textArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,8 +7,9 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.TextFormatting;
|
||||
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using ICSharpCode.AvalonEdit.Rendering;
|
||||
using ICSharpCode.AvalonEdit.Utils;
|
||||
|
@ -22,20 +23,70 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
/// </summary>
|
||||
public sealed class RectangleSelection : Selection
|
||||
{
|
||||
#region Commands
|
||||
/// <summary>
|
||||
/// Expands the selection left by one character, creating a rectangular selection.
|
||||
/// Key gesture: Alt+Shift+Left
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectLeftByCharacter = Command("BoxSelectLeftByCharacter");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection right by one character, creating a rectangular selection.
|
||||
/// Key gesture: Alt+Shift+Right
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectRightByCharacter = Command("BoxSelectRightByCharacter");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection left by one word, creating a rectangular selection.
|
||||
/// Key gesture: Ctrl+Alt+Shift+Left
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectLeftByWord = Command("BoxSelectLeftByWord");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection left by one word, creating a rectangular selection.
|
||||
/// Key gesture: Ctrl+Alt+Shift+Right
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectRightByWord = Command("BoxSelectRightByWord");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection up by one line, creating a rectangular selection.
|
||||
/// Key gesture: Alt+Shift+Up
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectUpByLine = Command("BoxSelectUpByLine");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection up by one line, creating a rectangular selection.
|
||||
/// Key gesture: Alt+Shift+Down
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectDownByLine = Command("BoxSelectDownByLine");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection to the start of the line, creating a rectangular selection.
|
||||
/// Key gesture: Alt+Shift+Home
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectToLineStart = Command("BoxSelectToLineStart");
|
||||
|
||||
/// <summary>
|
||||
/// Expands the selection to the end of the line, creating a rectangular selection.
|
||||
/// Key gesture: Alt+Shift+End
|
||||
/// </summary>
|
||||
public static readonly RoutedUICommand BoxSelectToLineEnd = Command("BoxSelectToLineEnd");
|
||||
|
||||
static RoutedUICommand Command(string name)
|
||||
{
|
||||
return new RoutedUICommand(name, name, typeof(RectangleSelection));
|
||||
}
|
||||
#endregion
|
||||
|
||||
TextDocument document;
|
||||
readonly int startLine, endLine;
|
||||
readonly double startXPos, endXPos;
|
||||
readonly int topLeftOffset, bottomRightOffset;
|
||||
readonly TextViewPosition start, end;
|
||||
|
||||
readonly List<SelectionSegment> segments = new List<SelectionSegment>();
|
||||
|
||||
void InitDocument()
|
||||
{
|
||||
document = textArea.Document;
|
||||
if (document == null)
|
||||
throw ThrowUtil.NoDocumentAssigned();
|
||||
}
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Creates a new rectangular selection.
|
||||
/// </summary>
|
||||
|
@ -50,6 +101,9 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
CalculateSegments();
|
||||
this.topLeftOffset = this.segments.First().StartOffset;
|
||||
this.bottomRightOffset = this.segments.Last().EndOffset;
|
||||
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
private RectangleSelection(TextArea textArea, int startLine, double startXPos, TextViewPosition end)
|
||||
|
@ -63,6 +117,9 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
CalculateSegments();
|
||||
this.topLeftOffset = this.segments.First().StartOffset;
|
||||
this.bottomRightOffset = this.segments.Last().EndOffset;
|
||||
|
||||
this.start = GetStart();
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
private RectangleSelection(TextArea textArea, TextViewPosition start, int endLine, double endXPos)
|
||||
|
@ -76,6 +133,16 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
CalculateSegments();
|
||||
this.topLeftOffset = this.segments.First().StartOffset;
|
||||
this.bottomRightOffset = this.segments.Last().EndOffset;
|
||||
|
||||
this.start = start;
|
||||
this.end = GetEnd();
|
||||
}
|
||||
|
||||
void InitDocument()
|
||||
{
|
||||
document = textArea.Document;
|
||||
if (document == null)
|
||||
throw ThrowUtil.NoDocumentAssigned();
|
||||
}
|
||||
|
||||
static double GetXPos(TextArea textArea, TextViewPosition pos)
|
||||
|
@ -87,12 +154,44 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
return visualLine.GetTextLineVisualXPosition(textLine, vc);
|
||||
}
|
||||
|
||||
int GetVisualColumnFromXPos(int line, double xPos)
|
||||
void CalculateSegments()
|
||||
{
|
||||
var vl = textArea.TextView.GetOrConstructVisualLine(textArea.Document.GetLineByNumber(line));
|
||||
return vl.GetVisualColumn(new Point(xPos, 0), true);
|
||||
DocumentLine nextLine = document.GetLineByNumber(Math.Min(startLine, endLine));
|
||||
do {
|
||||
VisualLine vl = textArea.TextView.GetOrConstructVisualLine(nextLine);
|
||||
int startVC = vl.GetVisualColumn(new Point(startXPos, 0), true);
|
||||
int endVC = vl.GetVisualColumn(new Point(endXPos, 0), true);
|
||||
|
||||
int baseOffset = vl.FirstDocumentLine.Offset;
|
||||
int startOffset = baseOffset + vl.GetRelativeOffset(startVC);
|
||||
int endOffset = baseOffset + vl.GetRelativeOffset(endVC);
|
||||
segments.Add(new SelectionSegment(startOffset, startVC, endOffset, endVC));
|
||||
|
||||
nextLine = vl.LastDocumentLine.NextLine;
|
||||
} while (nextLine != null && nextLine.LineNumber <= Math.Max(startLine, endLine));
|
||||
}
|
||||
|
||||
TextViewPosition GetStart()
|
||||
{
|
||||
SelectionSegment segment = (startLine < endLine ? segments.First() : segments.Last());
|
||||
if (startXPos < endXPos) {
|
||||
return new TextViewPosition(document.GetLocation(segment.StartOffset), segment.StartVisualColumn);
|
||||
} else {
|
||||
return new TextViewPosition(document.GetLocation(segment.EndOffset), segment.EndVisualColumn);
|
||||
}
|
||||
}
|
||||
|
||||
TextViewPosition GetEnd()
|
||||
{
|
||||
SelectionSegment segment = (startLine < endLine ? segments.Last() : segments.First());
|
||||
if (startXPos < endXPos) {
|
||||
return new TextViewPosition(document.GetLocation(segment.EndOffset), segment.EndVisualColumn);
|
||||
} else {
|
||||
return new TextViewPosition(document.GetLocation(segment.StartOffset), segment.StartVisualColumn);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string GetText()
|
||||
{
|
||||
|
@ -135,22 +234,14 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
get { return segments; }
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override TextViewPosition StartPosition {
|
||||
get { return start; }
|
||||
}
|
||||
|
||||
void CalculateSegments()
|
||||
{
|
||||
DocumentLine nextLine = document.GetLineByNumber(Math.Min(startLine, endLine));
|
||||
do {
|
||||
VisualLine vl = textArea.TextView.GetOrConstructVisualLine(nextLine);
|
||||
int startVC = vl.GetVisualColumn(new Point(startXPos, 0), true);
|
||||
int endVC = vl.GetVisualColumn(new Point(endXPos, 0), true);
|
||||
|
||||
int baseOffset = vl.FirstDocumentLine.Offset;
|
||||
int startOffset = baseOffset + vl.GetRelativeOffset(startVC);
|
||||
int endOffset = baseOffset + vl.GetRelativeOffset(endVC);
|
||||
segments.Add(new SelectionSegment(startOffset, startVC, endOffset, endVC));
|
||||
|
||||
nextLine = vl.LastDocumentLine.NextLine;
|
||||
} while (nextLine != null && nextLine.LineNumber <= Math.Max(startLine, endLine));
|
||||
/// <inheritdoc/>
|
||||
public override TextViewPosition EndPosition {
|
||||
get { return end; }
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -175,6 +266,12 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
return new RectangleSelection(textArea, startLine, startXPos, endPosition);
|
||||
}
|
||||
|
||||
int GetVisualColumnFromXPos(int line, double xPos)
|
||||
{
|
||||
var vl = textArea.TextView.GetOrConstructVisualLine(textArea.Document.GetLineByNumber(line));
|
||||
return vl.GetVisualColumn(new Point(xPos, 0), true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Selection UpdateOnDocumentChange(DocumentChangeEventArgs e)
|
||||
{
|
||||
|
|
|
@ -65,6 +65,16 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
this.textArea = textArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the start position of the selection.
|
||||
/// </summary>
|
||||
public abstract TextViewPosition StartPosition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the end position of the selection.
|
||||
/// </summary>
|
||||
public abstract TextViewPosition EndPosition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the selected text segments.
|
||||
/// </summary>
|
||||
|
|
|
@ -70,18 +70,12 @@ namespace ICSharpCode.AvalonEdit.Editing
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the start offset.
|
||||
/// </summary>
|
||||
public int StartOffset {
|
||||
get { return startOffset; }
|
||||
public override TextViewPosition StartPosition {
|
||||
get { return start; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the end offset.
|
||||
/// </summary>
|
||||
public int EndOffset {
|
||||
get { return endOffset; }
|
||||
public override TextViewPosition EndPosition {
|
||||
get { return end; }
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
|
@ -312,11 +312,14 @@ namespace ICSharpCode.AvalonEdit.Highlighting
|
|||
Debug.Assert(position == firstMatch.Index);
|
||||
|
||||
if (firstMatch == endSpanMatch) {
|
||||
PopColor(); // pop SpanColor
|
||||
HighlightingSpan poppedSpan = spanStack.Peek();
|
||||
if (!poppedSpan.SpanColorIncludesEnd)
|
||||
PopColor(); // pop SpanColor
|
||||
PushColor(poppedSpan.EndColor);
|
||||
position = firstMatch.Index + firstMatch.Length;
|
||||
PopColor(); // pop EndColor
|
||||
if (poppedSpan.SpanColorIncludesEnd)
|
||||
PopColor(); // pop SpanColor
|
||||
spanStack = spanStack.Pop();
|
||||
currentRuleSet = this.CurrentRuleSet;
|
||||
//FreeMatchArray(matches);
|
||||
|
@ -342,10 +345,13 @@ namespace ICSharpCode.AvalonEdit.Highlighting
|
|||
currentRuleSet = this.CurrentRuleSet;
|
||||
storedMatchArrays.Push(matches);
|
||||
matches = AllocateMatchArray(currentRuleSet.Spans.Count);
|
||||
if (newSpan.SpanColorIncludesStart)
|
||||
PushColor(newSpan.SpanColor);
|
||||
PushColor(newSpan.StartColor);
|
||||
position = firstMatch.Index + firstMatch.Length;
|
||||
PopColor();
|
||||
PushColor(newSpan.SpanColor);
|
||||
if (!newSpan.SpanColorIncludesStart)
|
||||
PushColor(newSpan.SpanColor);
|
||||
}
|
||||
endSpanMatch = null;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,18 @@ namespace ICSharpCode.AvalonEdit.Highlighting
|
|||
/// </summary>
|
||||
public HighlightingColor EndColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets whether the span color includes the start.
|
||||
/// The default is <c>false</c>.
|
||||
/// </summary>
|
||||
public bool SpanColorIncludesStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets whether the span color includes the end.
|
||||
/// The default is <c>false</c>.
|
||||
/// </summary>
|
||||
public bool SpanColorIncludesEnd { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
<?xml version="1.0"?>
|
||||
<SyntaxDefinition name="PowerShell" extensions=".ps1;.psm1;.psd1" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
|
||||
<Color name="Comment" foreground="Green" exampleText="// comment" />
|
||||
<Color name="String" foreground="Blue" exampleText="string text = "Hello, World!""/>
|
||||
<Color name="Char" foreground="Magenta" exampleText="char linefeed = '\n';"/>
|
||||
<Color name="Punctuation" exampleText="a(b.c);" />
|
||||
<Color name="NumberLiteral" foreground="DarkBlue" exampleText="3.1415f"/>
|
||||
<Color name="Keywords" fontWeight="bold" foreground="Blue" exampleText="if (a)"/>
|
||||
<Color name="Variable" foreground="Maroon" exampleText="$param = 1" />
|
||||
<Color name="ExceptionKeywords" fontWeight="bold" foreground="Teal" />
|
||||
<Color name="GotoKeywords" foreground="Navy" />
|
||||
<Color name="ReferenceTypes" foreground="Red" />
|
||||
<Color name="Command" fontWeight="bold" foreground="MidnightBlue" />
|
||||
<Color name="Operators" foreground="#FF8515EA" exampleText="-eq"/>
|
||||
|
||||
<RuleSet ignoreCase="true">
|
||||
<Span color="Comment">
|
||||
<Begin>\#</Begin>
|
||||
</Span>
|
||||
|
||||
<Span color="Comment" multiline="true">
|
||||
<Begin><\#</Begin>
|
||||
<End>\#></End>
|
||||
</Span>
|
||||
|
||||
<Span color="String">
|
||||
<Begin>"</Begin>
|
||||
<End>"</End>
|
||||
<RuleSet>
|
||||
<!-- span for escape sequences -->
|
||||
<Span begin="\\" end="."/>
|
||||
</RuleSet>
|
||||
</Span>
|
||||
|
||||
<Span color="Char">
|
||||
<Begin>'</Begin>
|
||||
<End>'</End>
|
||||
<RuleSet>
|
||||
<!-- span for escape sequences -->
|
||||
<Span begin="\\" end="."/>
|
||||
</RuleSet>
|
||||
</Span>
|
||||
|
||||
<Span color="String" multiline="true">
|
||||
<Begin color="String">@"</Begin>
|
||||
<End>"@</End>
|
||||
<RuleSet>
|
||||
<!-- span for escape sequences -->
|
||||
<Span begin='""' end=""/>
|
||||
</RuleSet>
|
||||
</Span>
|
||||
|
||||
<Keywords color="Keywords">
|
||||
<Word>while</Word>
|
||||
<Word>param</Word>
|
||||
<Word>end</Word>
|
||||
<Word>define</Word>
|
||||
<Word>else</Word>
|
||||
<Word>from</Word>
|
||||
<Word>foreach</Word>
|
||||
<Word>var</Word>
|
||||
<Word>dynamicparam</Word>
|
||||
<Word>filter</Word>
|
||||
<Word>dp</Word>
|
||||
<Word>until</Word>
|
||||
<Word>for</Word>
|
||||
<Word>exit</Word>
|
||||
<Word>switch</Word>
|
||||
<Word>process</Word>
|
||||
<Word>begin</Word>
|
||||
<Word>elseif</Word>
|
||||
<Word>if</Word>
|
||||
<Word>in</Word>
|
||||
<Word>data</Word>
|
||||
<Word>class</Word>
|
||||
<Word>using</Word>
|
||||
<Word>function</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="ExceptionKeywords">
|
||||
<Word>catch</Word>
|
||||
<Word>finally</Word>
|
||||
<Word>throw</Word>
|
||||
<Word>trap</Word>
|
||||
<Word>try</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="GotoKeywords">
|
||||
<Word>break</Word>
|
||||
<Word>continue</Word>
|
||||
<Word>return</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="ReferenceTypes">
|
||||
<Word>class</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="Operators">
|
||||
<Word>-not</Word>
|
||||
<Word>-band</Word>
|
||||
<Word>-bor</Word>
|
||||
<Word>-replace</Word>
|
||||
<Word>-ireplace</Word>
|
||||
<Word>-creplace</Word>
|
||||
<Word>-and</Word>
|
||||
<Word>-or</Word>
|
||||
<Word>-is</Word>
|
||||
<Word>-isnot</Word>
|
||||
<Word>-as</Word>
|
||||
<Word>-lt</Word>
|
||||
<Word>-le</Word>
|
||||
<Word>-gt</Word>
|
||||
<Word>-ge</Word>
|
||||
<Word>-eq</Word>
|
||||
<Word>-ne</Word>
|
||||
<Word>-contains</Word>
|
||||
<Word>-notcontains</Word>
|
||||
<Word>-like</Word>
|
||||
<Word>-notlike</Word>
|
||||
<Word>-match</Word>
|
||||
<Word>-notmatch</Word>
|
||||
</Keywords>
|
||||
|
||||
<Rule color="Variable">
|
||||
\$[\d\w_]+
|
||||
</Rule>
|
||||
|
||||
<Rule color="Command">
|
||||
[\w]+-[\w]+
|
||||
</Rule>
|
||||
|
||||
<!-- Digits -->
|
||||
<Rule color="NumberLiteral">
|
||||
\b0[xX][0-9a-fA-F]+ # hex number
|
||||
|
|
||||
( \b\d+(\.[0-9]+)? #number with optional floating point
|
||||
| \.[0-9]+ #or just starting with floating point
|
||||
)
|
||||
([eE][+-]?[0-9]+)? # optional exponent
|
||||
</Rule>
|
||||
|
||||
<Rule color="Punctuation">
|
||||
[?,.;()\[\]{}+\-/%*<>^+~!|&]+
|
||||
</Rule>
|
||||
</RuleSet>
|
||||
</SyntaxDefinition>
|
|
@ -33,13 +33,14 @@ namespace ICSharpCode.AvalonEdit.Highlighting
|
|||
hlm.RegisterHighlighting("C++", new[] { ".c", ".h", ".cc", ".cpp" , ".hpp" }, "CPP-Mode.xshd");
|
||||
hlm.RegisterHighlighting("Java", new[] { ".java" }, "Java-Mode.xshd");
|
||||
hlm.RegisterHighlighting("Patch", new[] { ".patch", ".diff" }, "Patch-Mode.xshd");
|
||||
hlm.RegisterHighlighting("PowerShell", new[] { ".ps1", ".psm1", ".psd1" }, "PowerShell.xshd");
|
||||
hlm.RegisterHighlighting("PHP", new[] { ".php" }, "PHP-Mode.xshd");
|
||||
hlm.RegisterHighlighting("TeX", new[] { ".tex" }, "Tex-Mode.xshd");
|
||||
hlm.RegisterHighlighting("VBNET", new[] { ".vb" }, "VBNET-Mode.xshd");
|
||||
hlm.RegisterHighlighting("XML", (".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").Split(';'),
|
||||
".xft;.map;.wsdl;.disco;.ps1xml;.nuspec").Split(';'),
|
||||
"XML-Mode.xshd");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<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" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
|
||||
<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;.ps1xml;.nuspec" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
|
||||
<Color foreground="Green" name="Comment" exampleText="<!-- comment -->" />
|
||||
<Color foreground="Blue" name="CData" exampleText="<![CDATA[data]]>" />
|
||||
<Color foreground="Blue" name="DocType" exampleText="<!DOCTYPE rootElement>" />
|
||||
|
|
|
@ -317,22 +317,11 @@ namespace ICSharpCode.AvalonEdit.Highlighting.Xshd
|
|||
StartExpression = CreateRegex(span, span.BeginRegex, span.BeginRegexType),
|
||||
EndExpression = CreateRegex(span, endRegex, span.EndRegexType),
|
||||
RuleSet = GetRuleSet(span, span.RuleSetReference),
|
||||
StartColor = MergeColor(wholeSpanColor, GetColor(span, span.BeginColorReference)),
|
||||
StartColor = GetColor(span, span.BeginColorReference),
|
||||
SpanColor = wholeSpanColor,
|
||||
EndColor = MergeColor(wholeSpanColor, GetColor(span, span.EndColorReference)),
|
||||
};
|
||||
}
|
||||
|
||||
static HighlightingColor MergeColor(HighlightingColor baseColor, HighlightingColor newColor)
|
||||
{
|
||||
if (baseColor == null)
|
||||
return newColor;
|
||||
if (newColor == null)
|
||||
return baseColor;
|
||||
return new HighlightingColor {
|
||||
Foreground = newColor.Foreground ?? baseColor.Foreground,
|
||||
FontWeight = newColor.FontWeight ?? baseColor.FontWeight,
|
||||
FontStyle = newColor.FontStyle ?? baseColor.FontStyle,
|
||||
EndColor = GetColor(span, span.EndColorReference),
|
||||
SpanColorIncludesStart = true,
|
||||
SpanColorIncludesEnd = true
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,9 @@
|
|||
<Compile Include="Editing\EmptySelection.cs">
|
||||
<DependentUpon>Selection.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Editing\ImeNativeWrapper.cs" />
|
||||
<Compile Include="Editing\SelectionSegment.cs" />
|
||||
<Compile Include="Editing\ImeSupport.cs" />
|
||||
<Compile Include="Folding\AbstractFoldingStrategy.cs" />
|
||||
<Compile Include="Folding\FoldingElementGenerator.cs" />
|
||||
<Compile Include="Folding\FoldingManager.cs" />
|
||||
|
@ -440,4 +442,7 @@
|
|||
<Resource Include="CodeCompletion\Images\Struct.png" />
|
||||
<Resource Include="CodeCompletion\Images\VirtualMethod.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Highlighting\Resources\PowerShell.xshd" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -381,5 +381,22 @@ namespace ICSharpCode.AvalonEdit
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool enableImeSupport = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets whether the support for Input Method Editors (IME)
|
||||
/// for non-alphanumeric scripts (Chinese, Japanese, Korean, ...) is enabled.
|
||||
/// </summary>
|
||||
[DefaultValue(true)]
|
||||
public virtual bool EnableImeSupport {
|
||||
get { return enableImeSupport; }
|
||||
set {
|
||||
if (enableImeSupport != value) {
|
||||
enableImeSupport = value;
|
||||
OnPropertyChanged("EnableImeSupport");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче