UI.hs 146 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NondecreasingIndentation #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}

12
13
14
{-# OPTIONS -fno-cse #-}
-- -fno-cse is needed for GLOBAL_VAR's to behave properly

15
16
17
18
-----------------------------------------------------------------------------
--
-- GHC Interactive User Interface
--
19
-- (c) The GHC Team 2005-2006
20
21
--
-----------------------------------------------------------------------------
22

23
module GHCi.UI (
24
25
26
27
28
29
        interactiveUI,
        GhciSettings(..),
        defaultGhciSettings,
        ghciCommands,
        ghciWelcomeMsg
    ) where
30

31
32
#include "HsVersions.h"

dterei's avatar
dterei committed
33
-- GHCi
34
35
36
37
import qualified GHCi.UI.Monad as GhciMonad ( args, runStmt, runDecls )
import GHCi.UI.Monad hiding ( args, runStmt, runDecls )
import GHCi.UI.Tags
import GHCi.UI.Info
38
import Debugger
39

40
-- The GHC interface
41
import GHCi
42
43
import GHCi.RemoteTypes
import GHCi.BreakArray
dterei's avatar
dterei committed
44
import DynFlags
45
import ErrUtils
46
import GhcMonad ( modifySession )
dterei's avatar
dterei committed
47
48
49
import qualified GHC
import GHC ( LoadHowMuch(..), Target(..),  TargetId(..), InteractiveImport(..),
             TyThing(..), Phase, BreakIndex, Resume, SingleStep, Ghc,
50
             getModuleGraph, handleSourceError )
51
import HsImpExp
52
import HsSyn
53
import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, hsc_IC,
54
                  setInteractivePrintName, hsc_dflags, msObjFilePath )
dterei's avatar
dterei committed
55
import Module
56
import Name
57
58
import Packages ( trusted, getPackageDetails, getInstalledPackageDetails,
                  listVisibleModuleNames, pprFlag )
59
import IfaceSyn ( showToHeader )
dterei's avatar
dterei committed
60
import PprTyThing
61
62
import PrelNames
import RdrName ( RdrName, getGRE_NameQualifier_maybes, getRdrName )
63
import SrcLoc
dterei's avatar
dterei committed
64
65
66
67
import qualified Lexer

import StringBuffer
import Outputable hiding ( printForUser, printForUserPartWay, bold )
68
69

-- Other random utilities
dterei's avatar
dterei committed
70
import BasicTypes hiding ( isTopLevel )
71
import Config
dterei's avatar
dterei committed
72
73
74
import Digraph
import Encoding
import FastString
75
import Linker
dterei's avatar
dterei committed
76
import Maybes ( orElse, expectJust )
dterei's avatar
dterei committed
77
78
import NameSet
import Panic hiding ( showException )
79
import Util
80
import qualified GHC.LanguageExtensions as LangExt
sof's avatar
sof committed
81

dterei's avatar
dterei committed
82
-- Haskell Libraries
83
import System.Console.Haskeline as Haskeline
84

dterei's avatar
dterei committed
85
import Control.Applicative hiding (empty)
86
87
import Control.DeepSeq (deepseq)
import Control.Monad as Monad
88
import Control.Monad.IO.Class
89
import Control.Monad.Trans.Class
90
import Control.Monad.Trans.Except
91

dterei's avatar
dterei committed
92
import Data.Array
Simon Marlow's avatar
Simon Marlow committed
93
import qualified Data.ByteString.Char8 as BS
dterei's avatar
dterei committed
94
import Data.Char
Ian Lynagh's avatar
Ian Lynagh committed
95
import Data.Function
96
import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef )
dterei's avatar
dterei committed
97
98
import Data.List ( find, group, intercalate, intersperse, isPrefixOf, nub,
                   partition, sort, sortBy )
99
import Data.Maybe
100
import qualified Data.Map as M
niksaz's avatar
niksaz committed
101
102
103
import Data.Time.LocalTime ( getZonedTime )
import Data.Time.Format ( formatTime, defaultTimeLocale )
import Data.Version ( showVersion )
dterei's avatar
dterei committed
104

105
import Exception hiding (catch)
106
import Foreign
107
import GHC.Stack hiding (SrcLoc(..))
dterei's avatar
dterei committed
108
109

import System.Directory
110
import System.Environment
dterei's avatar
dterei committed
111
import System.Exit ( exitWith, ExitCode(..) )
dterei's avatar
dterei committed
112
import System.FilePath
niksaz's avatar
niksaz committed
113
import System.Info
ross's avatar
ross committed
114
import System.IO
115
import System.IO.Error
dterei's avatar
dterei committed
116
import System.IO.Unsafe ( unsafePerformIO )
117
import System.Process
Simon Marlow's avatar
Simon Marlow committed
118
import Text.Printf
119
import Text.Read ( readMaybe )
Geraldus's avatar
Geraldus committed
120
import Text.Read.Lex (isSymbolChar)
121

niksaz's avatar
niksaz committed
122
123
import Unsafe.Coerce

dterei's avatar
dterei committed
124
125
126
127
128
129
#ifndef mingw32_HOST_OS
import System.Posix hiding ( getEnv )
#else
import qualified System.Win32
#endif

dterei's avatar
dterei committed
130
131
import GHC.IO.Exception ( IOErrorType(InvalidArgument) )
import GHC.IO.Handle ( hFlushAll )
dterei's avatar
dterei committed
132
import GHC.TopHandler ( topHandler )
133

134
135
-----------------------------------------------------------------------------

136
137
138
data GhciSettings = GhciSettings {
        availableCommands :: [Command],
        shortHelpText     :: String,
139
        fullHelpText      :: String,
niksaz's avatar
niksaz committed
140
141
        defPrompt         :: PromptFunction,
        defPromptCont     :: PromptFunction
142
143
144
145
146
147
148
    }

defaultGhciSettings :: GhciSettings
defaultGhciSettings =
    GhciSettings {
        availableCommands = ghciCommands,
        shortHelpText     = defShortHelpText,
149
        defPrompt         = default_prompt,
niksaz's avatar
niksaz committed
150
        defPromptCont     = default_prompt_cont,
151
        fullHelpText      = defFullHelpText
152
153
    }

