-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Ungarble output from several threads or commands
--   
--   Lets multiple threads and external processes concurrently output to
--   the console, without it getting all garbled up.
--   
--   Built on top of that is a way of defining multiple output regions,
--   which are automatically laid out on the screen and can be individually
--   updated by concurrent threads. Can be used for progress displays etc.
--   
@package concurrent-output
@version 1.7.4


-- | Concurrent output handling, internals.
--   
--   May change at any time.
module System.Console.Concurrent.Internal
data OutputHandle
OutputHandle :: TMVar Lock -> TMVar OutputBuffer -> TMVar OutputBuffer -> TMVar Integer -> TMVar [Async ()] -> TMVar () -> OutputHandle
[outputLock] :: OutputHandle -> TMVar Lock
[outputBuffer] :: OutputHandle -> TMVar OutputBuffer
[errorBuffer] :: OutputHandle -> TMVar OutputBuffer
[outputThreads] :: OutputHandle -> TMVar Integer
[processWaiters] :: OutputHandle -> TMVar [Async ()]
[waitForProcessLock] :: OutputHandle -> TMVar ()
data Lock
Locked :: Lock

-- | A shared global variable for the OutputHandle.
globalOutputHandle :: OutputHandle

-- | Holds a lock while performing an action. This allows the action to
--   perform its own output to the console, without using functions from
--   this module.
--   
--   While this is running, other threads that try to lockOutput will
--   block. Any calls to <a>outputConcurrent</a> and
--   <a>createProcessConcurrent</a> will not block, but the output will be
--   buffered and displayed only once the action is done.
lockOutput :: (MonadIO m, MonadMask m) => m a -> m a

-- | Blocks until we have the output lock.
takeOutputLock :: IO ()

-- | Tries to take the output lock, without blocking.
tryTakeOutputLock :: IO Bool
withLock :: (TMVar Lock -> STM a) -> IO a
takeOutputLock' :: Bool -> IO Bool

-- | Only safe to call after taking the output lock.
dropOutputLock :: IO ()

-- | Use this around any actions that use <a>outputConcurrent</a> or
--   <a>createProcessConcurrent</a>
--   
--   This is necessary to ensure that buffered concurrent output actually
--   gets displayed before the program exits.
withConcurrentOutput :: (MonadIO m, MonadMask m) => m a -> m a

-- | Blocks until any processes started by <a>createProcessConcurrent</a>
--   have finished, and any buffered output is displayed. Also blocks while
--   <a>lockOutput</a> is is use.
--   
--   <a>withConcurrentOutput</a> calls this at the end, so you do not
--   normally need to use this.
flushConcurrentOutput :: IO ()

-- | Values that can be output.
class Outputable v
toOutput :: Outputable v => v -> Text

-- | Displays a value to stdout.
--   
--   No newline is appended to the value, so if you want a newline, be sure
--   to include it yourself.
--   
--   Uses locking to ensure that the whole output occurs atomically even
--   when other threads are concurrently generating output.
--   
--   When something else is writing to the console at the same time, this
--   does not block. It buffers the value, so it will be displayed once the
--   other writer is done.
outputConcurrent :: Outputable v => v -> IO ()

-- | Like <a>outputConcurrent</a>, but displays to stderr.
--   
--   (Does not throw an exception.)
errorConcurrent :: Outputable v => v -> IO ()
outputConcurrent' :: Outputable v => StdHandle -> v -> IO ()
newtype ConcurrentProcessHandle
ConcurrentProcessHandle :: ProcessHandle -> ConcurrentProcessHandle
toConcurrentProcessHandle :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)

-- | Use this to wait for processes started with
--   <a>createProcessConcurrent</a> and <a>createProcessForeground</a>, and
--   get their exit status.
--   
--   Note that such processes are actually automatically waited for
--   internally, so not calling this explicitly will not result in zombie
--   processes. This behavior differs from <a>waitForProcess</a>
waitForProcessConcurrent :: ConcurrentProcessHandle -> IO ExitCode
asyncProcessWaiter :: IO () -> IO ()

