@@ -336,6 +336,8 @@ module private DoubleQuote =
336336[<Literal>]
337337let CloseCharacter = '"'
338338
339+ (* This is for [| |] and {| |} , since the implementation deals with chars only.
340+ We have to test if there is a { or [ before the cursor position and insert the closing '|'.*)
339341module private VerticalBar =
340342
341343[<Literal>]
@@ -344,6 +346,26 @@ module private VerticalBar =
344346[<Literal>]
345347let CloseCharacter = '|'
346348
349+ (* This is for attributes [< >] , since the implementation deals with chars only.
350+ We have to test if there is a [ before the cursor position and insert the closing '>'.*)
351+ module private AngleBrackets =
352+
353+ [<Literal>]
354+ let OpenCharacter = '<'
355+
356+ [<Literal>]
357+ let CloseCharacter = '>'
358+
359+ (* For multiline comments like this, since the implementation deals with chars only*)
360+ module private Asterisk =
361+
362+ [<Literal>]
363+ let OpenCharacter = '*'
364+
365+ [<Literal>]
366+ let CloseCharacter = '*'
367+
368+
347369type internal ParenthesisCompletionSession () =
348370
349371interface IEditorBraceCompletionSessionwith
@@ -393,48 +415,104 @@ type internal VerticalBarCompletionSession () =
393415member this.AllowOverType ( _session , _cancellationToken ) =
394416// TODO: Implement this for F#
395417true
396-
418+
419+ (* This is for [| |] and {| |} , since the implementation deals with chars only.
420+ We have to test if there is a { or [ before the cursor position and insert the closing '|'.*)
397421member this.CheckOpeningPoint ( _session , _cancellationToken ) =
398422let sourceCode = _ session.TextView.TextSnapshot
399423//let document = _session.TextView.TextSnapshot.GetOpenDocumentInCurrentContextWithChanges()
400424let position = _ session.TextView.Caret.Position.BufferPosition.Position
401- let ret = sourceCode.GetText( position-2 , 1 ) = " {" && sourceCode.GetText( position, 1 ) = " }"
402- || sourceCode.GetText( position-2 , 1 ) = " [" && sourceCode.GetText( position, 1 ) = " ]"
425+ let ret = position-2 >= 0 && position< sourceCode.Length&&
426+ ( sourceCode.GetText( position-2 , 1 ) = " {" && sourceCode.GetText( position, 1 ) = " }"
427+ || sourceCode.GetText( position-2 , 1 ) = " [" && sourceCode.GetText( position, 1 ) = " ]" )
403428 ret
404-
429+
430+ type internal AngleBracketCompletionSession () =
431+
432+ interface IEditorBraceCompletionSessionwith
433+
434+ member this.AfterReturn ( _session , _cancellationToken ) =
435+ ()
436+
437+ member this.AfterStart ( _session , _cancellationToken ) =
438+ ()
439+
440+ member this.AllowOverType ( _session , _cancellationToken ) =
441+ // TODO: Implement this for F#
442+ true
443+
444+ (* This is for attributes [< >] , since the implementation deals with chars only.
445+ We have to test if there is a [ before the cursor position and insert the closing '>'.*)
446+ member this.CheckOpeningPoint ( _session , _cancellationToken ) =
447+ let sourceCode = _ session.TextView.TextSnapshot
448+ let position = _ session.TextView.Caret.Position.BufferPosition.Position
449+ let ret = position-2 >= 0 && position< sourceCode.Length&&
450+ sourceCode.GetText( position-2 , 1 ) .Equals( " [" ) && sourceCode.GetText( position, 1 ) .Equals( " ]" )
451+ ret
452+
453+ (* For multi-line comments, test if it is between "()"*)
454+ type internal AsteriskCompletionSession () =
455+
456+ interface IEditorBraceCompletionSessionwith
457+
458+ member this.AfterReturn ( _session , _cancellationToken ) =
459+ ()
460+
461+ member this.AfterStart ( _session , _cancellationToken ) =
462+ ()
463+
464+ member this.AllowOverType ( _session , _cancellationToken ) =
465+ // TODO: Implement this for F#
466+ true
467+
468+ (* This is for attributes [< >] , since the implementation deals with chars only.
469+ We have to test if there is a [ before the cursor position and insert the closing '>'.*)
470+ member this.CheckOpeningPoint ( _session , _cancellationToken ) =
471+ let sourceCode = _ session.TextView.TextSnapshot
472+ let position = _ session.TextView.Caret.Position.BufferPosition.Position
473+ let ret = position-2 >= 0 && position< sourceCode.Length&&
474+ sourceCode.GetText( position-2 , 1 ) .Equals( " (" ) && sourceCode.GetText( position, 1 ) .Equals( " )" )
475+ ret
476+
405477[<ExportLanguageService( typeof< IEditorBraceCompletionSessionFactory>, FSharpConstants.FSharpLanguageName) >]
406478type internal FSharpEditorBraceCompletionSessionFactory () =
407479inherit ForegroundThreadAffinitizedObject()
408480
409481member __.IsSupportedOpeningBrace openingBrace =
410482match openingBracewith
411483| Parenthesis.OpenCharacter| CurlyBrackets.OpenCharacter| SquareBrackets.OpenCharacter
412- | DoubleQuote.OpenCharacter| VerticalBar.OpenCharacter-> true
484+ | DoubleQuote.OpenCharacter| VerticalBar.OpenCharacter| AngleBrackets.OpenCharacter
485+ | Asterisk.OpenCharacter-> true
413486| _ -> false
414487
415488member this.CheckCodeContext ( _document : Document , _position : int , _openingBrace , _cancellationToken ) =
416489 this.AssertIsForeground()
417- //TODO: We need to know if we are inside a F# comment. If we are, then don't do automatic completion.
490+ // We need to know if we are inside a F# comment. If we are, then don't do automatic completion.
418491let sourceCodeTask = _ document.GetTextAsync(_ cancellationToken)
419492 sourceCodeTask.Wait(_ cancellationToken)
420493let sourceCode = sourceCodeTask.Result
421- let colorizationData = Tokenizer.getColorizationData(_ document.Id, sourceCode, TextSpan(_ position-1 , 1 ), Some(_ document.FilePath), [], _ cancellationToken)
422- colorizationData.Exists( fun classifiedSpan ->
423- classifiedSpan.TextSpan.IntersectsWith_ position&&
424- (
425- match classifiedSpan.ClassificationTypewith
426- | ClassificationTypeNames.Comment
427- | ClassificationTypeNames.StringLiteral-> false
428- | _ -> true // anything else is a valid classification type
429- ))
494+
495+ _ position= 0
496+ || let colorizationData = Tokenizer.getColorizationData(_ document.Id, sourceCode, TextSpan(_ position-1 , 1 ), Some(_ document.FilePath), [], _ cancellationToken)
497+ in colorizationData.Count= 0
498+ || colorizationData.Exists( fun classifiedSpan ->
499+ classifiedSpan.TextSpan.IntersectsWith_ position&&
500+ (
501+ match classifiedSpan.ClassificationTypewith
502+ | ClassificationTypeNames.Comment
503+ | ClassificationTypeNames.StringLiteral-> false
504+ | _ -> true // anything else is a valid classification type
505+ ))
430506
431507member this.CreateEditorSession ( _document : Document , _openingPosition : int , openingBrace : char , _cancellationToken : CancellationToken ) =
432508match openingBracewith
433509| Parenthesis.OpenCharacter-> ParenthesisCompletionSession() :> IEditorBraceCompletionSession
434510| CurlyBrackets.OpenCharacter-> ParenthesisCompletionSession() :> IEditorBraceCompletionSession
435511| SquareBrackets.OpenCharacter-> ParenthesisCompletionSession() :> IEditorBraceCompletionSession
436512| VerticalBar.OpenCharacter-> VerticalBarCompletionSession() :> IEditorBraceCompletionSession
513+ | AngleBrackets.OpenCharacter-> AngleBracketCompletionSession() :> IEditorBraceCompletionSession
437514| DoubleQuote.OpenCharacter-> DoubleQuoteCompletionSession() :> IEditorBraceCompletionSession
515+ | Asterisk.OpenCharacter-> DoubleQuoteCompletionSession() :> IEditorBraceCompletionSession
438516| _ -> null
439517
440518interface IEditorBraceCompletionSessionFactorywith
@@ -454,6 +532,8 @@ type internal FSharpEditorBraceCompletionSessionFactory () =
454532[<BracePair( SquareBrackets.OpenCharacter, SquareBrackets.CloseCharacter) >]
455533[<BracePair( DoubleQuote.OpenCharacter, DoubleQuote.CloseCharacter) >]
456534[<BracePair( VerticalBar.OpenCharacter, VerticalBar.CloseCharacter) >]
535+ [<BracePair( AngleBrackets.OpenCharacter, AngleBrackets.CloseCharacter) >]
536+ [<BracePair( Asterisk.OpenCharacter, Asterisk.CloseCharacter) >]
457537type internal FSharpBraceCompletionSessionProvider
458538[<ImportingConstructor>]
459539(