154
155
156
ghciWelcomeMsg :: String
ghciWelcomeMsg = "GHCi, version " ++ cProjectVersion ++
                 ": http://www.haskell.org/ghc/  :? for help"
157

158
ghciCommands :: [Command]
159
ghciCommands = map mkCmd [
160
161
162
163
164
165
166
167
168
169
170
171
  -- Hugs users are accustomed to :e, so make sure it doesn't overlap
  ("?",         keepGoing help,                 noCompletion),
  ("add",       keepGoingPaths addModule,       completeFilename),
  ("abandon",   keepGoing abandonCmd,           noCompletion),
  ("break",     keepGoing breakCmd,             completeIdentifier),
  ("back",      keepGoing backCmd,              noCompletion),
  ("browse",    keepGoing' (browseCmd False),   completeModule),
  ("browse!",   keepGoing' (browseCmd True),    completeModule),
  ("cd",        keepGoing' changeDirectory,     completeFilename),
  ("check",     keepGoing' checkModule,         completeHomeModule),
  ("continue",  keepGoing continueCmd,          noCompletion),
  ("cmd",       keepGoing cmdCmd,               completeExpression),
172
173
  ("ctags",     keepGoing createCTagsWithLineNumbersCmd, completeFilename),
  ("ctags!",    keepGoing createCTagsWithRegExesCmd, completeFilename),
174
175
176
  ("def",       keepGoing (defineMacro False),  completeExpression),
  ("def!",      keepGoing (defineMacro True),   completeExpression),
  ("delete",    keepGoing deleteCmd,            noCompletion),
177
  ("edit",      keepGoing' editFile,            completeFilename),
178
179
180
181
182
  ("etags",     keepGoing createETagsFileCmd,   completeFilename),
  ("force",     keepGoing forceCmd,             completeExpression),
  ("forward",   keepGoing forwardCmd,           noCompletion),
  ("help",      keepGoing help,                 noCompletion),
  ("history",   keepGoing historyCmd,           noCompletion),
183
184
  ("info",      keepGoing' (info False),        completeIdentifier),
  ("info!",     keepGoing' (info True),         completeIdentifier),
185
  ("issafe",    keepGoing' isSafeCmd,           completeModule),
186
187
  ("kind",      keepGoing' (kindOfType False),  completeIdentifier),
  ("kind!",     keepGoing' (kindOfType True),   completeIdentifier),
188
189
  ("load",      keepGoingPaths (loadModule_ False), completeHomeModuleOrFile),
  ("load!",     keepGoingPaths (loadModule_ True), completeHomeModuleOrFile),
190
  ("list",      keepGoing' listCmd,             noCompletion),
191
  ("module",    keepGoing moduleCmd,            completeSetModule),
192
193
194
  ("main",      keepGoing runMain,              completeFilename),
  ("print",     keepGoing printCmd,             completeExpression),
  ("quit",      quit,                           noCompletion),
195
196
  ("reload",    keepGoing' (reloadModule False), noCompletion),
  ("reload!",   keepGoing' (reloadModule True), noCompletion),
197
  ("run",       keepGoing runRun,               completeFilename),
vivian's avatar
vivian committed
198
  ("script",    keepGoing' scriptCmd,           completeFilename),
199
  ("set",       keepGoing setCmd,               completeSetOptions),
200
  ("seti",      keepGoing setiCmd,              completeSeti),
201
  ("show",      keepGoing showCmd,              completeShowOptions),
202
  ("showi",     keepGoing showiCmd,             completeShowiOptions),
203
204
205
206
207
208
209
  ("sprint",    keepGoing sprintCmd,            completeExpression),
  ("step",      keepGoing stepCmd,              completeIdentifier),
  ("steplocal", keepGoing stepLocalCmd,         completeIdentifier),
  ("stepmodule",keepGoing stepModuleCmd,        completeIdentifier),
  ("type",      keepGoing' typeOfExpr,          completeExpression),
  ("trace",     keepGoing traceCmd,             completeExpression),
  ("undef",     keepGoing undefineMacro,        completeMacro),
210
211
  ("unset",     keepGoing unsetOptions,         completeSetOptions),
  ("where",     keepGoing whereCmd,             noCompletion)
212
  ] ++ map mkCmdHidden [ -- hidden commands
213
214
215
216
217
  ("all-types", keepGoing' allTypesCmd),
  ("complete",  keepGoing completeCmd),
  ("loc-at",    keepGoing' locAtCmd),
  ("type-at",   keepGoing' typeAtCmd),
  ("uses",      keepGoing' usesCmd)
218
  ]
219
220
221
222
223
224
225
226
227
228
229
230
 where
  mkCmd (n,a,c) = Command { cmdName = n
                          , cmdAction = a
                          , cmdHidden = False
                          , cmdCompletionFunc = c
                          }

  mkCmdHidden (n,a) = Command { cmdName = n
                              , cmdAction = a
                              , cmdHidden = True
                              , cmdCompletionFunc = noCompletion
                              }
231

dterei's avatar
dterei committed
232
-- We initialize readline (in the interactiveUI function) to use
233
234
235
236
-- word_break_chars as the default set of completion word break characters.
-- This can be overridden for a particular command (for example, filename
-- expansion shouldn't consider '/' to be a word break) by setting the third
-- entry in the Command tuple above.
dterei's avatar
dterei committed
237
--
238
239
-- NOTE: in order for us to override the default correctly, any custom entry
-- must be a SUBSET of word_break_chars.
240
word_break_chars :: String
Geraldus's avatar
Geraldus committed
241
242
243
244
245
246
word_break_chars = spaces ++ specials ++ symbols

symbols, specials, spaces :: String
symbols = "!#$%&*+/<=>?@\\^|-~"
specials = "(),;[]`{}"
spaces = " \t\n"
247

248
flagWordBreakChars :: String
249
250
251
flagWordBreakChars = " \t\n"


252
253
254
255
256
keepGoing :: (String -> GHCi ()) -> (String -> InputT GHCi Bool)
keepGoing a str = keepGoing' (lift . a) str

keepGoing' :: Monad m => (String -> m ()) -> String -> m Bool
keepGoing' a str = a str >> return False
257

258
keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi Bool)
Ian Lynagh's avatar
Ian Lynagh committed
259
260
keepGoingPaths a str
 = do case toArgs str of
Ian Lynagh's avatar
Ian Lynagh committed
261
          Left err -> liftIO $ hPutStrLn stderr err
Ian Lynagh's avatar
Ian Lynagh committed
262
263
          Right args -> a args
      return False
sof's avatar
sof committed
264

265
266
defShortHelpText :: String
defShortHelpText = "use :? for help.\n"
267

268
269
defFullHelpText :: String
defFullHelpText =
dterei's avatar
dterei committed
270
271
272
273
274
275
276
277
278
279
  " Commands available from the prompt:\n" ++
  "\n" ++
  "   <statement>                 evaluate/run <statement>\n" ++
  "   :                           repeat last command\n" ++
  "   :{\\n ..lines.. \\n:}\\n       multiline command\n" ++
  "   :add [*]<module> ...        add module(s) to the current target set\n" ++
  "   :browse[!] [[*]<mod>]       display the names defined by module <mod>\n" ++
  "                               (!: more details; *: all top-level names)\n" ++
  "   :cd <dir>                   change directory to <dir>\n" ++
  "   :cmd <expr>                 run the commands returned by <expr>::IO String\n" ++
280
  "   :complete <dom> [<rng>] <s> list completions for partial input string\n" ++
281
  "   :ctags[!] [<file>]          create tags file <file> for Vi (default: \"tags\")\n" ++
dterei's avatar
dterei committed
282
  "                               (!: use regex instead of line number)\n" ++
283
284
  "   :def <cmd> <expr>           define command :<cmd> (later defined command has\n" ++
  "                               precedence, ::<cmd> is always a builtin command)\n" ++
dterei's avatar
dterei committed
285
286
  "   :edit <file>                edit file\n" ++
  "   :edit                       edit last module\n" ++
287
  "   :etags [<file>]             create tags file <file> for Emacs (default: \"TAGS\")\n" ++
dterei's avatar
dterei committed
288
  "   :help, :?                   display this list of commands\n" ++
289
290
  "   :info[!] [<name> ...]       display information about the given names\n" ++
  "                               (!: do not filter instances)\n" ++
dterei's avatar
dterei committed
291
  "   :issafe [<mod>]             display safe haskell information of module <mod>\n" ++
292
293
  "   :kind[!] <type>             show the kind of <type>\n" ++
  "                               (!: also print the normalised type)\n" ++
294
295
  "   :load[!] [*]<module> ...    load module(s) and their dependents\n" ++
  "                               (!: defer type errors)\n" ++
dterei's avatar
dterei committed
296
297
298
  "   :main [<arguments> ...]     run the main function with the given arguments\n" ++
  "   :module [+/-] [*]<mod> ...  set the context for expression evaluation\n" ++
  "   :quit                       exit GHCi\n" ++
299
300
  "   :reload[!]                  reload the current module set\n" ++
  "                               (!: defer type errors)\n" ++
dterei's avatar
dterei committed
301
  "   :run function [<arguments> ...] run the function with the given arguments\n" ++
302
  "   :script <file>              run the script <file>\n" ++
dterei's avatar
dterei committed
303
  "   :type <expr>                show the type of <expr>\n" ++
304
305
  "   :type +d <expr>             show the type of <expr>, defaulting type variables\n" ++
  "   :type +v <expr>             show the type of <expr>, with its specified tyvars\n" ++
dterei's avatar
dterei committed
306
307
308
309
310
311
  "   :undef <cmd>                undefine user-defined command :<cmd>\n" ++
  "   :!<command>                 run the shell command <command>\n" ++
  "\n" ++
  " -- Commands for debugging:\n" ++
  "\n" ++
  "   :abandon                    at a breakpoint, abandon current computation\n" ++
312
  "   :back [<n>]                 go back in the history N steps (after :trace)\n" ++
dterei's avatar
dterei committed
313
314
315
316
317
318
  "   :break [<mod>] <l> [<col>]  set a breakpoint at the specified location\n" ++
  "   :break <name>               set a breakpoint on the specified function\n" ++
  "   :continue                   resume after a breakpoint\n" ++
  "   :delete <number>            delete the specified breakpoint\n" ++
  "   :delete *                   delete all breakpoints\n" ++
  "   :force <expr>               print <expr>, forcing unevaluated parts\n" ++
319
  "   :forward [<n>]              go forward in the history N step s(after :back)\n" ++
dterei's avatar
dterei committed
320
321
  "   :history [<n>]              after :trace, show the execution history\n" ++
  "   :list                       show the source code around current breakpoint\n" ++
322
  "   :list <identifier>          show the source code for <identifier>\n" ++
dterei's avatar
dterei committed
323
  "   :list [<module>] <line>     show the source code around line number <line>\n" ++
Austin Seipp's avatar
Austin Seipp committed
324
325
  "   :print [<name> ...]         show a value without forcing its computation\n" ++
  "   :sprint [<name> ...]        simplified version of :print\n" ++
dterei's avatar
dterei committed
326
327
328
329
330
331
  "   :step                       single-step after stopping at a breakpoint\n"++
  "   :step <expr>                single-step into <expr>\n"++
  "   :steplocal                  single-step within the current top-level binding\n"++
  "   :stepmodule                 single-step restricted to the current module\n"++
  "   :trace                      trace after stopping at a breakpoint\n"++
  "   :trace <expr>               evaluate <expr> with tracing on (see :history)\n"++
dterei's avatar
dterei committed
332

dterei's avatar
dterei committed
333
334
335
336
  "\n" ++
  " -- Commands for changing settings:\n" ++
  "\n" ++
  "   :set <option> ...           set options\n" ++
337
  "   :seti <option> ...          set options for interactive evaluation only\n" ++
dterei's avatar
dterei committed
338
339
340
  "   :set args <arg> ...         set the arguments returned by System.getArgs\n" ++
  "   :set prog <progname>        set the value returned by System.getProgName\n" ++
  "   :set prompt <prompt>        set the prompt used in GHCi\n" ++
niksaz's avatar
niksaz committed
341
342
343
344
  "   :set prompt-cont <prompt>   set the continuation prompt used in GHCi\n" ++
  "   :set prompt-function <expr> set the function to handle the prompt\n" ++
  "   :set prompt-cont-function <expr>" ++
                     "set the function to handle the continuation prompt\n" ++
dterei's avatar
dterei committed
345
346
347
348
349
350
  "   :set editor <cmd>           set the command used for :edit\n" ++
  "   :set stop [<n>] <cmd>       set the command to run when a breakpoint is hit\n" ++
  "   :unset <option> ...         unset options\n" ++
  "\n" ++
  "  Options for ':set' and ':unset':\n" ++
  "\n" ++
dterei's avatar
dterei committed
351
  "    +m            allow multiline commands\n" ++
dterei's avatar
dterei committed
352
353
354
  "    +r            revert top-level expressions after each evaluation\n" ++
  "    +s            print timing/memory stats after each evaluation\n" ++
  "    +t            print type after evaluation\n" ++
355
  "    +c            collect type/location info after loading modules\n" ++
dterei's avatar
dterei committed
356
  "    -<flags>      most GHC command line flags can also be set here\n" ++
357
  "                         (eg. -v2, -XFlexibleInstances, etc.)\n" ++
dterei's avatar
dterei committed
358
359
360
361
362
363
364
365
  "                    for GHCi-specific flags, see User's Guide,\n"++
  "                    Flag reference, Interactive-mode options\n" ++
  "\n" ++
  " -- Commands for displaying information:\n" ++
  "\n" ++
  "   :show bindings              show the current bindings made at the prompt\n" ++
  "   :show breaks                show the active breakpoints\n" ++
  "   :show context               show the breakpoint context\n" ++
366
  "   :show imports               show the current imports\n" ++
367
  "   :show linker                show current linker state\n" ++
dterei's avatar
dterei committed
368
369
  "   :show modules               show the currently loaded modules\n" ++
  "   :show packages              show the currently active package flags\n" ++
370
  "   :show paths                 show the currently active search paths\n" ++
371
  "   :show language              show the currently active language flags\n" ++
dterei's avatar
dterei committed
372
  "   :show <setting>             show value of <setting>, which is one of\n" ++
niksaz's avatar
niksaz committed
373
  "                                  [args, prog, editor, stop]\n" ++
374
  "   :showi language             show language flags for interactive evaluation\n" ++
dterei's avatar
dterei committed
375
  "\n"
376

Simon Marlow's avatar
Simon Marlow committed
377
findEditor :: IO String
Simon Marlow's avatar
Simon Marlow committed
378
findEditor = do
dterei's avatar
dterei committed
379
  getEnv "EDITOR"
380
    `catchIO` \_ -> do
381
#if mingw32_HOST_OS
Ian Lynagh's avatar
Ian Lynagh committed
382
383
        win <- System.Win32.getWindowsDirectory
        return (win </> "notepad.exe")
Simon Marlow's avatar
Simon Marlow committed
384
#else
Ian Lynagh's avatar
Ian Lynagh committed
385
        return ""
Simon Marlow's avatar
Simon Marlow committed
386
387
#endif

niksaz's avatar
niksaz committed
388
default_progname, default_stop :: String
Boris Lykah's avatar
Boris Lykah committed
389
390
391
default_progname = "<interactive>"
default_stop = ""

niksaz's avatar
niksaz committed
392
393
394
395
default_prompt, default_prompt_cont :: PromptFunction
default_prompt = generatePromptFunctionFromString "%s> "
default_prompt_cont = generatePromptFunctionFromString "%s| "

Simon Marlow's avatar
Simon Marlow committed
396
397
398
default_args :: [String]
default_args = []

399
interactiveUI :: GhciSettings -> [(FilePath, Maybe Phase)] -> Maybe [String]
400
              -> Ghc ()
401
interactiveUI config srcs maybe_exprs = do
402
403
404
405
406
407
408
409
   -- HACK! If we happen to get into an infinite loop (eg the user
   -- types 'let x=x in x' at the prompt), then the thread will block
   -- on a blackhole, and become unreachable during GC.  The GC will
   -- detect that it is unreachable and send it the NonTermination
   -- exception.  However, since the thread is unreachable, everything
   -- it refers to might be finalized, including the standard Handles.
   -- This sounds like a bug, but we don't have a good solution right
   -- now.
410
411
412
   _ <- liftIO $ newStablePtr stdin
   _ <- liftIO $ newStablePtr stdout
   _ <- liftIO $ newStablePtr stderr
413

Ian Lynagh's avatar
Ian Lynagh committed
414
    -- Initialise buffering for the *interpreted* I/O system
415
   (nobuffering, flush) <- initInterpBuffering
416

417
   -- The initial set of DynFlags used for interactive evaluation is the same
418
419
   -- as the global DynFlags, plus -XExtendedDefaultRules and
   -- -XNoMonomorphismRestriction.
420
   dflags <- getDynFlags
421
422
   let dflags' = (`xopt_set` LangExt.ExtendedDefaultRules)
               . (`xopt_unset` LangExt.MonomorphismRestriction)
423
424
               $ dflags
   GHC.setInteractiveDynFlags dflags'
425

426
427
428
429
430
   lastErrLocationsRef <- liftIO $ newIORef []
   progDynFlags <- GHC.getProgramDynFlags
   _ <- GHC.setProgramDynFlags $
      progDynFlags { log_action = ghciLogAction lastErrLocationsRef }

431
   when (isNothing maybe_exprs) $ do
Ian Lynagh's avatar
Ian Lynagh committed
432
433
434
        -- Only for GHCi (not runghc and ghc -e):

        -- Turn buffering off for the compiled program's stdout/stderr
435
        turnOffBuffering_ nobuffering
Ian Lynagh's avatar
Ian Lynagh committed
436
        -- Turn buffering off for GHCi's stdout
437
438
        liftIO $ hFlush stdout
        liftIO $ hSetBuffering stdout NoBuffering
Ian Lynagh's avatar
Ian Lynagh committed
439
440
        -- We don't want the cmd line to buffer any input that might be
        -- intended for the program, so unbuffer stdin.
441
442
        liftIO $ hSetBuffering stdin NoBuffering
        liftIO $ hSetBuffering stderr NoBuffering
443
#if defined(mingw32_HOST_OS)
444
445
446
        -- On Unix, stdin will use the locale encoding.  The IO library
        -- doesn't do this on Windows (yet), so for now we use UTF-8,
        -- for consistency with GHC 6.10 and to make the tests work.
447
        liftIO $ hSetEncoding stdin utf8
448
#endif
Ian Lynagh's avatar
Ian Lynagh committed
449

450
   default_editor <- liftIO $ findEditor
451
   eval_wrapper <- mkEvalWrapper default_progname default_args
452
   let prelude_import = simpleImportDecl preludeModuleName
Ian Lynagh's avatar
Ian Lynagh committed
453
   startGHCi (runGHCi srcs maybe_exprs)
454
        GHCiState{ progname           = default_progname,
455
                   args               = default_args,
456
                   evalWrapper        = eval_wrapper,
niksaz's avatar
niksaz committed
457
458
                   prompt             = default_prompt,
                   prompt_cont        = default_prompt_cont,
459
460
461
                   stop               = default_stop,
                   editor             = default_editor,
                   options            = [],
462
463
464
465
                   -- We initialize line number as 0, not 1, because we use
                   -- current line number while reporting errors which is
                   -- incremented after reading a line.
                   line_number        = 0,
466
467
468
469
                   break_ctr          = 0,
                   breaks             = [],
                   tickarrays         = emptyModuleEnv,
                   ghci_commands      = availableCommands config,
Ben Gamari's avatar
Ben Gamari committed
470
                   ghci_macros        = [],
471
472
473
474
                   last_command       = Nothing,
                   cmdqueue           = [],
                   remembered_ctx     = [],
                   transient_ctx      = [],
475
476
                   extra_imports      = [],
                   prelude_imports    = [prelude_import],
477
478
479
                   ghc_e              = isJust maybe_exprs,
                   short_help         = shortHelpText config,
                   long_help          = fullHelpText config,
480
                   lastErrorLocations = lastErrLocationsRef,
481
                   mod_infos          = M.empty,
482
483
                   flushStdHandles    = flush,
                   noBuffering        = nobuffering
mnislaih's avatar
mnislaih committed
484
                 }
485

486
487
   return ()

488
489
490
491
492
493
resetLastErrorLocations :: GHCi ()
resetLastErrorLocations = do
    st <- getGHCiState
    liftIO $ writeIORef (lastErrorLocations st) []

ghciLogAction :: IORef [(FastString, Int)] ->  LogAction
494
495
ghciLogAction lastErrLocations dflags flag severity srcSpan style msg = do
    defaultLogAction dflags flag severity srcSpan style msg
496
497
498
499
500
501
502
    case severity of
        SevError -> case srcSpan of
            RealSrcSpan rsp -> modifyIORef lastErrLocations
                (++ [(srcLocFile (realSrcSpanStart rsp), srcLocLine (realSrcSpanStart rsp))])
            _ -> return ()
        _ -> return ()

503
504
withGhcAppData :: (FilePath -> IO a) -> IO a -> IO a
withGhcAppData right left = do
505
    either_dir <- tryIO (getAppUserDataDirectory "ghc")
506
507
508
509
510
    case either_dir of
        Right dir ->
            do createDirectoryIfMissing False dir `catchIO` \_ -> return ()
               right dir
        _ -> left
511

Ian Lynagh's avatar
Ian Lynagh committed
512
513
runGHCi :: [(FilePath, Maybe Phase)] -> Maybe [String] -> GHCi ()
runGHCi paths maybe_exprs = do
514
  dflags <- getDynFlags
515
  let
516
   ignore_dot_ghci = gopt Opt_IgnoreDotGhci dflags
517

518
519
   current_dir = return (Just ".ghci")

Ian Lynagh's avatar
Ian Lynagh committed
520
   app_user_dir = liftIO $ withGhcAppData
521
522
                    (\dir -> return (Just (dir </> "ghci.conf")))
                    (return Nothing)
523
524

   home_dir = do
525
    either_dir <- liftIO $ tryIO (getEnv "HOME")
526
527
528
529
    case either_dir of
      Right home -> return (Just (home </> ".ghci"))
      _ -> return Nothing

530
531
532
533
   canonicalizePath' :: FilePath -> IO (Maybe FilePath)
   canonicalizePath' fp = liftM Just (canonicalizePath fp)
                `catchIO` \_ -> return Nothing

534
535
   sourceConfigFile :: FilePath -> GHCi ()
   sourceConfigFile file = do
Ian Lynagh's avatar
Ian Lynagh committed
536
     exists <- liftIO $ doesFileExist file
537
     when exists $ do
538
539
540
541
542
543
544
545
546
547
       either_hdl <- liftIO $ tryIO (openFile file ReadMode)
       case either_hdl of
         Left _e   -> return ()
         -- NOTE: this assumes that runInputT won't affect the terminal;
         -- can we assume this will always be the case?
         -- This would be a good place for runFileInputT.
         Right hdl ->
             do runInputTWithPrefs defaultPrefs defaultSettings $
                          runCommands $ fileLoop hdl
                liftIO (hClose hdl `catchIO` \_ -> return ())
548
549
550
551
552
                -- Don't print a message if this is really ghc -e (#11478).
                -- Also, let the user silence the message with -v0
                -- (the default verbosity in GHCi is 1).
                when (isNothing maybe_exprs && verbosity dflags > 0) $
                  liftIO $ putStrLn ("Loaded GHCi configuration from " ++ file)
553

554
555
  --

556
  setGHCContextFromGHCiState
Ian Lynagh's avatar
Ian Lynagh committed
557

558
559
  dot_cfgs <- if ignore_dot_ghci then return [] else do
    dot_files <- catMaybes <$> sequence [ current_dir, app_user_dir, home_dir ]
560
    liftIO $ filterM checkFileAndDirPerms dot_files
561
562
  mdot_cfgs <- liftIO $ mapM canonicalizePath' dot_cfgs

563
564
565
566
  let arg_cfgs = reverse $ ghciScripts dflags
    -- -ghci-script are collected in reverse order
    -- We don't require that a script explicitly added by -ghci-script
    -- is owned by the current user. (#6017)
567
  mapM_ sourceConfigFile $ nub $ (catMaybes mdot_cfgs) ++ arg_cfgs
568
    -- nub, because we don't want to read .ghci twice if the CWD is $HOME.
569

570
  -- Perform a :load for files given on the GHCi command line
571
572
573
  -- When in -e mode, if the load fails then we want to stop
  -- immediately rather than going on to evaluate the expression.
  when (not (null paths)) $ do
Ian Lynagh's avatar
Ian Lynagh committed
574
     ok <- ghciHandle (\e -> do showException e; return Failed) $
575
                -- TODO: this is a hack.
576
577
                runInputTWithPrefs defaultPrefs defaultSettings $
                    loadModule paths
Ian Lynagh's avatar
Ian Lynagh committed
578
     when (isJust maybe_exprs && failed ok) $
Ian Lynagh's avatar
Ian Lynagh committed
579
        liftIO (exitWith (ExitFailure 1))
580

581
582
  installInteractivePrint (interactivePrint dflags) (isJust maybe_exprs)

583
584
  -- if verbosity is greater than 0, or we are connected to a
  -- terminal, display the prompt in the interactive loop.
Ian Lynagh's avatar
Ian Lynagh committed
585
  is_tty <- liftIO (hIsTerminalDevice stdin)
586
587
  let show_prompt = verbosity dflags > 0 || is_tty

588
  -- reset line number
589
  modifyGHCiState $ \st -> st{line_number=0}
590

Ian Lynagh's avatar
Ian Lynagh committed
591
  case maybe_exprs of
Ian Lynagh's avatar
Ian Lynagh committed
592
        Nothing ->
sof's avatar
sof committed
593
          do
Ian Lynagh's avatar
Ian Lynagh committed
594
            -- enter the interactive loop
595
            runGHCiInput $ runCommands $ nextInputLine show_prompt is_tty
Ian Lynagh's avatar
Ian Lynagh committed
596
        Just exprs -> do
Ian Lynagh's avatar
Ian Lynagh committed
597
            -- just evaluate the expression we were given
Ian Lynagh's avatar
Ian Lynagh committed
598
            enqueueCommands exprs
dterei's avatar
dterei committed
599
600
601
602
603
604
605
606
            let hdle e = do st <- getGHCiState
                            -- flush the interpreter's stdout/stderr on exit (#3890)
                            flushInterpBuffers
                            -- Jump through some hoops to get the
                            -- current progname in the exception text:
                            -- <progname>: <exception>
                            liftIO $ withProgName (progname st)
                                   $ topHandler e
607
                                   -- this used to be topHandlerFastExit, see #2228
608
            runInputTWithPrefs defaultPrefs defaultSettings $ do
609
                -- make `ghc -e` exit nonzero on invalid input, see Trac #7962
610
611
612
613
                _ <- runCommands' hdle
                     (Just $ hdle (toException $ ExitFailure 1) >> return ())
                     (return Nothing)
                return ()
614
615

  -- and finally, exit
Ian Lynagh's avatar
Ian Lynagh committed
616
  liftIO $ when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
617

618
619
runGHCiInput :: InputT GHCi a -> GHCi a
runGHCiInput f = do
Ian Lynagh's avatar
Ian Lynagh committed
620
    dflags <- getDynFlags
621
622
623
624
625
626
627
628
629
630
    let ghciHistory = gopt Opt_GhciHistory dflags
    let localGhciHistory = gopt Opt_LocalGhciHistory dflags
    currentDirectory <- liftIO $ getCurrentDirectory

    histFile <- case (ghciHistory, localGhciHistory) of
      (True, True) -> return (Just (currentDirectory </> ".ghci_history"))
      (True, _) -> liftIO $ withGhcAppData
        (\dir -> return (Just (dir </> "ghci_history"))) (return Nothing)
      _ -> return Nothing

dterei's avatar
dterei committed
631
632
633
    runInputT
        (setComplete ghciCompleteWord $ defaultSettings {historyFile = histFile})
        f
634

635
-- | How to get the next input line from the user
636
637
638
nextInputLine :: Bool -> Bool -> InputT GHCi (Maybe String)
nextInputLine show_prompt is_tty
  | is_tty = do
dterei's avatar
dterei committed
639
640
    prmpt <- if show_prompt then lift mkPrompt else return ""
    r <- getInputLine prmpt
641
642
    incrementLineNo
    return r
643
644
645
  | otherwise = do
    when show_prompt $ lift mkPrompt >>= liftIO . putStr
    fileLoop stdin
646

647
-- NOTE: We only read .ghci files if they are owned by the current user,
648
649
650
-- and aren't world writable (files owned by root are ok, see #9324).
-- Otherwise, we could be accidentally running code planted by
-- a malicious third party.
651

rrt's avatar
rrt committed
652
653
654
655
-- Furthermore, We only read ./.ghci if . is owned by the current user
-- and isn't writable by anyone else.  I think this is sufficient: we
-- don't need to check .. and ../.. etc. because "."  always refers to
-- the same directory while a process is running.
656

657
658
checkFileAndDirPerms :: FilePath -> IO Bool
checkFileAndDirPerms file = do
659
  file_ok <- checkPerms file
thomie's avatar
thomie committed
660
661
662
663
  -- Do not check dir perms when .ghci doesn't exist, otherwise GHCi will
  -- print some confusing and useless warnings in some cases (e.g. in
  -- travis). Note that we can't add a test for this, as all ghci tests should
  -- run with -ignore-dot-ghci, which means we never get here.
664
  if file_ok then checkPerms (getDirectory file) else return False
665
666
667
668
669
670
  where
  getDirectory f = case takeDirectory f of
    "" -> "."
    d -> d

checkPerms :: FilePath -> IO Bool
671
#ifdef mingw32_HOST_OS
dterei's avatar
dterei committed
672
checkPerms _ = return True
sof's avatar
sof committed
673
#else
674
checkPerms file =
675
  handleIO (\_ -> return False) $ do
676
    st <- getFileStatus file
dterei's avatar
dterei committed
677
    me <- getRealUserID
678
679
680
681
682
    let mode = System.Posix.fileMode st
        ok = (fileOwner st == me || fileOwner st == 0) &&
             groupWriteMode /= mode `intersectFileModes` groupWriteMode &&
             otherWriteMode /= mode `intersectFileModes` otherWriteMode
    unless ok $
683
      -- #8248: Improving warning to include a possible fix.
684
      putStrLn $ "*** WARNING: " ++ file ++
685
                 " is writable by someone else, IGNORING!" ++
Ben Gamari's avatar
Ben Gamari committed
686
                 "\nSuggested fix: execute 'chmod go-w " ++ file ++ "'"
687
    return ok
sof's avatar
sof committed
688
#endif
689

690
incrementLineNo :: InputT GHCi ()
691
692
693
incrementLineNo = modifyGHCiState incLineNo
  where
    incLineNo st = st { line_number = line_number st + 1 }
vivian's avatar
vivian committed
694
695

fileLoop :: Handle -> InputT GHCi (Maybe String)
696
fileLoop hdl = do
697
   l <- liftIO $ tryIO $ hGetLine hdl
698
   case l of
699
        Left e | isEOFError e              -> return Nothing
700
701
702
703
704
               | -- as we share stdin with the program, the program
                 -- might have already closed it, so we might get a
                 -- handle-closed exception. We therefore catch that
                 -- too.
                 isIllegalOperation e      -> return Nothing
705
               | InvalidArgument <- etype  -> return Nothing
706
               | otherwise                 -> liftIO $ ioError e
707
708
709
710
711
                where etype = ioeGetErrorType e
                -- treat InvalidArgument in the same way as EOF:
                -- this can happen if the user closed stdin, or
                -- perhaps did getContents which closes stdin at
                -- EOF.
dterei's avatar
dterei committed
712
        Right l' -> do
713
           incrementLineNo
dterei's avatar
dterei committed
714
           return (Just l')
715

niksaz's avatar
niksaz committed
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
formatCurrentTime :: String -> IO String
formatCurrentTime format =
  getZonedTime >>= return . (formatTime defaultTimeLocale format)

getUserName :: IO String
getUserName = do
#ifdef mingw32_HOST_OS
  getEnv "USERNAME"
    `catchIO` \e -> do
      putStrLn $ show e
      return ""
#else
  getLoginName
#endif

getInfoForPrompt :: GHCi (SDoc, [String], Int)
getInfoForPrompt = do
733
  st <- getGHCiState
734
  imports <- GHC.getContext
735
  resumes <- GHC.getResumeContext
736
737
738
739

  context_bit <-
        case resumes of
            [] -> return empty
Simon Marlow's avatar
Simon Marlow committed
740
            r:_ -> do
741
742
743
744
745
                let ix = GHC.resumeHistoryIx r
                if ix == 0
                   then return (brackets (ppr (GHC.resumeSpan r)) <> space)
                   else do
                        let hist = GHC.resumeHistory r !! (ix-1)
dterei's avatar
dterei committed
746
747
748
                        pan <- GHC.getHistorySpan hist
                        return (brackets (ppr (negate ix) <> char ':'
                                          <+> ppr pan) <> space)
niksaz's avatar
niksaz committed
749

750
  let
Simon Marlow's avatar
Simon Marlow committed
751
        dots | _:rs <- resumes, not (null rs) = text "... "
752
753
             | otherwise = empty

754
755
        rev_imports = reverse imports -- rightmost are the most recent

756
        myIdeclName d | Just m <- ideclAs d = unLoc m
757
                      | otherwise           = unLoc (ideclName d)
758

niksaz's avatar
niksaz committed
759
760
761
762
763
764
        modules_names =
             ['*':(moduleNameString m) | IIModule m <- rev_imports] ++
             [moduleNameString (myIdeclName d) | IIDecl d <- rev_imports]
        line = 1 + line_number st

  return (dots <> context_bit, modules_names, line)
765

niksaz's avatar
niksaz committed
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
parseCallEscape :: String -> (String, String)
parseCallEscape s
  | not (all isSpace beforeOpen) = ("", "")
  | null sinceOpen               = ("", "")
  | null sinceClosed             = ("", "")
  | null cmd                     = ("", "")
  | otherwise                    = (cmd, tail sinceClosed)
  where
    (beforeOpen, sinceOpen) = span (/='(') s
    (cmd, sinceClosed) = span (/=')') (tail sinceOpen)

checkPromptStringForErrors :: String -> Maybe String
checkPromptStringForErrors ('%':'c':'a':'l':'l':xs) =
  case parseCallEscape xs of
    ("", "") -> Just ("Incorrect %call syntax. " ++
                      "Should be %call(a command and arguments).")
    (_, afterClosed) -> checkPromptStringForErrors afterClosed
checkPromptStringForErrors ('%':'%':xs) = checkPromptStringForErrors xs
checkPromptStringForErrors (_:xs) = checkPromptStringForErrors xs
checkPromptStringForErrors "" = Nothing

generatePromptFunctionFromString :: String -> PromptFunction
generatePromptFunctionFromString promptS = \_ _ -> do
    (context, modules_names, line) <- getInfoForPrompt

    let
        processString :: String -> GHCi SDoc
        processString ('%':'s':xs) =
            liftM2 (<>) (return modules_list) (processString xs)
            where
              modules_list = context <> modules_bit
              modules_bit = hsep $ map text modules_names
        processString ('%':'l':xs) =
            liftM2 (<>) (return $ ppr line) (processString xs)
        processString ('%':'d':xs) =
            liftM2 (<>) (liftM text formatted_time) (processString xs)
            where
              formatted_time = liftIO $ formatCurrentTime "%a %b %d"
        processString ('%':'t':xs) =
            liftM2 (<>) (liftM text formatted_time) (processString xs)
            where
              formatted_time = liftIO $ formatCurrentTime "%H:%M:%S"
        processString ('%':'T':xs) = do
            liftM2 (<>) (liftM text formatted_time) (processString xs)
            where
              formatted_time = liftIO $ formatCurrentTime "%I:%M:%S"
        processString ('%':'@':xs) = do
            liftM2 (<>) (liftM text formatted_time) (processString xs)
            where
              formatted_time = liftIO $ formatCurrentTime "%I:%M %P"
        processString ('%':'A':xs) = do
            liftM2 (<>) (liftM text formatted_time) (processString xs)
            where
              formatted_time = liftIO $ formatCurrentTime "%H:%M"
        processString ('%':'u':xs) =
            liftM2 (<>) (liftM text user_name) (processString xs)
            where
              user_name = liftIO $ getUserName
        processString ('%':'w':xs) =
            liftM2 (<>) (liftM text current_directory) (processString xs)
            where
              current_directory = liftIO $ getCurrentDirectory
        processString ('%':'o':xs) =
            liftM ((text os) <>) (processString xs)
        processString ('%':'a':xs) =
            liftM ((text arch) <>) (processString xs)
        processString ('%':'N':xs) =
            liftM ((text compilerName) <>) (processString xs)
        processString ('%':'V':xs) =
            liftM ((text $ showVersion compilerVersion) <>) (processString xs)
        processString ('%':'c':'a':'l':'l':xs) = do
            respond <- liftIO $ do
                (code, out, err) <-
                    readProcessWithExitCode
                    (head list_words) (tail list_words) ""
                    `catchIO` \e -> return (ExitFailure 1, "", show e)
                case code of
                    ExitSuccess -> return out
                    _ -> do
                        hPutStrLn stderr err
                        return ""
            liftM ((text respond) <>) (processString afterClosed)
            where
              (cmd, afterClosed) = parseCallEscape xs
              list_words = words cmd
        processString ('%':'%':xs) =
            liftM ((char '%') <>) (processString xs)
        processString (x:xs) =
            liftM (char x <>) (processString xs)
        processString "" =
            return empty

    processString promptS
dterei's avatar
dterei committed
859

niksaz's avatar
niksaz committed
860
861
862
mkPrompt :: GHCi String
mkPrompt = do
  st <- getGHCiState
863
  dflags <- getDynFlags
niksaz's avatar
niksaz committed
864
  (context, modules_names, line) <- getInfoForPrompt
865

niksaz's avatar
niksaz committed
866
867
868
869
  prompt_string <- (prompt st) modules_names line
  let prompt_doc = context <> prompt_string

  return (showSDoc dflags prompt_doc)
870

871
872
873
874
875
876
877
878
queryQueue :: GHCi (Maybe String)
queryQueue = do
  st <- getGHCiState
  case cmdqueue st of
    []   -> return Nothing
    c:cs -> do setGHCiState st{ cmdqueue = cs }
               return (Just c)

879
880
881
882
883
884
-- Reconfigurable pretty-printing Ticket #5461
installInteractivePrint :: Maybe String -> Bool -> GHCi ()
installInteractivePrint Nothing _  = return ()
installInteractivePrint (Just ipFun) exprmode = do
  ok <- trySuccess $ do
                (name:_) <- GHC.parseName ipFun
885
                modifySession (\he -> let new_ic = setInteractivePrintName (hsc_IC he) name
886
                                      in he{hsc_IC = new_ic})
887
888
889
890
                return Succeeded

  when (failed ok && exprmode) $ liftIO (exitWith (ExitFailure 1))

891
-- | The main read-eval-print loop
892
runCommands :: InputT GHCi (Maybe String) -> InputT GHCi ()
893
runCommands gCmd = runCommands' handler Nothing gCmd >> return ()
894

dterei's avatar
dterei committed
895
runCommands' :: (SomeException -> GHCi Bool) -- ^ Exception handler
896
             -> Maybe (GHCi ()) -- ^ Source error handler
897
898
899
900
901
902
             -> InputT GHCi (Maybe String)
             -> InputT GHCi (Maybe Bool)
         -- We want to return () here, but have to return (Maybe Bool)
         -- because gmask is not polymorphic enough: we want to use
         -- unmask at two different types.
runCommands' eh sourceErrorHandler gCmd = gmask $ \unmask -> do
903
    b <- ghandle (\e -> case fromException e of
vivian's avatar
vivian committed
904
                          Just UserInterrupt -> return $ Just False
905
                          _ -> case fromException e of
dterei's avatar
dterei committed
906
907
                                 Just ghce ->
                                   do liftIO (print (ghce :: GhcException))
vivian's avatar
vivian committed
908
                                      return Nothing
909
910
                                 _other ->
                                   liftIO (Exception.throwIO e))
911
            (unmask $ runOneCommand eh gCmd)
vivian's avatar
vivian committed
912
    case b of
913
      Nothing -> return Nothing
914
      Just success -> do
915
        unless success $ maybe (return ()) lift sourceErrorHandler
916
        unmask $ runCommands' eh sourceErrorHandler gCmd
917

918
919
920
921
922
-- | Evaluate a single line of user input (either :<command> or Haskell code).
-- A result of Nothing means there was no more input to process.
-- Otherwise the result is Just b where b is True if the command succeeded;
-- this is relevant only to ghc -e, which will exit with status 1
-- if the commmand was unsuccessful. GHCi will continue in either case.
923
runOneCommand :: (SomeException -> GHCi Bool) -> InputT GHCi (Maybe String)
vivian's avatar
vivian committed
924
            -> InputT GHCi (Maybe Bool)
dterei's avatar
dterei committed
925
runOneCommand eh gCmd = do
926
927
  -- run a previously queued command if there is one, otherwise get new
  -- input from user
dterei's avatar
dterei committed
928
929
930
  mb_cmd0 <- noSpace (lift queryQueue)
  mb_cmd1 <- maybe (noSpace gCmd) (return . Just) mb_cmd0
  case mb_cmd1 of
vivian's avatar
vivian committed
931
932
    Nothing -> return Nothing
    Just c  -> ghciHandle (\e -> lift $ eh e >>= return . Just) $
933
             handleSourceError printErrorAndFail
934
               (doCommand c)
vivian's avatar
vivian committed
935
936
               -- source error's are handled by runStmt
               -- is the handler necessary here?
937
  where
938
    printErrorAndFail err = do
939
        GHC.printException err
940
        return $ Just False     -- Exit ghc -e, but not GHCi
941

942
    noSpace q = q >>= maybe (return Nothing)
dterei's avatar
dterei committed
943
944
945
                            (\c -> case removeSpaces c of
                                     ""   -> noSpace q
                                     ":{" -> multiLineCmd q
946
                                     _    -> return (Just c) )
947
    multiLineCmd q = do
948
      st <- getGHCiState
949
      let p = prompt st
niksaz's avatar
niksaz committed
950
      setGHCiState st{ prompt = prompt_cont st }
951
952
      mb_cmd <- collectCommand q "" `GHC.gfinally`
                modifyGHCiState (\st' -> st' { prompt = p })
953
      return mb_cmd
dterei's avatar
dterei committed
954
    -- we can't use removeSpaces for the sublines here, so