-- | Wrapper around <a>createProcess</a> that prevents multiple processes
--   that are running concurrently from writing to stdout/stderr at the
--   same time.
--   
--   If the process does not output to stdout or stderr, it's run by
--   createProcess entirely as usual. Only processes that can generate
--   output are handled specially:
--   
--   A process is allowed to write to stdout and stderr in the usual way,
--   assuming it can successfully take the output lock.
--   
--   When the output lock is held (ie, by another concurrent process, or
--   because <a>outputConcurrent</a> is being called at the same time), the
--   process is instead run with its stdout and stderr redirected to a
--   buffer. The buffered output will be displayed as soon as the output
--   lock becomes free.
--   
--   Currently only available on Unix systems, not Windows.
createProcessConcurrent :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)

-- | Wrapper around <a>createProcess</a> that makes sure a process is run
--   in the foreground, with direct access to stdout and stderr. Useful
--   when eg, running an interactive process.
createProcessForeground :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)
fgProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)
bgProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)
willOutput :: StdStream -> Bool

-- | Buffered output.
data OutputBuffer
OutputBuffer :: [OutputBufferedActivity] -> OutputBuffer
data StdHandle
StdOut :: StdHandle
StdErr :: StdHandle
toHandle :: StdHandle -> Handle
bufferFor :: StdHandle -> TMVar OutputBuffer
data OutputBufferedActivity
Output :: Text -> OutputBufferedActivity
InTempFile :: FilePath -> Bool -> OutputBufferedActivity
[tempFile] :: OutputBufferedActivity -> FilePath
[endsInNewLine] :: OutputBufferedActivity -> Bool
data AtEnd
AtEnd :: AtEnd
data BufSig
BufSig :: BufSig
setupOutputBuffer :: StdHandle -> Handle -> StdStream -> Handle -> IO (StdHandle, MVar OutputBuffer, TMVar BufSig, TMVar AtEnd)
outputDrainer :: StdStream -> Handle -> MVar OutputBuffer -> TMVar BufSig -> TMVar AtEnd -> IO ()
registerOutputThread :: IO ()
unregisterOutputThread :: IO ()
bufferWriter :: [(StdHandle, MVar OutputBuffer, TMVar BufSig, TMVar AtEnd)] -> IO ()
addOutputBuffer :: OutputBufferedActivity -> OutputBuffer -> IO OutputBuffer

-- | Adds a value to the output buffer for later display.
--   
--   Note that buffering large quantities of data this way will keep it
--   resident in memory until it can be displayed. While
--   <a>outputConcurrent</a> uses temp files if the buffer gets too big,
--   this STM function cannot do so.
bufferOutputSTM :: Outputable v => StdHandle -> v -> STM ()
bufferOutputSTM' :: StdHandle -> OutputBuffer -> STM ()

-- | A STM action that waits for some buffered output to become available,
--   and returns it.
--   
--   The function can select a subset of output when only some is desired;
--   the fst part is returned and the snd is left in the buffer.
--   
--   This will prevent it from being displayed in the usual way, so you'll
--   need to use <a>emitOutputBuffer</a> to display it yourself.
outputBufferWaiterSTM :: (OutputBuffer -> (OutputBuffer, OutputBuffer)) -> STM (StdHandle, OutputBuffer)
waitAnyBuffer :: OutputBuffer -> (OutputBuffer, OutputBuffer)

-- | Use with <a>outputBufferWaiterSTM</a> to make it only return buffered
--   output that ends with a newline. Anything buffered without a newline
--   is left in the buffer.
waitCompleteLines :: OutputBuffer -> (OutputBuffer, OutputBuffer)
endsNewLine :: Text -> Bool

-- | Emits the content of the OutputBuffer to the Handle
--   
--   If you use this, you should use <a>lockOutput</a> to ensure you're the
--   only thread writing to the console.
emitOutputBuffer :: StdHandle -> OutputBuffer -> IO ()
instance GHC.Classes.Eq System.Console.Concurrent.Internal.AtEnd
instance GHC.Classes.Eq System.Console.Concurrent.Internal.OutputBuffer
instance GHC.Classes.Eq System.Console.Concurrent.Internal.OutputBufferedActivity
instance System.Console.Concurrent.Internal.Outputable Data.Text.Internal.Text
instance System.Console.Concurrent.Internal.Outputable GHC.Base.String


-- | Concurrent output handling.
--   
--   <pre>
--   import Control.Concurrent.Async
--   import System.Console.Concurrent
--   
--   main = withConcurrentOutput $
--   	outputConcurrent "washed the car\n"
--   		`concurrently`
--   outputConcurrent "walked the dog\n"
--   	`concurrently`
--   	createProcessConcurrent (proc "ls" [])
--   </pre>
module System.Console.Concurrent

