Skip to content
This repository has been archived by the owner on Jul 19, 2022. It is now read-only.

Commit

Permalink
Pin open definitions to hash on perspective change
Browse files Browse the repository at this point in the history
When there's any number of definitions open and a new perspective is
selected, the definitions that were open with references based on names,
will no longer have a resolvable name if they were to be re-queried (on
a page refresh for instance). Fix this by changing all open definitions
to be referenced by hash when the perspective is changed.
  • Loading branch information
hojberg committed Nov 23, 2021
1 parent c244cab commit bb76e99
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/App.elm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import UI.Tooltip as Tooltip
import UnisonShare.SidebarContent
import Url exposing (Url)
import Workspace
import Workspace.WorkspaceItems as WorkspaceItems



Expand Down Expand Up @@ -291,16 +292,29 @@ 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.focusReference
|> 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
|> fetchNamespaceDetails
|> 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
Expand Down
16 changes: 16 additions & 0 deletions src/Definition/Reference.elm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
1 change: 1 addition & 0 deletions src/Route.elm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Route exposing
, navigateToPerspective
, perspectiveParams
, replacePerspective
, toDefinition
, toRoute
, toUrlString
, updatePerspectiveParams
Expand Down
10 changes: 10 additions & 0 deletions src/Workspace.elm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Workspace exposing
, OutMsg(..)
, init
, open
, replaceWorkspaceItemReferencesWithHashOnly
, subscriptions
, update
, view
Expand Down Expand Up @@ -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
Expand Down
41 changes: 41 additions & 0 deletions src/Workspace/WorkspaceItem.elm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
-}
Expand Down Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions src/Workspace/WorkspaceItems.elm
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,13 @@ focus items =
Just data.focus


focusReference : WorkspaceItems -> Maybe Reference
focusReference items =
items
|> focus
|> Maybe.map WorkspaceItem.reference


focusOn : WorkspaceItems -> Reference -> WorkspaceItems
focusOn items ref =
let
Expand Down

0 comments on commit bb76e99

Please sign in to comment.