packages feed

ribosome-0.9.9.9: lib/Ribosome/Api/Path.hs

-- |API function for file system paths.
module Ribosome.Api.Path where

import Exon (exon)
import Path (Abs, Dir, File, Path, SomeBase (Abs, Rel), parseSomeDir, parseSomeFile, (</>))

import Ribosome.Host.Api.Effect (nvimCommand, vimCallFunction)
import Ribosome.Host.Data.Report (Report)
import Ribosome.Host.Effect.Rpc (Rpc)
import Ribosome.Internal.Path (failInvalidPath)
import Ribosome.Host.Path (pathText)

-- |Get Neovim's current working directory.
nvimCwd ::
  Member Rpc r =>
  Sem r (Path Abs Dir)
nvimCwd =
  vimCallFunction "getcwd" []

-- |Set Neovim's current working directory.
nvimSetCwd ::
  Member Rpc r =>
  Path Abs Dir ->
  Sem r ()
nvimSetCwd dir =
  nvimCommand [exon|cd #{pathText dir}|]

-- |Convert an abstract path to an absolute one, using Neovim's current working directory as the base for relative
-- paths.
nvimRelativePath ::
  Member Rpc r =>
  SomeBase t ->
  Sem r (Path Abs t)
nvimRelativePath = \case
  Abs p ->
    pure p
  Rel p -> do
    cwd <- nvimCwd
    pure (cwd </> p)

-- |Parse a directory path and prepend Neovim's current working directory to it if it's relative.
parseNvimDir ::
  Member Rpc r =>
  Text ->
  Sem r (Maybe (Path Abs Dir))
parseNvimDir "" =
  Just <$> nvimCwd
parseNvimDir p =
  traverse nvimRelativePath (parseSomeDir (toString p))

-- |Parse a file path and prepend Neovim's current working directory to it if it's relative.
parseNvimFile ::
  Member Rpc r =>
  Text ->
  Sem r (Maybe (Path Abs File))
parseNvimFile =
  traverse nvimRelativePath . parseSomeFile . toString

-- |Parse a directory path and prepend Neovim's current working directory to it if it's relative.
--
-- If parsing fails, emit an error 'Report'.
nvimDir ::
  Members [Rpc, Stop Report] r =>
  Text ->
  Sem r (Path Abs Dir)
nvimDir spec =
  failInvalidPath spec =<< parseNvimDir spec

-- |Parse a file path and prepend Neovim's current working directory to it if it's relative.
--
-- If parsing fails, emit an error 'Report'.
nvimFile ::
  Members [Rpc, Stop Report] r =>
  Text ->
  Sem r (Path Abs File)
nvimFile spec =
  failInvalidPath spec =<< parseNvimFile spec