-- | Use this around any actions that use <a>outputConcurrent</a> or
--   <a>createProcessConcurrent</a>
--   
--   This is necessary to ensure that buffered concurrent output actually
--   gets displayed before the program exits.
withConcurrentOutput :: (MonadIO m, MonadMask m) => m a -> m a

-- | Values that can be output.
class Outputable v
toOutput :: Outputable v => v -> Text

-- | Displays a value to stdout.
--   
--   No newline is appended to the value, so if you want a newline, be sure
--   to include it yourself.
--   
--   Uses locking to ensure that the whole output occurs atomically even
--   when other threads are concurrently generating output.
--   
--   When something else is writing to the console at the same time, this
--   does not block. It buffers the value, so it will be displayed once the
--   other writer is done.
outputConcurrent :: Outputable v => v -> IO ()

-- | Like <a>outputConcurrent</a>, but displays to stderr.
--   
--   (Does not throw an exception.)
errorConcurrent :: Outputable v => v -> IO ()
data ConcurrentProcessHandle

-- | Wrapper around <a>createProcess</a> that prevents multiple processes
--   that are running concurrently from writing to stdout/stderr at the
--   same time.
--   
--   If the process does not output to stdout or stderr, it's run by
--   createProcess entirely as usual. Only processes that can generate
--   output are handled specially:
--   
--   A process is allowed to write to stdout and stderr in the usual way,
--   assuming it can successfully take the output lock.
--   
--   When the output lock is held (ie, by another concurrent process, or
--   because <a>outputConcurrent</a> is being called at the same time), the
--   process is instead run with its stdout and stderr redirected to a
--   buffer. The buffered output will be displayed as soon as the output
--   lock becomes free.
--   
--   Currently only available on Unix systems, not Windows.
createProcessConcurrent :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)

-- | Use this to wait for processes started with
--   <a>createProcessConcurrent</a> and <a>createProcessForeground</a>, and
--   get their exit status.
--   
--   Note that such processes are actually automatically waited for
--   internally, so not calling this explicitly will not result in zombie
--   processes. This behavior differs from <a>waitForProcess</a>
waitForProcessConcurrent :: ConcurrentProcessHandle -> IO ExitCode

-- | Wrapper around <a>createProcess</a> that makes sure a process is run
--   in the foreground, with direct access to stdout and stderr. Useful
--   when eg, running an interactive process.
createProcessForeground :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ConcurrentProcessHandle)

-- | Blocks until any processes started by <a>createProcessConcurrent</a>
--   have finished, and any buffered output is displayed. Also blocks while
--   <a>lockOutput</a> is is use.
--   
--   <a>withConcurrentOutput</a> calls this at the end, so you do not
--   normally need to use this.
flushConcurrentOutput :: IO ()

-- | Holds a lock while performing an action. This allows the action to
--   perform its own output to the console, without using functions from
--   this module.
--   
--   While this is running, other threads that try to lockOutput will
--   block. Any calls to <a>outputConcurrent</a> and
--   <a>createProcessConcurrent</a> will not block, but the output will be
--   buffered and displayed only once the action is done.
lockOutput :: (MonadIO m, MonadMask m) => m a -> m a

-- | Buffered output.
data OutputBuffer
data StdHandle
StdOut :: StdHandle
StdErr :: StdHandle

-- | Adds a value to the output buffer for later display.
--   
--   Note that buffering large quantities of data this way will keep it
--   resident in memory until it can be displayed. While
--   <a>outputConcurrent</a> uses temp files if the buffer gets too big,
--   this STM function cannot do so.
bufferOutputSTM :: Outputable v => StdHandle -> v -> STM ()

-- | A STM action that waits for some buffered output to become available,
--   and returns it.
--   
--   The function can select a subset of output when only some is desired;
--   the fst part is returned and the snd is left in the buffer.
--   
--   This will prevent it from being displayed in the usual way, so you'll
--   need to use <a>emitOutputBuffer</a> to display it yourself.
outputBufferWaiterSTM :: (OutputBuffer -> (OutputBuffer, OutputBuffer)) -> STM (StdHandle, OutputBuffer)
waitAnyBuffer :: OutputBuffer -> (OutputBuffer, OutputBuffer)

