Show term/type hashes (for adds/removes) in diff output, if ambiguous

This commit is contained in:
Mitchell Rosen 2019-12-14 23:04:33 -05:00
parent 834f4f6c5c
commit 764b2f4ae8
5 changed files with 67 additions and 20 deletions

View File

@ -1303,21 +1303,28 @@ prettyDiff diff = let
orig = Names.originalNames diff
adds = Names.addedNames diff
removes = Names.removedNames diff
addedTerms = [ n | (n,r) <- R.toList (Names.terms0 adds)
, not $ R.memberRan r (Names.terms0 removes) ]
addedTypes = [ n | (n,r) <- R.toList (Names.types0 adds)
, not $ R.memberRan r (Names.types0 removes) ]
added = Name.sortNames . nubOrd $ (addedTerms <> addedTypes)
removedTerms = [ n | (n,r) <- R.toList (Names.terms0 removes)
, not $ R.memberRan r (Names.terms0 adds)
, Set.notMember n addedTermsSet ] where
addedTermsSet = Set.fromList addedTerms
removedTypes = [ n | (n,r) <- R.toList (Names.types0 removes)
, not $ R.memberRan r (Names.types0 adds)
, Set.notMember n addedTypesSet ] where
addedTypesSet = Set.fromList addedTypes
removed = Name.sortNames . nubOrd $ (removedTerms <> removedTypes)
addedTerms = [ (n,r) | (n,r) <- R.toList (Names.terms0 adds)
, not $ R.memberRan r (Names.terms0 removes) ]
addedTypes = [ (n,r) | (n,r) <- R.toList (Names.types0 adds)
, not $ R.memberRan r (Names.types0 removes) ]
added = HQ'.sort (hqTerms ++ hqTypes)
where
hqTerms = [ Names.hqName adds n (Right r) | (n, r) <- addedTerms ]
hqTypes = [ Names.hqName adds n (Left r) | (n, r) <- addedTypes ]
removedTerms = [ (n,r) | (n,r) <- R.toList (Names.terms0 removes)
, not $ R.memberRan r (Names.terms0 adds)
, Set.notMember n addedTermsSet ] where
addedTermsSet = Set.fromList (map fst addedTerms)
removedTypes = [ (n,r) | (n,r) <- R.toList (Names.types0 removes)
, not $ R.memberRan r (Names.types0 adds)
, Set.notMember n addedTypesSet ] where
addedTypesSet = Set.fromList (map fst addedTypes)
removed = HQ'.sort (hqTerms ++ hqTypes)
where
hqTerms = [ Names.hqName removes n (Right r) | (n, r) <- removedTerms ]
hqTypes = [ Names.hqName removes n (Left r) | (n, r) <- removedTypes ]
movedTerms = [ (n,n2) | (n,r) <- R.toList (Names.terms0 removes)
, n2 <- toList (R.lookupRan r (Names.terms adds)) ]
@ -1342,14 +1349,14 @@ prettyDiff diff = let
-- todo: split out updates
P.green "+ Adds / updates:", "",
P.indentN 2 . P.wrap $
P.sep " " (prettyName <$> added)
P.sep " " (P.syntaxToColor . prettyHashQualified' <$> added)
]
else mempty,
if not $ null removed then
P.lines [
P.hiBlack "- Deletes:", "",
P.indentN 2 . P.wrap $
P.sep " " (prettyName <$> removed)
P.sep " " (P.syntaxToColor . prettyHashQualified' <$> removed)
]
else mempty,
if not $ null moved then

View File

@ -94,6 +94,16 @@ requalify hq r = case hq of
NameOnly n -> fromNamedReferent n r
HashQualified n _ -> fromNamedReferent n r
-- | Sort a list of hash-qualified names first by name, then if those match, by
-- hash.
sort :: [HashQualified] -> [HashQualified]
sort =
Name.sortNamed' toName $ \hq1 hq2 ->
case (hq1, hq2) of
(NameOnly{}, HashQualified{}) -> LT
(NameOnly{}, NameOnly{}) -> EQ
(HashQualified{}, NameOnly{}) -> GT
(HashQualified _ h1, HashQualified _ h2) -> compare h1 h2
instance IsString HashQualified where
fromString = unsafeFromText . Text.pack

View File

@ -9,6 +9,7 @@ module Unison.Name
, parent
, sortNames
, sortNamed
, sortNamed'
, stripNamePrefix
, stripPrefixes
, suffixes
@ -44,6 +45,14 @@ sortNamed by as = let
comp (_,s) (_,s2) = RFC5051.compareUnicode s s2
in fst <$> sortBy comp as'
-- | Like sortNamed, but takes an additional backup comparison function if two
-- names are equal.
sortNamed' :: (a -> Name) -> (a -> a -> Ordering) -> [a] -> [a]
sortNamed' by by2 as = let
as' = [ (a, Text.unpack (toText (by a))) | a <- as ]
comp (a,s) (a2,s2) = RFC5051.compareUnicode s s2 <> by2 a a2
in fst <$> sortBy comp as'
unsafeFromText :: Text -> Name
unsafeFromText t =
if Text.any (== '#') t then error $ "not a name: " <> show t else Name t

View File

@ -18,6 +18,7 @@ module Unison.Names2
, filterByHQs
, filterBySHs
, filterTypes
, hqName
, hqTermName
, hqTypeName
, hqTermAliases
@ -216,6 +217,26 @@ addType n r = (<> fromTypes [(n, r)])
addTerm :: Ord n => n -> Referent -> Names' n -> Names' n
addTerm n r = (<> fromTerms [(n, r)])
-- | Like hqTermName and hqTypeName, but considers term and type names to
-- conflict with each other (so will hash-qualify if there is e.g. both a term
-- and a type named "foo").
--
-- This is useful in contexts such as printing branch diffs. Example:
--
-- - Deletes:
--
-- foo
-- foo
--
-- We want to append the hash regardless of whether or not one is a term and the
-- other is a type.
hqName :: Ord n => Names' n -> n -> Either Reference Referent -> HQ.HashQualified' n
hqName b n = \case
Left r -> if ambiguous then hqTypeName' b n r else HQ.fromName n
Right r -> if ambiguous then hqTermName' b n r else HQ.fromName n
where
ambiguous = Set.size (termsNamed b n) + Set.size (typesNamed b n) > 1
-- Conditionally apply hash qualifier to term name.
-- Should be the same as the input name if the Names0 is unconflicted.
hqTermName :: Ord n => Names' n -> n -> Referent -> HQ.HashQualified' n

View File

@ -181,7 +181,7 @@ I can force my delete through by re-issuing the command.
- Deletes:
a.foo
a.foo#0ja a.foo#jk1
Tip: You can always `undo` if this wasn't what you wanted.
@ -279,7 +279,7 @@ type Foo = Foo Boolean
- Deletes:
a.Foo
a.Foo#d97 a.Foo#gq9
Tip: You can always `undo` if this wasn't what you wanted.
@ -310,7 +310,7 @@ type Foo = Foo Boolean
- Deletes:
a.Foo.Foo
a.Foo.Foo#d97#0 a.Foo.Foo#gq9#0
Tip: You can always `undo` if this wasn't what you wanted.
@ -376,7 +376,7 @@ type foo = Foo Nat
- Deletes:
foo
foo#d97 foo#jk1
Tip: You can always `undo` if this wasn't what you wanted.