@@ -638,9 +638,9 @@ type internal TypeCheckInfo
638638 GetEnvironmentLookupResolutions( nenv, ad, m, plid, filterCtors, showObsolete)
639639
640640 /// Find record fields in the best naming environment.
641- let GetClassOrRecordFieldsEnvironmentLookupResolutions ( cursorPos , plid ) =
641+ let GetClassOrRecordFieldsEnvironmentLookupResolutions ( cursorPos , plid , fieldsOnly ) =
642642 let ( nenv , ad ), m = GetBestEnvForPos cursorPos
643- let items = ResolvePartialLongIdentToClassOrRecdFields ncenv nenv m ad plid false
643+ let items = ResolvePartialLongIdentToClassOrRecdFields ncenv nenv m ad plid false fieldsOnly
644644 let items = items |> List.map ItemWithNoInst
645645 let items = items |> RemoveDuplicateItems g
646646 let items = items |> RemoveExplicitlySuppressed g
@@ -913,6 +913,21 @@ type internal TypeCheckInfo
913913 let toCompletionItems ( items : ItemWithInst list , denv : DisplayEnv , m : range ) =
914914 items |> List.map DefaultCompletionItem, denv, m
915915
916+ /// Find record fields in the best naming environment.
917+ let GetEnvironmentLookupResolutionsIncludingRecordFieldsAtPosition cursorPos plid envItems =
918+ // An empty record expression may be completed into something like these:
919+ // { XXX = ... }
920+ // { xxx with XXX ... }
921+ // Provide both expression items in scope and available record fields.
922+ let ( nenv , _ ), m = GetBestEnvForPos cursorPos
923+
924+ let fieldItems , _ , _ = GetClassOrRecordFieldsEnvironmentLookupResolutions( cursorPos, plid, true )
925+ let fieldCompletionItems , _ , _ as fieldsResult = ( fieldItems, nenv.DisplayEnv, m) |> toCompletionItems
926+
927+ match envItems with
928+ | Some( items, denv, m) -> Some( fieldCompletionItems @ items, denv, m)
929+ | _ -> Some( fieldsResult)
930+
916931 /// Get the auto-complete items at a particular location.
917932 let GetDeclItemsForNamesAtPosition ( parseResultsOpt : FSharpParseFileResults option , origLongIdentOpt : string list option ,
918933 residueOpt : string option , lastDotPos : int option , line : int , lineStr : string , colAtEndOfNamesAndResidue , filterCtors , resolveOverloads ,
@@ -963,27 +978,38 @@ type internal TypeCheckInfo
963978 |> Option.map toCompletionItems
964979
965980 // Completion at ' { XXX = ... } "
966- | Some( CompletionContext.RecordField( RecordContext.New( plid, _))) ->
967- // { x. } can be either record construction or computation expression. Try to get all visible record fields first
968- match GetClassOrRecordFieldsEnvironmentLookupResolutions( mkPos line loc, plid) |> toCompletionItems with
969- | [],_,_ ->
970- // no record fields found, return completion list as if we were outside any computation expression
971- GetDeclaredItems ( parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false , fun () -> [])
972- | result -> Some( result)
981+ | Some( CompletionContext.RecordField( RecordContext.New(( plid, _), isFirstField))) ->
982+ if isFirstField then
983+ let cursorPos = mkPos line loc
984+ let envItems = GetDeclaredItems ( parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false , fun () -> [])
985+ GetEnvironmentLookupResolutionsIncludingRecordFieldsAtPosition cursorPos plid envItems
986+ else
987+ // { x. } can be either record construction or computation expression. Try to get all visible record fields first
988+ match GetClassOrRecordFieldsEnvironmentLookupResolutions( mkPos line loc, plid, false ) |> toCompletionItems with
989+ | [],_,_ ->
990+ // no record fields found, return completion list as if we were outside any computation expression
991+ GetDeclaredItems ( parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false , fun () -> [])
992+ | result -> Some( result)
993+
994+ // Completion at '{ ... }'
995+ | Some( CompletionContext.RecordField RecordContext.Empty) ->
996+ let cursorPos = mkPos line loc
997+ let envItems = GetDeclaredItems ( parseResultsOpt, lineStr, origLongIdentOpt, colAtEndOfNamesAndResidue, residueOpt, lastDotPos, line, loc, filterCtors, resolveOverloads, false , fun () -> [])
998+ GetEnvironmentLookupResolutionsIncludingRecordFieldsAtPosition cursorPos [] envItems
973999
9741000 // Completion at ' { XXX = ... with ... } "
9751001 | Some( CompletionContext.RecordField( RecordContext.CopyOnUpdate( r, ( plid, _)))) ->
9761002 match GetRecdFieldsForExpr( r) with
9771003 | None ->
978- Some ( GetClassOrRecordFieldsEnvironmentLookupResolutions( mkPos line loc, plid))
1004+ Some ( GetClassOrRecordFieldsEnvironmentLookupResolutions( mkPos line loc, plid, false ))
9791005 |> Option.map toCompletionItems
9801006 | Some ( items, denv, m) ->
9811007 Some ( List.map ItemWithNoInst items, denv, m)
9821008 |> Option.map toCompletionItems
9831009
9841010 // Completion at ' { XXX = ... with ... } "
9851011 | Some( CompletionContext.RecordField( RecordContext.Constructor( typeName))) ->
986- Some( GetClassOrRecordFieldsEnvironmentLookupResolutions( mkPos line loc, [ typeName]))
1012+ Some( GetClassOrRecordFieldsEnvironmentLookupResolutions( mkPos line loc, [ typeName], false ))
9871013 |> Option.map toCompletionItems
9881014
9891015 // No completion at '...: string'
0 commit comments