diff --git a/src/App.elm b/src/App.elm index 7590a5b..ba053b8 100644 --- a/src/App.elm +++ b/src/App.elm @@ -33,6 +33,7 @@ import UI.Tooltip as Tooltip import UnisonShare.SidebarContent import Url exposing (Url) import Workspace +import Workspace.WorkspaceItems as WorkspaceItems @@ -291,8 +292,21 @@ replacePerspective ({ env } as model) perspective = ( codebaseTree, codebaseTreeCmd ) = CodebaseTree.init newEnv + -- Update all open references to be hash based to ensure that we can + -- refresh the page and fetch them appropriately even if they are + -- outside of the current perspective + workspace = + Workspace.replaceWorkspaceItemReferencesWithHashOnly model.workspace + + -- Re-navigate to the currently open definition by hash + focusedReferenceRoute = + workspace.workspaceItems + |> WorkspaceItems.focusedReference + |> Maybe.map (Route.toDefinition model.route) + |> Maybe.withDefault model.route + changeRouteCmd = - Route.replacePerspective model.navKey (Perspective.toParams perspective) model.route + Route.replacePerspective model.navKey (Perspective.toParams perspective) focusedReferenceRoute fetchNamespaceDetailsCmd = perspective @@ -300,7 +314,7 @@ replacePerspective ({ env } as model) perspective = |> Maybe.map (Api.perform env.apiBasePath) |> Maybe.withDefault Cmd.none in - ( { model | env = newEnv, codebaseTree = codebaseTree } + ( { model | env = newEnv, codebaseTree = codebaseTree, workspace = workspace } , Cmd.batch [ Cmd.map CodebaseTreeMsg codebaseTreeCmd , changeRouteCmd diff --git a/src/Definition/Reference.elm b/src/Definition/Reference.elm index 1bfbc69..f0211cf 100644 --- a/src/Definition/Reference.elm +++ b/src/Definition/Reference.elm @@ -107,3 +107,19 @@ toIcon ref = DataConstructorReference _ -> Icon.dataConstructor + + +map : (HashQualified -> HashQualified) -> Reference -> Reference +map f ref = + case ref of + TermReference hq -> + TermReference (f hq) + + TypeReference hq -> + TypeReference (f hq) + + AbilityConstructorReference hq -> + AbilityConstructorReference (f hq) + + DataConstructorReference hq -> + DataConstructorReference (f hq) diff --git a/src/Route.elm b/src/Route.elm index 9de9db9..131def7 100644 --- a/src/Route.elm +++ b/src/Route.elm @@ -8,6 +8,7 @@ module Route exposing , navigateToPerspective , perspectiveParams , replacePerspective + , toDefinition , toRoute , toUrlString , updatePerspectiveParams diff --git a/src/Workspace.elm b/src/Workspace.elm index ad10d3a..9bacd8c 100644 --- a/src/Workspace.elm +++ b/src/Workspace.elm @@ -4,6 +4,7 @@ module Workspace exposing , OutMsg(..) , init , open + , replaceWorkspaceItemReferencesWithHashOnly , subscriptions , update , view @@ -222,6 +223,15 @@ open env model ref = openItem env model Nothing ref +replaceWorkspaceItemReferencesWithHashOnly : Model -> Model +replaceWorkspaceItemReferencesWithHashOnly model = + let + workspaceItems = + WorkspaceItems.map WorkspaceItem.toHashReference model.workspaceItems + in + { model | workspaceItems = workspaceItems } + + openItem : Env -> WithWorkspaceItems m -> Maybe Reference -> Reference -> ( WithWorkspaceItems m, Cmd Msg, OutMsg ) openItem env ({ workspaceItems } as model) relativeToRef ref = -- We don't want to refetch or replace any already open definitions, but we diff --git a/src/Workspace/WorkspaceItem.elm b/src/Workspace/WorkspaceItem.elm index ac5eee4..eaf3601 100644 --- a/src/Workspace/WorkspaceItem.elm +++ b/src/Workspace/WorkspaceItem.elm @@ -127,6 +127,31 @@ reference item = r +{-| Convert the Reference of a WorkspaceItem to be HashOnly +-} +toHashReference : WorkspaceItem -> WorkspaceItem +toHashReference workspaceItem = + let + toHashOnly hash hq = + case hq of + HQ.NameOnly _ -> + HQ.HashOnly hash + + HQ.HashOnly h -> + HQ.HashOnly h + + HQ.HashQualified _ h -> + HQ.HashOnly h + in + case workspaceItem of + Success r d -> + Success (Reference.map (toHashOnly (itemHash d.item)) r) d + + -- Can't change references where we don't have hash information + _ -> + workspaceItem + + {-| Builtins and Types can't be expanded, so we can skip the Medium Zoom level entirely TODO: Remove isTypeItem from this conditional when we can collapse types (TypeSummary) -} @@ -229,6 +254,22 @@ hasDoc item = False +itemHash : Item -> Hash +itemHash item = + case item of + TermItem (Term h _ _) -> + h + + TypeItem (Type h _ _) -> + h + + AbilityConstructorItem (AbilityConstructor h _) -> + h + + DataConstructorItem (DataConstructor h _) -> + h + + -- VIEW diff --git a/src/Workspace/WorkspaceItems.elm b/src/Workspace/WorkspaceItems.elm index e7af58a..e68f61d 100644 --- a/src/Workspace/WorkspaceItems.elm +++ b/src/Workspace/WorkspaceItems.elm @@ -288,6 +288,13 @@ focus items = Just data.focus +focusedReference : WorkspaceItems -> Maybe Reference +focusedReference items = + items + |> focus + |> Maybe.map WorkspaceItem.reference + + focusOn : WorkspaceItems -> Reference -> WorkspaceItems focusOn items ref = let diff --git a/tests/Workspace/WorkspaceItemsTests.elm b/tests/Workspace/WorkspaceItemsTests.elm index df8763c..910e2af 100644 --- a/tests/Workspace/WorkspaceItemsTests.elm +++ b/tests/Workspace/WorkspaceItemsTests.elm @@ -20,7 +20,7 @@ appendWithFocus = WorkspaceItems.appendWithFocus WorkspaceItems.empty term currentFocusedRef = - getFocusedRef result + WorkspaceItems.focusedReference result in describe "WorkspaceItems.appendWithFocus" [ test "Appends the term" <| @@ -39,7 +39,7 @@ prependWithFocus = WorkspaceItems.prependWithFocus WorkspaceItems.empty term currentFocusedRef = - getFocusedRef result + WorkspaceItems.focusedReference result in describe "WorkspaceItems.prependWithFocus" [ test "Prepends the term" <| @@ -73,7 +73,7 @@ insertWithFocusAfter = WorkspaceItems.insertWithFocusAfter workspaceItems afterRef toInsert currentFocusedRef = - getFocusedRef inserted + WorkspaceItems.focusedReference inserted in describe "WorkspaceItems.insertWithFocusAfter" [ test "Inserts after the 'after ref'" <| @@ -125,7 +125,7 @@ insertWithFocusBefore = WorkspaceItems.insertWithFocusBefore workspaceItems beforeRef toInsert currentFocusedRef = - getFocusedRef inserted + WorkspaceItems.focusedReference inserted in describe "WorkspaceItems.insertWithFocusBefore" [ test "Inserts before the 'before ref'" <| @@ -315,7 +315,7 @@ next = result = workspaceItems |> WorkspaceItems.next - |> getFocusedRef + |> WorkspaceItems.focusedReference |> Maybe.map Reference.toString in Expect.equal (Just "term__#c") result @@ -325,7 +325,7 @@ next = result = WorkspaceItems.fromItems before focused [] |> WorkspaceItems.next - |> getFocusedRef + |> WorkspaceItems.focusedReference |> Maybe.map Reference.toString in Expect.equal (Just "term__#focus") result @@ -341,7 +341,7 @@ prev = result = workspaceItems |> WorkspaceItems.prev - |> getFocusedRef + |> WorkspaceItems.focusedReference |> Maybe.map Reference.toString in Expect.equal (Just "term__#b") result @@ -351,13 +351,36 @@ prev = result = WorkspaceItems.fromItems [] focused after |> WorkspaceItems.prev - |> getFocusedRef + |> WorkspaceItems.focusedReference |> Maybe.map Reference.toString in Expect.equal (Just "term__#focus") result ] +focusedReference : Test +focusedReference = + describe "WorkspaceItems.focusedReference" + [ test "return the reference of the focused item when one exists" <| + \_ -> + let + result = + workspaceItems + |> WorkspaceItems.focusedReference + |> Maybe.map Reference.toString + in + Expect.equal (Just "term__#focus") result + , test "returns Nothing when Empty" <| + \_ -> + let + result = + WorkspaceItems.empty + |> WorkspaceItems.focusedReference + in + Expect.equal Nothing result + ] + + -- MOVE @@ -533,8 +556,3 @@ after = workspaceItems : WorkspaceItems workspaceItems = WorkspaceItems.fromItems before focused after - - -getFocusedRef : WorkspaceItems -> Maybe Reference -getFocusedRef = - WorkspaceItems.focus >> Maybe.map reference