packages feed

tilia-0.1.4.0: src/Tilia/Editor.hs

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}

-- | Definitions to support editor integrations.
module Tilia.Editor
  ( editorSession,
    Compiled (..),
    compiledSession,
    formatBuffer,
  )
where

import Data.Choice (Choice)
import Data.Either (fromRight)
import Data.Text (Text)
import Tilia.Cabal.Project (ProjectRoot (..), findProjectRoot)
import Tilia.Cabal.Target
  ( Target (Everything),
    componentsOfTarget,
  )
import Tilia.Format
  ( Compiled (..),
    FormatError (NoProject),
    Session,
    compiledSession,
    newSession,
    planSourceFor,
    sessionRoot,
  )
import Tilia.Ignore (isIgnoredInProject)
import Tilia.Run (Outcome (Unchanged), outcomeOf)

-- | Create a 'Session' for the project a file belongs to, with a plan that
-- covers every component of it.
editorSession ::
  -- | The file.
  FilePath ->
  -- | A build plan to trust as up to date rather than have Cabal solve one.
  Maybe FilePath ->
  -- | Whether to read from and write to the cache.
  Choice "useCache" ->
  -- | Whether to download sources that are missing.
  Choice "download" ->
  -- | Check AST equivalence.
  Choice "checkAst" ->
  -- | Check idempotence.
  Choice "checkIdempotence" ->
  -- | Record how fixities were settled, to be read with
  -- 'Tilia.Format.fixityNotesOf'.
  Choice "debugFixity" ->
  IO (Either FormatError Session)
editorSession
  file
  givenPlan
  caching
  downloading
  checkAst
  checkIdempotence
  debugFixity =
    findProjectRoot file >>= \case
      Nothing -> pure (Left (NoProject file))
      Just root -> do
        planSource <-
          planSourceFor givenPlan (fromRight [] <$> componentsOfTarget root Everything)
        newSession
          root
          planSource
          caching
          downloading
          checkAst
          checkIdempotence
          debugFixity

-- | Format given text on the assumption it comes from the specified
-- 'FilePath'.
formatBuffer ::
  -- | The session.
  Session ->
  -- | The file.
  FilePath ->
  -- | The text to format.
  Text ->
  IO Outcome
formatBuffer session file before =
  isIgnoredInProject (prPath (sessionRoot session)) file >>= \case
    True -> pure Unchanged
    False -> outcomeOf session file before