module Unison.Codebase.Editor.HandleInput.Rename (handleRename) where

import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.MonadUtils qualified as Cli
import Unison.Codebase.Editor.HandleInput.MoveBranch (moveBranchFunc)
import Unison.Codebase.Editor.HandleInput.MoveTerm (moveTermSteps)
import Unison.Codebase.Editor.HandleInput.MoveType (moveTypeSteps)
import Unison.Codebase.Editor.Output qualified as Output
import Unison.Codebase.Path qualified as Path
import Unison.HashQualifiedPrime qualified as HQ'
import Unison.NameSegment (NameSegment)
import Unison.Prelude

-- | Rename changes only the final segment of a name.
-- For example, `rename foo.bar.baz Qux` produces `foo.bar.Qux`.
handleRename :: Path.Path' -> NameSegment -> Text -> Cli ()
handleRename :: Path' -> NameSegment -> Text -> Cli ()
handleRename Path'
src' NameSegment
newNameSeg Text
description = do
  -- The destination path has the same parent as the source, but with the new name segment
  case Path' -> Maybe (Split Path')
forall path. Pathy path => path -> Maybe (Split path)
Path.split Path'
src' of
    Maybe (Split Path')
Nothing -> Output -> Cli ()
Cli.respond (Path' -> Output
Output.MoveNothingFound Path'
src')
    Just (Path'
parentPath, NameSegment
_oldNameSeg) -> do
      let dest' :: Path'
dest' = Split Path' -> Path'
forall path. Pathy path => Split path -> path
Path.unsplit (Path'
parentPath, NameSegment
newNameSeg)
      -- Use the same logic as MoveAll, but construct the destination from the source parent + new segment
      Maybe (Absolute, Branch IO -> Branch IO)
moveBranchFunc <- Bool
-> Path' -> Path' -> Cli (Maybe (Absolute, Branch IO -> Branch IO))
moveBranchFunc Bool
False Path'
src' Path'
dest'
      [(Absolute, Branch0 IO -> Branch0 IO)]
moveTermTypeSteps <- case (,) (Split Path' -> Split Path' -> (Split Path', Split Path'))
-> Maybe (Split Path')
-> Maybe (Split Path' -> (Split Path', Split Path'))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Path' -> Maybe (Split Path')
forall path. Pathy path => path -> Maybe (Split path)
Path.split Path'
src' Maybe (Split Path' -> (Split Path', Split Path'))
-> Maybe (Split Path') -> Maybe (Split Path', Split Path')
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Path' -> Maybe (Split Path')
forall path. Pathy path => path -> Maybe (Split path)
Path.split Path'
dest' of
        Maybe (Split Path', Split Path')
Nothing -> [(Absolute, Branch0 IO -> Branch0 IO)]
-> Cli [(Absolute, Branch0 IO -> Branch0 IO)]
forall a. a -> Cli a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
        Just (Split Path' -> HashQualified (Split Path')
forall n. n -> HashQualified n
HQ'.NameOnly -> HashQualified (Split Path')
src, Split Path'
dest) -> do
          [(Absolute, Branch0 IO -> Branch0 IO)]
termSteps <- HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 IO -> Branch0 IO)]
forall (m :: * -> *).
HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 m -> Branch0 m)]
moveTermSteps HashQualified (Split Path')
src Split Path'
dest
          [(Absolute, Branch0 IO -> Branch0 IO)]
typeSteps <- HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 IO -> Branch0 IO)]
forall (m :: * -> *).
HashQualified (Split Path')
-> Split Path' -> Cli [(Absolute, Branch0 m -> Branch0 m)]
moveTypeSteps HashQualified (Split Path')
src Split Path'
dest
          [(Absolute, Branch0 IO -> Branch0 IO)]
-> Cli [(Absolute, Branch0 IO -> Branch0 IO)]
forall a. a -> Cli a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(Absolute, Branch0 IO -> Branch0 IO)]
termSteps [(Absolute, Branch0 IO -> Branch0 IO)]
-> [(Absolute, Branch0 IO -> Branch0 IO)]
-> [(Absolute, Branch0 IO -> Branch0 IO)]
forall a. [a] -> [a] -> [a]
++ [(Absolute, Branch0 IO -> Branch0 IO)]
typeSteps)
      case (Maybe (Absolute, Branch IO -> Branch IO)
moveBranchFunc, [(Absolute, Branch0 IO -> Branch0 IO)]
moveTermTypeSteps) of
        (Maybe (Absolute, Branch IO -> Branch IO)
Nothing, []) -> Output -> Cli ()
Cli.respond (Path' -> Output
Output.MoveNothingFound Path'
src')
        (Maybe (Absolute, Branch IO -> Branch IO)
mupdates, [(Absolute, Branch0 IO -> Branch0 IO)]
steps) -> do
          ProjectPath
pp <- Cli ProjectPath
Cli.getCurrentProjectPath
          Text
-> ProjectBranch
-> [(Absolute, Branch IO -> Branch IO)]
-> [(Absolute, Branch0 IO -> Branch0 IO)]
-> Cli ()
forall (f :: * -> *) (g :: * -> *).
(Foldable f, Foldable g, Functor g) =>
Text
-> ProjectBranch
-> f (Absolute, Branch IO -> Branch IO)
-> g (Absolute, Branch0 IO -> Branch0 IO)
-> Cli ()
Cli.updateAndStepAt Text
description (ProjectPath
pp ProjectPath
-> Getting ProjectBranch ProjectPath ProjectBranch -> ProjectBranch
forall s a. s -> Getting a s a -> a
^. Getting ProjectBranch ProjectPath ProjectBranch
#branch) (Maybe (Absolute, Branch IO -> Branch IO)
-> [(Absolute, Branch IO -> Branch IO)]
forall a. Maybe a -> [a]
maybeToList Maybe (Absolute, Branch IO -> Branch IO)
mupdates) [(Absolute, Branch0 IO -> Branch0 IO)]
steps
          Output -> Cli ()
Cli.respond (Path' -> Path' -> Output
Output.RenameResult Path'
src' Path'
dest')