Snippets
Created by
Tuomas Hietanen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | // Example follows this, translated to FSharp:
// https://msdn.microsoft.com/en-us/library/dn903708.aspx
// Just instead of copy&pasting C#, add a new F# class library and paste this code to there,
// then add that to reference to your C#-project.
// If you want to deploy without C# project, see e.g. this:
// You need to use some VSIX-package to deploy the code:
// https://github.com/fsharp-vsix/FsVSIX
// One more thing to get this to work: Open the source.extension.vsixmanifest file
// Go to Assets -> Edit -> Project and change your fsharp dll to dropdown.
// This tells MEF to which dll to use to inject dependencies to Visual Studio.
// Corresponding XML:
// <Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="..." Path="|...|" />
#if INTERACTIVE
#I @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0\"
#r "Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll"
#r "Microsoft.VisualStudio.Language.Intellisense.dll"
#r "Microsoft.VisualStudio.CoreUtility.dll"
#r "Microsoft.VisualStudio.Text.Data.dll"
#r "Microsoft.VisualStudio.Text.Logic.dll"
#r "Microsoft.VisualStudio.Text.UI.dll"
#r "Microsoft.VisualStudio.Text.UI.Wpf.dll"
#I @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\"
#r "PresentationFramework.Core.dll"
#r "PresentationFramework.dll"
#r "WindowsBase.dll"
#r "System.ComponentModel.Composition.dll"
#endif
namespace VisualStudioTooltips
open Microsoft.VisualStudio.Imaging.Interop
open System.Windows
open System.Windows.Controls
open System.Windows.Documents
open Microsoft.VisualStudio.Text
open System.Threading.Tasks
open System
open System.Collections.Generic
open Microsoft.VisualStudio.Language.Intellisense
open Microsoft.VisualStudio.Text.Editor
open Microsoft.VisualStudio.Text.Operations
open Microsoft.VisualStudio.Utilities
open System.ComponentModel.Composition
type internal UpperCaseSuggestedAction (span:ITrackingSpan) =
let snapshot = span.TextBuffer.CurrentSnapshot
let upper = span.GetText(snapshot).ToUpper()
let display = sprintf "Convert '%s' to upper case" (span.GetText snapshot)
interface ISuggestedAction with
member __.GetPreviewAsync (_) =
let textBlock = TextBlock(Padding = Thickness(5.))
textBlock.Inlines.Add (Run upper)
Task.FromResult<obj> textBlock
member __.GetActionSetsAsync (_) =
Task.FromResult<IEnumerable<SuggestedActionSet>>(null)
member val HasActionSets = false with get
member val DisplayText = display with get
member val IconMoniker = Unchecked.defaultof<ImageMoniker> with get
member val IconAutomationText = Unchecked.defaultof<string> with get
member val InputGestureText = Unchecked.defaultof<string> with get
member val HasPreview = true with get
member __.Invoke (_) =
span.TextBuffer.Replace(span.GetSpan(snapshot).Span, upper) |> ignore
()
member __.TryGetTelemetryId
([<System.Runtime.InteropServices.Out>] telemetryId : Guid byref) =
telemetryId <- Guid.Empty
false
member __.Dispose() = ()
//type internal LowerCaseSuggestedAction : ISuggestedAction
[<Export(typeof<ISuggestedActionsSourceProvider>)>]
[<Name "Test Suggested Actions">]
[<ContentType "text">]
type internal TestSuggestedActionsSourceProvider() as this =
[<Import(typeof<ITextStructureNavigatorSelectorService>)>]
member val NavigatorService =
Unchecked.defaultof<ITextStructureNavigatorSelectorService> with get, set
interface ISuggestedActionsSourceProvider with
member this.CreateSuggestedActionsSource(textView, textBuffer) =
if textBuffer = null && textView = null then
Unchecked.defaultof<ISuggestedActionsSource>
else
new TestSuggestedActionsSource(this, textView, textBuffer)
:> ISuggestedActionsSource
and internal TestSuggestedActionsSource
( prov:TestSuggestedActionsSourceProvider,
textView:ITextView, textBuffer:ITextBuffer) =
let event = DelegateEvent<EventHandler<EventArgs>>()
let tryGetWordUnderCaret() =
let caret = textView.Caret
if caret.Position.BufferPosition.Position <= 0 then
false, Unchecked.defaultof<TextExtent>
else
let point = caret.Position.BufferPosition - 1
let navigator = prov.NavigatorService.GetTextStructureNavigator textBuffer
true, navigator.GetExtentOfWord point
interface ISuggestedActionsSource with
member __.HasSuggestedActionsAsync(requestedActionCategories, range, cToken) =
System.Threading.Tasks.Task.Factory.StartNew(fun () ->
let ok, extent = tryGetWordUnderCaret()
if ok then // don't display the action if the extent has whitespace
extent.IsSignificant
else false
)
member __.GetSuggestedActions(requestedActionCategories, range, cToken) =
let ok, extent = tryGetWordUnderCaret()
if ok && extent.IsSignificant then
let trackingSpan =
range.Snapshot.CreateTrackingSpan(
extent.Span.Span, SpanTrackingMode.EdgeInclusive)
use upperAction = new UpperCaseSuggestedAction(trackingSpan)
//let lowerAction = LowerCaseSuggestedAction trackingSpan :> ISuggestedAction
[| (SuggestedActionSet [| upperAction; (* lowerAction *) |]) |]
:> IEnumerable<SuggestedActionSet>
else
[||] :> IEnumerable<SuggestedActionSet>
[<CLIEvent>]
member __.SuggestedActionsChanged = event.Publish
member __.TryGetTelemetryId(
[<System.Runtime.InteropServices.Out>] telemetryId : Guid byref) =
telemetryId <- Guid.Empty
false
interface IDisposable with
member __.Dispose() = ()
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.