Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vs-editor-api.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKirill Osenkov <github@osenkov.com>2017-12-13 08:56:41 +0300
committerKirill Osenkov <github@osenkov.com>2017-12-13 08:56:41 +0300
commit662e5076a5ca1820e1c671d62665743eae594702 (patch)
tree2769058e8e054176e8fb0abba979b92049284bf7 /src
parentd622288d6145af5bd99847a8b4a2a70dd52c1554 (diff)
Updating to Editor 15.6.241-preview.
Diffstat (limited to 'src')
-rw-r--r--src/Core/Def/BaseUtility/TypeConversionAttribute.cs35
-rw-r--r--src/Core/Def/ImageId.cs35
-rw-r--r--src/Microsoft.VisualStudio.Text.Implementation.csproj8
-rw-r--r--src/Microsoft.VisualStudio.Text.Implementation.nuspec29
-rw-r--r--src/Text/Def/TextLogic/TextLogic.csproj3
-rw-r--r--src/Text/Def/TextUI/Adornments/IToolTipProvider.cs4
-rw-r--r--src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs2
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenter.cs45
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenterFactory.cs33
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipService.cs29
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactory.cs38
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactoryService.cs37
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/ToolTipParameters.cs63
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextElement.cs41
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextRun.cs45
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElement.cs49
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElementStyle.cs18
-rw-r--r--src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ImageElement.cs29
-rw-r--r--src/Text/Def/TextUI/Operations/IEditorOperations.cs1
-rw-r--r--src/Text/Def/TextUI/Operations/IEditorOperations3.cs11
-rw-r--r--src/Text/Def/TextUI/TextUI.csproj15
-rw-r--r--src/Text/Impl/EditorOperations/EditorOperations.cs77
-rw-r--r--src/Text/Impl/EditorOperations/Strings.Designer.cs9
-rw-r--r--src/Text/Impl/EditorOperations/Strings.resx5
-rw-r--r--src/Text/Impl/TextModel/Storage/Page.cs3
-rw-r--r--src/Text/Impl/TextModel/Storage/PageManager.cs49
26 files changed, 665 insertions, 48 deletions
diff --git a/src/Core/Def/BaseUtility/TypeConversionAttribute.cs b/src/Core/Def/BaseUtility/TypeConversionAttribute.cs
new file mode 100644
index 0000000..6d1923f
--- /dev/null
+++ b/src/Core/Def/BaseUtility/TypeConversionAttribute.cs
@@ -0,0 +1,35 @@
+namespace Microsoft.VisualStudio.Utilities
+{
+ using System;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// Marks a class exported with a MEF <see cref="ExportAttribute"/> as a conversion from one type to another.
+ /// </summary>
+ public sealed class TypeConversionAttribute : SingletonBaseMetadataAttribute
+ {
+ private readonly Type from;
+ private readonly Type to;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="TypeConversionAttribute"/>.
+ /// </summary>
+ /// <param name="fromFullName">The <see cref="Type"/> being converted from.</param>
+ /// <param name="toFullName">The <see cref="Type"/> being converted to.</param>
+ public TypeConversionAttribute(Type from, Type to)
+ {
+ this.from = from ?? throw new ArgumentNullException(nameof(from));
+ this.to = to ?? throw new ArgumentNullException(nameof(to));
+ }
+
+ /// <summary>
+ /// The name of the being converted from.
+ /// </summary>
+ public string FromFullName => this.from.AssemblyQualifiedName;
+
+ /// <summary>
+ /// The name of the exact type being converted to.
+ /// </summary>
+ public string ToFullName => this.to.AssemblyQualifiedName;
+ }
+}
diff --git a/src/Core/Def/ImageId.cs b/src/Core/Def/ImageId.cs
new file mode 100644
index 0000000..d540c16
--- /dev/null
+++ b/src/Core/Def/ImageId.cs
@@ -0,0 +1,35 @@
+namespace Microsoft.VisualStudio.Core.Imaging
+{
+ using System;
+
+ /// <summary>
+ /// Unique identifier for Visual Studio image asset.
+ /// </summary>
+ /// <remarks>
+ /// On Windows systems, <see cref="ImageId"/> can be converted to and from
+ /// various other image representations via the ImageIdExtensions extension methods.
+ /// </remarks>
+ public struct ImageId
+ {
+ /// <summary>
+ /// The <see cref="Guid"/> identifying the group to which this image belongs.
+ /// </summary>
+ public readonly Guid Guid;
+
+ /// <summary>
+ /// The <see cref="int"/> identifying the particular image from the group that this id maps to.
+ /// </summary>
+ public readonly int Id;
+
+ /// <summary>
+ /// Creates a new instance of ImageId.
+ /// </summary>
+ /// <param name="guid">The <see cref="Guid"/> identifying the group to which this image belongs.</param>
+ /// <param name="id">The <see cref="int"/> identifying the particular image from the group that this id maps to.</param>
+ public ImageId(Guid guid, int id)
+ {
+ this.Guid = guid;
+ this.Id = id;
+ }
+ }
+}
diff --git a/src/Microsoft.VisualStudio.Text.Implementation.csproj b/src/Microsoft.VisualStudio.Text.Implementation.csproj
index 36b258b..728f071 100644
--- a/src/Microsoft.VisualStudio.Text.Implementation.csproj
+++ b/src/Microsoft.VisualStudio.Text.Implementation.csproj
@@ -5,16 +5,16 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
<DelaySign>false</DelaySign>
- <Version>15.0.6-pre</Version>
+ <Version>15.0.7-pre</Version>
<AssemblyVersion>15.0.0.0</AssemblyVersion>
- <NuGetVersionEditor>15.6.162-preview</NuGetVersionEditor>
+ <NuGetVersionEditor>15.6.241-preview</NuGetVersionEditor>
</PropertyGroup>
<PropertyGroup>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageId>Microsoft.VisualStudio.Text.Implementation</PackageId>
- <Authors>vsideeng@microsoft.com</Authors>
- <Owners>vsideeng@microsoft.com</Owners>
+ <Authors>Microsoft</Authors>
+ <Owners>Microsoft</Owners>
<Company>Microsoft</Company>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<LicenseUrl>https://aka.ms/pexunj</LicenseUrl>
diff --git a/src/Microsoft.VisualStudio.Text.Implementation.nuspec b/src/Microsoft.VisualStudio.Text.Implementation.nuspec
new file mode 100644
index 0000000..6299099
--- /dev/null
+++ b/src/Microsoft.VisualStudio.Text.Implementation.nuspec
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
+ <metadata>
+ <id>Microsoft.VisualStudio.Text.Implementation</id>
+ <version>15.0.7-pre</version>
+ <authors>Microsoft</authors>
+ <owners>Microsoft</owners>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <licenseUrl>https://github.com/Microsoft/vs-editor-api/blob/367d01a0b186f034178c5d5338c436e203eff8b4/LICENSE</licenseUrl>
+ <projectUrl>https://github.com/Microsoft/vs-editor-api</projectUrl>
+ <description>Microsoft® Visual Studio® Editor Platform</description>
+ <copyright>© Microsoft Corporation. All rights reserved.</copyright>
+ <repository url="https://github.com/Microsoft/vs-editor-api" />
+ <dependencies>
+ <group targetFramework=".NETFramework4.6">
+ <dependency id="Microsoft.VisualStudio.Text.Data" version="15.6.241-preview" exclude="Build,Analyzers" />
+ <dependency id="Microsoft.VisualStudio.Text.Logic" version="15.6.241-preview" exclude="Build,Analyzers" />
+ <dependency id="Microsoft.VisualStudio.Language.StandardClassification" version="15.6.241-preview" exclude="Build,Analyzers" />
+ <dependency id="Microsoft.VisualStudio.CoreUtility" version="15.6.241-preview" exclude="Build,Analyzers" />
+ <dependency id="Microsoft.VisualStudio.Text.UI" version="15.6.241-preview" exclude="Build,Analyzers" />
+ <dependency id="System.Collections.Immutable" version="1.3.1" exclude="Build,Analyzers" />
+ </group>
+ </dependencies>
+ </metadata>
+ <files>
+ <file src="bin\Release\Microsoft.VisualStudio.Text.Implementation\Microsoft.VisualStudio.Text.Implementation.dll" target="lib\net46" />
+ <file src="bin\Release\Microsoft.VisualStudio.Text.Implementation\Microsoft.VisualStudio.Text.Implementation.pdb" target="lib\net46" />
+ </files>
+</package> \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/TextLogic.csproj b/src/Text/Def/TextLogic/TextLogic.csproj
index 638e3f5..522d638 100644
--- a/src/Text/Def/TextLogic/TextLogic.csproj
+++ b/src/Text/Def/TextLogic/TextLogic.csproj
@@ -15,6 +15,9 @@
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
+ <PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
+ </ItemGroup>
+ <ItemGroup>
<ProjectReference Include="..\TextData\TextData.csproj" />
<ProjectReference Include="..\..\..\Core\Def\CoreUtility.csproj" />
</ItemGroup>
diff --git a/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs b/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs
index c215ef7..f141e61 100644
--- a/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs
+++ b/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs
@@ -4,11 +4,13 @@
//
namespace Microsoft.VisualStudio.Text.Adornments
{
+ using System;
using Microsoft.VisualStudio.Text;
/// <summary>
/// Creates and displays tooltips, using an arbitrary object as content.
/// </summary>
+ [Obsolete("Use " + nameof(IToolTipService) + " instead")]
public interface IToolTipProvider
{
/// <summary>
@@ -42,4 +44,4 @@ namespace Microsoft.VisualStudio.Text.Adornments
/// </summary>
void ClearToolTip();
}
-} \ No newline at end of file
+}
diff --git a/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs b/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs
index d257230..f9a8bbc 100644
--- a/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs
+++ b/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs
@@ -4,6 +4,7 @@
//
namespace Microsoft.VisualStudio.Text.Adornments
{
+ using System;
using Microsoft.VisualStudio.Text.Editor;
/// <summary>
@@ -13,6 +14,7 @@ namespace Microsoft.VisualStudio.Text.Adornments
/// <remarks>This is a MEF component part, and should be exported with the following attribute:
/// [Export(typeof(IToolTipProviderFactory))]
/// </remarks>
+ [Obsolete("Use " + nameof(IToolTipService) + " instead")]
public interface IToolTipProviderFactory
{
/// <summary>
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenter.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenter.cs
new file mode 100644
index 0000000..57f5fc7
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenter.cs
@@ -0,0 +1,45 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// A platform-specific ToolTip implementation.
+ /// </summary>
+ /// <remarks>
+ /// This type is proffered to the IDE via an <see cref="IToolTipPresenterFactory"/> and is
+ /// always constructed and called purely on the UI thread. Each <see cref="IToolTipPresenter"/>
+ /// is a single-use object that is responsible for converting the given content to
+ /// into platform-specific UI elements and displaying them in a popup UI.
+ /// </remarks>
+ public interface IToolTipPresenter
+ {
+ /// <summary>
+ /// Invoked upon dismissal of the ToolTip's popup view.
+ /// </summary>
+ /// <remarks>
+ /// This event should be fired regardless of the reason for the popup's dismissal.
+ /// </remarks>
+ event EventHandler Dismissed;
+
+ /// <summary>
+ /// Constructs a popup containing a platform-specific UI representation of <paramref name="content"/>.
+ /// </summary>
+ /// <remarks>
+ /// This method can be called multiple times to refresh the content and applicableToSpan.
+ /// </remarks>
+ /// <param name="applicableToSpan">The span of text for which the tooltip is kept open.</param>
+ /// <param name="content">
+ /// A platform independent representation of the tooltip content. <see cref="IToolTipPresenter"/>s
+ /// should use the <see cref="IViewElementFactoryService"/> to convert <paramref name="content"/>
+ /// to platform specific UI elements.
+ /// </param>
+ void StartOrUpdate(ITrackingSpan applicableToSpan, IEnumerable<object> content);
+
+ /// <summary>
+ /// Dismisses the popup and causes <see cref="Dismissed"/> to be fired.
+ /// </summary>
+ void Dismiss();
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenterFactory.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenterFactory.cs
new file mode 100644
index 0000000..cbeb4bf
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipPresenterFactory.cs
@@ -0,0 +1,33 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Proffers a platform-specific <see cref="IToolTipPresenter"/> to the IDE.
+ /// </summary>
+ /// <remarks>
+ /// This class will always be constructed and called purely from the UI thread.
+ /// Extenders can construct their own presenter and supersede the default
+ /// one via MEF ordering. Presenter providers should return a new ToolTip each
+ /// time they are called and should support multiple simultaneous open tips.
+ /// </remarks>
+ /// <example>
+ /// [Export(typeof(IToolTipPresenterFactory))]
+ /// [Name(nameof("super cool tooltip factory"))]
+ /// [Order(Before = "default")]
+ /// </example>
+ public interface IToolTipPresenterFactory
+ {
+ /// <summary>
+ /// Constructs a new instance of <see cref="IToolTipPresenter"/> for the current platform.
+ /// </summary>
+ /// <param name="textView">
+ /// The view that owns the tooltip.
+ /// </param>
+ /// <param name="parameters">
+ /// Parameters to create the tooltip with. Never null.
+ /// </param>
+ /// <returns>A <see cref="IToolTipPresenter"/> for the current platform.</returns>
+ IToolTipPresenter Create(ITextView textView, ToolTipParameters parameters);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipService.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipService.cs
new file mode 100644
index 0000000..983ba1a
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/IToolTipService.cs
@@ -0,0 +1,29 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Cross platform service for the creation and management of ToolTips.
+ /// </summary>
+ /// <remarks>
+ /// This class is a MEF component part and it can be imported via the code in the example.
+ /// </remarks>
+ /// <example>
+ /// [Import]
+ /// internal IToolTipService tooltipService;
+ /// </example>
+ public interface IToolTipService
+ {
+ /// <summary>
+ /// Creates a new non-visible ToolTip presenter.
+ /// </summary>
+ /// <param name="textView">
+ /// The view that owns the tooltip.
+ /// </param>
+ /// <param name="parameters">
+ /// Parameters to create the tooltip with. Default is mouse tracking.
+ /// </param>
+ /// <returns>A new non-visible <see cref="IToolTipPresenter"/>.</returns>
+ IToolTipPresenter CreatePresenter(ITextView textView, ToolTipParameters parameters = null);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactory.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactory.cs
new file mode 100644
index 0000000..eaf2893
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactory.cs
@@ -0,0 +1,38 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+ using Microsoft.VisualStudio.Text.Editor;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Converts from an object to its equivalent platform specific UI element.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This type allows the same intermediate type to be rendered on different platforms through
+ /// the use of platform specific exports that live in that platform's UI layer.
+ /// </para>
+ /// <para>
+ /// You can supersede an existing <see cref="IViewElementFactory"/> for a (to, from) type
+ /// pair via MEF <see cref="OrderAttribute"/>s.
+ /// </para>
+ /// </remarks>
+ /// <example>
+ /// [Export(typeof(IViewElementFactory))]
+ /// [Name("object item")]
+ /// [Conversion(from: typeof(object), to: typeof(UIElement))]
+ /// [Order(After = "Foo", Before = "Bar")]
+ /// </example>
+ public interface IViewElementFactory
+ {
+ /// <summary>
+ /// Converts <paramref name="model"/> into an equivalent object of type <typeparamref name="TView"/>.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown if the conversion is unknown or unsupported.</exception>
+ /// <typeparam name="TView">The base type of the view element on the specific platform.</typeparam>
+ /// <param name="textView">The view that owns the control that will host this view element.</param>
+ /// <param name="model">The object to convert to a view element.</param>
+ /// <returns>A new object of type <typeparamref name="TView"/>.</returns>
+ TView CreateViewElement<TView>(ITextView textView, object model) where TView : class;
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactoryService.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactoryService.cs
new file mode 100644
index 0000000..c5d324a
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/IViewElementFactoryService.cs
@@ -0,0 +1,37 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System.ComponentModel.Composition;
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// A service for converting from data objects to their platform specific UI representation.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This is a MEF service that can be obtained via the <see cref="ImportAttribute"/> in a MEF exported class.
+ /// </para>
+ /// <para>
+ /// The editor supports <see cref="ClassifiedTextElement"/>s, <see cref="ImageElement"/>s, and <see cref="object"/>
+ /// on all platforms. Text and image elements are converted to colorized text and images respectively and
+ /// other objects are displayed as the <see cref="string"/> returned by <see cref="object.ToString()"/>
+ /// unless an extender exports a <see cref="IViewElementFactory"/> for that type.
+ /// </para>
+ /// On Windows only, <see cref="ITextBuffer"/>, <see cref="ITextView"/>, and UIElement are also directly
+ /// supported.
+ /// </remarks>
+ /// <example>
+ /// [Import]
+ /// internal IViewElementFactoryService viewElementFactoryService;
+ /// </example>
+ public interface IViewElementFactoryService
+ {
+ /// <summary>
+ /// Converts <paramref name="model"/> into an equivalent object of type <typeparamref name="TView"/>.
+ /// </summary>
+ /// <typeparam name="TView">The base type of the view element on the specific platform.</typeparam>
+ /// <param name="textView">The textView that owns the control that will host this view element.</param>
+ /// <param name="model">The object to convert to a view element.</param>
+ /// <returns>A new object of type <typeparamref name="TView"/> or null if the conversion is unknown.</returns>
+ TView CreateViewElement<TView>(ITextView textView, object model) where TView : class;
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/ToolTipParameters.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/ToolTipParameters.cs
new file mode 100644
index 0000000..2f7a31e
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/ToolTipParameters.cs
@@ -0,0 +1,63 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+
+ /// <summary>
+ /// Determines behavior for a <see cref="IToolTipPresenter"/>.
+ /// </summary>
+ public sealed class ToolTipParameters
+ {
+ private readonly Func<bool> keepOpenFunc;
+
+ /// <summary>
+ /// Default options for a mouse tracking tooltip.
+ /// </summary>
+ public static readonly ToolTipParameters Default = new ToolTipParameters();
+
+ /// <summary>
+ /// Creates a new instance of <see cref="ToolTipParameters"/>.
+ /// </summary>
+ /// <param name="trackMouse">
+ /// If true, dismisses the tooltip when the mouse leaves the applicable span.
+ /// </param>
+ /// <param name="ignoreBufferChange">
+ /// If true, and if the tooltip is mouse tracking, does not dismiss when the buffer changes.
+ /// </param>
+ /// <param name="keepOpenFunc">
+ /// A callback function that determines wehther or not to keep open the tooltip
+ /// in mouse tracking sessions, despite the mouse being outside the tooltip.
+ /// </param>
+ public ToolTipParameters(
+ bool trackMouse = true,
+ bool ignoreBufferChange = false,
+ Func<bool> keepOpenFunc = null)
+ {
+ this.TrackMouse = trackMouse;
+ this.IgnoreBufferChange = ignoreBufferChange;
+
+ if (!trackMouse && ignoreBufferChange)
+ {
+ throw new ArgumentException($"{nameof(ignoreBufferChange)} can only be true if {nameof(trackMouse)} is false");
+ }
+
+ this.keepOpenFunc = keepOpenFunc;
+ }
+
+ /// <summary>
+ /// Gets whether or not the tooltip can be dismissed by the mouse leaving the
+ /// applicable span.
+ /// </summary>
+ public bool TrackMouse { get; }
+
+ /// <summary>
+ /// Gets whether or not the tooltip is closed when the buffer changes.
+ /// </summary>
+ public bool IgnoreBufferChange { get; }
+
+ /// <summary>
+ /// Gets whether or not the tooltip should stay open even if the
+ /// mouse is outside of the tip.
+ /// </summary>
+ public bool KeepOpen => this.keepOpenFunc?.Invoke() ?? false;
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextElement.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextElement.cs
new file mode 100644
index 0000000..f003e81
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextElement.cs
@@ -0,0 +1,41 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Immutable;
+
+ /// <summary>
+ /// Represents a block of classified text in an <see cref="IToolTipService"/> <see cref="IToolTipPresenter"/>.
+ /// </summary>
+ /// <remarks>
+ /// Classified text is a span of text with a corresponding classification type name. On
+ /// <see cref="IToolTipPresenter.StartOrUpdate(ITrackingSpan, System.Collections.Generic.IEnumerable{object})"/>,
+ /// the classified text is converted to a platform-specific block of runs of formatted (colorized) text via
+ /// the <see cref="IViewElementFactoryService"/> and is displayed.
+ /// </remarks>
+ public sealed class ClassifiedTextElement
+ {
+ /// <summary>
+ /// Creates a new instance of classified text.
+ /// </summary>
+ /// <param name="runs">A sequence of zero or more runs of classified text.</param>
+ public ClassifiedTextElement(params ClassifiedTextRun[] runs)
+ {
+ this.Runs = runs?.ToImmutableList() ?? throw new ArgumentNullException(nameof(runs));
+ }
+
+ /// <summary>
+ /// Creates a new instance of classified text.
+ /// </summary>
+ /// <param name="runs">A sequence of zero or more runs of classified text.</param>
+ public ClassifiedTextElement(IEnumerable<ClassifiedTextRun> runs)
+ {
+ this.Runs = runs?.ToImmutableList() ?? throw new ArgumentNullException(nameof(runs));
+ }
+
+ /// <summary>
+ /// A sequence of classified runs of text.
+ /// </summary>
+ public IEnumerable<ClassifiedTextRun> Runs { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextRun.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextRun.cs
new file mode 100644
index 0000000..11f10db
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ClassifiedTextRun.cs
@@ -0,0 +1,45 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+ using Microsoft.VisualStudio.Text.Classification;
+
+ /// <summary>
+ /// Represents a contiguous run of classified text in an <see cref="IToolTipService"/> <see cref="IToolTipPresenter"/>.
+ /// </summary>
+ /// <remarks>
+ /// Classified text runs live in <see cref="ClassifiedTextElement"/>s and are a string, classification pair. On
+ /// <see cref="IToolTipPresenter.StartOrUpdate(ITrackingSpan, System.Collections.Generic.IEnumerable{object})"/>,
+ /// the classified text is converted to a platform-specific run of formatted (colorized) text via
+ /// the <see cref="IViewElementFactoryService"/> and is displayed.
+ /// </remarks>
+ public sealed class ClassifiedTextRun
+ {
+ /// <summary>
+ /// Creates a new run of classified text.
+ /// </summary>
+ /// <param name="classificationTypeName">
+ /// A name indicating a <see cref="IClassificationType"/> that maps to a format that will be applied to the text.
+ /// </param>
+ /// <param name="text">The text rendered by this run.</param>
+ /// <remarks>
+ /// Classification types can be platform specific. Only classifications defined in PredefinedClassificationTypeNames
+ /// are supported cross platform.
+ /// </remarks>
+ public ClassifiedTextRun(string classificationTypeName, string text)
+ {
+ this.ClassificationTypeName = classificationTypeName
+ ?? throw new ArgumentNullException(nameof(classificationTypeName));
+ this.Text = text ?? throw new ArgumentNullException(nameof(text));
+ }
+
+ /// <summary>
+ /// The name of the classification which maps to formatting properties that will be applied to this text.
+ /// </summary>
+ public string ClassificationTypeName { get; }
+
+ /// <summary>
+ /// The text that will be formatted by <see cref="ClassificationTypeName"/>'s corresponding formatting.
+ /// </summary>
+ public string Text { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElement.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElement.cs
new file mode 100644
index 0000000..22d0b42
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElement.cs
@@ -0,0 +1,49 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Immutable;
+
+ /// <summary>
+ /// Represents a container of zero or more elements for display in an <see cref="IToolTipPresenter"/>.
+ /// </summary>
+ /// <remarks>
+ /// Elements are translated to platform-specific UI constructs via the <see cref="IViewElementFactoryService"/>.
+ /// </remarks>
+ public sealed class ContainerElement
+ {
+ /// <summary>
+ /// Constructs a new container.
+ /// </summary>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="elements"/> is <c>null</c>.</exception>
+ /// <param name="style">The layout style for the container.</param>
+ /// <param name="elements">The <see cref="IViewElementFactoryService"/> elements to display.</param>
+ public ContainerElement(ContainerElementStyle style, IEnumerable<object> elements)
+ {
+ this.Style = style;
+ this.Elements = elements?.ToImmutableList() ?? throw new ArgumentNullException(nameof(elements));
+ }
+
+ /// <summary>
+ /// Constructs a new container.
+ /// </summary>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="elements"/> is <c>null</c>.</exception>
+ /// <param name="style">The layout style for the container.</param>
+ /// <param name="elements">The elements to translate to UI and display via the <see cref="IViewElementFactoryService"/>.</param>
+ public ContainerElement(ContainerElementStyle style, params object[] elements)
+ {
+ this.Style = style;
+ this.Elements = elements?.ToImmutableList() ?? throw new ArgumentNullException(nameof(elements));
+ }
+
+ /// <summary>
+ /// The elements to be displayed in the container.
+ /// </summary>
+ public IEnumerable<object> Elements { get; }
+
+ /// <summary>
+ /// The layout style for the container.
+ /// </summary>
+ public ContainerElementStyle Style { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElementStyle.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElementStyle.cs
new file mode 100644
index 0000000..d9f8b22
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ContainerElementStyle.cs
@@ -0,0 +1,18 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// The layout style for a <see cref="ContainerElement"/>.
+ /// </summary>
+ public enum ContainerElementStyle
+ {
+ /// <summary>
+ /// Contents are end-to-end, and wrapped when the control becomes too wide.
+ /// </summary>
+ Wrapped,
+
+ /// <summary>
+ /// Contents are stacked vertically.
+ /// </summary>
+ Stacked
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ImageElement.cs b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ImageElement.cs
new file mode 100644
index 0000000..f4c477c
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ToolTipService/ViewElementFactories/ImageElement.cs
@@ -0,0 +1,29 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using Microsoft.VisualStudio.Core.Imaging;
+
+ /// <summary>
+ /// Represents an image in an <see cref="IToolTipService"/> <see cref="IToolTipPresenter"/>.
+ /// </summary>
+ ///
+ /// <remarks>
+ /// <see cref="ImageElement"/>s should be constructed with <see cref="Microsoft.VisualStudio.Core.Imaging.ImageId"/>s
+ /// that correspond to an image on that platform.
+ /// </remarks>
+ public sealed class ImageElement
+ {
+ /// <summary>
+ /// Creates a new instance of an image element.
+ /// </summary>
+ /// <param name="iamgeId"> A unique identifier for an image.</param>
+ public ImageElement(ImageId imageId)
+ {
+ this.ImageId = imageId;
+ }
+
+ /// <summary>
+ /// A unique identifier for an image.
+ /// </summary>
+ public ImageId ImageId { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Operations/IEditorOperations.cs b/src/Text/Def/TextUI/Operations/IEditorOperations.cs
index 9668e55..55c7c67 100644
--- a/src/Text/Def/TextUI/Operations/IEditorOperations.cs
+++ b/src/Text/Def/TextUI/Operations/IEditorOperations.cs
@@ -891,7 +891,6 @@ namespace Microsoft.VisualStudio.Text.Operations
/// Returns an empty string if the provided <paramref name="point"/> is not in virtual space.
/// </remarks>
string GetWhitespaceForVirtualSpace(VirtualSnapshotPoint point);
-
#endregion
#region Properties
diff --git a/src/Text/Def/TextUI/Operations/IEditorOperations3.cs b/src/Text/Def/TextUI/Operations/IEditorOperations3.cs
index e176fde..eceb30d 100644
--- a/src/Text/Def/TextUI/Operations/IEditorOperations3.cs
+++ b/src/Text/Def/TextUI/Operations/IEditorOperations3.cs
@@ -35,5 +35,16 @@ namespace Microsoft.VisualStudio.Text.Operations
/// </para>
/// </remarks>
bool TrimTrailingWhiteSpace();
+
+ /// <summary>
+ /// Duplicates the current selection, or the whole line (if there is no selection), without changing the clipboard.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// Multiple selection cases like block selection will treat each selection independently.
+ /// </remarks>
+ bool DuplicateSelection();
}
}
diff --git a/src/Text/Def/TextUI/TextUI.csproj b/src/Text/Def/TextUI/TextUI.csproj
index ef71217..18cf4e5 100644
--- a/src/Text/Def/TextUI/TextUI.csproj
+++ b/src/Text/Def/TextUI/TextUI.csproj
@@ -22,19 +22,4 @@
<None Include="Diagrams\BasePrimitives.cd" />
<None Include="Diagrams\Editor.cd" />
</ItemGroup>
- <ItemGroup>
- <EmbeddedResource Update="Strings.resx">
- <Generator>ResXFileCodeGenerator</Generator>
- <LastGenOutput>Strings.Designer.cs</LastGenOutput>
- <LogicalName>Microsoft.VisualStudio.Text.Editor.Strings.resources</LogicalName>
- <ManifestResourceName>Microsoft.VisualStudio.Text.Editor.Strings.resources</ManifestResourceName>
- </EmbeddedResource>
- </ItemGroup>
- <ItemGroup>
- <Compile Update="Strings.Designer.cs">
- <DesignTime>True</DesignTime>
- <AutoGen>True</AutoGen>
- <DependentUpon>Strings.resx</DependentUpon>
- </Compile>
- </ItemGroup>
</Project>
diff --git a/src/Text/Impl/EditorOperations/EditorOperations.cs b/src/Text/Impl/EditorOperations/EditorOperations.cs
index 50582ff..5ac282a 100644
--- a/src/Text/Impl/EditorOperations/EditorOperations.cs
+++ b/src/Text/Impl/EditorOperations/EditorOperations.cs
@@ -4583,6 +4583,83 @@ namespace Microsoft.VisualStudio.Text.Operations.Implementation
return !edit.Canceled;
}
}
+
+ private void DuplicateLine(SnapshotPoint triggerPoint, ITextEdit edit, bool insertBelow = false)
+ {
+ var line = triggerPoint.GetContainingLine();
+ string textToInsert = line.GetText();
+ int whereToInsert;
+
+ if (insertBelow)
+ {
+ whereToInsert = line.End;
+ edit.Insert(whereToInsert, TextBufferOperationHelpers.GetNewLineCharacterToInsert(line, _editorOptions));
+ edit.Insert(whereToInsert, textToInsert);
+ }
+ else
+ {
+ whereToInsert = line.Start;
+ edit.Insert(whereToInsert, textToInsert);
+ edit.Insert(whereToInsert, TextBufferOperationHelpers.GetNewLineCharacterToInsert(line, _editorOptions));
+ }
+ }
+
+ public bool DuplicateSelection()
+ {
+ Func<bool> func = () =>
+ {
+ using (ITextEdit edit = _textView.TextBuffer.CreateEdit())
+ {
+ if (_textView.Selection.IsEmpty)
+ {
+ DuplicateLine(_textView.Caret.Position.BufferPosition, edit);
+ }
+ else
+ {
+ var virtualSelectedSpans = _textView.Selection.VirtualSelectedSpans;
+
+ // This is used only in the case of zero width block selection in order to maintain the block selection after
+ // our edit. On the first span we want to insert the copied text after the current row so that the top of the block
+ // selection doesn't move. An all others, we want to insert above so the bottom of the block selection does move.
+ bool insertBelow = virtualSelectedSpans.Count > 1;
+ foreach (var virtualSpan in virtualSelectedSpans)
+ {
+ if (virtualSpan.Length > 0)
+ {
+ if (!virtualSpan.IsInVirtualSpace)
+ {
+ edit.Insert(virtualSpan.Start.Position, virtualSpan.GetText());
+ }
+ else
+ {
+ // Is this all in virtual space, if so, do nothing
+ if (!virtualSpan.Start.IsInVirtualSpace)
+ {
+ // Ok, we need to pad with whitespace as well as duplicate. Append the amount of virtual space as spaces after the inserted text
+ // since we're inserting before the caret.
+ edit.Insert(virtualSpan.Start.Position, virtualSpan.GetText());
+
+ int whiteSpaceSize = virtualSpan.Length - virtualSpan.SnapshotSpan.Length;
+ string insertedSpace = GetWhiteSpaceForPositionAndVirtualSpace(virtualSpan.SnapshotSpan.End, whiteSpaceSize, useBufferPrimitives: true);
+ edit.Insert(virtualSpan.Start.Position, insertedSpace);
+ }
+ }
+ }
+ else
+ {
+ // This must be a zero-width block selection, treat like several instances of no-selection and just duplicate the lines.
+ DuplicateLine(virtualSpan.Start.Position, edit, insertBelow);
+ insertBelow = false;
+ }
+ }
+ }
+
+ edit.Apply();
+ return !(edit.HasFailedChanges || edit.Canceled);
+ }
+ };
+ return ExecuteAction(Strings.DuplicateSelection, func, ensureVisible: true);
+ }
}
/// <summary>
diff --git a/src/Text/Impl/EditorOperations/Strings.Designer.cs b/src/Text/Impl/EditorOperations/Strings.Designer.cs
index 71c4a07..a7ebcea 100644
--- a/src/Text/Impl/EditorOperations/Strings.Designer.cs
+++ b/src/Text/Impl/EditorOperations/Strings.Designer.cs
@@ -223,6 +223,15 @@ namespace Microsoft.VisualStudio.Text.Operations.Implementation {
}
/// <summary>
+ /// Looks up a localized string similar to Duplicate Selection.
+ /// </summary>
+ internal static string DuplicateSelection {
+ get {
+ return ResourceManager.GetString("DuplicateSelection", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Looks up a localized string similar to Increase line indent.
/// </summary>
internal static string IncreaseLineIndent {
diff --git a/src/Text/Impl/EditorOperations/Strings.resx b/src/Text/Impl/EditorOperations/Strings.resx
index fd8f056..3246ccd 100644
--- a/src/Text/Impl/EditorOperations/Strings.resx
+++ b/src/Text/Impl/EditorOperations/Strings.resx
@@ -258,4 +258,7 @@
<data name="TrimTrailingWhitespace" xml:space="preserve">
<value>Trim trailing whitespace</value>
</data>
-</root>
+ <data name="DuplicateSelection" xml:space="preserve">
+ <value>Duplicate Selection</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/Text/Impl/TextModel/Storage/Page.cs b/src/Text/Impl/TextModel/Storage/Page.cs
index 5256373..5721fb0 100644
--- a/src/Text/Impl/TextModel/Storage/Page.cs
+++ b/src/Text/Impl/TextModel/Storage/Page.cs
@@ -40,9 +40,8 @@ namespace Microsoft.VisualStudio.Text.Implementation
_uncompressedContents.SetTarget(contents);
}
- this.Manager.UpdateMRU(this);
+ this.Manager.UpdateMRU(this, contents);
return contents;
-
}
}
}
diff --git a/src/Text/Impl/TextModel/Storage/PageManager.cs b/src/Text/Impl/TextModel/Storage/PageManager.cs
index eca1287..1d19ac2 100644
--- a/src/Text/Impl/TextModel/Storage/PageManager.cs
+++ b/src/Text/Impl/TextModel/Storage/PageManager.cs
@@ -6,8 +6,7 @@
// Use at your own risk.
//
using System;
-using System.Collections.Immutable;
-using System.Diagnostics;
+using System.Collections.Generic;
using System.Threading;
using Microsoft.VisualStudio.Text.Utilities;
@@ -15,45 +14,47 @@ namespace Microsoft.VisualStudio.Text.Implementation
{
internal class PageManager
{
- // this class inherits from page so that it participates in the MRU list, of which it is the sentinel node.
- private ImmutableList<Page> _mru = ImmutableList<Page>.Empty;
+ // .Item1 == topemost item in the real MRU (.Item2). It is called out as a special case because updating the
+ // MRU to put the topmost item at the top of the MRU is a very hot path & has showed up in perf traces.
+ private Tuple<Page, List<Tuple<Page, char[]>>> _mru;
private readonly int _maxPages;
public PageManager()
{
_maxPages = TextModelOptions.CompressedStorageMaxLoadedPages;
+ _mru = Tuple.Create((Page)null, new List<Tuple<Page, char[]>>(_maxPages));
}
- public void UpdateMRU(Page page)
+ public void UpdateMRU(Page page, char[] contents)
{
var oldMRU = Volatile.Read(ref _mru);
while (true)
{
- ImmutableList<Page> newMRU;
+ if (oldMRU.Item1 == page)
+ {
+ // This is the very hot path so return immediately if the new page is already topmost.
+ return;
+ }
- int index = oldMRU.IndexOf(page);
- if (index >= 0)
+ int index = oldMRU.Item2.Count - 1; // Intentionally skip checking the topmost item (we know, due to the check above, that it isn't page).
+ while (--index >= 0)
{
- if (index == (oldMRU.Count - 1))
+ if (oldMRU.Item2[index].Item1 == page)
{
- // Page is already at the top of the MRU so nothing needs to be done.
- return;
+ break;
}
-
- // Was in the list, but not at the top. Remove it in preparation for adding it later.
- newMRU = oldMRU.RemoveAt(index);
- }
- else if (oldMRU.Count >= _maxPages)
- {
- // Wasn't in the list and the list is full. Remove the oldest in preparation for adding it later.
- newMRU = oldMRU.RemoveAt(0);
- }
- else
- {
- newMRU = oldMRU;
}
- newMRU = newMRU.Add(page);
+ var newMRUList = new List<Tuple<Page, char[]>>(_maxPages);
+ newMRUList.AddRange(oldMRU.Item2);
+ if (index >= 0)
+ newMRUList.RemoveAt(index);
+ else if (newMRUList.Count >= _maxPages)
+ newMRUList.RemoveAt(0);
+
+ newMRUList.Add(Tuple.Create(page, contents));
+
+ var newMRU = Tuple.Create(page, newMRUList);
var result = Interlocked.CompareExchange(ref _mru, newMRU, oldMRU);
if (result == oldMRU)