leksah-0.8.0.6: src/IDE/Debug.hs
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
{-# OPTIONS_GHC -XScopedTypeVariables #-}
-----------------------------------------------------------------------------
--
-- Module : IDE.Debug
-- Copyright : (c) Hamish Mackenzie, Juergen Nicklisch-Franken
-- License : GNU-GPL
--
-- Maintainer : <maintainer at leksah.org>
-- Stability : provisional
-- Portability : portable
--
--
-- | The debug methods of ide.
--
---------------------------------------------------------------------------------
module IDE.Debug (
debugCommand
, debugCommand'
, debugToggled
, debugQuit
, debugExecuteSelection
, debugExecuteAndShowSelection
, debugSetBreakpoint
, debugDeleteAllBreakpoints
, debugDeleteBreakpoint
, debugContinue
, debugAbandon
, debugStop
, debugStep
, debugStepExpression
, debugStepExpr
, debugStepLocal
, debugStepModule
, debugTrace
, debugTraceExpression
, debugTraceExpr
, debugHistory
, debugBack
, debugForward
, debugForce
, debugPrint
, debugSimplePrint
, debugShowBindings
, debugShowBreakpoints
, debugShowContext
, debugShowModules
, debugShowPackages
, debugShowLanguages
, debugInformation
, debugKind
, debugType
, debugSetPrintEvldWithShow
, debugSetBreakOnException
, debugSetBreakOnError
, debugSetPrintBindResult
) where
import Control.Monad.Reader
import IDE.Core.State
import IDE.LogRef
import Control.Exception (SomeException(..))
import IDE.Pane.SourceBuffer
(selectedLocation, selectedText, selectedModuleName,
insertTextAfterSelection, selectedTextOrCurrentLine)
import IDE.Metainfo.Provider (getActivePackageDescr)
import Distribution.Text (display)
import IDE.Pane.Log (appendLog)
import Data.List (isSuffixOf)
import IDE.System.Process (interruptProcessGroup)
import IDE.Utils.GUIUtils (getDebugToggled)
import IDE.Package (debugStart, executeDebugCommand, printBindResultFlag, breakOnErrorFlag,
breakOnExceptionFlag, printEvldWithShowFlag)
import IDE.Utils.Tool (ToolOutput(..), toolProcess)
debugCommand :: String -> ([ToolOutput] -> IDEAction) -> IDEAction
debugCommand command handler = debugCommand' command
(\to -> do
handler to
triggerEventIDE VariablesChanged
return ())
debugCommand' :: String -> ([ToolOutput] -> IDEAction) -> IDEAction
debugCommand' command handler = do
ideR <- ask
catchIDE (executeDebugCommand command handler)
(\(e :: SomeException) -> putStrLn (show e))
debugToggled :: IDEAction
debugToggled = do
toggled <- getDebugToggled
if toggled
then debugStart
else debugQuit
debugQuit :: IDEAction
debugQuit = debugCommand ":quit" logOutput
debugExecuteSelection :: IDEAction
debugExecuteSelection = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> do
debugSetLiberalScope
debugCommand text logOutput
Nothing -> ideMessage Normal "Please select some text in the editor to execute"
debugExecuteAndShowSelection :: IDEAction
debugExecuteAndShowSelection = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> do
debugSetLiberalScope
debugCommand text (\to -> do
insertTextAfterSelection $ " " ++ buildOutputString to
logOutput to)
Nothing -> ideMessage Normal "Please select some text in the editor to execute"
where
buildOutputString :: [ToolOutput] -> String
buildOutputString (ToolOutput str:[]) = str
buildOutputString (ToolOutput str:r) = str ++ "\n" ++ (buildOutputString r)
buildOutputString (_:r) = buildOutputString r
buildOutputString [] = ""
debugSetLiberalScope :: IDEAction
debugSetLiberalScope = do
maybeModuleName <- selectedModuleName
case maybeModuleName of
Just moduleName -> do
debugCommand (":module *" ++ moduleName) (\ _ -> return ())
Nothing -> do
mbPackage <- getActivePackageDescr
case mbPackage of
Nothing -> return ()
Just p -> let packageNames = map (display . modu . mdModuleId) (pdModules p)
in debugCommand' (foldl (\a b -> a ++ " *" ++ b) ":module + " packageNames)
(\ _ -> return ())
debugAbandon :: IDEAction
debugAbandon = debugCommand ":abandon" logOutput
debugBack :: IDEAction
debugBack = do
currentHist' <- readIDE currentHist
rootPath <- activeProjectDir
modifyIDE_ (\ide -> ide{currentHist = min (currentHist' - 1) 0})
debugCommand ":back" (logOutputForHistoricContext rootPath)
debugForward :: IDEAction
debugForward = do
currentHist' <- readIDE currentHist
rootPath <- activeProjectDir
modifyIDE_ (\ide -> ide{currentHist = currentHist' + 1})
debugCommand ":forward" (logOutputForHistoricContext rootPath)
debugStop :: IDEAction
debugStop = do
maybeGhci <- readIDE ghciState
liftIO $ case maybeGhci of
Just ghci -> toolProcess ghci >>= interruptProcessGroup
Nothing -> return ()
debugContinue :: IDEAction
debugContinue = do
rootPath <- activeProjectDir
debugCommand ":continue" (logOutputForLiveContext rootPath)
debugDeleteAllBreakpoints :: IDEAction
debugDeleteAllBreakpoints = do
debugCommand ":delete *" $ \output -> do
logOutput output
setBreakpointList []
debugDeleteBreakpoint :: String -> LogRef -> IDEAction
debugDeleteBreakpoint indexString lr = do
debugCommand (":delete " ++ indexString) $ \output -> do
logOutput output
bl <- readIDE breakpointRefs
setBreakpointList $ filter (/= lr) bl
ideR <- ask
return ()
debugForce :: IDEAction
debugForce = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> debugCommand (":force " ++ text) logOutput
Nothing -> ideMessage Normal "Please select an expression in the editor"
debugHistory :: IDEAction
debugHistory = debugCommand ":history" logOutput
debugPrint :: IDEAction
debugPrint = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> debugCommand (":print " ++ text) logOutput
Nothing -> ideMessage Normal "Please select an name in the editor"
debugSimplePrint :: IDEAction
debugSimplePrint = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> debugCommand (":force " ++ text) logOutput
Nothing -> ideMessage Normal "Please select an name in the editor"
debugStep :: IDEAction
debugStep = do
rootPath <- activeProjectDir
debugSetLiberalScope
debugCommand ":step" (logOutputForLiveContext rootPath)
debugStepExpression :: IDEAction
debugStepExpression = do
maybeText <- selectedTextOrCurrentLine
debugSetLiberalScope
debugStepExpr maybeText
debugStepExpr :: Maybe String -> IDEAction
debugStepExpr maybeText = do
rootPath <- activeProjectDir
case maybeText of
Just text -> debugCommand (":step " ++ text) (logOutputForLiveContext rootPath)
Nothing -> ideMessage Normal "Please select an expression in the editor"
debugStepLocal :: IDEAction
debugStepLocal = do
rootPath <- activeProjectDir
debugCommand ":steplocal" (logOutputForLiveContext rootPath)
debugStepModule :: IDEAction
debugStepModule = do
rootPath <- activeProjectDir
debugCommand ":stepmodule" (logOutputForLiveContext rootPath)
debugTrace :: IDEAction
debugTrace = do
rootPath <- activeProjectDir
debugCommand ":trace" (\to -> do
logOutputForLiveContext rootPath to
triggerEventIDE TraceChanged
return ())
debugTraceExpression :: IDEAction
debugTraceExpression = do
maybeText <- selectedTextOrCurrentLine
debugSetLiberalScope
debugTraceExpr maybeText
debugTraceExpr :: Maybe String -> IDEAction
debugTraceExpr maybeText =
case maybeText of
Just text -> debugCommand (":trace " ++ text) (\to -> do
rootPath <- activeProjectDir
logOutputForLiveContext rootPath to
triggerEventIDE TraceChanged
return ())
Nothing -> ideMessage Normal "Please select an expression in the editor"
debugShowBindings :: IDEAction
debugShowBindings = debugCommand ":show bindings" logOutput
debugShowBreakpoints :: IDEAction
debugShowBreakpoints = do
rootPath <- activeProjectDir
debugCommand ":show breaks" (logOutputForBreakpoints rootPath)
debugShowContext :: IDEAction
debugShowContext = do
rootPath <- activeProjectDir
debugCommand ":show context" (logOutputForLiveContext rootPath)
debugShowModules :: IDEAction
debugShowModules = debugCommand ":show modules" $
logOutputLines_ $ \log output -> liftIO $ do
case output of
ToolInput line -> appendLog log (line ++ "\n") InputTag
ToolOutput line | ", interpreted )" `isSuffixOf` line
-> appendLog log (line ++ "\n") LogTag
ToolOutput line -> appendLog log (line ++ "\n") InfoTag
ToolError line -> appendLog log (line ++ "\n") ErrorTag
ToolPrompt -> defaultLineLogger' log output
ToolExit _ -> appendLog log "X--X--X ghci process exited unexpectedly X--X--X" FrameTag
return ()
debugShowPackages :: IDEAction
debugShowPackages = debugCommand ":show packages" logOutput
debugShowLanguages :: IDEAction
debugShowLanguages = debugCommand ":show languages" logOutput
debugInformation :: IDEAction
debugInformation = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> do
debugSetLiberalScope
debugCommand (":info "++text) logOutput
Nothing -> ideMessage Normal "Please select a name in the editor"
debugKind :: IDEAction
debugKind = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> do
debugSetLiberalScope
debugCommand (":kind "++text) logOutput
Nothing -> ideMessage Normal "Please select a type in the editor"
debugType :: IDEAction
debugType = do
maybeText <- selectedTextOrCurrentLine
case maybeText of
Just text -> do
debugSetLiberalScope
debugCommand (":type "++text) logOutput
Nothing -> ideMessage Normal "Please select an expression in the editor"
debugSetBreakpoint :: IDEAction
debugSetBreakpoint = do
rootPath <- activeProjectDir
maybeModuleName <- selectedModuleName
case maybeModuleName of
Just moduleName -> do
-- ### debugCommand (":add *"++moduleName) $ logOutputForBuild True
maybeText <- selectedText
case maybeText of
Just text -> do
debugCommand (":module *" ++ moduleName) logOutput
debugCommand (":break " ++ text) (logOutputForSetBreakpoint rootPath)
Nothing -> do
maybeLocation <- selectedLocation
case maybeLocation of
Just (line, lineOffset) ->
debugCommand (":break " ++ moduleName ++ " " ++ (show (line+1)) ++ " " ++
(show lineOffset)) (logOutputForSetBreakpoint rootPath)
Nothing -> ideMessage Normal "Unknown error setting breakpoint"
ref <- ask
return ()
Nothing -> ideMessage Normal "Please select module file in the editor"
debugSet :: (Bool -> String) -> Bool -> IDEAction
debugSet flag value = do
debugCommand (":set "++(flag value)) logOutput
debugSetPrintEvldWithShow :: Bool -> IDEAction
debugSetPrintEvldWithShow = debugSet printEvldWithShowFlag
debugSetBreakOnException :: Bool -> IDEAction
debugSetBreakOnException = debugSet breakOnExceptionFlag
debugSetBreakOnError :: Bool -> IDEAction
debugSetBreakOnError = debugSet breakOnErrorFlag
debugSetPrintBindResult :: Bool -> IDEAction
debugSetPrintBindResult = debugSet printBindResultFlag