@@ -30,10 +30,12 @@ open Microsoft.VisualStudio.Text
3030open Microsoft.VisualStudio .Text .Editor
3131open System.Diagnostics
3232open System.Runtime .InteropServices
33+ open System.Composition
34+ open Microsoft.CodeAnalysis .Host .Mef
35+ open Microsoft.VisualStudio .Utilities
3336
3437[<AutoOpen>]
3538module private FSharpBraceCompletionSessionProviderHelpers =
36- open System.Runtime .InteropServices
3739
3840let getLanguageService < 'T when 'T :> ILanguageService and 'T : null > ( document : Document ) =
3941match document.Projectwith
@@ -71,7 +73,7 @@ type internal IEditorBraceCompletionSessionFactory =
7173
7274abstract TryCreateSession : Document * openingPosition : int * openingBrace : char * CancellationToken -> IEditorBraceCompletionSession
7375
74- type internal BraceCompletionSession
76+ type internal FSharpBraceCompletionSession
7577(
7678 textView: ITextView,
7779 subjectBuffer: ITextBuffer,
@@ -192,7 +194,6 @@ type internal BraceCompletionSession
192194
193195if afterBrace.HasValuethen
194196 textView.Caret.MoveTo( afterBrace.Value) |> ignore
195-
196197
197198interface IBraceCompletionSessionwith
198199
@@ -316,17 +317,79 @@ type internal BraceCompletionSession
316317
317318member __.TextView = textView
318319
319- type internal BraceCompletionSessionProvider
320+ module private Parenthesis =
321+
322+ [<Literal>]
323+ let OpenCharacter = '('
324+
325+ [<Literal>]
326+ let CloseCharacter = ')'
327+
328+ type internal ParenthesisCompletionSession () =
329+
330+ interface IEditorBraceCompletionSessionwith
331+
332+ member this.AfterReturn ( _session , _cancellationToken ) =
333+ ()
334+
335+ member this.AfterStart ( _session , _cancellationToken ) =
336+ ()
337+
338+ member this.AllowOverType ( _session , _cancellationToken ) =
339+ // TODO: Implement this for F#
340+ true
341+
342+ member this.CheckOpeningPoint ( _session , _cancellationToken ) =
343+ // TODO: Implement this for F#
344+ true
345+
346+ [<Shared>]
347+ [<ExportLanguageService( typeof< IEditorBraceCompletionSessionFactory>, FSharpConstants.FSharpLanguageName) >]
348+ type internal FSharpEditorBraceCompletionSessionFactory
349+ [<ImportingConstructor>] (_ smartIndetationService: ISmartIndentationService, _ undoManager: ITextBufferUndoManagerProvider) =
350+ inherit ForegroundThreadAffinitizedObject()
351+
352+ member __.IsSupportedOpeningBrace openingBrace =
353+ match openingBracewith
354+ | Parenthesis.OpenCharacter-> true
355+ | _ -> false
356+
357+ member this.CheckCodeContext ( _document , _position , _openingBrace , _cancellationToken ) =
358+ this.AssertIsForeground();
359+
360+ // TODO: We need to know if we are inside a F# comment. If we are, then don't do automatic completion.
361+ true
362+
363+ member this.CreateEditorSession ( _document : Document , _openingPosition : int , openingBrace : char , _cancellationToken : CancellationToken ) =
364+ match openingBracewith
365+ | Parenthesis.OpenCharacter-> ParenthesisCompletionSession() :> IEditorBraceCompletionSession
366+ | _ -> null
367+
368+ interface IEditorBraceCompletionSessionFactorywith
369+
370+ member this.TryCreateSession ( document , openingPosition , openingBrace , cancellationToken ) : IEditorBraceCompletionSession =
371+ this.AssertIsForeground()
372+
373+ if this.IsSupportedOpeningBrace( openingBrace) && this.CheckCodeContext( document, openingPosition, openingBrace, cancellationToken) then
374+ this.CreateEditorSession( document, openingPosition, openingBrace, cancellationToken)
375+ else
376+ null
377+
378+ [<Export( typeof< IBraceCompletionSessionProvider>) >]
379+ [<ContentType( FSharpConstants.FSharpContentTypeName) >]
380+ [<BracePair( Parenthesis.OpenCharacter, Parenthesis.CloseCharacter) >]
381+ type internal FSharpBraceCompletionSessionProvider
382+ [<ImportingConstructor>]
320383(
321384 undoManager: ITextBufferUndoManagerProvider,
322- _ editorOperationsFactoryService : IEditorOperationsFactoryService
385+ editorOperationsFactoryService : IEditorOperationsFactoryService
323386) =
324387
325388inherit ForegroundThreadAffinitizedObject()
326389
327390interface IBraceCompletionSessionProviderwith
328391
329- member this.TryCreateSession ( textView , openingPoint , openingBrace , _closingBrace , session ) =
392+ member this.TryCreateSession ( textView , openingPoint , openingBrace , closingBrace , session ) =
330393 this.AssertIsForeground();
331394
332395let textSnapshot = openingPoint.Snapshot
@@ -343,9 +406,17 @@ type internal BraceCompletionSessionProvider
343406
344407match editorSessionFactory.TryCreateSession( document, openingPoint.Position, openingBrace, cancellationToken) with
345408| null -> null
346- | _ editorSession->
347- let _undoHistory = undoManager.GetTextBufferUndoManager( textView.TextBuffer) .TextBufferUndoHistory
348- null
409+ | editorSession->
410+ let undoHistory = undoManager.GetTextBufferUndoManager( textView.TextBuffer) .TextBufferUndoHistory
411+ FSharpBraceCompletionSession(
412+ textView,
413+ openingPoint.Snapshot.TextBuffer,
414+ openingPoint,
415+ openingBrace,
416+ closingBrace,
417+ undoHistory,
418+ editorOperationsFactoryService,
419+ editorSession) :> IBraceCompletionSession
349420
350421match sessionwith
351422| null -> false