Shellac-editline-0.9: src/System/Console/Shell/Backend/Editline.hs
{-
-
- Copyright 2005-2008, Robert Dockins.
-
-}
{- | This module implements a Shellac backend based on the editline library.
Both the code for this binding and the editline library itself are
licenced under BSD-style licences.
-}
module System.Console.Shell.Backend.Editline
( editlineBackend
) where
import System.IO ( stdin, stdout, stderr, hFlush, hPutStr, hPutStrLn, hGetChar
, hSetBuffering, hGetBuffering
, BufferMode(..)
)
import qualified Control.Exception as Ex
import System.Console.Editline
import qualified System.Console.Editline.Readline as EL
import System.Console.Shell.Backend
editlineBackend :: ShellBackend ()
editlineBackend = ShBackend
{ initBackend = return ()
, shutdownBackend = \_ -> return ()
, outputString = \_ -> editlineOutput
, flushOutput = \_ -> hFlush stdout
, getInput = \_ -> EL.readline
, getSingleChar = \_ -> editlineGetSingleChar
, addHistory = \_ -> EL.addHistory
, getWordBreakChars = \_ -> EL.getBasicWordBreakCharacters
, setWordBreakChars = \_ -> EL.setBasicWordBreakCharacters
, onCancel = \_ -> hPutStrLn stdout "canceled..."
, setAttemptedCompletionFunction = \_ -> editlineCompletionFunction
, setDefaultCompletionFunction = \_ -> EL.setCompletionEntryFunction
, completeFilename = \_ -> EL.filenameCompletionFunction
, completeUsername = \_ -> EL.usernameCompletionFunction
, clearHistoryState = \_ -> EL.clearHistory
, setMaxHistoryEntries = \_ -> EL.stifleHistory
, getMaxHistoryEntries = \_ -> EL.historyMaxEntries
, readHistory = \_ -> EL.readHistory
, writeHistory = \_ -> EL.writeHistory
}
editlineCompletionFunction :: CompletionFunction -> IO ()
editlineCompletionFunction f = EL.setAttemptedCompletionFunction (Just complete)
where complete word begin end = do
buffer <- EL.getLineBuffer
let before = take begin buffer
let after = drop end buffer
f (before,word,after)
editlineGetSingleChar :: String -> IO (Maybe Char)
editlineGetSingleChar prompt = do
hPutStr stdout prompt
hFlush stdout
Ex.bracket (hGetBuffering stdin) (hSetBuffering stdin) $ \_ -> do
hSetBuffering stdin NoBuffering
c <- hGetChar stdin
hPutStrLn stdout ""
return (Just c)
editlineOutput :: BackendOutput -> IO ()
editlineOutput (RegularOutput str) = hPutStr stdout str
editlineOutput (InfoOutput str) = hPutStr stdout str
editlineOutput (ErrorOutput str) = hPutStr stderr str