-- | Use with <a>outputBufferWaiterSTM</a> to make it only return buffered
--   output that ends with a newline. Anything buffered without a newline
--   is left in the buffer.
waitCompleteLines :: OutputBuffer -> (OutputBuffer, OutputBuffer)

-- | Emits the content of the OutputBuffer to the Handle
--   
--   If you use this, you should use <a>lockOutput</a> to ensure you're the
--   only thread writing to the console.
emitOutputBuffer :: StdHandle -> OutputBuffer -> IO ()


-- | Console regions are displayed near the bottom of the console, and can
--   be updated concurrently by threads. Any other output displayed using
--   <a>outputConcurrent</a> and <a>createProcessConcurrent</a> will scroll
--   up above the open console regions.
--   
--   For example, this program:
--   
--   <pre>
--   import Control.Concurrent.Async
--   import Control.Concurrent
--   import System.Console.Concurrent
--   import System.Console.Regions
--   import System.Process
--   
--   main = displayConsoleRegions $ do
--   	mapConcurrently download [1..5]
--   	`concurrently` mapM_ message [1..10]
--   	`concurrently` createProcessConcurrent (proc "echo" ["hello world"])
--   
--   message :: Int -&gt; IO ()
--   message n = do
--   	threadDelay 500000
--   	outputConcurrent ("Message " ++ show n ++ "\n")
--   
--   download :: Int -&gt; IO ()
--   download n = withConsoleRegion Linear $ \r -&gt; do
--   	setConsoleRegion r basemsg
--   	go n r
--     where
--   	basemsg = "Download " ++ show n
--   go c r
--   	| c &lt; 1 = finishConsoleRegion r (basemsg ++ " done!")
--   		| otherwise = do
--   			threadDelay 1000000
--   			appendConsoleRegion r " ... "
--   			go (c-1) r
--   </pre>
--   
--   Will display like this:
--   
--   <pre>
--   Message 1
--   hello world
--   Message 2
--   Download 1 ...
--   Download 2 ...
--   Download 3 ...
--   </pre>
--   
--   Once the 1st download has finished, and another message has displayed,
--   the console will update like this:
--   
--   <pre>
--   Message 1
--   hello world
--   Message 2
--   Download 1 done!
--   Message 3
--   Download 2 ... ...
--   Download 3 ... ...
--   </pre>
module System.Console.Regions

-- | A handle allowing access to a region of the console.
data ConsoleRegion

-- | Controls how a region is laid out in the console.
--   
--   Here's an annotated example of how the console layout works.
--   
--   <pre>
--   scrolling......
--   scrolling......
--   scrolling......
--   aaaaaa......... -- Linear
--   bbbbbbbbbbbbbbb -- Linear
--   bbb............       (expanded to multiple lines)
--   ccccccccc...... -- Linear
--   ddddeeeefffffff -- [InLine]
--   fffffggggg.....       (expanded to multiple lines)
--   </pre>
data RegionLayout
Linear :: RegionLayout
InLine :: ConsoleRegion -> RegionLayout

-- | Values that can be displayed in a region.
class ToRegionContent v
toRegionContent :: ToRegionContent v => v -> RegionContent
newtype RegionContent
RegionContent :: (STM Text) -> RegionContent

-- | Many actions in this module can be run in either the IO monad or the
--   STM monad. Using STM allows making several changes to the displayed
--   regions atomically, with the display updated a single time.
class LiftRegion m
liftRegion :: LiftRegion m => STM a -> m a

-- | Handles all display for the other functions in this module.
--   
--   Note that this uses <a>lockOutput</a>, so it takes over all output to
--   the console while the passed IO action is running. As well as
--   displaying the console regions, this handles display of anything
--   buffered by <a>outputConcurrent</a> and
--   <a>createProcessConcurrent</a>.
--   
--   When standard output is not an ANSI capable terminal, console regions
--   are not displayed.
displayConsoleRegions :: (MonadIO m, MonadMask m) => m a -> m a

-- | Runs the action with a new console region, closing the region when the
--   action finishes or on exception.
withConsoleRegion :: (LiftRegion m, MonadIO m, MonadMask m) => RegionLayout -> (ConsoleRegion -> m a) -> m a

-- | Opens a new console region.
openConsoleRegion :: LiftRegion m => RegionLayout -> m ConsoleRegion

