Skip to content

Instantly share code, notes, and snippets.

@danidiaz
Last active Feb 17, 2021
Embed
What would you like to do?
simplistic rlwrap clone in Haskell. To wrap sqlite, invoke it as "hlwrap sqlite3 -interactive" or "hlwrap hist_file -- sqlite3 -interactive".
cabal-version: 3.0
name: hlwrap
version: 0.1.0.0
executable hlwrap
main-is: Main.hs
build-depends: base >=4.14 && <4.15,
haskeline ^>= 0.8.1.1,
process ^>= 1.6.11.0,
split ^>= 0.2.3.4,
default-language: Haskell2010
-- | Invoke it as
-- > hlwrap sqlite3 -interactive
--
-- or
--
-- > hlwrap some_histfile -- sqlite3 -interactive
module Main where
import Control.Monad.IO.Class (MonadIO (liftIO))
import Data.List.Split
import System.Console.Haskeline
( InputT,
Settings (historyFile),
defaultSettings,
getInputLine,
runInputT,
)
import System.Environment (getArgs)
import System.IO
( BufferMode (NoBuffering),
Handle,
hPutStrLn,
hSetBuffering,
)
import System.Process
( CreateProcess (std_in),
StdStream (CreatePipe),
createProcess,
proc,
terminateProcess,
)
main :: IO ()
main = do
args <- splitOn ["--"] <$> getArgs
let (mhistoryFile, program, programArgs) = case args of
[program : programArgs] -> (Nothing, program, programArgs)
[[], program : programArgs] -> (Nothing, program, programArgs)
[historyFile : [], program : programArgs] -> (Just historyFile, program, programArgs)
spec = (proc program programArgs) {std_in = CreatePipe}
(Just h, Nothing, Nothing, ph) <- createProcess spec
hSetBuffering h NoBuffering
runInputT (defaultSettings {historyFile = mhistoryFile}) $ loop h
terminateProcess ph
loop :: Handle -> InputT IO ()
loop h =
let go = do
minput <- getInputLine ""
case minput of
Nothing -> return ()
Just input -> do
liftIO $ hPutStrLn h input
go
in go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment