From ef6b6ecc1baa04fd376bd23fcf53e5a093c41793 Mon Sep 17 00:00:00 2001 From: Dmitry Astapov Date: Fri, 28 Feb 2025 12:18:58 +0000 Subject: [PATCH] ;run: accept commands on stdin, repl hides prompt when non-interactive --- hledger/Hledger/Cli/Commands/Run.hs | 32 +++++++++++++++++++---------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/hledger/Hledger/Cli/Commands/Run.hs b/hledger/Hledger/Cli/Commands/Run.hs index 903961bf3..4276d1118 100644 --- a/hledger/Hledger/Cli/Commands/Run.hs +++ b/hledger/Hledger/Cli/Commands/Run.hs @@ -33,6 +33,7 @@ import Control.Monad.Extra (concatMapM) import System.Console.CmdArgs.Explicit (expandArgsAt) import System.Directory (doesFileExist) +import System.IO (stdin, hIsTerminalDevice) import System.IO.Unsafe (unsafePerformIO) import System.Console.Haskeline @@ -73,12 +74,16 @@ run :: Maybe Journal -> (String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO run defaultJournalOverride findBuiltinCommand cliopts@CliOpts{rawopts_=rawopts} = do withJournalCached defaultJournalOverride cliopts $ \j -> do let args = dbg1 "args" $ listofstringopt "args" rawopts - -- Check if arguments could be interpreted as files. - -- If not, assume that they are commands specified directly on the command line - allAreFiles <- and <$> mapM (doesFileExist . snd . splitReaderPrefix) args - case allAreFiles of - True -> runFromFiles j findBuiltinCommand args - False -> runFromArgs j findBuiltinCommand args + isTerminal <- hIsTerminalDevice stdin + if args == [] && not isTerminal + then runREPL j findBuiltinCommand + else do + -- Check if arguments could be interpreted as files. + -- If not, assume that they are commands specified directly on the command line + allAreFiles <- and <$> mapM (doesFileExist . snd . splitReaderPrefix) args + case allAreFiles of + True -> runFromFiles j findBuiltinCommand args + False -> runFromArgs j findBuiltinCommand args -- | The actual repl command. repl :: (String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())) -> CliOpts -> IO () @@ -135,12 +140,16 @@ runCommand defaultJrnl findBuiltinCommand cmdline = do -- | Run an interactive REPL. runREPL :: Journal -> (String -> Maybe (Mode RawOpts, CliOpts -> Journal -> IO ())) -> IO () runREPL defaultJrnl findBuiltinCommand = do - putStrLn "Enter hledger commands. To exit, enter 'quit' or 'exit', or send EOF." - runInputT defaultSettings loop + isTerminal <- hIsTerminalDevice stdin + if not isTerminal + then runInputT defaultSettings (loop "") + else do + putStrLn "Enter hledger commands. To exit, enter 'quit' or 'exit', or send EOF." + runInputT defaultSettings (loop "% ") where - loop :: InputT IO () - loop = do - minput <- getInputLine "% " + loop :: String -> InputT IO () + loop prompt = do + minput <- getInputLine prompt case minput of Nothing -> return () Just "quit" -> return () @@ -148,6 +157,7 @@ runREPL defaultJrnl findBuiltinCommand = do Just input -> do liftIO $ (runCommand defaultJrnl findBuiltinCommand $ parseCommand input) `catch` (\(e::ErrorCall) -> putStr $ show e) + loop prompt -- | Cache of all journals that have been read by commands given to "run", -- keyed by the fully-expanded filename.