-- | Makes a new region, but does not add it to the display.
newConsoleRegion :: (LiftRegion m) => ToRegionContent v => RegionLayout -> v -> m ConsoleRegion

-- | Closes a console region. Once closed, the region is removed from the
--   display.
closeConsoleRegion :: LiftRegion m => ConsoleRegion -> m ()

-- | Sets the value of a console region. This will cause the console to be
--   updated to display the new value.
--   
--   It's fine for the value to be longer than the terminal is wide, or to
--   include newlines ('\n'). Regions expand to multiple lines as
--   necessary.
--   
--   The value can include ANSI SGR escape sequences for changing the
--   colors etc of all or part of a region.
--   
--   Other ANSI escape sequences, especially those doing cursor movement,
--   will mess up the layouts of regions. Caveat emptor.
setConsoleRegion :: (ToRegionContent v, LiftRegion m) => ConsoleRegion -> v -> m ()

-- | Appends a value to the current value of a console region.
--   
--   <pre>
--   appendConsoleRegion progress "." -- add another dot to progress display
--   </pre>
appendConsoleRegion :: (Outputable v, LiftRegion m) => ConsoleRegion -> v -> m ()

-- | Closes the console region, and displays the passed value in the
--   scrolling area above the active console regions. When Nothing is
--   passed, displays the current value of the console region.
finishConsoleRegion :: (Outputable v, LiftRegion m) => ConsoleRegion -> v -> m ()

-- | Gets the current content of a console region.
getConsoleRegion :: LiftRegion m => ConsoleRegion -> m Text

-- | Changes how a console region displays.
--   
--   Each time the region's value changes, the STM action is provided with
--   the current value of the region, and returns the value to display.
--   
--   For example, this will prevent a region from ever displaying more than
--   10 characters wide, and will make it display text reversed:
--   
--   <pre>
--   tuneDisplay myregion $ pure . T.take 10
--   tuneDisplay myregion $ pure . T.reverse
--   </pre>
--   
--   Note that repeated calls to tuneDisplay are cumulative.
--   
--   Normally, the STM action should avoid retrying, as that would block
--   all display updates.
tuneDisplay :: LiftRegion m => ConsoleRegion -> (Text -> STM Text) -> m ()

-- | Gets the width of the console.
--   
--   On Unix, this is automatically updated when the terminal is resized.
--   On Windows, it is only initialized on program start.
consoleWidth :: STM Int

-- | Get the height of the console.
consoleHeight :: STM Int

-- | All the regions that are currently displayed on the screen.
--   
--   The list is ordered from the bottom of the screen up. Reordering it
--   will change the order in which regions are displayed. It's also fine
--   to remove, duplicate, or add new regions to the list.
regionList :: TMVar [ConsoleRegion]
instance GHC.Show.Show System.Console.Regions.LineUpdate
instance GHC.Classes.Eq System.Console.Regions.LineUpdate
instance GHC.Classes.Eq System.Console.Regions.RegionLayout
instance GHC.Classes.Eq System.Console.Regions.ConsoleRegion
instance System.Console.Regions.LiftRegion GHC.Conc.Sync.STM
instance System.Console.Regions.LiftRegion GHC.Types.IO
instance System.Console.Regions.ToRegionContent GHC.Base.String
instance System.Console.Regions.ToRegionContent Data.Text.Internal.Text
instance System.Console.Regions.ToRegionContent (GHC.Conc.Sync.STM Data.Text.Internal.Text)


-- | The functions exported by this module are intended to be drop-in
--   replacements for those from System.Process, when converting a whole
--   program to use System.Console.Concurrent.
--   
--   Not currently available on Windows.
module System.Process.Concurrent

-- | Calls <a>createProcessConcurrent</a>
--   
--   You should use the waitForProcess in this module on the resulting
--   ProcessHandle. Using System.Process.waitForProcess instead can have
--   mildly unexpected results.
--   
--   Not available on Windows.
createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

-- | Calls <a>waitForProcessConcurrent</a>
--   
--   You should only use this on a ProcessHandle obtained by calling
--   createProcess from this module. Using this with a ProcessHandle
--   obtained from System.Process.createProcess etc will have extremely
--   unexpected results; it can wait a very long time before returning.
waitForProcess :: ProcessHandle -> IO ExitCode
