packages feed

leksah 0.15.1.4 → 0.15.2.0

raw patch · 56 files changed

+3139/−2226 lines, 56 filesdep +base-compatdep ~haskell-src-extsdep ~jsaddledep ~leksahbinary-addedPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: base-compat

Dependency ranges changed: haskell-src-exts, jsaddle, leksah, leksah-server, webkitgtk3-javascriptcore

API changes (from Hackage documentation)

- IDE.BufferMode: addedIndex :: IDEBuffer -> Int
- IDE.BufferMode: bufferName :: IDEBuffer -> Text
- IDE.BufferMode: fileName :: IDEBuffer -> Maybe FilePath
- IDE.BufferMode: instance Eq BufferState
- IDE.BufferMode: instance Ord BufferState
- IDE.BufferMode: instance Pane IDEBuffer IDEM
- IDE.BufferMode: instance Read BufferState
- IDE.BufferMode: instance Show BufferState
- IDE.BufferMode: instance Typeable BufferState
- IDE.BufferMode: instance Typeable IDEBuffer
- IDE.BufferMode: modTime :: IDEBuffer -> IORef (Maybe UTCTime)
- IDE.BufferMode: mode :: IDEBuffer -> Mode
- IDE.BufferMode: modeEditComment :: Mode -> IDEAction
- IDE.BufferMode: modeEditFromCandy :: Mode -> IDEAction
- IDE.BufferMode: modeEditInCommentOrString :: Mode -> Text -> Bool
- IDE.BufferMode: modeEditInsertCode :: Mode -> forall editor. TextEditor editor => Text -> EditorIter editor -> EditorBuffer editor -> IDEAction
- IDE.BufferMode: modeEditKeystrokeCandy :: Mode -> Maybe Char -> (Text -> Bool) -> IDEAction
- IDE.BufferMode: modeEditToCandy :: Mode -> (Text -> Bool) -> IDEAction
- IDE.BufferMode: modeEditUncomment :: Mode -> IDEAction
- IDE.BufferMode: modeName :: Mode -> Text
- IDE.BufferMode: modeSelectedModuleName :: Mode -> IDEM (Maybe Text)
- IDE.BufferMode: modeTransformToCandy :: Mode -> forall editor. TextEditor editor => (Text -> Bool) -> EditorBuffer editor -> IDEAction
- IDE.BufferMode: scrolledWindow :: IDEBuffer -> ScrolledWindow
- IDE.BufferMode: sourceView :: IDEBuffer -> EditorView editor
- IDE.Build: instance (Show alpha, Show beta) => Show (Chain alpha beta)
- IDE.Build: instance Eq MakeOp
- IDE.Build: instance Ord MakeOp
- IDE.Build: instance Show MakeOp
- IDE.Build: msBackgroundBuild :: MakeSettings -> Bool
- IDE.Build: msDontInstallLast :: MakeSettings -> Bool
- IDE.Build: msJumpToWarnings :: MakeSettings -> Bool
- IDE.Build: msMakeMode :: MakeSettings -> Bool
- IDE.Build: msRunUnitTests :: MakeSettings -> Bool
- IDE.Build: msSaveAllBeforeBuild :: MakeSettings -> Bool
- IDE.Build: msSingleBuildWithoutLinking :: MakeSettings -> Bool
- IDE.Command.Print: exitCode :: PrintError -> Int
- IDE.Command.Print: instance Read PrintError
- IDE.Command.Print: instance Show PrintError
- IDE.Command.Print: printCmd :: PrintError -> FilePath
- IDE.Command.Print: stderr :: PrintError -> Text
- IDE.Command.VCS.Types: instance Applicative VCSAction
- IDE.Command.VCS.Types: instance Functor VCSAction
- IDE.Command.VCS.Types: instance Monad VCSAction
- IDE.Command.VCS.Types: instance MonadIO VCSAction
- IDE.Command.VCS.Types: instance MonadReader (VCSConf, FilePath) VCSAction
- IDE.Core.State: instance Eq MessageLevel
- IDE.Core.State: instance Exception IDEException
- IDE.Core.State: instance Ord MessageLevel
- IDE.Core.State: instance PaneMonad IDEM
- IDE.Core.State: instance Show IDEException
- IDE.Core.State: instance Show MessageLevel
- IDE.Core.State: instance Typeable IDEException
- IDE.Core.Types: accelerator :: ActionDescr alpha -> [KeyString]
- IDE.Core.Types: action :: ActionDescr alpha -> ReaderT alpha IO ()
- IDE.Core.Types: activeExe :: IDE -> Maybe Text
- IDE.Core.Types: activePack :: IDE -> Maybe IDEPackage
- IDE.Core.Types: allLogRefs :: IDE -> Seq LogRef
- IDE.Core.Types: autoCommand :: IDE -> IDEAction
- IDE.Core.Types: autoLoad :: Prefs -> Bool
- IDE.Core.Types: autoURI :: IDE -> Maybe Text
- IDE.Core.Types: backgroundBuild :: Prefs -> Bool
- IDE.Core.Types: blacklist :: GUIHistory' -> Bool
- IDE.Core.Types: breakOnError :: Prefs -> Bool
- IDE.Core.Types: breakOnException :: Prefs -> Bool
- IDE.Core.Types: breakpointBG :: EditorStyle -> (Color, Color)
- IDE.Core.Types: breakpointBackgroundDark :: Prefs -> Color
- IDE.Core.Types: breakpointBackgroundLight :: Prefs -> Color
- IDE.Core.Types: browser :: Prefs -> Text
- IDE.Core.Types: bufferProjCache :: IDE -> Map FilePath [IDEPackage]
- IDE.Core.Types: candy :: IDE -> CandyTable
- IDE.Core.Types: caseSense :: SearchMode -> Bool
- IDE.Core.Types: categoryForPane :: Prefs -> [(Text, Text)]
- IDE.Core.Types: collectAtStart :: Prefs -> Bool
- IDE.Core.Types: completeRestricted :: Prefs -> Bool
- IDE.Core.Types: completion :: IDE -> ((Int, Int), Maybe CompletionWindow)
- IDE.Core.Types: contextBG :: EditorStyle -> (Color, Color)
- IDE.Core.Types: contextBackgroundDark :: Prefs -> Color
- IDE.Core.Types: contextBackgroundLight :: Prefs -> Color
- IDE.Core.Types: currentEBC :: IDE -> (Maybe LogRef, Maybe LogRef, Maybe LogRef)
- IDE.Core.Types: currentHist :: IDE -> Int
- IDE.Core.Types: currentState :: IDE -> IDEState
- IDE.Core.Types: cwListStore :: CompletionWindow -> ListStore Text
- IDE.Core.Types: cwTreeView :: CompletionWindow -> TreeView
- IDE.Core.Types: cwWindow :: CompletionWindow -> Window
- IDE.Core.Types: debugState :: IDE -> Maybe (IDEPackage, ToolState)
- IDE.Core.Types: defaultPath :: Prefs -> PanePath
- IDE.Core.Types: defaultSize :: Prefs -> (Int, Int)
- IDE.Core.Types: docuSearchURL :: Prefs -> Text
- IDE.Core.Types: dontInstallLast :: Prefs -> Bool
- IDE.Core.Types: endWithLastConn :: Prefs -> Bool
- IDE.Core.Types: facetS :: GUIHistory' -> Maybe Text
- IDE.Core.Types: findbar :: IDE -> (Bool, Maybe (Toolbar, ListStore Text))
- IDE.Core.Types: forceLineEnds :: Prefs -> Bool
- IDE.Core.Types: foundBG :: EditorStyle -> (Color, Color)
- IDE.Core.Types: foundBackgroundDark :: Prefs -> Color
- IDE.Core.Types: foundBackgroundLight :: Prefs -> Color
- IDE.Core.Types: frameState :: IDE -> FrameState IDEM
- IDE.Core.Types: guiHistory :: IDE -> (Bool, [GUIHistory], Int)
- IDE.Core.Types: handlers :: IDE -> Map Text [(Unique, IDEEvent -> IDEM IDEEvent)]
- IDE.Core.Types: hlintQueue :: IDE -> Maybe (TVar [Either FilePath FilePath])
- IDE.Core.Types: instance Bounded LogRefType
- IDE.Core.Types: instance Enum LogRefType
- IDE.Core.Types: instance Eq GUIHistory'
- IDE.Core.Types: instance Eq IDEPackage
- IDE.Core.Types: instance Eq LogRef
- IDE.Core.Types: instance Eq LogRefType
- IDE.Core.Types: instance Eq Prefs
- IDE.Core.Types: instance Eq SearchHint
- IDE.Core.Types: instance Eq SearchMode
- IDE.Core.Types: instance Eq SensitivityMask
- IDE.Core.Types: instance Event IDEEvent Text
- IDE.Core.Types: instance EventSelector Text
- IDE.Core.Types: instance EventSource IDERef IDEEvent IDEM Text
- IDE.Core.Types: instance MonadIDE (IDEEventM t)
- IDE.Core.Types: instance MonadIDE IDEM
- IDE.Core.Types: instance MonadIDE PackageM
- IDE.Core.Types: instance MonadIDE WorkspaceM
- IDE.Core.Types: instance Ord GUIHistory'
- IDE.Core.Types: instance Ord IDEPackage
- IDE.Core.Types: instance Ord LogRefType
- IDE.Core.Types: instance Ord Modifier
- IDE.Core.Types: instance Ord SearchMode
- IDE.Core.Types: instance Ord SensitivityMask
- IDE.Core.Types: instance Read SearchMode
- IDE.Core.Types: instance Show GUIHistory'
- IDE.Core.Types: instance Show IDEPackage
- IDE.Core.Types: instance Show LogRef
- IDE.Core.Types: instance Show LogRefType
- IDE.Core.Types: instance Show Prefs
- IDE.Core.Types: instance Show SearchMode
- IDE.Core.Types: instance Show SensitivityMask
- IDE.Core.Types: instance Show Workspace
- IDE.Core.Types: instance Typeable LogLaunch
- IDE.Core.Types: ipdBenchmarks :: IDEPackage -> [Text]
- IDE.Core.Types: ipdBuildDir :: IDEPackage -> FilePath
- IDE.Core.Types: ipdBuildFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdCabalFile :: IDEPackage -> FilePath
- IDE.Core.Types: ipdConfigFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdDepends :: IDEPackage -> [Dependency]
- IDE.Core.Types: ipdExeFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdExes :: IDEPackage -> [Text]
- IDE.Core.Types: ipdExtensions :: IDEPackage -> [Extension]
- IDE.Core.Types: ipdExtraSrcs :: IDEPackage -> Set FilePath
- IDE.Core.Types: ipdHaddockFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdHasLibs :: IDEPackage -> Bool
- IDE.Core.Types: ipdInstallFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdMain :: IDEPackage -> [(FilePath, BuildInfo, Bool)]
- IDE.Core.Types: ipdModules :: IDEPackage -> Map ModuleName BuildInfo
- IDE.Core.Types: ipdPackageId :: IDEPackage -> PackageIdentifier
- IDE.Core.Types: ipdRegisterFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdSandboxSources :: IDEPackage -> [IDEPackage]
- IDE.Core.Types: ipdSdistFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdSrcDirs :: IDEPackage -> [FilePath]
- IDE.Core.Types: ipdTestFlags :: IDEPackage -> [Text]
- IDE.Core.Types: ipdTests :: IDEPackage -> [Text]
- IDE.Core.Types: ipdUnregisterFlags :: IDEPackage -> [Text]
- IDE.Core.Types: isToggle :: ActionDescr alpha -> Bool
- IDE.Core.Types: jumpToWarnings :: Prefs -> Bool
- IDE.Core.Types: keymapName :: Prefs -> Text
- IDE.Core.Types: label :: ActionDescr alpha -> Text
- IDE.Core.Types: lintBG :: EditorStyle -> (Color, Color)
- IDE.Core.Types: lintBackgroundDark :: Prefs -> Color
- IDE.Core.Types: lintBackgroundLight :: Prefs -> Color
- IDE.Core.Types: logBuffer :: LogLaunch -> TextBuffer
- IDE.Core.Types: logLaunch :: LogLaunchData -> LogLaunch
- IDE.Core.Types: logLaunches :: IDE -> Map Text LogLaunchData
- IDE.Core.Types: logLines :: LogRef -> Maybe (Int, Int)
- IDE.Core.Types: logRefIdea :: LogRef -> Maybe (Text, Idea)
- IDE.Core.Types: logRefPackage :: LogRef -> IDEPackage
- IDE.Core.Types: logRefSrcSpan :: LogRef -> SrcSpan
- IDE.Core.Types: logRefType :: LogRef -> LogRefType
- IDE.Core.Types: logviewFont :: Prefs -> Maybe Text
- IDE.Core.Types: makeMode :: Prefs -> Bool
- IDE.Core.Types: matchBG :: EditorStyle -> (Color, Color)
- IDE.Core.Types: matchBackgroundDark :: Prefs -> Color
- IDE.Core.Types: matchBackgroundLight :: Prefs -> Color
- IDE.Core.Types: mbInfo :: GUIHistory' -> Maybe Descr
- IDE.Core.Types: mbPid :: LogLaunchData -> Maybe ProcessHandle
- IDE.Core.Types: moduleS :: GUIHistory' -> Maybe ModuleName
- IDE.Core.Types: name :: ActionDescr alpha -> ActionString
- IDE.Core.Types: packageBlacklist :: Prefs -> [Dependency]
- IDE.Core.Types: packageInfo :: IDE -> Maybe (GenScope, GenScope)
- IDE.Core.Types: packageVcsConf :: Workspace -> Map FilePath VCSConf
- IDE.Core.Types: paneN :: GUIHistory' -> Maybe Text
- IDE.Core.Types: pathForCategory :: Prefs -> [(Text, PanePath)]
- IDE.Core.Types: preferDark :: EditorStyle -> Bool
- IDE.Core.Types: prefs :: IDE -> Prefs
- IDE.Core.Types: prefsFormat :: Prefs -> Int
- IDE.Core.Types: prefsSaveTime :: Prefs -> Text
- IDE.Core.Types: printBindResult :: Prefs -> Bool
- IDE.Core.Types: printEvldWithShow :: Prefs -> Bool
- IDE.Core.Types: recentFiles :: IDE -> [FilePath]
- IDE.Core.Types: recentPanes :: IDE -> [PaneName]
- IDE.Core.Types: recentWorkspaces :: IDE -> [FilePath]
- IDE.Core.Types: refDescription :: LogRef -> Text
- IDE.Core.Types: removeTBlanks :: Prefs -> Bool
- IDE.Core.Types: retrieveStrategy :: Prefs -> RetrieveStrategy
- IDE.Core.Types: retrieveURL :: Prefs -> Text
- IDE.Core.Types: rightMargin :: Prefs -> (Bool, Int)
- IDE.Core.Types: runUnitTests :: Prefs -> Bool
- IDE.Core.Types: runningTool :: IDE -> Maybe ProcessHandle
- IDE.Core.Types: saveAllBeforeBuild :: Prefs -> Bool
- IDE.Core.Types: scope :: GUIHistory' -> Scope
- IDE.Core.Types: server :: IDE -> Maybe Handle
- IDE.Core.Types: serverIP :: Prefs -> Text
- IDE.Core.Types: serverPort :: Prefs -> Int
- IDE.Core.Types: serverQueue :: IDE -> Maybe (MVar (ServerCommand, ServerAnswer -> IDEM ()))
- IDE.Core.Types: showHiddenFiles :: Prefs -> Bool
- IDE.Core.Types: showLineNumbers :: Prefs -> Bool
- IDE.Core.Types: singleBuildWithoutLinking :: Prefs -> Bool
- IDE.Core.Types: sourceCandy :: Prefs -> (Bool, Text)
- IDE.Core.Types: sourceDirectories :: Prefs -> [FilePath]
- IDE.Core.Types: sourceStyle :: Prefs -> (Bool, Text)
- IDE.Core.Types: specialKey :: IDE -> SpecialKeyCons IDERef
- IDE.Core.Types: specialKeys :: IDE -> SpecialKeyTable IDERef
- IDE.Core.Types: stockID :: ActionDescr alpha -> Maybe Text
- IDE.Core.Types: styleName :: EditorStyle -> Maybe Text
- IDE.Core.Types: systemInfo :: IDE -> Maybe GenScope
- IDE.Core.Types: tabWidth :: Prefs -> Int
- IDE.Core.Types: textEditorType :: Prefs -> Text
- IDE.Core.Types: textviewFont :: Prefs -> Maybe Text
- IDE.Core.Types: toolbar :: IDE -> (Bool, Maybe Toolbar)
- IDE.Core.Types: tooltip :: ActionDescr alpha -> Maybe Text
- IDE.Core.Types: unpackDirectory :: Prefs -> Maybe FilePath
- IDE.Core.Types: useCabalDev :: Prefs -> Bool
- IDE.Core.Types: useCtrlTabFlipping :: Prefs -> Bool
- IDE.Core.Types: useVado :: Prefs -> Bool
- IDE.Core.Types: vcsData :: IDE -> (Map FilePath MenuItem, Maybe (Maybe Text))
- IDE.Core.Types: workspInfoCache :: IDE -> PackageDescrCache
- IDE.Core.Types: workspace :: IDE -> Maybe Workspace
- IDE.Core.Types: workspaceInfo :: IDE -> Maybe (GenScope, GenScope)
- IDE.Core.Types: wrapLines :: Prefs -> Bool
- IDE.Core.Types: wsActiveExe :: Workspace -> Maybe Text
- IDE.Core.Types: wsActivePackFile :: Workspace -> Maybe FilePath
- IDE.Core.Types: wsFile :: Workspace -> FilePath
- IDE.Core.Types: wsName :: Workspace -> Text
- IDE.Core.Types: wsNobuildPack :: Workspace -> [IDEPackage]
- IDE.Core.Types: wsPackages :: Workspace -> [IDEPackage]
- IDE.Core.Types: wsPackagesFiles :: Workspace -> [FilePath]
- IDE.Core.Types: wsSaveTime :: Workspace -> Text
- IDE.Core.Types: wsVersion :: Workspace -> Int
- IDE.Core.Types: yiControl :: IDE -> Control
- IDE.Find: caseSensitive :: FindState -> Bool
- IDE.Find: entireWord :: FindState -> Bool
- IDE.Find: entryHist :: FindState -> [Text]
- IDE.Find: entryStr :: FindState -> Text
- IDE.Find: instance Eq FindState
- IDE.Find: instance Ord FindState
- IDE.Find: instance Read FindState
- IDE.Find: instance Show FindState
- IDE.Find: lineNr :: FindState -> Int
- IDE.Find: regex :: FindState -> Bool
- IDE.Find: replaceHist :: FindState -> [Text]
- IDE.Find: replaceStr :: FindState -> Text
- IDE.Find: wrapAround :: FindState -> Bool
- IDE.ImportTool: hiddenModule :: HiddenModuleResult -> Text
- IDE.ImportTool: instance Eq HiddenModuleResult
- IDE.ImportTool: instance Eq NotInScopeParseResult
- IDE.ImportTool: instance Show HiddenModuleResult
- IDE.ImportTool: missingPackage :: HiddenModuleResult -> PackageId
- IDE.Keymap: instance Keymap KeymapI
- IDE.Leksah: instance Eq Flag
- IDE.Leksah: instance Show Flag
- IDE.Pane.Breakpoints: instance Eq BreakpointsState
- IDE.Pane.Breakpoints: instance Ord BreakpointsState
- IDE.Pane.Breakpoints: instance Pane IDEBreakpoints IDEM
- IDE.Pane.Breakpoints: instance Read BreakpointsState
- IDE.Pane.Breakpoints: instance RecoverablePane IDEBreakpoints BreakpointsState IDEM
- IDE.Pane.Breakpoints: instance Show BreakpointsState
- IDE.Pane.Breakpoints: instance Typeable BreakpointsState
- IDE.Pane.Breakpoints: instance Typeable IDEBreakpoints
- IDE.Pane.Errors: data IDEErrors
- IDE.Pane.Errors: instance Eq ErrorsState
- IDE.Pane.Errors: instance Ord ErrorsState
- IDE.Pane.Errors: instance Pane IDEErrors IDEM
- IDE.Pane.Errors: instance Read ErrorsState
- IDE.Pane.Errors: instance RecoverablePane IDEErrors ErrorsState IDEM
- IDE.Pane.Errors: instance Show ErrorsState
- IDE.Pane.Errors: instance Typeable ErrorsState
- IDE.Pane.Errors: instance Typeable IDEErrors
- IDE.Pane.Errors: selectError :: Maybe LogRef -> IDEAction
- IDE.Pane.Files: fileStore :: IDEFiles -> TreeStore FileRecord
- IDE.Pane.Files: getFiles :: Maybe PanePath -> IDEM IDEFiles
- IDE.Pane.Files: instance Eq FileRecord
- IDE.Pane.Files: instance Eq FilesState
- IDE.Pane.Files: instance Ord FileRecord
- IDE.Pane.Files: instance Ord FilesState
- IDE.Pane.Files: instance Pane IDEFiles IDEM
- IDE.Pane.Files: instance Read FilesState
- IDE.Pane.Files: instance RecoverablePane IDEFiles FilesState IDEM
- IDE.Pane.Files: instance Show FilesState
- IDE.Pane.Files: instance Typeable FilesState
- IDE.Pane.Files: instance Typeable IDEFiles
- IDE.Pane.Files: refreshFiles :: IDEAction
- IDE.Pane.Files: scrolledView :: IDEFiles -> ScrolledWindow
- IDE.Pane.Files: treeView :: IDEFiles -> TreeView
- IDE.Pane.Grep: activeGrep :: IDEGrep -> MVar Bool
- IDE.Pane.Grep: grepStore :: IDEGrep -> TreeStore GrepRecord
- IDE.Pane.Grep: instance Eq GrepState
- IDE.Pane.Grep: instance Ord GrepState
- IDE.Pane.Grep: instance Pane IDEGrep IDEM
- IDE.Pane.Grep: instance Read GrepState
- IDE.Pane.Grep: instance RecoverablePane IDEGrep GrepState IDEM
- IDE.Pane.Grep: instance Show GrepState
- IDE.Pane.Grep: instance Typeable GrepState
- IDE.Pane.Grep: instance Typeable IDEGrep
- IDE.Pane.Grep: scrolledView :: IDEGrep -> ScrolledWindow
- IDE.Pane.Grep: treeView :: IDEGrep -> TreeView
- IDE.Pane.Grep: waitingGrep :: IDEGrep -> MVar Bool
- IDE.Pane.HLint: instance Eq HLintState
- IDE.Pane.HLint: instance Ord HLintState
- IDE.Pane.HLint: instance Pane IDEHLint IDEM
- IDE.Pane.HLint: instance Read HLintState
- IDE.Pane.HLint: instance RecoverablePane IDEHLint HLintState IDEM
- IDE.Pane.HLint: instance Show HLintState
- IDE.Pane.HLint: instance Typeable HLintState
- IDE.Pane.HLint: instance Typeable IDEHLint
- IDE.Pane.Info: instance Eq InfoState
- IDE.Pane.Info: instance Ord InfoState
- IDE.Pane.Info: instance Pane IDEInfo IDEM
- IDE.Pane.Info: instance Read InfoState
- IDE.Pane.Info: instance RecoverablePane IDEInfo InfoState IDEM
- IDE.Pane.Info: instance Show InfoState
- IDE.Pane.Info: instance Typeable IDEInfo
- IDE.Pane.Info: instance Typeable InfoState
- IDE.Pane.Log: instance Eq LogState
- IDE.Pane.Log: instance Ord LogState
- IDE.Pane.Log: instance Pane IDELog IDEM
- IDE.Pane.Log: instance Read LogState
- IDE.Pane.Log: instance RecoverablePane IDELog LogState IDEM
- IDE.Pane.Log: instance Show LogState
- IDE.Pane.Log: instance Typeable IDELog
- IDE.Pane.Log: instance Typeable LogState
- IDE.Pane.Log: logButtons :: IDELog -> HBox
- IDE.Pane.Log: logLaunchBox :: IDELog -> ComboBox
- IDE.Pane.Log: logLaunchTextView :: IDELog -> TextView
- IDE.Pane.Log: logMainContainer :: IDELog -> VBox
- IDE.Pane.Modules: blacklistB :: IDEModules -> CheckButton
- IDE.Pane.Modules: dependsB :: IDEModules -> CheckButton
- IDE.Pane.Modules: descrSortedStore :: IDEModules -> TypedTreeModelSort Descr
- IDE.Pane.Modules: descrStore :: IDEModules -> TreeStore Descr
- IDE.Pane.Modules: descrView :: IDEModules -> TreeView
- IDE.Pane.Modules: expanderState :: IDEModules -> IORef ExpanderState
- IDE.Pane.Modules: instance Eq ExpanderState
- IDE.Pane.Modules: instance Eq ModulesState
- IDE.Pane.Modules: instance Eq SelectionState
- IDE.Pane.Modules: instance Ord ExpanderState
- IDE.Pane.Modules: instance Ord ModulesState
- IDE.Pane.Modules: instance Ord SelectionState
- IDE.Pane.Modules: instance Ord a => Ord (Tree a)
- IDE.Pane.Modules: instance Pane IDEModules IDEM
- IDE.Pane.Modules: instance Read ExpanderState
- IDE.Pane.Modules: instance Read ModulesState
- IDE.Pane.Modules: instance RecoverablePane IDEModules ModulesState IDEM
- IDE.Pane.Modules: instance Show ExpanderState
- IDE.Pane.Modules: instance Show ModulesState
- IDE.Pane.Modules: instance Show SelectionState
- IDE.Pane.Modules: instance Typeable IDEModules
- IDE.Pane.Modules: instance Typeable ModulesState
- IDE.Pane.Modules: oldSelection :: IDEModules -> IORef SelectionState
- IDE.Pane.Modules: outer :: IDEModules -> VBox
- IDE.Pane.Modules: packageDExp :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: packageDExpNoBlack :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: packageExp :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: packageExpNoBlack :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: packageScopeB :: IDEModules -> RadioButton
- IDE.Pane.Modules: paned :: IDEModules -> HPaned
- IDE.Pane.Modules: systemExp :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: systemExpNoBlack :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: systemScopeB :: IDEModules -> RadioButton
- IDE.Pane.Modules: treeStore :: IDEModules -> TreeStore ModuleRecord
- IDE.Pane.Modules: treeView :: IDEModules -> TreeView
- IDE.Pane.Modules: workspaceDExp :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: workspaceDExpNoBlack :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: workspaceExp :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: workspaceExpNoBlack :: ExpanderState -> ExpanderFacet
- IDE.Pane.Modules: workspaceScopeB :: IDEModules -> RadioButton
- IDE.Pane.PackageEditor: instance Default Benchmark'
- IDE.Pane.PackageEditor: instance Default BuildInfo
- IDE.Pane.PackageEditor: instance Default BuildType
- IDE.Pane.PackageEditor: instance Default CompilerFlavor
- IDE.Pane.PackageEditor: instance Default Executable
- IDE.Pane.PackageEditor: instance Default Executable'
- IDE.Pane.PackageEditor: instance Default Library
- IDE.Pane.PackageEditor: instance Default Library'
- IDE.Pane.PackageEditor: instance Default RepoKind
- IDE.Pane.PackageEditor: instance Default RepoType
- IDE.Pane.PackageEditor: instance Default SourceRepo
- IDE.Pane.PackageEditor: instance Default Test'
- IDE.Pane.PackageEditor: instance Eq Benchmark'
- IDE.Pane.PackageEditor: instance Eq Executable'
- IDE.Pane.PackageEditor: instance Eq Library'
- IDE.Pane.PackageEditor: instance Eq PackageDescriptionEd
- IDE.Pane.PackageEditor: instance Eq Test'
- IDE.Pane.PackageEditor: instance Pane PackagePane IDEM
- IDE.Pane.PackageEditor: instance Read PackageState
- IDE.Pane.PackageEditor: instance RecoverablePane PackagePane PackageState IDEM
- IDE.Pane.PackageEditor: instance Show Benchmark'
- IDE.Pane.PackageEditor: instance Show Executable'
- IDE.Pane.PackageEditor: instance Show Library'
- IDE.Pane.PackageEditor: instance Show PackageState
- IDE.Pane.PackageEditor: instance Show Test'
- IDE.Pane.PackageEditor: instance Typeable PackagePane
- IDE.Pane.PackageEditor: instance Typeable PackageState
- IDE.Pane.PackageFlags: flagsBox :: IDEFlags -> VBox
- IDE.Pane.PackageFlags: instance Eq FlagsState
- IDE.Pane.PackageFlags: instance Ord FlagsState
- IDE.Pane.PackageFlags: instance Pane IDEFlags IDEM
- IDE.Pane.PackageFlags: instance Read FlagsState
- IDE.Pane.PackageFlags: instance RecoverablePane IDEFlags FlagsState IDEM
- IDE.Pane.PackageFlags: instance Show FlagsState
- IDE.Pane.PackageFlags: instance Typeable FlagsState
- IDE.Pane.PackageFlags: instance Typeable IDEFlags
- IDE.Pane.Preferences: IDEPrefs :: VBox -> IDEPrefs
- IDE.Pane.Preferences: data IDEPrefs
- IDE.Pane.Preferences: data PrefsState
- IDE.Pane.Preferences: defaultPrefs :: Prefs
- IDE.Pane.Preferences: getPrefs :: Maybe PanePath -> IDEM IDEPrefs
- IDE.Pane.Preferences: instance Eq PrefsState
- IDE.Pane.Preferences: instance Ord PrefsState
- IDE.Pane.Preferences: instance Pane IDEPrefs IDEM
- IDE.Pane.Preferences: instance Read PrefsState
- IDE.Pane.Preferences: instance RecoverablePane IDEPrefs PrefsState IDEM
- IDE.Pane.Preferences: instance Show PrefsState
- IDE.Pane.Preferences: instance Typeable IDEPrefs
- IDE.Pane.Preferences: instance Typeable PrefsState
- IDE.Pane.Preferences: prefsBox :: IDEPrefs -> VBox
- IDE.Pane.Preferences: prefsDescription :: FilePath -> [PackageIdentifier] -> FieldDescriptionPP Prefs IDEM
- IDE.Pane.Preferences: readPrefs :: FilePath -> IO Prefs
- IDE.Pane.Preferences: writePrefs :: FilePath -> Prefs -> IO ()
- IDE.Pane.Search: entry :: IDESearch -> Entry
- IDE.Pane.Search: instance Eq SearchState
- IDE.Pane.Search: instance Ord SearchState
- IDE.Pane.Search: instance Pane IDESearch IDEM
- IDE.Pane.Search: instance Read SearchState
- IDE.Pane.Search: instance RecoverablePane IDESearch SearchState IDEM
- IDE.Pane.Search: instance Show SearchState
- IDE.Pane.Search: instance Typeable IDESearch
- IDE.Pane.Search: instance Typeable SearchState
- IDE.Pane.Search: modeSelection :: IDESearch -> SearchMode -> IDEAction
- IDE.Pane.Search: scopeSelection :: IDESearch -> Scope -> IDEAction
- IDE.Pane.Search: scrolledView :: IDESearch -> ScrolledWindow
- IDE.Pane.Search: searchMetaGUI :: IDESearch -> Text -> IDEAction
- IDE.Pane.Search: searchModeRef :: IDESearch -> IORef SearchMode
- IDE.Pane.Search: searchScopeRef :: IDESearch -> IORef Scope
- IDE.Pane.Search: searchStore :: IDESearch -> ListStore Descr
- IDE.Pane.Search: setChoices :: IDESearch -> [Descr] -> IDEAction
- IDE.Pane.Search: topBox :: IDESearch -> VBox
- IDE.Pane.Search: treeView :: IDESearch -> TreeView
- IDE.Pane.SourceBuffer: addedIndex :: IDEBuffer -> Int
- IDE.Pane.SourceBuffer: bufferName :: IDEBuffer -> Text
- IDE.Pane.SourceBuffer: editCandy :: ReaderT IDERef IO ()
- IDE.Pane.SourceBuffer: fileName :: IDEBuffer -> Maybe FilePath
- IDE.Pane.SourceBuffer: instance Eq CharacterCategory
- IDE.Pane.SourceBuffer: instance RecoverablePane IDEBuffer BufferState IDEM
- IDE.Pane.SourceBuffer: modTime :: IDEBuffer -> IORef (Maybe UTCTime)
- IDE.Pane.SourceBuffer: mode :: IDEBuffer -> Mode
- IDE.Pane.SourceBuffer: scrolledWindow :: IDEBuffer -> ScrolledWindow
- IDE.Pane.SourceBuffer: sourceView :: IDEBuffer -> EditorView editor
- IDE.Pane.Trace: instance Eq TraceState
- IDE.Pane.Trace: instance Ord TraceState
- IDE.Pane.Trace: instance Pane IDETrace IDEM
- IDE.Pane.Trace: instance Read TraceState
- IDE.Pane.Trace: instance RecoverablePane IDETrace TraceState IDEM
- IDE.Pane.Trace: instance Show TraceState
- IDE.Pane.Trace: instance Typeable IDETrace
- IDE.Pane.Trace: instance Typeable TraceState
- IDE.Pane.Variables: instance Eq VariablesState
- IDE.Pane.Variables: instance Ord VariablesState
- IDE.Pane.Variables: instance Pane IDEVariables IDEM
- IDE.Pane.Variables: instance Read VariablesState
- IDE.Pane.Variables: instance RecoverablePane IDEVariables VariablesState IDEM
- IDE.Pane.Variables: instance Show VariablesState
- IDE.Pane.Variables: instance Typeable IDEVariables
- IDE.Pane.Variables: instance Typeable VariablesState
- IDE.Pane.WebKit.Documentation: instance Eq DocumentationState
- IDE.Pane.WebKit.Documentation: instance Ord DocumentationState
- IDE.Pane.WebKit.Documentation: instance Pane IDEDocumentation IDEM
- IDE.Pane.WebKit.Documentation: instance Read DocumentationState
- IDE.Pane.WebKit.Documentation: instance RecoverablePane IDEDocumentation DocumentationState IDEM
- IDE.Pane.WebKit.Documentation: instance Show DocumentationState
- IDE.Pane.WebKit.Documentation: instance Typeable DocumentationState
- IDE.Pane.WebKit.Documentation: instance Typeable IDEDocumentation
- IDE.Pane.WebKit.Documentation: scrolledView :: IDEDocumentation -> ScrolledWindow
- IDE.Pane.WebKit.Documentation: uri :: DocumentationState -> Maybe Text
- IDE.Pane.WebKit.Documentation: webView :: IDEDocumentation -> WebView
- IDE.Pane.WebKit.Documentation: zoom :: DocumentationState -> Float
- IDE.Pane.WebKit.Inspect: inspectView :: IDEInspect -> WebView
- IDE.Pane.WebKit.Inspect: instance Eq InspectState
- IDE.Pane.WebKit.Inspect: instance Ord InspectState
- IDE.Pane.WebKit.Inspect: instance Pane IDEInspect IDEM
- IDE.Pane.WebKit.Inspect: instance Read InspectState
- IDE.Pane.WebKit.Inspect: instance RecoverablePane IDEInspect InspectState IDEM
- IDE.Pane.WebKit.Inspect: instance Show InspectState
- IDE.Pane.WebKit.Inspect: instance Typeable IDEInspect
- IDE.Pane.WebKit.Inspect: instance Typeable InspectState
- IDE.Pane.WebKit.Inspect: scrollWin :: IDEInspect -> ScrolledWindow
- IDE.Pane.WebKit.Output: alwaysHtml :: OutputState -> Bool
- IDE.Pane.WebKit.Output: alwaysHtmlRef :: IDEOutput -> IORef Bool
- IDE.Pane.WebKit.Output: instance Eq OutputState
- IDE.Pane.WebKit.Output: instance Ord OutputState
- IDE.Pane.WebKit.Output: instance Pane IDEOutput IDEM
- IDE.Pane.WebKit.Output: instance Read OutputState
- IDE.Pane.WebKit.Output: instance RecoverablePane IDEOutput OutputState IDEM
- IDE.Pane.WebKit.Output: instance Show OutputState
- IDE.Pane.WebKit.Output: instance Typeable IDEOutput
- IDE.Pane.WebKit.Output: instance Typeable OutputState
- IDE.Pane.WebKit.Output: uriEntry :: IDEOutput -> Entry
- IDE.Pane.WebKit.Output: vbox :: IDEOutput -> VBox
- IDE.Pane.WebKit.Output: webView :: IDEOutput -> WebView
- IDE.Pane.WebKit.Output: zoom :: OutputState -> Float
- IDE.Pane.Workspace: data IDEWorkspace
- IDE.Pane.Workspace: getWorkspace :: Maybe PanePath -> IDEM IDEWorkspace
- IDE.Pane.Workspace: instance Eq WorkspaceState
- IDE.Pane.Workspace: instance Ord WorkspaceState
- IDE.Pane.Workspace: instance Pane IDEWorkspace IDEM
- IDE.Pane.Workspace: instance Read WorkspaceState
- IDE.Pane.Workspace: instance RecoverablePane IDEWorkspace WorkspaceState IDEM
- IDE.Pane.Workspace: instance Show WorkspaceState
- IDE.Pane.Workspace: instance Typeable IDEWorkspace
- IDE.Pane.Workspace: instance Typeable WorkspaceState
- IDE.Pane.Workspace: showWorkspace :: IDEAction
- IDE.Pane.Workspace: updateWorkspace :: Bool -> Bool -> IDEAction
- IDE.Session: instance Eq PaneState
- IDE.Session: instance Ord PaneState
- IDE.Session: instance Read PaneState
- IDE.Session: instance Show PaneState
- IDE.Session: viewDark :: IDEAction
- IDE.SymbolNavigation: instance Eq Locality
- IDE.SymbolNavigation: instance Ord Locality
- IDE.SymbolNavigation: instance Show Locality
- IDE.TextEditor.Class: breakpointBG :: EditorStyle -> (Color, Color)
- IDE.TextEditor.Class: contextBG :: EditorStyle -> (Color, Color)
- IDE.TextEditor.Class: foundBG :: EditorStyle -> (Color, Color)
- IDE.TextEditor.Class: lintBG :: EditorStyle -> (Color, Color)
- IDE.TextEditor.Class: matchBG :: EditorStyle -> (Color, Color)
- IDE.TextEditor.Class: preferDark :: EditorStyle -> Bool
- IDE.TextEditor.Class: styleName :: EditorStyle -> Maybe Text
- IDE.TextEditor.CodeMirror: instance Show CodeMirror
- IDE.TextEditor.CodeMirror: instance TextEditor CodeMirror
- IDE.TextEditor.CodeMirror: instance Typeable CodeMirror
- IDE.TextEditor.GtkSourceView: instance Show GtkSourceView
- IDE.TextEditor.GtkSourceView: instance TextEditor GtkSourceView
- IDE.TextEditor.GtkSourceView: instance Typeable GtkSourceView
- IDE.TextEditor.Yi: instance Show Yi
- IDE.TextEditor.Yi: instance Typeable Yi
- IDE.Utils.GUIUtils: getCandyState :: PaneMonad alpha => alpha Bool
- IDE.Utils.GUIUtils: getForgetSession :: PaneMonad alpha => alpha Bool
- IDE.Utils.GUIUtils: setCandyState :: PaneMonad alpha => Bool -> alpha ()
+ IDE.BufferMode: [addedIndex] :: IDEBuffer -> Int
+ IDE.BufferMode: [bufferName] :: IDEBuffer -> Text
+ IDE.BufferMode: [fileName] :: IDEBuffer -> Maybe FilePath
+ IDE.BufferMode: [modTime] :: IDEBuffer -> IORef (Maybe UTCTime)
+ IDE.BufferMode: [modeEditComment] :: Mode -> IDEAction
+ IDE.BufferMode: [modeEditFromCandy] :: Mode -> IDEAction
+ IDE.BufferMode: [modeEditInCommentOrString] :: Mode -> Text -> Bool
+ IDE.BufferMode: [modeEditInsertCode] :: Mode -> forall editor. TextEditor editor => Text -> EditorIter editor -> EditorBuffer editor -> IDEAction
+ IDE.BufferMode: [modeEditKeystrokeCandy] :: Mode -> Maybe Char -> (Text -> Bool) -> IDEAction
+ IDE.BufferMode: [modeEditToCandy] :: Mode -> (Text -> Bool) -> IDEAction
+ IDE.BufferMode: [modeEditUncomment] :: Mode -> IDEAction
+ IDE.BufferMode: [modeName] :: Mode -> Text
+ IDE.BufferMode: [modeSelectedModuleName] :: Mode -> IDEM (Maybe Text)
+ IDE.BufferMode: [modeTransformFromCandy] :: Mode -> forall editor. TextEditor editor => EditorBuffer editor -> IDEAction
+ IDE.BufferMode: [modeTransformToCandy] :: Mode -> forall editor. TextEditor editor => (Text -> Bool) -> EditorBuffer editor -> IDEAction
+ IDE.BufferMode: [mode] :: IDEBuffer -> Mode
+ IDE.BufferMode: [scrolledWindow] :: IDEBuffer -> ScrolledWindow
+ IDE.BufferMode: [sourceView] :: IDEBuffer -> EditorView editor
+ IDE.BufferMode: instance GHC.Classes.Eq IDE.BufferMode.BufferState
+ IDE.BufferMode: instance GHC.Classes.Ord IDE.BufferMode.BufferState
+ IDE.BufferMode: instance GHC.Read.Read IDE.BufferMode.BufferState
+ IDE.BufferMode: instance GHC.Show.Show IDE.BufferMode.BufferState
+ IDE.BufferMode: instance Graphics.UI.Frame.Panes.Pane IDE.BufferMode.IDEBuffer IDE.Core.Types.IDEM
+ IDE.Build: [msBackgroundBuild] :: MakeSettings -> Bool
+ IDE.Build: [msDontInstallLast] :: MakeSettings -> Bool
+ IDE.Build: [msJumpToWarnings] :: MakeSettings -> Bool
+ IDE.Build: [msMakeMode] :: MakeSettings -> Bool
+ IDE.Build: [msRunUnitTests] :: MakeSettings -> Bool
+ IDE.Build: [msSaveAllBeforeBuild] :: MakeSettings -> Bool
+ IDE.Build: [msSingleBuildWithoutLinking] :: MakeSettings -> Bool
+ IDE.Build: instance (GHC.Show.Show alpha, GHC.Show.Show beta) => GHC.Show.Show (IDE.Build.Chain alpha beta)
+ IDE.Build: instance GHC.Classes.Eq IDE.Build.MakeOp
+ IDE.Build: instance GHC.Classes.Ord IDE.Build.MakeOp
+ IDE.Build: instance GHC.Show.Show IDE.Build.MakeOp
+ IDE.Command.Print: [exitCode] :: PrintError -> Int
+ IDE.Command.Print: [printCmd] :: PrintError -> FilePath
+ IDE.Command.Print: [stderr] :: PrintError -> Text
+ IDE.Command.Print: instance GHC.Read.Read IDE.Command.Print.PrintError
+ IDE.Command.Print: instance GHC.Show.Show IDE.Command.Print.PrintError
+ IDE.Command.VCS.Types: instance Control.Monad.IO.Class.MonadIO IDE.Command.VCS.Types.VCSAction
+ IDE.Command.VCS.Types: instance Control.Monad.Reader.Class.MonadReader (IDE.Core.Types.VCSConf, GHC.IO.FilePath) IDE.Command.VCS.Types.VCSAction
+ IDE.Command.VCS.Types: instance GHC.Base.Applicative IDE.Command.VCS.Types.VCSAction
+ IDE.Command.VCS.Types: instance GHC.Base.Functor IDE.Command.VCS.Types.VCSAction
+ IDE.Command.VCS.Types: instance GHC.Base.Monad IDE.Command.VCS.Types.VCSAction
+ IDE.Core.State: instance GHC.Classes.Eq IDE.Core.State.MessageLevel
+ IDE.Core.State: instance GHC.Classes.Ord IDE.Core.State.MessageLevel
+ IDE.Core.State: instance GHC.Exception.Exception IDE.Core.State.IDEException
+ IDE.Core.State: instance GHC.Show.Show IDE.Core.State.IDEException
+ IDE.Core.State: instance GHC.Show.Show IDE.Core.State.MessageLevel
+ IDE.Core.State: instance Graphics.UI.Frame.Panes.PaneMonad IDE.Core.Types.IDEM
+ IDE.Core.Types: [accelerator] :: ActionDescr alpha -> [KeyString]
+ IDE.Core.Types: [action] :: ActionDescr alpha -> ReaderT alpha IO ()
+ IDE.Core.Types: [activeExe] :: IDE -> Maybe Text
+ IDE.Core.Types: [activePack] :: IDE -> Maybe IDEPackage
+ IDE.Core.Types: [allLogRefs] :: IDE -> Seq LogRef
+ IDE.Core.Types: [autoCommand] :: IDE -> IDEAction
+ IDE.Core.Types: [autoLoad] :: Prefs -> Bool
+ IDE.Core.Types: [autoURI] :: IDE -> Maybe Text
+ IDE.Core.Types: [backgroundBuild] :: Prefs -> Bool
+ IDE.Core.Types: [blacklist] :: GUIHistory' -> Bool
+ IDE.Core.Types: [breakOnError] :: Prefs -> Bool
+ IDE.Core.Types: [breakOnException] :: Prefs -> Bool
+ IDE.Core.Types: [breakpointBG] :: EditorStyle -> (Color, Color)
+ IDE.Core.Types: [breakpointBackgroundDark] :: Prefs -> Color
+ IDE.Core.Types: [breakpointBackgroundLight] :: Prefs -> Color
+ IDE.Core.Types: [browser] :: Prefs -> Text
+ IDE.Core.Types: [bufferProjCache] :: IDE -> Map FilePath [IDEPackage]
+ IDE.Core.Types: [candy] :: IDE -> CandyTable
+ IDE.Core.Types: [caseSense] :: SearchMode -> Bool
+ IDE.Core.Types: [categoryForPane] :: Prefs -> [(Text, Text)]
+ IDE.Core.Types: [collectAtStart] :: Prefs -> Bool
+ IDE.Core.Types: [completeRestricted] :: Prefs -> Bool
+ IDE.Core.Types: [completion] :: IDE -> ((Int, Int), Maybe CompletionWindow)
+ IDE.Core.Types: [contextBG] :: EditorStyle -> (Color, Color)
+ IDE.Core.Types: [contextBackgroundDark] :: Prefs -> Color
+ IDE.Core.Types: [contextBackgroundLight] :: Prefs -> Color
+ IDE.Core.Types: [currentEBC] :: IDE -> (Maybe LogRef, Maybe LogRef, Maybe LogRef)
+ IDE.Core.Types: [currentHist] :: IDE -> Int
+ IDE.Core.Types: [currentState] :: IDE -> IDEState
+ IDE.Core.Types: [cwListStore] :: CompletionWindow -> ListStore Text
+ IDE.Core.Types: [cwTreeView] :: CompletionWindow -> TreeView
+ IDE.Core.Types: [cwWindow] :: CompletionWindow -> Window
+ IDE.Core.Types: [darkUserInterface] :: Prefs -> Bool
+ IDE.Core.Types: [debugState] :: IDE -> Maybe (IDEPackage, ToolState)
+ IDE.Core.Types: [defaultPath] :: Prefs -> PanePath
+ IDE.Core.Types: [defaultSize] :: Prefs -> (Int, Int)
+ IDE.Core.Types: [docuSearchURL] :: Prefs -> Text
+ IDE.Core.Types: [dontInstallLast] :: Prefs -> Bool
+ IDE.Core.Types: [endWithLastConn] :: Prefs -> Bool
+ IDE.Core.Types: [facetS] :: GUIHistory' -> Maybe Text
+ IDE.Core.Types: [findbar] :: IDE -> (Bool, Maybe (Toolbar, ListStore Text))
+ IDE.Core.Types: [forceLineEnds] :: Prefs -> Bool
+ IDE.Core.Types: [foundBG] :: EditorStyle -> (Color, Color)
+ IDE.Core.Types: [foundBackgroundDark] :: Prefs -> Color
+ IDE.Core.Types: [foundBackgroundLight] :: Prefs -> Color
+ IDE.Core.Types: [frameState] :: IDE -> FrameState IDEM
+ IDE.Core.Types: [guiHistory] :: IDE -> (Bool, [GUIHistory], Int)
+ IDE.Core.Types: [handlers] :: IDE -> Map Text [(Unique, IDEEvent -> IDEM IDEEvent)]
+ IDE.Core.Types: [hlintOnSave] :: Prefs -> Bool
+ IDE.Core.Types: [hlintQueue] :: IDE -> Maybe (TVar [Either FilePath FilePath])
+ IDE.Core.Types: [ipdBenchmarks] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdBuildFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdCabalFile] :: IDEPackage -> FilePath
+ IDE.Core.Types: [ipdConfigFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdDepends] :: IDEPackage -> [Dependency]
+ IDE.Core.Types: [ipdExeFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdExes] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdExtensions] :: IDEPackage -> [Extension]
+ IDE.Core.Types: [ipdExtraSrcs] :: IDEPackage -> Set FilePath
+ IDE.Core.Types: [ipdHaddockFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdHasLibs] :: IDEPackage -> Bool
+ IDE.Core.Types: [ipdInstallFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdMain] :: IDEPackage -> [(FilePath, BuildInfo, Bool)]
+ IDE.Core.Types: [ipdModules] :: IDEPackage -> Map ModuleName BuildInfo
+ IDE.Core.Types: [ipdPackageId] :: IDEPackage -> PackageIdentifier
+ IDE.Core.Types: [ipdRegisterFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdSandboxSources] :: IDEPackage -> [IDEPackage]
+ IDE.Core.Types: [ipdSdistFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdSrcDirs] :: IDEPackage -> [FilePath]
+ IDE.Core.Types: [ipdTestFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdTests] :: IDEPackage -> [Text]
+ IDE.Core.Types: [ipdUnregisterFlags] :: IDEPackage -> [Text]
+ IDE.Core.Types: [isToggle] :: ActionDescr alpha -> Bool
+ IDE.Core.Types: [jumpToWarnings] :: Prefs -> Bool
+ IDE.Core.Types: [keymapName] :: Prefs -> Text
+ IDE.Core.Types: [label] :: ActionDescr alpha -> Text
+ IDE.Core.Types: [lintBG] :: EditorStyle -> (Color, Color)
+ IDE.Core.Types: [lintBackgroundDark] :: Prefs -> Color
+ IDE.Core.Types: [lintBackgroundLight] :: Prefs -> Color
+ IDE.Core.Types: [logBuffer] :: LogLaunch -> TextBuffer
+ IDE.Core.Types: [logLaunch] :: LogLaunchData -> LogLaunch
+ IDE.Core.Types: [logLaunches] :: IDE -> Map Text LogLaunchData
+ IDE.Core.Types: [logLines] :: LogRef -> Maybe (Int, Int)
+ IDE.Core.Types: [logRefIdea] :: LogRef -> Maybe (Text, Idea)
+ IDE.Core.Types: [logRefPackage] :: LogRef -> IDEPackage
+ IDE.Core.Types: [logRefSrcSpan] :: LogRef -> SrcSpan
+ IDE.Core.Types: [logRefType] :: LogRef -> LogRefType
+ IDE.Core.Types: [logviewFont] :: Prefs -> Maybe Text
+ IDE.Core.Types: [makeMode] :: Prefs -> Bool
+ IDE.Core.Types: [matchBG] :: EditorStyle -> (Color, Color)
+ IDE.Core.Types: [matchBackgroundDark] :: Prefs -> Color
+ IDE.Core.Types: [matchBackgroundLight] :: Prefs -> Color
+ IDE.Core.Types: [mbInfo] :: GUIHistory' -> Maybe Descr
+ IDE.Core.Types: [mbPid] :: LogLaunchData -> Maybe ProcessHandle
+ IDE.Core.Types: [moduleS] :: GUIHistory' -> Maybe ModuleName
+ IDE.Core.Types: [name] :: ActionDescr alpha -> ActionString
+ IDE.Core.Types: [packageBlacklist] :: Prefs -> [Dependency]
+ IDE.Core.Types: [packageInfo] :: IDE -> Maybe (GenScope, GenScope)
+ IDE.Core.Types: [packageVcsConf] :: Workspace -> Map FilePath VCSConf
+ IDE.Core.Types: [paneN] :: GUIHistory' -> Maybe Text
+ IDE.Core.Types: [pathForCategory] :: Prefs -> [(Text, PanePath)]
+ IDE.Core.Types: [preferDark] :: EditorStyle -> Bool
+ IDE.Core.Types: [prefsFormat] :: Prefs -> Int
+ IDE.Core.Types: [prefsSaveTime] :: Prefs -> Text
+ IDE.Core.Types: [prefs] :: IDE -> Prefs
+ IDE.Core.Types: [printBindResult] :: Prefs -> Bool
+ IDE.Core.Types: [printEvldWithShow] :: Prefs -> Bool
+ IDE.Core.Types: [recentFiles] :: IDE -> [FilePath]
+ IDE.Core.Types: [recentPanes] :: IDE -> [PaneName]
+ IDE.Core.Types: [recentWorkspaces] :: IDE -> [FilePath]
+ IDE.Core.Types: [refDescription] :: LogRef -> Text
+ IDE.Core.Types: [removeTBlanks] :: Prefs -> Bool
+ IDE.Core.Types: [retrieveStrategy] :: Prefs -> RetrieveStrategy
+ IDE.Core.Types: [retrieveURL] :: Prefs -> Text
+ IDE.Core.Types: [rightMargin] :: Prefs -> (Bool, Int)
+ IDE.Core.Types: [runUnitTests] :: Prefs -> Bool
+ IDE.Core.Types: [runningTool] :: IDE -> Maybe ProcessHandle
+ IDE.Core.Types: [saveAllBeforeBuild] :: Prefs -> Bool
+ IDE.Core.Types: [saveSessionOnClose] :: Prefs -> Bool
+ IDE.Core.Types: [scope] :: GUIHistory' -> Scope
+ IDE.Core.Types: [serverIP] :: Prefs -> Text
+ IDE.Core.Types: [serverPort] :: Prefs -> Int
+ IDE.Core.Types: [serverQueue] :: IDE -> Maybe (MVar (ServerCommand, ServerAnswer -> IDEM ()))
+ IDE.Core.Types: [server] :: IDE -> Maybe Handle
+ IDE.Core.Types: [showHiddenFiles] :: Prefs -> Bool
+ IDE.Core.Types: [showLineNumbers] :: Prefs -> Bool
+ IDE.Core.Types: [showWorkspaceIcons] :: Prefs -> Bool
+ IDE.Core.Types: [singleBuildWithoutLinking] :: Prefs -> Bool
+ IDE.Core.Types: [sourceCandy] :: Prefs -> (Bool, Text)
+ IDE.Core.Types: [sourceDirectories] :: Prefs -> [FilePath]
+ IDE.Core.Types: [sourceStyle] :: Prefs -> (Bool, Text)
+ IDE.Core.Types: [specialKey] :: IDE -> SpecialKeyCons IDERef
+ IDE.Core.Types: [specialKeys] :: IDE -> SpecialKeyTable IDERef
+ IDE.Core.Types: [stockID] :: ActionDescr alpha -> Maybe Text
+ IDE.Core.Types: [styleName] :: EditorStyle -> Maybe Text
+ IDE.Core.Types: [systemInfo] :: IDE -> Maybe GenScope
+ IDE.Core.Types: [tabWidth] :: Prefs -> Int
+ IDE.Core.Types: [textEditorType] :: Prefs -> Text
+ IDE.Core.Types: [textviewFont] :: Prefs -> Maybe Text
+ IDE.Core.Types: [toolbar] :: IDE -> (Bool, Maybe Toolbar)
+ IDE.Core.Types: [tooltip] :: ActionDescr alpha -> Maybe Text
+ IDE.Core.Types: [unpackDirectory] :: Prefs -> Maybe FilePath
+ IDE.Core.Types: [useCabalDev] :: Prefs -> Bool
+ IDE.Core.Types: [useCtrlTabFlipping] :: Prefs -> Bool
+ IDE.Core.Types: [useVado] :: Prefs -> Bool
+ IDE.Core.Types: [vcsData] :: IDE -> (Map FilePath MenuItem, Maybe (Maybe Text))
+ IDE.Core.Types: [workspInfoCache] :: IDE -> PackageDescrCache
+ IDE.Core.Types: [workspaceInfo] :: IDE -> Maybe (GenScope, GenScope)
+ IDE.Core.Types: [workspace] :: IDE -> Maybe Workspace
+ IDE.Core.Types: [wrapLines] :: Prefs -> Bool
+ IDE.Core.Types: [wsActiveExe] :: Workspace -> Maybe Text
+ IDE.Core.Types: [wsActivePackFile] :: Workspace -> Maybe FilePath
+ IDE.Core.Types: [wsFile] :: Workspace -> FilePath
+ IDE.Core.Types: [wsName] :: Workspace -> Text
+ IDE.Core.Types: [wsNobuildPack] :: Workspace -> [IDEPackage]
+ IDE.Core.Types: [wsPackagesFiles] :: Workspace -> [FilePath]
+ IDE.Core.Types: [wsPackages] :: Workspace -> [IDEPackage]
+ IDE.Core.Types: [wsSaveTime] :: Workspace -> Text
+ IDE.Core.Types: [wsVersion] :: Workspace -> Int
+ IDE.Core.Types: [yiControl] :: IDE -> Control
+ IDE.Core.Types: candyState :: Prefs -> Bool
+ IDE.Core.Types: instance Control.Event.Event IDE.Core.Types.IDEEvent Data.Text.Internal.Text
+ IDE.Core.Types: instance Control.Event.EventSelector Data.Text.Internal.Text
+ IDE.Core.Types: instance Control.Event.EventSource IDE.Core.Types.IDERef IDE.Core.Types.IDEEvent IDE.Core.Types.IDEM Data.Text.Internal.Text
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.GUIHistory'
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.IDEPackage
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.LogRef
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.LogRefType
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.Prefs
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.SearchHint
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.SearchMode
+ IDE.Core.Types: instance GHC.Classes.Eq IDE.Core.Types.SensitivityMask
+ IDE.Core.Types: instance GHC.Classes.Ord Graphics.UI.Gtk.Gdk.Enums.Modifier
+ IDE.Core.Types: instance GHC.Classes.Ord IDE.Core.Types.GUIHistory'
+ IDE.Core.Types: instance GHC.Classes.Ord IDE.Core.Types.IDEPackage
+ IDE.Core.Types: instance GHC.Classes.Ord IDE.Core.Types.LogRefType
+ IDE.Core.Types: instance GHC.Classes.Ord IDE.Core.Types.SearchMode
+ IDE.Core.Types: instance GHC.Classes.Ord IDE.Core.Types.SensitivityMask
+ IDE.Core.Types: instance GHC.Enum.Bounded IDE.Core.Types.LogRefType
+ IDE.Core.Types: instance GHC.Enum.Enum IDE.Core.Types.LogRefType
+ IDE.Core.Types: instance GHC.Read.Read IDE.Core.Types.SearchMode
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.GUIHistory'
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.IDEPackage
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.LogRef
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.LogRefType
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.Prefs
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.SearchMode
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.SensitivityMask
+ IDE.Core.Types: instance GHC.Show.Show IDE.Core.Types.Workspace
+ IDE.Core.Types: instance IDE.Core.Types.MonadIDE (IDE.Core.Types.IDEEventM t)
+ IDE.Core.Types: instance IDE.Core.Types.MonadIDE IDE.Core.Types.IDEM
+ IDE.Core.Types: instance IDE.Core.Types.MonadIDE IDE.Core.Types.PackageM
+ IDE.Core.Types: instance IDE.Core.Types.MonadIDE IDE.Core.Types.WorkspaceM
+ IDE.Core.Types: ipdLib :: IDEPackage -> Maybe Text
+ IDE.Core.Types: ipdPackageDir :: IDEPackage -> FilePath
+ IDE.Core.Types: ipdPackageName :: IDEPackage -> Text
+ IDE.Find: [caseSensitive] :: FindState -> Bool
+ IDE.Find: [entireWord] :: FindState -> Bool
+ IDE.Find: [entryHist] :: FindState -> [Text]
+ IDE.Find: [entryStr] :: FindState -> Text
+ IDE.Find: [lineNr] :: FindState -> Int
+ IDE.Find: [regex] :: FindState -> Bool
+ IDE.Find: [replaceHist] :: FindState -> [Text]
+ IDE.Find: [replaceStr] :: FindState -> Text
+ IDE.Find: [wrapAround] :: FindState -> Bool
+ IDE.Find: instance GHC.Classes.Eq IDE.Find.FindState
+ IDE.Find: instance GHC.Classes.Ord IDE.Find.FindState
+ IDE.Find: instance GHC.Read.Read IDE.Find.FindState
+ IDE.Find: instance GHC.Show.Show IDE.Find.FindState
+ IDE.ImportTool: [hiddenModule] :: HiddenModuleResult -> Text
+ IDE.ImportTool: [missingPackage] :: HiddenModuleResult -> PackageId
+ IDE.ImportTool: instance GHC.Classes.Eq IDE.ImportTool.HiddenModuleResult
+ IDE.ImportTool: instance GHC.Classes.Eq IDE.ImportTool.NotInScopeParseResult
+ IDE.ImportTool: instance GHC.Show.Show IDE.ImportTool.HiddenModuleResult
+ IDE.ImportTool: resolveMenuItems :: LogRef -> [(Text, IDEAction)]
+ IDE.Keymap: instance IDE.Keymap.Keymap IDE.Core.Types.KeymapI
+ IDE.Leksah: instance GHC.Classes.Eq IDE.Leksah.Flag
+ IDE.Leksah: instance GHC.Show.Show IDE.Leksah.Flag
+ IDE.Metainfo.Provider: getAllPackageIds :: IDEM [PackageIdentifier]
+ IDE.Metainfo.Provider: getAllPackageIds' :: IDEM (Either Text [PackageIdentifier])
+ IDE.Pane.Breakpoints: instance GHC.Classes.Eq IDE.Pane.Breakpoints.BreakpointsState
+ IDE.Pane.Breakpoints: instance GHC.Classes.Ord IDE.Pane.Breakpoints.BreakpointsState
+ IDE.Pane.Breakpoints: instance GHC.Read.Read IDE.Pane.Breakpoints.BreakpointsState
+ IDE.Pane.Breakpoints: instance GHC.Show.Show IDE.Pane.Breakpoints.BreakpointsState
+ IDE.Pane.Breakpoints: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Breakpoints.IDEBreakpoints IDE.Core.Types.IDEM
+ IDE.Pane.Breakpoints: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Breakpoints.IDEBreakpoints IDE.Pane.Breakpoints.BreakpointsState IDE.Core.Types.IDEM
+ IDE.Pane.Errors: data ErrorsPane
+ IDE.Pane.Errors: instance GHC.Classes.Eq IDE.Pane.Errors.ErrorRecord
+ IDE.Pane.Errors: instance GHC.Classes.Eq IDE.Pane.Errors.ErrorsState
+ IDE.Pane.Errors: instance GHC.Classes.Ord IDE.Pane.Errors.ErrorsState
+ IDE.Pane.Errors: instance GHC.Read.Read IDE.Pane.Errors.ErrorsState
+ IDE.Pane.Errors: instance GHC.Show.Show IDE.Pane.Errors.ErrorsState
+ IDE.Pane.Errors: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Errors.ErrorsPane IDE.Core.Types.IDEM
+ IDE.Pane.Errors: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Errors.ErrorsPane IDE.Pane.Errors.ErrorsState IDE.Core.Types.IDEM
+ IDE.Pane.Files: [deprecatedLabel] :: IDEFiles -> Label
+ IDE.Pane.Files: instance GHC.Classes.Eq IDE.Pane.Files.FilesState
+ IDE.Pane.Files: instance GHC.Classes.Ord IDE.Pane.Files.FilesState
+ IDE.Pane.Files: instance GHC.Read.Read IDE.Pane.Files.FilesState
+ IDE.Pane.Files: instance GHC.Show.Show IDE.Pane.Files.FilesState
+ IDE.Pane.Files: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Files.IDEFiles IDE.Core.Types.IDEM
+ IDE.Pane.Files: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Files.IDEFiles IDE.Pane.Files.FilesState IDE.Core.Types.IDEM
+ IDE.Pane.Grep: [activeGrep] :: IDEGrep -> MVar Bool
+ IDE.Pane.Grep: [grepStore] :: IDEGrep -> TreeStore GrepRecord
+ IDE.Pane.Grep: [scrolledView] :: IDEGrep -> ScrolledWindow
+ IDE.Pane.Grep: [treeView] :: IDEGrep -> TreeView
+ IDE.Pane.Grep: [waitingGrep] :: IDEGrep -> MVar Bool
+ IDE.Pane.Grep: instance GHC.Classes.Eq IDE.Pane.Grep.GrepState
+ IDE.Pane.Grep: instance GHC.Classes.Ord IDE.Pane.Grep.GrepState
+ IDE.Pane.Grep: instance GHC.Read.Read IDE.Pane.Grep.GrepState
+ IDE.Pane.Grep: instance GHC.Show.Show IDE.Pane.Grep.GrepState
+ IDE.Pane.Grep: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Grep.IDEGrep IDE.Core.Types.IDEM
+ IDE.Pane.Grep: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Grep.IDEGrep IDE.Pane.Grep.GrepState IDE.Core.Types.IDEM
+ IDE.Pane.HLint: instance GHC.Classes.Eq IDE.Pane.HLint.HLintState
+ IDE.Pane.HLint: instance GHC.Classes.Ord IDE.Pane.HLint.HLintState
+ IDE.Pane.HLint: instance GHC.Read.Read IDE.Pane.HLint.HLintState
+ IDE.Pane.HLint: instance GHC.Show.Show IDE.Pane.HLint.HLintState
+ IDE.Pane.HLint: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.HLint.IDEHLint IDE.Core.Types.IDEM
+ IDE.Pane.HLint: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.HLint.IDEHLint IDE.Pane.HLint.HLintState IDE.Core.Types.IDEM
+ IDE.Pane.Info: instance GHC.Classes.Eq IDE.Pane.Info.InfoState
+ IDE.Pane.Info: instance GHC.Classes.Ord IDE.Pane.Info.InfoState
+ IDE.Pane.Info: instance GHC.Read.Read IDE.Pane.Info.InfoState
+ IDE.Pane.Info: instance GHC.Show.Show IDE.Pane.Info.InfoState
+ IDE.Pane.Info: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Info.IDEInfo IDE.Core.Types.IDEM
+ IDE.Pane.Info: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Info.IDEInfo IDE.Pane.Info.InfoState IDE.Core.Types.IDEM
+ IDE.Pane.Log: [logButtons] :: IDELog -> HBox
+ IDE.Pane.Log: [logLaunchBox] :: IDELog -> ComboBox
+ IDE.Pane.Log: [logLaunchTextView] :: IDELog -> TextView
+ IDE.Pane.Log: [logMainContainer] :: IDELog -> VBox
+ IDE.Pane.Log: instance GHC.Classes.Eq IDE.Pane.Log.LogState
+ IDE.Pane.Log: instance GHC.Classes.Ord IDE.Pane.Log.LogState
+ IDE.Pane.Log: instance GHC.Read.Read IDE.Pane.Log.LogState
+ IDE.Pane.Log: instance GHC.Show.Show IDE.Pane.Log.LogState
+ IDE.Pane.Log: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Log.IDELog IDE.Core.Types.IDEM
+ IDE.Pane.Log: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Log.IDELog IDE.Pane.Log.LogState IDE.Core.Types.IDEM
+ IDE.Pane.Modules: [blacklistB] :: IDEModules -> CheckButton
+ IDE.Pane.Modules: [dependsB] :: IDEModules -> CheckButton
+ IDE.Pane.Modules: [descrSortedStore] :: IDEModules -> TypedTreeModelSort Descr
+ IDE.Pane.Modules: [descrStore] :: IDEModules -> TreeStore Descr
+ IDE.Pane.Modules: [descrView] :: IDEModules -> TreeView
+ IDE.Pane.Modules: [expanderState] :: IDEModules -> IORef ExpanderState
+ IDE.Pane.Modules: [oldSelection] :: IDEModules -> IORef SelectionState
+ IDE.Pane.Modules: [outer] :: IDEModules -> VBox
+ IDE.Pane.Modules: [packageDExpNoBlack] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [packageDExp] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [packageExpNoBlack] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [packageExp] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [packageScopeB] :: IDEModules -> RadioButton
+ IDE.Pane.Modules: [paned] :: IDEModules -> HPaned
+ IDE.Pane.Modules: [systemExpNoBlack] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [systemExp] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [systemScopeB] :: IDEModules -> RadioButton
+ IDE.Pane.Modules: [treeStore] :: IDEModules -> TreeStore ModuleRecord
+ IDE.Pane.Modules: [treeView] :: IDEModules -> TreeView
+ IDE.Pane.Modules: [workspaceDExpNoBlack] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [workspaceDExp] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [workspaceExpNoBlack] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [workspaceExp] :: ExpanderState -> ExpanderFacet
+ IDE.Pane.Modules: [workspaceScopeB] :: IDEModules -> RadioButton
+ IDE.Pane.Modules: instance GHC.Classes.Eq IDE.Pane.Modules.ExpanderState
+ IDE.Pane.Modules: instance GHC.Classes.Eq IDE.Pane.Modules.ModulesState
+ IDE.Pane.Modules: instance GHC.Classes.Eq IDE.Pane.Modules.SelectionState
+ IDE.Pane.Modules: instance GHC.Classes.Ord IDE.Pane.Modules.ExpanderState
+ IDE.Pane.Modules: instance GHC.Classes.Ord IDE.Pane.Modules.ModulesState
+ IDE.Pane.Modules: instance GHC.Classes.Ord IDE.Pane.Modules.SelectionState
+ IDE.Pane.Modules: instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Tree.Tree a)
+ IDE.Pane.Modules: instance GHC.Read.Read IDE.Pane.Modules.ExpanderState
+ IDE.Pane.Modules: instance GHC.Read.Read IDE.Pane.Modules.ModulesState
+ IDE.Pane.Modules: instance GHC.Show.Show IDE.Pane.Modules.ExpanderState
+ IDE.Pane.Modules: instance GHC.Show.Show IDE.Pane.Modules.ModulesState
+ IDE.Pane.Modules: instance GHC.Show.Show IDE.Pane.Modules.SelectionState
+ IDE.Pane.Modules: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Modules.IDEModules IDE.Core.Types.IDEM
+ IDE.Pane.Modules: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Modules.IDEModules IDE.Pane.Modules.ModulesState IDE.Core.Types.IDEM
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.Compiler.CompilerFlavor
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.BuildInfo
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.BuildType
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.Executable
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.Library
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.RepoKind
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.RepoType
+ IDE.Pane.PackageEditor: instance Default.Default Distribution.PackageDescription.SourceRepo
+ IDE.Pane.PackageEditor: instance Default.Default IDE.Pane.PackageEditor.Benchmark'
+ IDE.Pane.PackageEditor: instance Default.Default IDE.Pane.PackageEditor.Executable'
+ IDE.Pane.PackageEditor: instance Default.Default IDE.Pane.PackageEditor.Library'
+ IDE.Pane.PackageEditor: instance Default.Default IDE.Pane.PackageEditor.Test'
+ IDE.Pane.PackageEditor: instance GHC.Classes.Eq IDE.Pane.PackageEditor.Benchmark'
+ IDE.Pane.PackageEditor: instance GHC.Classes.Eq IDE.Pane.PackageEditor.Executable'
+ IDE.Pane.PackageEditor: instance GHC.Classes.Eq IDE.Pane.PackageEditor.Library'
+ IDE.Pane.PackageEditor: instance GHC.Classes.Eq IDE.Pane.PackageEditor.PackageDescriptionEd
+ IDE.Pane.PackageEditor: instance GHC.Classes.Eq IDE.Pane.PackageEditor.Test'
+ IDE.Pane.PackageEditor: instance GHC.Read.Read IDE.Pane.PackageEditor.PackageState
+ IDE.Pane.PackageEditor: instance GHC.Show.Show IDE.Pane.PackageEditor.Benchmark'
+ IDE.Pane.PackageEditor: instance GHC.Show.Show IDE.Pane.PackageEditor.Executable'
+ IDE.Pane.PackageEditor: instance GHC.Show.Show IDE.Pane.PackageEditor.Library'
+ IDE.Pane.PackageEditor: instance GHC.Show.Show IDE.Pane.PackageEditor.PackageState
+ IDE.Pane.PackageEditor: instance GHC.Show.Show IDE.Pane.PackageEditor.Test'
+ IDE.Pane.PackageEditor: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.PackageEditor.PackagePane IDE.Core.Types.IDEM
+ IDE.Pane.PackageEditor: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.PackageEditor.PackagePane IDE.Pane.PackageEditor.PackageState IDE.Core.Types.IDEM
+ IDE.Pane.PackageFlags: [flagsBox] :: IDEFlags -> VBox
+ IDE.Pane.PackageFlags: instance GHC.Classes.Eq IDE.Pane.PackageFlags.FlagsState
+ IDE.Pane.PackageFlags: instance GHC.Classes.Ord IDE.Pane.PackageFlags.FlagsState
+ IDE.Pane.PackageFlags: instance GHC.Read.Read IDE.Pane.PackageFlags.FlagsState
+ IDE.Pane.PackageFlags: instance GHC.Show.Show IDE.Pane.PackageFlags.FlagsState
+ IDE.Pane.PackageFlags: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.PackageFlags.IDEFlags IDE.Core.Types.IDEM
+ IDE.Pane.PackageFlags: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.PackageFlags.IDEFlags IDE.Pane.PackageFlags.FlagsState IDE.Core.Types.IDEM
+ IDE.Pane.Search: [entry] :: IDESearch -> Entry
+ IDE.Pane.Search: [modeSelection] :: IDESearch -> SearchMode -> IDEAction
+ IDE.Pane.Search: [scopeSelection] :: IDESearch -> Scope -> IDEAction
+ IDE.Pane.Search: [scrolledView] :: IDESearch -> ScrolledWindow
+ IDE.Pane.Search: [searchMetaGUI] :: IDESearch -> Text -> IDEAction
+ IDE.Pane.Search: [searchModeRef] :: IDESearch -> IORef SearchMode
+ IDE.Pane.Search: [searchScopeRef] :: IDESearch -> IORef Scope
+ IDE.Pane.Search: [searchStore] :: IDESearch -> ListStore Descr
+ IDE.Pane.Search: [setChoices] :: IDESearch -> [Descr] -> IDEAction
+ IDE.Pane.Search: [topBox] :: IDESearch -> VBox
+ IDE.Pane.Search: [treeView] :: IDESearch -> TreeView
+ IDE.Pane.Search: instance GHC.Classes.Eq IDE.Pane.Search.SearchState
+ IDE.Pane.Search: instance GHC.Classes.Ord IDE.Pane.Search.SearchState
+ IDE.Pane.Search: instance GHC.Read.Read IDE.Pane.Search.SearchState
+ IDE.Pane.Search: instance GHC.Show.Show IDE.Pane.Search.SearchState
+ IDE.Pane.Search: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Search.IDESearch IDE.Core.Types.IDEM
+ IDE.Pane.Search: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Search.IDESearch IDE.Pane.Search.SearchState IDE.Core.Types.IDEM
+ IDE.Pane.SourceBuffer: [addedIndex] :: IDEBuffer -> Int
+ IDE.Pane.SourceBuffer: [bufferName] :: IDEBuffer -> Text
+ IDE.Pane.SourceBuffer: [fileName] :: IDEBuffer -> Maybe FilePath
+ IDE.Pane.SourceBuffer: [modTime] :: IDEBuffer -> IORef (Maybe UTCTime)
+ IDE.Pane.SourceBuffer: [mode] :: IDEBuffer -> Mode
+ IDE.Pane.SourceBuffer: [scrolledWindow] :: IDEBuffer -> ScrolledWindow
+ IDE.Pane.SourceBuffer: [sourceView] :: IDEBuffer -> EditorView editor
+ IDE.Pane.SourceBuffer: instance GHC.Classes.Eq IDE.Pane.SourceBuffer.CharacterCategory
+ IDE.Pane.SourceBuffer: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.BufferMode.IDEBuffer IDE.BufferMode.BufferState IDE.Core.Types.IDEM
+ IDE.Pane.SourceBuffer: selectedTextOrCurrentIdentifier :: IDEM (Maybe Text)
+ IDE.Pane.SourceBuffer: switchBuffersCandy :: IDEAction
+ IDE.Pane.Trace: instance GHC.Classes.Eq IDE.Pane.Trace.TraceState
+ IDE.Pane.Trace: instance GHC.Classes.Ord IDE.Pane.Trace.TraceState
+ IDE.Pane.Trace: instance GHC.Read.Read IDE.Pane.Trace.TraceState
+ IDE.Pane.Trace: instance GHC.Show.Show IDE.Pane.Trace.TraceState
+ IDE.Pane.Trace: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Trace.IDETrace IDE.Core.Types.IDEM
+ IDE.Pane.Trace: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Trace.IDETrace IDE.Pane.Trace.TraceState IDE.Core.Types.IDEM
+ IDE.Pane.Variables: instance GHC.Classes.Eq IDE.Pane.Variables.VariablesState
+ IDE.Pane.Variables: instance GHC.Classes.Ord IDE.Pane.Variables.VariablesState
+ IDE.Pane.Variables: instance GHC.Read.Read IDE.Pane.Variables.VariablesState
+ IDE.Pane.Variables: instance GHC.Show.Show IDE.Pane.Variables.VariablesState
+ IDE.Pane.Variables: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Variables.IDEVariables IDE.Core.Types.IDEM
+ IDE.Pane.Variables: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Variables.IDEVariables IDE.Pane.Variables.VariablesState IDE.Core.Types.IDEM
+ IDE.Pane.WebKit.Documentation: [scrolledView] :: IDEDocumentation -> ScrolledWindow
+ IDE.Pane.WebKit.Documentation: [uri] :: DocumentationState -> Maybe Text
+ IDE.Pane.WebKit.Documentation: [webView] :: IDEDocumentation -> WebView
+ IDE.Pane.WebKit.Documentation: [zoom] :: DocumentationState -> Float
+ IDE.Pane.WebKit.Documentation: instance GHC.Classes.Eq IDE.Pane.WebKit.Documentation.DocumentationState
+ IDE.Pane.WebKit.Documentation: instance GHC.Classes.Ord IDE.Pane.WebKit.Documentation.DocumentationState
+ IDE.Pane.WebKit.Documentation: instance GHC.Read.Read IDE.Pane.WebKit.Documentation.DocumentationState
+ IDE.Pane.WebKit.Documentation: instance GHC.Show.Show IDE.Pane.WebKit.Documentation.DocumentationState
+ IDE.Pane.WebKit.Documentation: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.WebKit.Documentation.IDEDocumentation IDE.Core.Types.IDEM
+ IDE.Pane.WebKit.Documentation: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.WebKit.Documentation.IDEDocumentation IDE.Pane.WebKit.Documentation.DocumentationState IDE.Core.Types.IDEM
+ IDE.Pane.WebKit.Inspect: [inspectView] :: IDEInspect -> WebView
+ IDE.Pane.WebKit.Inspect: [scrollWin] :: IDEInspect -> ScrolledWindow
+ IDE.Pane.WebKit.Inspect: instance GHC.Classes.Eq IDE.Pane.WebKit.Inspect.InspectState
+ IDE.Pane.WebKit.Inspect: instance GHC.Classes.Ord IDE.Pane.WebKit.Inspect.InspectState
+ IDE.Pane.WebKit.Inspect: instance GHC.Read.Read IDE.Pane.WebKit.Inspect.InspectState
+ IDE.Pane.WebKit.Inspect: instance GHC.Show.Show IDE.Pane.WebKit.Inspect.InspectState
+ IDE.Pane.WebKit.Inspect: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.WebKit.Inspect.IDEInspect IDE.Core.Types.IDEM
+ IDE.Pane.WebKit.Inspect: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.WebKit.Inspect.IDEInspect IDE.Pane.WebKit.Inspect.InspectState IDE.Core.Types.IDEM
+ IDE.Pane.WebKit.Output: [alwaysHtmlRef] :: IDEOutput -> IORef Bool
+ IDE.Pane.WebKit.Output: [alwaysHtml] :: OutputState -> Bool
+ IDE.Pane.WebKit.Output: [uriEntry] :: IDEOutput -> Entry
+ IDE.Pane.WebKit.Output: [vbox] :: IDEOutput -> VBox
+ IDE.Pane.WebKit.Output: [webView] :: IDEOutput -> WebView
+ IDE.Pane.WebKit.Output: [zoom] :: OutputState -> Float
+ IDE.Pane.WebKit.Output: instance GHC.Classes.Eq IDE.Pane.WebKit.Output.OutputState
+ IDE.Pane.WebKit.Output: instance GHC.Classes.Ord IDE.Pane.WebKit.Output.OutputState
+ IDE.Pane.WebKit.Output: instance GHC.Read.Read IDE.Pane.WebKit.Output.OutputState
+ IDE.Pane.WebKit.Output: instance GHC.Show.Show IDE.Pane.WebKit.Output.OutputState
+ IDE.Pane.WebKit.Output: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.WebKit.Output.IDEOutput IDE.Core.Types.IDEM
+ IDE.Pane.WebKit.Output: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.WebKit.Output.IDEOutput IDE.Pane.WebKit.Output.OutputState IDE.Core.Types.IDEM
+ IDE.Pane.Workspace: data WorkspacePane
+ IDE.Pane.Workspace: getWorkspacePane :: IDEM WorkspacePane
+ IDE.Pane.Workspace: instance GHC.Classes.Eq IDE.Pane.Workspace.WorkspaceRecord
+ IDE.Pane.Workspace: instance GHC.Classes.Eq IDE.Pane.Workspace.WorkspaceState
+ IDE.Pane.Workspace: instance GHC.Classes.Ord IDE.Pane.Workspace.WorkspaceRecord
+ IDE.Pane.Workspace: instance GHC.Classes.Ord IDE.Pane.Workspace.WorkspaceState
+ IDE.Pane.Workspace: instance GHC.Read.Read IDE.Pane.Workspace.WorkspaceState
+ IDE.Pane.Workspace: instance GHC.Show.Show IDE.Pane.Workspace.WorkspaceState
+ IDE.Pane.Workspace: instance Graphics.UI.Frame.Panes.Pane IDE.Pane.Workspace.WorkspacePane IDE.Core.Types.IDEM
+ IDE.Pane.Workspace: instance Graphics.UI.Frame.Panes.RecoverablePane IDE.Pane.Workspace.WorkspacePane IDE.Pane.Workspace.WorkspaceState IDE.Core.Types.IDEM
+ IDE.Pane.Workspace: rebuildWorkspacePane :: IDEAction
+ IDE.Pane.Workspace: refreshWorkspacePane :: IDEAction
+ IDE.Pane.Workspace: showWorkspacePane :: IDEAction
+ IDE.Preferences: applyInterfaceTheme :: IDEAction
+ IDE.Preferences: defaultPrefs :: Prefs
+ IDE.Preferences: readPrefs :: FilePath -> IO Prefs
+ IDE.Preferences: runPreferencesDialog :: IDEAction
+ IDE.Preferences: writePrefs :: FilePath -> Prefs -> IO ()
+ IDE.Sandbox: sandboxDeleteSource :: FilePath -> PackageAction
+ IDE.Session: instance GHC.Classes.Eq IDE.Session.PaneState
+ IDE.Session: instance GHC.Classes.Ord IDE.Session.PaneState
+ IDE.Session: instance GHC.Read.Read IDE.Session.PaneState
+ IDE.Session: instance GHC.Show.Show IDE.Session.PaneState
+ IDE.SymbolNavigation: instance GHC.Classes.Eq IDE.SymbolNavigation.Locality
+ IDE.SymbolNavigation: instance GHC.Classes.Ord IDE.SymbolNavigation.Locality
+ IDE.SymbolNavigation: instance GHC.Show.Show IDE.SymbolNavigation.Locality
+ IDE.TextEditor.Class: [breakpointBG] :: EditorStyle -> (Color, Color)
+ IDE.TextEditor.Class: [contextBG] :: EditorStyle -> (Color, Color)
+ IDE.TextEditor.Class: [foundBG] :: EditorStyle -> (Color, Color)
+ IDE.TextEditor.Class: [lintBG] :: EditorStyle -> (Color, Color)
+ IDE.TextEditor.Class: [matchBG] :: EditorStyle -> (Color, Color)
+ IDE.TextEditor.Class: [preferDark] :: EditorStyle -> Bool
+ IDE.TextEditor.Class: [styleName] :: EditorStyle -> Maybe Text
+ IDE.TextEditor.Class: scrollToCursor :: TextEditor editor => EditorView editor -> IDEAction
+ IDE.TextEditor.CodeMirror: instance GHC.Show.Show IDE.TextEditor.CodeMirror.CodeMirror
+ IDE.TextEditor.CodeMirror: instance IDE.TextEditor.Class.TextEditor IDE.TextEditor.CodeMirror.CodeMirror
+ IDE.TextEditor.GtkSourceView: instance GHC.Show.Show IDE.TextEditor.GtkSourceView.GtkSourceView
+ IDE.TextEditor.GtkSourceView: instance IDE.TextEditor.Class.TextEditor IDE.TextEditor.GtkSourceView.GtkSourceView
+ IDE.TextEditor.Yi: instance GHC.Show.Show IDE.TextEditor.Yi.Yi
+ IDE.Utils.DirectoryUtils: setModificationTimeOnOSX :: FilePath -> UTCTime -> IO ()
+ IDE.Utils.GUIUtils: showDialogOptions :: Text -> MessageType -> [(Text, IO ())] -> Maybe Int -> IO ()
+ IDE.Utils.GUIUtils: showInputDialog :: Text -> Text -> IO (Maybe Text)
+ IDE.Utils.GUIUtils: treeStoreGetForest :: TreeStore a -> IO (Forest a)
+ IDE.Utils.GUIUtils: treeViewContextMenu' :: TreeViewClass treeView => treeView -> TreeStore a -> (a -> TreePath -> TreeStore a -> IDEM [[(Text, IDEAction)]]) -> IDEM (ConnectId treeView, ConnectId treeView)
+ IDE.Utils.GUIUtils: treeViewToggleRow :: TreeViewClass self => self -> TreePath -> IO Bool
+ IDE.Utils.GtkBindings: treeViewSetActiveOnSingleClick :: TreeViewClass self => self -> Bool -> IO ()
- IDE.BufferMode: Mode :: Text -> IDEAction -> IDEAction -> IDEM (Maybe Text) -> ((Text -> Bool) -> IDEAction) -> (forall editor. TextEditor editor => (Text -> Bool) -> EditorBuffer editor -> IDEAction) -> IDEAction -> (Maybe Char -> (Text -> Bool) -> IDEAction) -> (forall editor. TextEditor editor => Text -> EditorIter editor -> EditorBuffer editor -> IDEAction) -> (Text -> Bool) -> Mode
+ IDE.BufferMode: Mode :: Text -> IDEAction -> IDEAction -> IDEM (Maybe Text) -> ((Text -> Bool) -> IDEAction) -> (forall editor. TextEditor editor => (Text -> Bool) -> EditorBuffer editor -> IDEAction) -> (forall editor. TextEditor editor => EditorBuffer editor -> IDEAction) -> IDEAction -> (Maybe Char -> (Text -> Bool) -> IDEAction) -> (forall editor. TextEditor editor => Text -> EditorIter editor -> EditorBuffer editor -> IDEAction) -> (Text -> Bool) -> Mode
- IDE.Core.Types: Prefs :: Int -> Text -> Bool -> (Bool, Int) -> Int -> Bool -> (Bool, Text) -> Text -> Bool -> Bool -> Maybe Text -> (Bool, Text) -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Bool -> Text -> Maybe Text -> (Int, Int) -> Text -> [(Text, PanePath)] -> PanePath -> [(Text, Text)] -> [Dependency] -> Bool -> Bool -> Text -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Text -> Bool -> Int -> [FilePath] -> Maybe FilePath -> Text -> RetrieveStrategy -> Bool -> Prefs
+ IDE.Core.Types: Prefs :: Int -> Text -> Bool -> (Bool, Int) -> Int -> Bool -> (Bool, Text) -> Bool -> Bool -> Text -> Bool -> Bool -> Maybe Text -> (Bool, Text) -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Color -> Bool -> Text -> Maybe Text -> (Int, Int) -> Text -> [(Text, PanePath)] -> PanePath -> [(Text, Text)] -> [Dependency] -> Bool -> Bool -> Text -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Text -> Bool -> Bool -> Bool -> Int -> [FilePath] -> Maybe FilePath -> Text -> RetrieveStrategy -> Bool -> Prefs
- IDE.Core.Types: type ModuleDescrCache = Map ModuleName (UTCTime, Maybe FilePath, ModuleDescr)
+ IDE.Core.Types: type ModuleDescrCache = Map ModuleKey (UTCTime, Maybe FilePath, ModuleDescr)
- IDE.Pane.Errors: getErrors :: Maybe PanePath -> IDEM IDEErrors
+ IDE.Pane.Errors: getErrors :: Maybe PanePath -> IDEM ErrorsPane
- IDE.Pane.Errors: selectMatchingErrors :: Maybe SrcSpan -> IDEM ()
+ IDE.Pane.Errors: selectMatchingErrors :: Maybe SrcSpan -> IDEAction
- IDE.Pane.Files: IDEFiles :: ScrolledWindow -> TreeView -> TreeStore FileRecord -> IDEFiles
+ IDE.Pane.Files: IDEFiles :: Label -> IDEFiles
- IDE.Pane.Modules: addModule :: [ModuleRecord] -> PackageAction
+ IDE.Pane.Modules: addModule :: [Text] -> PackageAction
- IDE.Utils.GUIUtils: chooseFile :: Window -> Text -> Maybe FilePath -> IO (Maybe FilePath)
+ IDE.Utils.GUIUtils: chooseFile :: Window -> Text -> Maybe FilePath -> [(String, [String])] -> IO (Maybe FilePath)

Files

Readme.md view
@@ -10,6 +10,8 @@  ## Installation +Requirements: ghc >= 7.8.3 cabal >= 1.18+ You can get Leksah up and running quickly on Windows and OS X using the [official binaries](https://github.com/leksah/leksah/wiki/download). @@ -34,7 +36,7 @@     cabal install leksah     leksah -### Buildling on OS X+### Building on OS X  [Install MacPorts](https://www.macports.org/install.php). @@ -95,7 +97,6 @@      cabal update     cabal install Cabal-    cabal install regex-tdfa-text --ghc-options=-XFlexibleContexts     cabal install alex happy     cabal install gtk2hs-buildtools     cabal install leksah
data/keymap.lkshk view
@@ -8,7 +8,7 @@ --<compose> is often labelled Alt Gr. -- --The defined values for the keys can can be found at--- http://gitweb.freedesktop.org/?p=xorg/proto/x11proto.git;a=blob_plain;f=keysymdef.h.+-- http://www.cl.cam.ac.uk/%7Emgk25/ucs/keysymdef.h -- The names of the keys are the names of the macros without the prefix.  
data/leksah-welcome/src/Main.hs view
@@ -16,12 +16,12 @@ --   * Package -> New  -- Next we are importing some things from other modules.--- Leksah can normally addd these imports for you, just+-- Leksah can normally add these imports for you, just -- press Ctrl+R (OS X Command+R)  import Data.Monoid ((<>)) --- This strang looking comment adds code only needed when running the+-- This strange looking comment adds code only needed when running the -- doctest tests embedded in the comments -- $setup -- >>> import Data.List (stripPrefix)
data/leksah.menu view
@@ -1,17 +1,31 @@    <ui>     <menubar>       <menu name="_File" action="File">-       <menuitem name="_New Module..." action="FileNew" />-       <menuitem name="New _Text File" action="FileNewTextFile" />-       <menuitem name="_Open..." action="FileOpen" />-       <menuitem name="Open _Recent" action="RecentFiles"/>+       <menu name="_New" action="FileNew">+           <menuitem name="_Package..." action="FileNewPackage" />+           <menuitem name="_Module..." action="FileNewModule" />+           <menuitem name="_Text File..." action="FileNewTextFile" />+           <separator />+           <menuitem name="_Workspace..." action="FileNewWorkspace" />+       </menu>+       <menu name="_Open" action="FileOpen">+           <menuitem name="_Workspace..." action="FileOpenWorkspace" />+           <menuitem name="_Package..." action="FileOpenPackage" />+           <menuitem name="_File..." action="FileOpenFile" />+       </menu>+       <separator />        <menuitem name="_Save" action="FileSave" />        <menuitem name="Save _As..." action="FileSaveAs" />        <menuitem name="Save _All" action="FileSaveAll" />-       <menuitem name="_Revert" action="FileRevert" />        <menuitem name="_Close" action="FileClose" />        <menuitem name="_Print File" action="FilePrint" />        <separator/>+       <menu name="Recent Files" action="FileRecentFiles">+       </menu>+       <menu name="Recent Workspaces" action="FileRecentWorkspaces">+       </menu>+       <separator/>+       <menuitem name="Close Workspace" action="FileCloseWorkspace" />        <menuitem name="Close All" action="FileCloseAll" />        <menuitem name="Close All but Package" action="FileCloseAllButPackage" />        <menuitem name="Close All but Workspace" action="FileCloseAllButWorkspace" />@@ -44,22 +58,17 @@        <menuitem name="Align ::" action="EditAlignTypeSig" />      </menu>     <menu name="_Workspace" action="Workspace">-       <menuitem name="_New..." action="NewWorkspace" />-       <menuitem name="_Open..." action="OpenWorkspace" />-       <menuitem name="Open _Recent" action="RecentWorkspaces"/>-       <menuitem name="_Close" action="CloseWorkspace" />-       <separator/>-       <menuitem name="_Clean" action="CleanWorkspace" />-       <menuitem name="_Make" action="MakeWorkspace" />+       <menuitem name="_Add Package..." action="WorkspaceAddPackage" />+       <menuitem name="_Add Copy Of Installed Package..." action="WorkspaceAddPackageCopy" />+       <separator />+       <menuitem name="Cl_ean All packages" action="CleanWorkspace" />+       <menuitem name="_Build All packages" action="MakeWorkspace" />        <separator/>        <menuitem name="_Next Error" action="NextError" />        <menuitem name="_Previous Error" action="PreviousError" />        <menuitem name="Resol_ve Errors" action="ResolveErrors" />      </menu>     <menu name="_Package" action="Package">-       <menuitem name="_New..." action="NewPackage" />-       <menuitem name="_Add..." action="AddPackage" />-       <menuitem name="_Add From Source Repository..." action="ClonePackage" />        <menu name="_Edit" action="PackageEdit">           <menuitem name="With _Package Editor" action="EditPackage" />           <menuitem name="With _Text Editor" action="EditPackageText" />@@ -87,10 +96,10 @@        <menuitem name="SDist" action="SdistPackage" />        <menuitem name="_Build Documentation" action="DocPackage" />        <separator/>-       <menuitem name="Open Documentation" action="OpenDocPackage" />+       <menuitem name="_Open Documentation" action="OpenDocPackage" />      </menu>     <menu name="_Debug" action="Debug">-       <menuitem name="GHCi" action="DebugToggled" />+       <menuitem name="_Enable GHCi" action="DebugToggled" />        <menuitem name="Continue" action="DebugContinue" />        <menuitem name="Abandon" action="DebugAbandon" />        <menuitem name="Stop" action="DebugStop" />@@ -108,7 +117,7 @@     <menu name="_Panes" action="Panes">        <menuitem name="_Browser" action="ShowBrowser" />        <menuitem name="_Modules" action="ShowModules" />-       <menuitem name="_Info" action="ShowInfo" />+       <menuitem name="Symbol _Info" action="ShowInfo" />        <separator/>        <menuitem name="_Debugger" action="ShowDebugger" />        <menuitem name="_Breakpoints" action="ShowBreakpointsPane" />@@ -118,7 +127,6 @@        <menuitem name="_Web Inspector" action="ShowInspect" />        <separator/>        <menuitem name="_Errors" action="ShowErrors" />-       <menuitem name="_Files" action="ShowFiles" />        <menuitem name="_Grep" action="ShowGrep" />        <menuitem name="_Documentation" action="ShowDocumentation" />        <menuitem name="_Log" action="ShowLog" />@@ -134,7 +142,7 @@        <menuitem name="_Group" action="ViewNest" />        <menuitem name="_Detach" action="ViewDetach" />        <menuitem name="_Full Screen" action="ViewFullScreen" />-       <menuitem name="Dark" action="ViewDark" />+       <menuitem name="_Use Dark Interface" action="UseDarkInterface" />        <separator/>        <menuitem name="Move _Left" action="ViewMoveLeft" />        <menuitem name="Move _Right" action="ViewMoveRight" />@@ -150,18 +158,17 @@        <menuitem name="Clear Log" action="ClearLog" />        <menuitem name="Toggle Toolbar" action="ToggleToolbar" />      </menu>-    <menu name="_Configuration" action="Configuration">-       <menuitem name="Source Candy" action="EditCandy" />-       <menuitem name="Edit general Preferences" action="PrefsEdit" />-       <separator/>-       <menuitem name="Update workspace data" action="UpdateMetadataCurrent" />-       <menuitem name="Rebuild workspace data" action="RebuildMetadataCurrent" />-       <menuitem name="Update system data" action="UpdateMetadataLib" />-       <menuitem name="Rebuild system data" action="RebuildMetadataLib" />+    <menu name="_Tools" action="Tools">+       <menuitem name="Update Workspace Data" action="UpdateMetadataCurrent" />+       <menuitem name="Rebuild Workspace Data" action="RebuildMetadataCurrent" />+       <menuitem name="Update System Data" action="UpdateMetadataLib" />+       <menuitem name="Rebuild System Data" action="RebuildMetadataLib" />        <separator/>-       <menuitem name="Save Session" action="SaveSession" />+       <menuitem name="Save Session As..." action="SaveSession" />        <menuitem name="Load Session" action="LoadSession" />-       <menuitem name="Forget Session" action="ForgetSession" />+       <separator/>+       <menuitem name="_Preferences" action="PrefsEdit" />+       <separator/>     </menu>     <menu name="Version Con_trol" action="vcs">     </menu>@@ -174,8 +181,8 @@     <toolbar name="toolbar">      <placeholder name="FileToolItems">        <separator/>-       <toolitem name="New" action="FileNew"/>-       <toolitem name="Open" action="FileOpen"/>+       <toolitem name="New Module" action="FileNewModule"/>+       <toolitem name="Open" action="FileOpenFile"/>        <toolitem name="Save" action="FileSave"/>        <toolitem name="Close" action="ViewClosePane"/>        <separator/>
leksah.cabal view
@@ -1,5 +1,5 @@ name: leksah-version: 0.15.1.4+version: 0.15.2.0 cabal-version: >=1.18 build-type: Simple license: GPL@@ -51,6 +51,12 @@     language-specs/lucius.lang     language-specs/julius.lang     language-specs/jmacro.lang+    pics/ide_folder.png+    pics/ide_source_folder.png+    pics/ide_component.png+    pics/ide_source_dependency.png+    pics/ide_package.png+    pics/ide_cabal_file.png     pics/ide_class.png     pics/ide_configure.png     pics/ide_data.png@@ -82,6 +88,9 @@     pics/ide_rebuild_meta.png     pics/ide_empty.png     pics/ide_js.png+    pics/ide_error.png+    pics/ide_warning.png+    pics/ide_suggestion.png     doc/Keybindings.svg     doc/leksah_manual.lyx     doc/screenshots2/screenshot_buffer_menu.png@@ -249,6 +258,7 @@         IDE.Session         IDE.Command         IDE.Keymap+        IDE.Utils.DirectoryUtils         IDE.Utils.GUIUtils         IDE.SymbolNavigation         IDE.Package@@ -260,7 +270,6 @@         IDE.Core.Types         IDE.Core.State         IDE.Metainfo.Provider-        IDE.Pane.Preferences         IDE.Pane.PackageEditor         IDE.Pane.HLint         IDE.Pane.Info@@ -277,6 +286,7 @@         IDE.Pane.Trace         IDE.Pane.Variables         IDE.Pane.Errors+        IDE.Preferences         IDE.TextEditor         IDE.Workspaces         IDE.Workspaces.Writer@@ -304,12 +314,14 @@         IDE.TextEditor.Yi         IDE.TextEditor.GtkSourceView         IDE.Utils.ExternalTool+        IDE.Utils.GtkBindings     build-depends:+        base-compat >=0.9.0 && <0.10,         gtk3 >=0.14.1 && <0.15,         gtksourceview3 >=0.13.1.5 && <0.14,         webkitgtk3 >=0.13 && <0.15,         webkitgtk3-javascriptcore -any,-        jsaddle >=0.2.1.0 && <0.3,+        jsaddle >=0.3.0.0 && <0.4,         ghcjs-codemirror -any,         blaze-html -any,         lens -any,@@ -336,7 +348,7 @@         binary-shared >=0.8 && <0.9,         deepseq >=1.1.0.0 && <1.5,         hslogger >=1.0.7 && <1.3,-        leksah-server >=0.15.0.8 && <0.16,+        leksah-server >=0.15.2.0 && <0.16,         ghc >=6.10.1 && <7.11,         strict >=0.3.2 && <0.4,         conduit >=1.0.8 && <1.3,@@ -347,14 +359,13 @@         vcsgui >=0.1.0 && <0.2,         vcswrapper >=0.1.0 && <0.2,         QuickCheck >=2.4.2 && <2.9,-        haskell-src-exts >=1.13.5 && <1.17,+        haskell-src-exts >=1.13.5 && <1.18,         hlint >=1.9.21 && <1.10,         vado >=0.0.1 && <0.1,         shakespeare >=2.0.0.1 && <2.1,         cpphs >=1.19 && <1.20,         stm >=2.4.4 && <2.5-    cpp-options: -DWEBKITGTK-                 -DLEKSAH_WITH_CODE_MIRROR+    cpp-options: -DWEBKITGTK -DLEKSAH_WITH_CODE_MIRROR     default-language: Haskell2010     default-extensions: ViewPatterns     hs-source-dirs: src@@ -389,7 +400,7 @@         ghc-options: -optl-headerpad_max_install_names     main-is: Main.hs     build-depends:-        leksah ==0.15.1.4,+        leksah ==0.15.2.0,         base >=4.0.0.0 && <=4.9,         gtk3 >=0.14.1 && <0.15,         stm >=2.4.4 && <2.5@@ -400,7 +411,7 @@ executable bewleksah     main-is: Main.hs     build-depends:-        leksah ==0.15.1.4,+        leksah ==0.15.2.0,         base >=4.0.0.0 && <=4.9,         jsaddle -any,         ghcjs-dom >=0.2.1.0 && <0.3,@@ -423,7 +434,7 @@         base >=4.0.0.0 && <4.9,         Cabal >=1.10.2.0 && <1.23,         QuickCheck >=2.4.2 && <2.9,-        leksah ==0.15.1.4,+        leksah ==0.15.2.0,         containers -any,         ltk -any,         leksah-server -any,
osx/launcher.sh view
@@ -36,7 +36,6 @@ export PATH="$bundle_bin":$PATH  export GTK2_RC_FILES="$bundle_etc/gtk-3.0/gtkrc"-export GTK_IM_MODULE_FILE="$bundle_etc/gtk-3.0/gtk.immodules" export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-3.0/gdk-pixbuf.loaders" export FONTCONFIG_PATH="$bundle_etc/fonts" export PANGO_RC_FILE="$bundle_etc/pango/pangorc"
osx/leksah.bundle view
@@ -83,10 +83,6 @@   </binary>    <binary>-    ${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/-  </binary>--  <binary>     ${prefix}/lib/gio/modules/   </binary> @@ -104,10 +100,6 @@    <data>     ${prefix}/etc/fonts/-  </data>--  <data>-    ${prefix}/etc/pango/   </data>    <!-- Translation filenames, one for each program or library that you
osx/makedmg.sh view
@@ -62,9 +62,6 @@ echo Fixing pixbuf loader paths sed -i "" -e "s|@executable_path/../Resources/|@executable_path/../|" Leksah/Leksah.app/Contents/Resources/etc/gtk-3.0/gdk-pixbuf.loaders || exit -echo Fixing pango module paths-sed -i "" -e "s|@executable_path/../Resources/|@executable_path/../|" Leksah/Leksah.app/Contents/Resources/etc/pango/pango.modules || exit- LEKSAH_DMG="$LEKSAH_X_X_X_X_GHC_X_X_X.dmg" if test -e "$LEKSAH_DMG"; then    rm "$LEKSAH_DMG"
osx/makedmgs.sh view
@@ -1,12 +1,12 @@ #!/bin/sh -ex -export GHCVERSION=-7.8.3-scripts/clean.sh-osx/makedmg.sh-export GHCVERSION=-7.10.1-scripts/clean.sh+#export GHCVERSION=-7.8.3+#scripts/clean.sh+#osx/makedmg.sh+export GHCVERSION=-7.10.2+#scripts/clean.sh osx/makedmg.sh export GHCVERSION=-scripts/clean.sh+#scripts/clean.sh osx/makedmg.sh 
+ pics/ide_cabal_file.png view

binary file changed (absent → 276 bytes)

+ pics/ide_component.png view

binary file changed (absent → 508 bytes)

+ pics/ide_error.png view

binary file changed (absent → 375 bytes)

+ pics/ide_folder.png view

binary file changed (absent → 202 bytes)

+ pics/ide_package.png view

binary file changed (absent → 398 bytes)

pics/ide_source.png view

binary file changed (469 → 456 bytes)

+ pics/ide_source_dependency.png view

binary file changed (absent → 554 bytes)

+ pics/ide_source_folder.png view

binary file changed (absent → 260 bytes)

+ pics/ide_suggestion.png view

binary file changed (absent → 478 bytes)

+ pics/ide_warning.png view

binary file changed (absent → 379 bytes)

src/IDE/BufferMode.hs view
@@ -36,7 +36,6 @@ import IDE.SourceCandy        (getCandylessText, keystrokeCandy, transformFromCandy,         transformToCandy)-import IDE.Utils.GUIUtils (getCandyState) import Control.Monad (when) import Data.Maybe (mapMaybe, catMaybes) import IDE.Utils.FileUtils@@ -152,6 +151,7 @@     modeSelectedModuleName :: IDEM (Maybe Text),     modeEditToCandy        :: (Text -> Bool) -> IDEAction,     modeTransformToCandy   :: forall editor . TextEditor editor => (Text -> Bool) -> EditorBuffer editor -> IDEAction,+    modeTransformFromCandy   :: forall editor . TextEditor editor => EditorBuffer editor -> IDEAction,     modeEditFromCandy      :: IDEAction,     modeEditKeystrokeCandy :: Maybe Char -> (Text -> Bool) -> IDEAction,     modeEditInsertCode     :: forall editor . TextEditor editor => Text -> EditorIter editor -> EditorBuffer editor -> IDEAction,@@ -189,6 +189,9 @@     modeTransformToCandy = \ inCommentOrString ebuf -> do         ct <- readIDE candy         transformToCandy ct ebuf inCommentOrString,+    modeTransformFromCandy = \buf -> do+        ct <- readIDE candy+        transformFromCandy ct buf,     modeEditToCandy = \ inCommentOrString -> do         ct <- readIDE candy         inActiveBufContext () $ \_ _ ebuf _ _ ->@@ -234,6 +237,9 @@     modeTransformToCandy = \ inCommentOrString ebuf -> do         ct <- readIDE candy         transformToCandy ct ebuf inCommentOrString,+    modeTransformFromCandy = \buf -> do+        ct <- readIDE candy+        transformFromCandy ct buf,     modeEditToCandy = \ inCommentOrString -> do         ct <- readIDE candy         inActiveBufContext () $ \_ _ ebuf _ _ ->@@ -268,6 +274,7 @@         return (),     modeSelectedModuleName   = return Nothing,     modeTransformToCandy     = \ _ _ -> return (),+    modeTransformFromCandy   = \_ -> return (),     modeEditToCandy          = \ _ -> return (),     modeEditFromCandy        = return (),     modeEditKeystrokeCandy   = \ _ _ -> return (),@@ -282,6 +289,7 @@     modeEditUncomment        = return (),     modeSelectedModuleName   = return Nothing,     modeTransformToCandy     = \ _ _ -> return (),+    modeTransformFromCandy   = \_ -> return (),     modeEditToCandy          = \ _ -> return (),     modeEditFromCandy        = return (),     modeEditKeystrokeCandy   = \_ _ -> return (),
src/IDE/Command.hs view
@@ -36,7 +36,8 @@ ) where  import Graphics.UI.Gtk-       (toToolbar, ToolbarClass, Toolbar(..), keyToChar, eventKeyVal,+       (iconThemeAddBuiltinIcon, iconThemeLoadIcon, iconThemeGetDefault,+        toToolbar, ToolbarClass, Toolbar(..), keyToChar, eventKeyVal,         eventModifier, eventKeyName, EKey, containerAdd,         windowAddAccelGroup, keyPressEvent, boxPackEnd, boxPackStart,         widgetSetName, vBoxNew, windowSetIconFromFile, Widget, Window,@@ -55,7 +56,8 @@         actionGroupNew, UIManager, widgetShowAll, menuItemSetSubmenu,         widgetDestroy, menuItemGetSubmenu, menuShellAppend,         menuItemActivate, menuItemNewWithLabel, menuNew, Packing(..),-        ToolbarStyle(..), PositionType(..), on, IconSize(..), Modifier(..))+        ToolbarStyle(..), PositionType(..), on, IconSize(..), Modifier(..),+        widgetSetSensitive) import System.FilePath import Data.Version import Prelude hiding (catch)@@ -64,11 +66,11 @@  import IDE.Core.State import IDE.Pane.SourceBuffer-import IDE.Pane.Preferences import IDE.Pane.PackageFlags import IDE.Pane.PackageEditor import IDE.Pane.Errors import IDE.Package+import IDE.Preferences (runPreferencesDialog, applyInterfaceTheme) import IDE.HLint import IDE.Sandbox import IDE.Pane.Log@@ -87,7 +89,7 @@ import IDE.Debug import System.Directory (doesFileExist) import Graphics.UI.Gtk.Gdk.EventM (EventM)-import qualified Data.Map as  Map (lookup)+import qualified Data.Map as  Map (lookup, empty) import Data.List (sort) import Control.Event (registerEvent) import IDE.Pane.Breakpoints@@ -103,9 +105,8 @@ import IDE.Pane.WebKit.Documentation (getDocumentation) import IDE.Pane.WebKit.Output (getOutputPane) import IDE.Pane.WebKit.Inspect (getInspectPane)-import IDE.Pane.Files (refreshFiles, getFiles) import Control.Monad.IO.Class (MonadIO(..))-import Control.Monad (unless, when)+import Control.Monad (unless, when, forM_, filterM, liftM) import Control.Monad.Trans.Reader (ask) import System.Log.Logger (debugM) import Foreign.C.Types (CInt(..))@@ -114,13 +115,16 @@ import Graphics.UI.GtkInternals (unToolbar) import IDE.Session        (saveSessionAs, loadSession, saveSession, sessionClosePane,-        loadSessionPrompt, saveSessionAsPrompt, viewFullScreen, viewDark)+        loadSessionPrompt, saveSessionAsPrompt, viewFullScreen) import qualified Data.Text as T (unpack, pack)+import Data.Time.Clock (getCurrentTime, utctDay)+import Data.Time.Calendar (toGregorian) import Data.Text (Text) import qualified Data.Text.IO as T (readFile) import Data.Monoid (Monoid(..), (<>)) import qualified Text.Printf as S (printf) import Text.Printf (PrintfType)+import Graphics.UI.Gtk.General.IconTheme (IconLookupFlags(..))  printf :: PrintfType r => Text -> r printf = S.printf . T.unpack@@ -142,15 +146,24 @@     AD "vcs" (__ "Version Con_trol") Nothing Nothing (return ()) [] False     ,AD "FilePrint" (__ "_Print File") Nothing Nothing filePrint [] False     ,AD "File" (__ "_File") Nothing Nothing (return ()) [] False-    ,AD "FileNew" (__ "_New Module...") Nothing (Just "gtk-new")+    ,AD "FileNew" (__ "_New") Nothing Nothing (return ()) [] False+    ,AD "FileNewWorkspace" (__ "_Workspace...") Nothing Nothing+        (workspaceNew >> showWorkspacePane) [] False+    ,AD "FileNewPackage" (__ "_Package...") Nothing Nothing+        (showWorkspacePane >> workspaceTry workspacePackageNew) [] False+    ,AD "FileNewModule" (__ "_Module...") Nothing (Just "gtk-new")         (packageTry $ addModule []) [] False-    ,AD "FileNewTextFile" (__ "_New Text File") Nothing Nothing+    ,AD "FileNewTextFile" (__ "_Text File...") Nothing Nothing         fileNew [] False-    ,AD "FileOpen" (__ "_Open...") Nothing (Just "gtk-open")+    ,AD "FileOpen" (__ "_Open") Nothing Nothing (return ()) [] False+    ,AD "FileOpenWorkspace" (__ "_Workspace...") Nothing Nothing+        (workspaceOpen >> showWorkspacePane) [] False+    ,AD "FileOpenPackage" (__ "_Package...") Nothing Nothing+        (showWorkspacePane >> workspaceTry workspaceAddPackage) [] False+    ,AD "FileOpenFile" (__ "_File...") Nothing (Just "gtk-open")         fileOpen [] False-    ,AD "RecentFiles" (__ "Open _Recent") Nothing Nothing (return ()) [] False-    ,AD "FileRevert" (__ "_Revert") Nothing Nothing-        fileRevert [] False+    ,AD "FileRecentFiles" (__ "Recent Files") Nothing Nothing (return ()) [] False+    ,AD "FileRecentWorkspaces" (__ "Recent Workspaces") Nothing Nothing (return ()) [] False     ,AD "FileSave" (__ "_Save") Nothing (Just "gtk-save")         (do fileSave False; return ()) [] False     ,AD "FileSaveAs" (__ "Save _As...") Nothing (Just "gtk-save-as")@@ -159,6 +172,8 @@         (do fileSaveAll (\ b -> return (bufferName b /= "_Eval.hs")); return ()) [] False     ,AD "FileClose" (__ "_Close") Nothing (Just "gtk-close")         (do fileClose; return ()) [] False+    ,AD "FileCloseWorkspace" (__ "Close Workspace") Nothing Nothing+        workspaceClose [] False     ,AD "FileCloseAll" (__ "Close All") Nothing Nothing         (do fileCloseAll (\ b -> return (bufferName b /= "_Eval.hs")); return ()) [] False     ,AD "FileCloseAllButPackage" (__ "Close All But Package") Nothing Nothing@@ -212,17 +227,13 @@         (align ':') [] False      ,AD "Workspace" (__ "_Workspace") Nothing Nothing (return ()) [] False-    ,AD "NewWorkspace" (__ "_New...") Nothing Nothing-        (workspaceNew >> showWorkspace) [] False-    ,AD "OpenWorkspace" (__ "_Open...") Nothing Nothing-        (workspaceOpen >> showWorkspace) [] False-    ,AD "RecentWorkspaces" (__ "Open _Recent") Nothing Nothing (return ()) [] False-    ,AD "CloseWorkspace" (__ "_Close") Nothing Nothing-        workspaceClose [] False--    ,AD "CleanWorkspace" (__ "Cl_ean") (Just (__ "Cleans all packages")) (Just "ide_clean")+    ,AD "WorkspaceAddPackage" (__ "_Add Package...") Nothing Nothing+        (showWorkspacePane >> workspaceTry workspaceAddPackage) [] False+    ,AD "WorkspaceAddPackageCopy" (__ "_Add Copy Of Installed Package...") Nothing Nothing+    (showWorkspacePane >> workspaceTry workspacePackageClone) [] False+    ,AD "CleanWorkspace" (__ "Cl_ean All packages") (Just (__ "Cleans all packages in the workspace")) (Just "ide_clean")         (workspaceTry workspaceClean) [] False-    ,AD "MakeWorkspace" (__ "_Make") (Just (__ "Makes all of this workspace")) (Just "ide_configure")+    ,AD "MakeWorkspace" (__ "_Build All packages") (Just (__ "Builds all of the packages in the workspace")) (Just "ide_configure")         (workspaceTry workspaceMake) [] False     ,AD "NextError" (__ "_Next Error") (Just (__ "Go to the next error")) (Just "ide_error_next")         nextError [] False@@ -230,12 +241,6 @@         previousError [] False      ,AD "Package" (__ "_Package") Nothing Nothing (return ()) [] False-    ,AD "NewPackage" (__ "_New...") Nothing Nothing-        (showWorkspace >> workspaceTry workspacePackageNew) [] False-    ,AD "AddPackage" (__ "_Add...") Nothing Nothing-        (showWorkspace >> workspaceTry workspaceAddPackage) [] False-    ,AD "ClonePackage" (__ "Add From Source _Repository...") Nothing Nothing-        (showWorkspace >> workspaceTry workspacePackageClone) [] False --    ,AD "RecentPackages" "_Recent Packages" Nothing Nothing (return ()) [] False     ,AD "PackageEdit" (__ "_Edit") Nothing Nothing (return ()) [] False     ,AD "EditPackage" (__ "With _Package Editor") Nothing Nothing@@ -286,7 +291,7 @@         (packageTry packageTest) [] False     ,AD "SdistPackage" (__ "Source Dist") Nothing Nothing         (packageTry packageSdist) [] False-    ,AD "OpenDocPackage" (__ "_Open Doc") Nothing Nothing+    ,AD "OpenDocPackage" (__ "_Open Documentation") Nothing Nothing         (packageTry packageOpenDoc) [] False      ,AD "Debug" (__ "_Debug") Nothing Nothing (return ()) [] False@@ -361,29 +366,27 @@         debugType [] False      ,AD "Metadata" (__ "_Metadata") Nothing Nothing (return ()) [] False-    ,AD "UpdateMetadataCurrent" (__ "_Update workspace data") (Just (__ "Updates data for the current workspace"))+    ,AD "UpdateMetadataCurrent" (__ "_Update Workspace Data") (Just (__ "Updates data for the current workspace"))             (Just "ide_rebuild_meta") updateWorkspaceInfo [] False-    ,AD "RebuildMetadataCurrent" (__ "_Rebuild workspace data") (Just (__ "Rebuilds data for the current workspace"))+    ,AD "RebuildMetadataCurrent" (__ "_Rebuild Workspace Data") (Just (__ "Rebuilds data for the current workspace"))             Nothing rebuildWorkspaceInfo [] False-    ,AD "UpdateMetadataLib" (__ "U_pdate system data") Nothing Nothing+    ,AD "UpdateMetadataLib" (__ "U_pdate System Data") Nothing Nothing         updateSystemInfo [] False-    ,AD "RebuildMetadataLib" (__ "R_ebuild system data") Nothing Nothing+    ,AD "RebuildMetadataLib" (__ "R_ebuild System Data") Nothing Nothing         rebuildSystemInfo [] False      ,AD "Session" (__ "_Session") Nothing Nothing (return ()) [] False-    ,AD "SaveSession" (__ "_Save Session") Nothing Nothing+    ,AD "SaveSession" (__ "_Save Session As...") Nothing Nothing         saveSessionAsPrompt [] False     ,AD "LoadSession" (__ "_Load Session") Nothing Nothing         loadSessionPrompt [] False-    ,AD "ForgetSession" (__ "_Forget Session") Nothing Nothing-        (return ()) [] True      ,AD "Panes" (__ "_Panes") Nothing Nothing (return ()) [] False     ,AD "ShowBrowser" (__ "Browser") Nothing Nothing         showBrowser [] False     ,AD "ShowModules" (__ "Modules") Nothing Nothing         showModules [] False-    ,AD "ShowInfo" (__ "Info") Nothing Nothing+    ,AD "ShowInfo" (__ "Symbol _Info") Nothing Nothing         showInfo [] False     ,AD "ShowDebugger" (__ "Debugger") Nothing Nothing         showDebugger [] False@@ -395,8 +398,6 @@         showVariables [] False     ,AD "ShowSearch" (__ "Search") Nothing Nothing         (getSearch Nothing  >>= \ p -> displayPane p False) [] False-    ,AD "ShowFiles" (__ "Files") Nothing Nothing-        (getFiles Nothing  >>= \ p -> displayPane p False >> refreshFiles) [] False     ,AD "ShowGrep" (__ "Grep") Nothing Nothing         (getGrep Nothing  >>= \ p -> displayPane p False) [] False     ,AD "ShowDocumentation" (__ "Documentation") Nothing Nothing@@ -410,7 +411,7 @@     ,AD "ShowLog" (__ "Log") Nothing Nothing         showLog [] False     ,AD "ShowWorkspace" (__ "Workspace") Nothing Nothing-        showWorkspace [] False+        showWorkspacePane [] False      ,AD "View" (__ "_View") Nothing Nothing (return ()) [] False     ,AD "ViewMoveLeft" (__ "Move _Left") Nothing Nothing@@ -433,9 +434,8 @@         viewDetachInstrumented [] False     ,AD "ViewFullScreen" (__ "_Full Screen") Nothing Nothing         viewFullScreen [] True-    ,AD "ViewDark" (__ "Dark") Nothing Nothing-        viewDark [] True-+    ,AD "UseDarkInterface" (__ "_Use Dark Interface") Nothing Nothing+        viewUseDarkInterface [] True     ,AD "ViewTabsLeft" (__ "Tabs Left") Nothing Nothing         (viewTabsPos PosLeft) [] False     ,AD "ViewTabsRight" (__ "Tabs Right") Nothing Nothing@@ -468,11 +468,9 @@     ,AD "ToggleToolbar" (__ "Toggle Toolbar") Nothing Nothing         toggleToolbar [] False -    ,AD "Configuration" (__ "_Configuration") Nothing Nothing (return ()) [] False-    ,AD "EditCandy" (__ "_To Candy") Nothing Nothing-        editCandy [] True-    ,AD "PrefsEdit" (__ "_Edit Prefs") Nothing Nothing-        (getPrefs Nothing >>= \ p -> displayPane p False) [] False+    ,AD "Tools" (__ "_Tools") Nothing Nothing (return ()) [] False+    ,AD "PrefsEdit" (__ "_Preferences") Nothing Nothing+        runPreferencesDialog [] False      ,AD "Help" (__ "_Help") Nothing Nothing (return ()) [] False     ,AD "HelpDebug" (__ "Debug") Nothing Nothing (do@@ -489,7 +487,7 @@         runUnitTestsToggled [] True     ,AD "MakeModeToggled" (__ "_MakeMode") (Just (__ "Make dependent packages")) (Just "ide_make")         makeModeToggled [] True-    ,AD "DebugToggled" "_GHCi" (Just (__ "Use GHCi debugger to build and run")) (Just "ide_debug")+    ,AD "DebugToggled" "_Enable GHCi" (Just (__ "Use GHCi debugger to build and run")) (Just "ide_debug")         debugToggled [] True     ,AD "OpenDocu" (__ "_OpenDocu") (Just (__ "Opens a browser for a search of the selected data")) Nothing         openDocu [] True@@ -509,28 +507,40 @@     recentFiles'       <-  readIDE recentFiles     recentWorkspaces'  <-  readIDE recentWorkspaces     recentFilesItem    <-  getRecentFiles-    recentWorkspacesItem <-  getRecentWorkspaces+    recentWorkspacesItem <- getRecentWorkspaces     reifyIDE (\ ideR -> do         recentFilesMenu    <-  menuNew-        mapM_ (\s -> do-            fe <- doesFileExist s-            when fe $ do-                mi <- menuItemNewWithLabel $ T.pack s-                mi `on` menuItemActivate $ reflectIDE (fileOpen' s) ideR-                menuShellAppend recentFilesMenu mi) recentFiles'+        existingRecentFiles <- filterM doesFileExist recentFiles'+        if null existingRecentFiles+            then do+                mi <- menuItemNewWithLabel (T.pack "No recently opened files")+                widgetSetSensitive mi False+                menuShellAppend recentFilesMenu mi+            else+                forM_ recentFiles' $ \s -> do+                    mi <- menuItemNewWithLabel $ T.pack s+                    mi `on` menuItemActivate $ reflectIDE (fileOpen' s) ideR+                    menuShellAppend recentFilesMenu mi         oldSubmenu <- menuItemGetSubmenu recentFilesItem         when (isJust oldSubmenu) $ do             widgetHide (fromJust oldSubmenu)             widgetDestroy (fromJust oldSubmenu)         menuItemSetSubmenu recentFilesItem recentFilesMenu         widgetShowAll recentFilesMenu+         recentWorkspacesMenu    <-  menuNew-        mapM_ (\s -> do-            fe <- doesFileExist s-            when fe $ do-                mi <- menuItemNewWithLabel $ T.pack s-                mi `on` menuItemActivate $ reflectIDE (workspaceOpenThis True (Just s) >> showWorkspace) ideR-                menuShellAppend recentWorkspacesMenu mi) recentWorkspaces'+        existingRecentWorkspaces <- filterM doesFileExist recentWorkspaces'+        if null existingRecentWorkspaces+            then do+                mi <- menuItemNewWithLabel (T.pack "No recently opened workspaces")+                widgetSetSensitive mi False+                menuShellAppend recentWorkspacesMenu mi+            else+                forM_ existingRecentWorkspaces $ \s -> do+                    mi <- menuItemNewWithLabel $ T.pack s+                    mi `on` menuItemActivate $ reflectIDE (workspaceOpenThis True (Just s) >> showWorkspacePane) ideR+                    menuShellAppend recentWorkspacesMenu mi+         oldSubmenu <- menuItemGetSubmenu recentWorkspacesItem         when (isJust oldSubmenu) $ do             widgetHide (fromJust oldSubmenu)@@ -623,13 +633,12 @@     menuShellAppend menu mi2     mi3 <- menuItemNewWithLabel (__ "Search (metadata)")     mi3 `on` menuItemActivate $-      reflectIDE_ $-         getSearch Nothing >>=-           (\ search ->-              do mbtext <- selectedText-                 case mbtext of-                     Just t -> searchMetaGUI search t-                     Nothing -> ideMessage Normal (__ "Select a text first"))+      reflectIDE_ $ do+         mbtext <- selectedTextOrCurrentIdentifier -- if no text selected, search for current identifier+         searchPane <- getSearch Nothing+         case mbtext of+              Just t  -> searchMetaGUI searchPane t+              Nothing -> ideMessage Normal (__ "No identifier selected")     menuShellAppend menu mi3     let interpretingEntries = [castToWidget mi16]     let interpretingSelEntries@@ -652,7 +661,9 @@ canQuit :: IDEM Bool canQuit = do     modifyIDE_ (\ide -> ide{currentState = IsShuttingDown})-    saveSession :: IDEAction+    prefs <- readIDE prefs+    when (saveSessionOnClose prefs) $+        saveSession     can <- fileCloseAll (\_ -> return True)     unless can $ modifyIDE_ (\ide -> ide{currentState = IsRunning})     return can@@ -670,10 +681,11 @@ aboutDialog = do     d <- aboutDialogNew     dd <- getDataDir+    (year, _, _) <- liftM (toGregorian . utctDay) getCurrentTime     license <- catch (T.readFile $ dd </> T.unpack (__ "LICENSE")) (\ (_ :: SomeException) -> return "")     set d [ aboutDialogName := ("Leksah" :: Text)           , aboutDialogVersion := T.pack $ showVersion version-          , aboutDialogCopyright := __ "Copyright 2007-2011 Jürgen Nicklisch-Franken, Hamish Mackenzie"+          , aboutDialogCopyright := __ "Copyright 2007-" <> T.pack (show year) <> " Jürgen Nicklisch-Franken, Hamish Mackenzie"           , aboutDialogComments := __ "An integrated development environement (IDE) for the " <>                                __ "programming language Haskell and the Glasgow Haskell Compiler"           , aboutDialogLicense := Just license@@ -688,12 +700,16 @@ newIcons = catch (do         iconFactory <- iconFactoryNew         dataDir <- getDataDir-        mapM_ (loadIcon dataDir iconFactory) ["ide_class","ide_configure","ide_data","ide_error_next",++        mapM_ (loadIcon dataDir iconFactory)+            ["ide_class","ide_configure","ide_data","ide_error_next",             "ide_error_prev","ide_function","ide_instance", "ide_konstructor","ide_make",             "ide_method","ide_newtype","ide_other","ide_rule","ide_run","ide_slot",             "ide_source","ide_type","leksah", "ide_reexported", "ide_clean", "ide_link", "ide_build",             "ide_debug", "ide_step", "ide_local", "ide_module", "ide_continue", "ide_rebuild_meta",-            "ide_empty","ide_source_local", "ide_js"]+            "ide_empty","ide_source_local", "ide_js", "ide_folder", "ide_source_folder",+            "ide_cabal_file", "ide_package", "ide_component", "ide_source_dependency", "ide_error",+            "ide_warning", "ide_suggestion"  ]         iconFactoryAddDefault iconFactory)     (\(e :: SomeException) -> getDataDir >>= \dataDir -> throwIDE (T.pack $ printf (__ "Can't load icons from %s %s") dataDir (show e)))     where@@ -701,6 +717,7 @@         pb      <-  pixbufNewFromFile $ dataDir </> "pics" </> (name <> ".png")         icon    <-  iconSetNewFromPixbuf pb         iconFactoryAdd iconFactory (T.pack name) icon+        iconThemeAddBuiltinIcon name 16 pb  setSensitivity :: [(SensitivityMask, Bool)] -> IDEAction setSensitivity = mapM_ setSensitivitySingle@@ -720,7 +737,7 @@     ,"OpenDocPackage","FileCloseAll"] getActionsFor SensitivityError = getActionsFor' ["NextError", "PreviousError"] getActionsFor SensitivityEditor = getActionsFor' ["EditUndo", "EditRedo",-        "EditGotoLine","EditComment", "EditUncomment",+        "EditGotoLine","EditComment", "EditUncomment", "EditSelectAll",         "EditShiftLeft", "EditShiftRight","FileClose",         "OpenDocu"         ]@@ -752,6 +769,16 @@             instrumentSecWindow win             liftIO $ widgetShowAll win +viewUseDarkInterface :: IDEAction+viewUseDarkInterface = do+    useDark <- getDarkState+    prefs <- readIDE prefs+    when (useDark /= darkUserInterface prefs) $ do+        let prefs' = prefs {darkUserInterface = useDark}+        modifyIDE_ (\ide -> ide {prefs = prefs'})+        applyInterfaceTheme++ instrumentWindow :: Window -> Prefs -> Widget -> IDEAction instrumentWindow win prefs topWidget = do     -- sets the icon@@ -779,7 +806,6 @@         windowAddAccelGroup win acc         containerAdd win vb         reflectIDE (do-            setCandyState (fst (sourceCandy prefs))             setBackgroundBuildToggled (backgroundBuild prefs)             setRunUnitTests (runUnitTests prefs)             setMakeModeToggled (makeMode prefs)) ideR@@ -822,8 +848,7 @@             flipUp             return True         _                                                            -> do-                bs <- getCandyState-                when bs (editKeystrokeCandy mbChar)+                when (candyState prefs') (editKeystrokeCandy mbChar)                 sk  <- readIDE specialKey                 sks <- readIDE specialKeys                 case sk of@@ -899,8 +924,14 @@     registerEvent stRef "UpdateWorkspaceInfo"         (\ e@UpdateWorkspaceInfo  -> updateWorkspaceInfo >> return e)     registerEvent stRef "WorkspaceChanged"-        (\ e@(WorkspaceChanged showPane updateFileCache)-                                  -> postAsyncIDE (updateWorkspace showPane updateFileCache) >> return e)+        (\ e@(WorkspaceChanged showPane updateFileCache) -> do+                                     postAsyncIDE $ do+                                         refreshWorkspacePane+                                         when showPane+                                            showWorkspacePane+                                         when updateFileCache $+                                            modifyIDE_ (\ide -> ide{bufferProjCache = Map.empty})+                                     return e)     registerEvent stRef "RecordHistory"         (\ rh@(RecordHistory h)   -> recordHistory h >> return rh)     registerEvent stRef "Sensitivity"@@ -922,9 +953,7 @@     registerEvent stRef "ErrorAdded"         (\ e@(ErrorAdded show' i ref) -> postAsyncIDE (addErrorToList show' i ref) >> return e)     registerEvent stRef "CurrentErrorChanged"-        (\ e@(CurrentErrorChanged mbLogRef) -> postAsyncIDE (do-            selectRef mbLogRef-            selectError mbLogRef)  >> return e)+        (\ e@(CurrentErrorChanged mbLogRef) -> postAsyncIDE (selectRef mbLogRef)  >> return e)     registerEvent stRef "BreakpointChanged"         (\ e@BreakpointChanged    -> postAsyncIDE fillBreakpointList >> return e)     registerEvent stRef "CurrentBreakChanged"@@ -942,7 +971,12 @@     registerEvent stRef "SelectSrcSpan"         (\ e@(SelectSrcSpan mbSpan) -> selectMatchingErrors mbSpan >> return e)     registerEvent stRef "SavedFile"-        (\ e@(SavedFile file) -> scheduleHLint (Right file) >> return e)+        (\ e@(SavedFile file) -> do+              prefs <- readIDE prefs+              when (hlintOnSave prefs && takeExtension file `elem` [".hs", ".lhs"]) $+                  scheduleHLint (Right file)+              return e)+     return ()  
src/IDE/Completion.hs view
@@ -31,7 +31,6 @@ import qualified Control.Monad.Reader as Gtk (liftIO) import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Applicative ((<$>))-import IDE.Utils.GUIUtils (getDarkState) import Data.Text (Text) import qualified Data.Text as T        (empty, commonPrefixes, pack, unpack, null, stripPrefix,
src/IDE/Core/State.hs view
@@ -445,7 +445,7 @@             modifyIDE_ (\ide -> ide{activePack = Just ideP})         _ -> return ()     where-        key = ipdBuildDir+        key = ipdPackageDir         idePKey = key ideP         exchange p | key p == idePKey = ideP                    | otherwise        = p
src/IDE/Core/Types.hs view
@@ -45,8 +45,10 @@ ,   runDebug  ,   IDEPackage(..)-,   ipdBuildDir+,   ipdPackageDir ,   ipdAllDirs+,   ipdLib+,   ipdPackageName ,   Workspace(..) ,   wsAllPackages ,   VCSConf@@ -56,6 +58,7 @@ ,   KeyString  ,   Prefs(..)+,   candyState ,   cabalCommand ,   EditorStyle(..) ,   editorStyle@@ -99,7 +102,7 @@ import Data.Unique (newUnique, Unique(..)) import Graphics.UI.Frame.Panes import Distribution.Package-    (PackageIdentifier(..), Dependency(..))+       (PackageName(..), PackageIdentifier(..), Dependency(..)) import Distribution.PackageDescription (BuildInfo) import Data.Map (Map(..)) import Data.Set (Set(..))@@ -119,7 +122,7 @@ import IDE.Core.CTypes import IDE.StrippedPrefs(RetrieveStrategy) import System.IO (Handle)-import Distribution.Text(disp)+import Distribution.Text (display, disp) import Text.PrettyPrint (render) import Control.Monad.Trans.Class (lift) import Control.Monad.IO.Class (liftIO, MonadIO)@@ -133,11 +136,12 @@ import Foreign (Ptr) import Control.Monad.Reader.Class (MonadReader(..)) import Data.Text (Text)-import qualified Data.Text as T (unpack)+import qualified Data.Text as T (pack, unpack) import Language.Haskell.HLint3 (Idea(..)) import Data.Function (on) import Control.Concurrent.STM.TVar (TVar) import Data.Sequence (Seq)+import Data.Maybe (maybeToList)  -- --------------------------------------------------------------------- -- IDE State@@ -382,7 +386,7 @@ ,   ipdBenchmarks      ::   [Text] ,   ipdMain            ::   [(FilePath, BuildInfo, Bool)] ,   ipdExtraSrcs       ::   Set FilePath-,   ipdSrcDirs         ::   [FilePath]+,   ipdSrcDirs         ::   [FilePath] -- ^ Relative paths to the source directories ,   ipdExtensions      ::   [Extension] ,   ipdConfigFlags     ::   [Text] ,   ipdBuildFlags      ::   [Text]@@ -403,11 +407,21 @@ instance Ord IDEPackage where     compare x y     =   compare (ipdPackageId x) (ipdPackageId y) -ipdBuildDir :: IDEPackage -> FilePath-ipdBuildDir = dropFileName . ipdCabalFile+-- | The directory of the cabal file+ipdPackageDir :: IDEPackage -> FilePath+ipdPackageDir = dropFileName . ipdCabalFile +-- | Gets the package name+ipdPackageName :: IDEPackage -> Text+ipdPackageName = T.pack . (\(PackageName s) -> s) . pkgName . ipdPackageId++-- | Gets the library name if the package has a library component+ipdLib :: IDEPackage -> Maybe Text+ipdLib pkg = if ipdHasLibs pkg then Just (ipdPackageName pkg) else Nothing++-- | All directory of the package and those of all its source dependencies ipdAllDirs :: IDEPackage -> [FilePath]-ipdAllDirs p = ipdBuildDir p : (ipdSandboxSources p >>= ipdAllDirs)+ipdAllDirs p = ipdPackageDir p : (ipdSandboxSources p >>= ipdAllDirs)  -- --------------------------------------------------------------------- -- Workspace@@ -461,6 +475,8 @@     ,   tabWidth            ::   Int     ,   wrapLines           ::   Bool     ,   sourceCandy         ::   (Bool,Text)+    ,   darkUserInterface   ::   Bool+    ,   saveSessionOnClose  ::   Bool     ,   keymapName          ::   Text     ,   forceLineEnds       ::   Bool     ,   removeTBlanks       ::   Bool@@ -504,6 +520,8 @@     ,   printBindResult     ::   Bool     ,   serverIP            ::   Text     ,   showHiddenFiles     ::   Bool+    ,   showWorkspaceIcons  ::   Bool+    ,   hlintOnSave         ::   Bool             -- As well used by server     ,   serverPort          ::   Int     ,   sourceDirectories   ::   [FilePath]@@ -516,6 +534,9 @@ cabalCommand :: Prefs -> FilePath cabalCommand p = if useCabalDev p then "cabal-dev" else "cabal" +candyState :: Prefs -> Bool+candyState = fst . sourceCandy+ data EditorStyle = EditorStyle { styleName    :: Maybe Text                                , preferDark   :: Bool                                , foundBG      :: (Color, Color)@@ -590,7 +611,7 @@             show (srcSpanStartColumn s) ++ "-" ++ show (srcSpanEndColumn s)  logRefRootPath :: LogRef -> FilePath-logRefRootPath = ipdBuildDir . logRefPackage+logRefRootPath = ipdPackageDir . logRefPackage  logRefFilePath :: LogRef -> FilePath logRefFilePath = srcSpanFilename . logRefSrcSpan@@ -677,4 +698,4 @@     |   CompartmentCollect Bool  type PackageDescrCache = Map PackageIdentifier ModuleDescrCache-type ModuleDescrCache = Map ModuleName (UTCTime, Maybe FilePath, ModuleDescr)+type ModuleDescrCache = Map ModuleKey (UTCTime, Maybe FilePath, ModuleDescr)
src/IDE/Find.hs view
@@ -9,7 +9,7 @@ -- -- Maintainer  :  <maintainer at leksah.org> -- Stability   :  provisional--- Portability :  portablea+-- Portability :  portable -- -- | The toolbar for searching and replacing in a text buffer --@@ -27,12 +27,9 @@ ,   getFindState ,   setFindState ,   editFind- ,   showToolbar ,   hideToolbar ,   toggleToolbar-- ) where  import Graphics.UI.Gtk@@ -326,7 +323,7 @@         return False      replaceButton `onToolButtonClicked` replace toolbar Forward ideR-    let performReplaceAll = replaceAll toolbar Forward ideR+    let performReplaceAll = replaceAll toolbar Initial ideR     replaceAllButton `onToolButtonClicked` performReplaceAll      let ctrl "c" = toggleToolButton caseSensitiveButton >> return True@@ -488,7 +485,6 @@                 ideR     return () - replaceAll :: Toolbar -> SearchHint -> IDERef -> IO () replaceAll fb hint ideR   =  do     entry          <- getFindEntry fb@@ -499,7 +495,7 @@     caseSensitive  <- getCaseSensitive fb     wrapAround     <- getWrapAround fb     regex          <- getRegex fb-    found <- reflectIDE (editReplaceAll entireWord caseSensitive wrapAround regex search replace hint)+    found <- reflectIDE (editReplaceAll entireWord caseSensitive regex search replace hint)                 ideR     return () @@ -513,43 +509,45 @@ editFind' :: Regex -> Int -> Bool -> Text -> SearchHint -> IDEM Bool editFind' exp matchIndex wrapAround dummy hint =     inActiveBufContext False $ \_ sv ebuf _ _ -> do-    i1 <- getStartIter ebuf-    i2 <- getEndIter ebuf-    text <- getText ebuf i1 i2 True-    removeTagByName ebuf "found"-    startMark <- getInsertMark ebuf-    st1 <- getIterAtMark ebuf startMark-    mbsr2 <--        if hint == Backward-            then do-                st2 <- backwardCharC st1-                st3 <- backwardCharC st2-                mbsr <- backSearch exp matchIndex ebuf text st3-                case mbsr of-                    Nothing ->-                        if wrapAround-                            then backSearch exp matchIndex ebuf text i2-                            else return Nothing-                    m -> return m-            else do-                st2 <- if hint == Forward-                    then forwardCharC st1-                    else return st1-                mbsr <- forwardSearch exp matchIndex ebuf text st2-                case mbsr of-                    Nothing ->-                        if wrapAround-                            then forwardSearch exp matchIndex ebuf text i1-                            else return Nothing-                    m -> return m-    case mbsr2 of-        Just (start,end,_) -> do --found-            --widgetGrabFocus sourceView-            scrollToIter sv start 0.2 Nothing-            applyTagByName ebuf "found" start end-            placeCursor ebuf start-            return True-        Nothing -> return False+        i1 <- getStartIter ebuf+        i2 <- getEndIter ebuf+        text <- getText ebuf i1 i2 True+        removeTagByName ebuf "found"+        startMark <- getInsertMark ebuf+        st1 <- getIterAtMark ebuf startMark+        mbsr2 <-+            if hint == Backward+                then do+                    st2 <- backwardCharC st1+                    st3 <- backwardCharC st2+                    mbsr <- backSearch exp matchIndex ebuf text st3+                    case mbsr of+                        Nothing ->+                            if wrapAround+                                then backSearch exp matchIndex ebuf text i2+                                else return Nothing+                        m -> return m+                else do+                    st2 <- if hint == Forward+                        then forwardCharC st1+                        else return st1+                    mbsr <- if hint == Initial+                            then initialSearch exp matchIndex ebuf text st2+                            else forwardSearch exp matchIndex ebuf text st2+                    case mbsr of+                        Nothing ->+                            if wrapAround+                                then forwardSearch exp matchIndex ebuf text i1+                                else return Nothing+                        m -> return m+        case mbsr2 of+            Just (start,end,_) -> do --found+                --widgetGrabFocus sourceView+                scrollToIter sv start 0.2 Nothing+                applyTagByName ebuf "found" start end+                placeCursor ebuf start+                return True+            Nothing -> return False     where         backSearch exp matchIndex ebuf text iter = do             offset <- getOffset iter@@ -559,6 +557,8 @@             offset <- getOffset iter             findMatch exp matchIndex ebuf text (>= offset) False +        initialSearch exp matchIndex ebuf text iter = findMatch exp matchIndex ebuf text (>= 0) False+ regexAndMatchIndex :: Bool -> Bool -> Bool -> Text -> IO (Maybe (Regex, Int)) regexAndMatchIndex caseSensitive entireWord regex string =     if T.null string@@ -595,21 +595,22 @@  editReplace :: Bool -> Bool -> Bool -> Bool -> Text -> Text -> SearchHint -> IDEM Bool editReplace entireWord caseSensitive wrapAround regex search replace hint =-    editReplace' entireWord caseSensitive wrapAround regex search replace hint True+    editReplace' entireWord caseSensitive wrapAround regex search replace hint False  editReplace' :: Bool -> Bool -> Bool -> Bool -> Text -> Text -> SearchHint -> Bool -> IDEM Bool-editReplace' entireWord caseSensitive wrapAround regex search replace hint mayRepeat =+editReplace' entireWord caseSensitive wrapAround regex search replace hint fromStart =     inActiveBufContext False $ \_ _ ebuf _ _ -> do         insertMark <- getInsertMark ebuf         iter       <- getIterAtMark ebuf insertMark-        offset     <- getOffset iter+        offset   <- getOffset iter+        let offset' = if fromStart then 0 else offset         mbExpAndMatchIndex <- liftIO $ regexAndMatchIndex caseSensitive entireWord regex search         case mbExpAndMatchIndex of             Just (exp, matchIndex) -> do                 iStart <- getStartIter ebuf                 iEnd   <- getEndIter ebuf                 text   <- getText ebuf iStart iEnd True-                match  <- findMatch exp matchIndex ebuf text (== offset) False+                match  <- findMatch exp matchIndex ebuf text (== offset') False                 case match of                     Just (iterStart, iterEnd, matches) -> do                         mbText <- liftIO $ replacementText regex text matchIndex matches $ T.unpack replace@@ -654,11 +655,14 @@  regexReplacement text matchIndex matches (x : xs) = x : regexReplacement text matchIndex matches xs -editReplaceAll :: Bool -> Bool -> Bool -> Bool -> Text -> Text -> SearchHint -> IDEM Bool-editReplaceAll entireWord caseSensitive wrapAround regex search replace hint = do-    res <- editReplace' entireWord caseSensitive False regex search replace hint True+editReplaceAll :: Bool -> Bool -> Bool -> Text -> Text -> SearchHint -> IDEM Bool+editReplaceAll = editReplaceAll' True++editReplaceAll' :: Bool -> Bool -> Bool -> Bool -> Text -> Text -> SearchHint -> IDEM Bool+editReplaceAll' fromStart entireWord caseSensitive regex search replace hint = do+    res <- editReplace' entireWord caseSensitive False regex search replace hint fromStart     if res-        then editReplaceAll entireWord caseSensitive False regex search replace hint+        then editReplaceAll' False entireWord caseSensitive regex search replace hint         else return False  compileRegex :: Bool -> Text -> Either String Regex@@ -680,19 +684,19 @@         Nothing -> throwIDE "Find>>needFindbar: Findbar not initialized"         Just p  -> return p +-- | Find action. If SearchHint==Initial then we'll use the selected text or current identifier to populate the find text box editFindInc :: SearchHint -> IDEAction editFindInc hint = do     ideR <- ask     (fb,_) <- needFindbar     case hint of-        Initial -> inActiveBufContext () $ \_ _ ebuf _ _ -> do-            hasSelection <- hasSelection ebuf-            when hasSelection $ do-                (i1,i2)   <- getSelectionBounds ebuf-                text      <- getText ebuf i1 i2 False-                findEntry <- liftIO $ getFindEntry fb-                liftIO $ entrySetText (castToEntry findEntry) text-                return ()+        Initial -> do+               mbtext <- selectedTextOrCurrentIdentifier -- if no text selected, search for current identifier+               case mbtext of+                 Just text -> do+                     findEntry <- liftIO $ getFindEntry fb+                     liftIO $ entrySetText (castToEntry findEntry) text+                 Nothing -> return ()         _ -> return ()     showFindbar     reifyIDE $ \ideR   -> do
src/IDE/HLint.hs view
@@ -26,7 +26,7 @@ import Prelude hiding(getChar, getLine) import IDE.Core.Types        (logRefFullFilePath, Prefs(..), LogRef(..), LogRefType(..),-        wsAllPackages, ipdBuildDir, IDEM, IDEAction, IDE(..),+        wsAllPackages, ipdPackageDir, IDEM, IDEAction, IDE(..),         IDEPackage(..), PackageAction) import Control.Monad.Reader (asks, MonadReader(..)) import IDE.Core.State@@ -111,7 +111,7 @@ runHLint (Right sourceFile) = do     liftIO . debugM "leksah" $ "runHLint"     packages <- maybe [] wsAllPackages <$> readIDE workspace-    case sortBy (flip (comparing (length . ipdBuildDir))) $ filter (belongsToPackage sourceFile) packages of+    case sortBy (flip (comparing (length . ipdPackageDir))) $ filter (belongsToPackage sourceFile) packages of         (package:_) -> runHLint' package (Just sourceFile)         _ -> liftIO . debugM "leksah" $ "runHLint package not found for " <> sourceFile runHLint (Left cabalFile) = do@@ -131,8 +131,8 @@                     Just f  -> return [f]                     Nothing -> getSourcePaths (ipdPackageId package) modules     res <- forM paths $ \ full -> do-        let file = makeRelative (ipdBuildDir package) full-        postSyncIDE $ removeLintLogRefs (ipdBuildDir package) file+        let file = makeRelative (ipdPackageDir package) full+        postSyncIDE $ removeLintLogRefs (ipdPackageDir package) file         text <- liftIO $ T.readFile full         liftIO . debugM "leksah" $ "runHLint parsing " <> full         do result <- liftIO $ parseModuleEx flags full (Just (T.unpack text))@@ -172,7 +172,7 @@ hlintSettings :: IDEPackage -> IDEM (ParseFlags, [Classify], Hint) hlintSettings package = do     mbHlintDir <- liftIO $ leksahSubDir "hlint"-    let cabalMacros = ipdBuildDir package </> "dist/build/autogen/cabal_macros.h"+    let cabalMacros = ipdPackageDir package </> "dist/build/autogen/cabal_macros.h"     cabalMacrosExist <- liftIO $ doesFileExist cabalMacros     defines <- liftIO $ if cabalMacrosExist                             then do@@ -192,7 +192,7 @@     forM_ ideas $ \ idea@Idea{..} -> do         let text = getText (HSE.srcSpanFilename ideaSpan)             fixColumn c = max 0 (c - 1)-            srcSpan = SrcSpan (makeRelative (ipdBuildDir package) $ HSE.srcSpanFilename ideaSpan)+            srcSpan = SrcSpan (makeRelative (ipdPackageDir package) $ HSE.srcSpanFilename ideaSpan)                               (HSE.srcSpanStartLine ideaSpan)                               (HSE.srcSpanStartColumn ideaSpan - 1)                               (HSE.srcSpanEndLine ideaSpan)@@ -213,7 +213,7 @@ logHLintError :: Bool -> IDEPackage -> ParseError -> IDEAction logHLintError fileScope package error = do     let loc = parseErrorLocation error-        srcSpan = SrcSpan (makeRelative (ipdBuildDir package) $ HSE.srcFilename loc)+        srcSpan = SrcSpan (makeRelative (ipdPackageDir package) $ HSE.srcFilename loc)                           (HSE.srcLine loc)                           (HSE.srcColumn loc - 1)                           (HSE.srcLine loc)
src/IDE/ImportTool.hs view
@@ -17,6 +17,7 @@     resolveErrors ,   addOneImport ,   addResolveMenuItems+,   resolveMenuItems ,   parseHiddenModule ,   HiddenModuleResult(..) ) where@@ -546,6 +547,14 @@                 setModified gtkbuf True                 continuation True         _  -> return ()++resolveMenuItems :: LogRef -> [(Text, IDEAction)]+resolveMenuItems logRef+    | isJust (parseNotInScope msg)   = [("Add Import", addImport logRef [] (\ _ -> return ()))]+    | isJust (parseHiddenModule msg) = [("Add Package", void $ addPackages [logRef])]+    | length (parsePerhapsYouIntendedToUse msg) == 1 = [("Add Extension", addExtension logRef (\ _ -> return ()))]+    | otherwise = []+    where msg = refDescription logRef  addResolveMenuItems ideR theMenu logRef = do     let msg = refDescription logRef
src/IDE/Leksah.hs view
@@ -46,7 +46,7 @@ import Graphics.UI.Editor.MakeEditor import Graphics.UI.Editor.Parameters import IDE.Command-import IDE.Pane.Preferences+import IDE.Preferences import IDE.Keymap import IDE.Pane.SourceBuffer import IDE.Find@@ -410,7 +410,6 @@     on win deleteEvent . liftIO $ reflectIDE quit ideR >> return True     reflectIDE (instrumentWindow win startupPrefs (castToWidget nb)) ideR     reflectIDE (do-        setCandyState (fst (sourceCandy startupPrefs))         setBackgroundBuildToggled (backgroundBuild startupPrefs)         setRunUnitTests (runUnitTests startupPrefs)         setMakeModeToggled (makeMode startupPrefs)) ideR
src/IDE/LogRef.hs view
@@ -383,7 +383,7 @@ logOutputLines logLaunch lineLogger = do     log :: Log.IDELog <- lift $ postSyncIDE Log.getLog     results <- CL.mapM (postSyncIDE . lineLogger log logLaunch) =$ CL.consume-    lift $ triggerEventIDE (StatusbarChanged [CompartmentState "", CompartmentBuild False])+    lift . postSyncIDE $ triggerEventIDE (StatusbarChanged [CompartmentState "", CompartmentBuild False])     return results  logOutputLines_ :: LogLaunch@@ -514,7 +514,7 @@                         logLn <- Log.appendLog log logLaunch (line <> "\n") LogTag                         reflectIDE (triggerEventIDE (StatusbarChanged [CompartmentState                             (T.pack $ "Compiling " ++ show n ++ " of " ++ show total), CompartmentBuild False])) ideR-                        let root = ipdBuildDir package+                        let root = ipdPackageDir package                             fullFilePath = root </> file                         reflectIDE (removeBuildLogRefs root file) ideR                         when inDocTest $ logPrevious testFails@@ -574,7 +574,7 @@                         -> LogLaunch           -- ^ loglaunch                         -> C.Sink ToolOutput IDEM () logOutputForBreakpoints package logLaunch = do-    breaks <- logOutputLines logLaunch (\log logLaunch out ->+    breaks <- logOutputLines logLaunch (\log logLaunch out -> postSyncIDE $         case out of             ToolOutput line -> do                 logLineNumber <- liftIO $ Log.appendLog log logLaunch (line <> "\n") LogTag@@ -602,7 +602,7 @@             _ -> do                 defaultLineLogger log logLaunch out                 return Nothing)-    lift . addLogRefs . Seq.fromList $ catMaybes breaks+    lift . postSyncIDE . addLogRefs . Seq.fromList $ catMaybes breaks  logOutputForSetBreakpointDefault :: IDEPackage                                  -> C.Sink ToolOutput IDEM ()@@ -626,7 +626,7 @@             _ -> do                 defaultLineLogger log logLaunch out                 return Nothing)-    lift $ unless (null refs) $ do+    lift . unless (null refs) . postSyncIDE $ do         addLogRefs . Seq.singleton $ last refs         lastContext 
src/IDE/Metainfo/Provider.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE OverloadedStrings #-} -----------------------------------------------------------------------------@@ -33,16 +34,20 @@ ,   getSystemInfo  ,   getPackageImportInfo -- Scope for the import tool+,   getAllPackageIds+,   getAllPackageIds' ) where +import Prelude ()+import Prelude.Compat hiding(catch, readFile) import System.IO (hClose, openBinaryFile, IOMode(..)) import System.IO.Strict (readFile) import qualified Data.Map as Map-import Control.Monad+import Control.Monad (void, filterM, foldM, liftM, when) import System.FilePath import System.Directory-import Data.List-import Data.Maybe+import Data.List (nub, (\\), find, partition, maximumBy, foldl')+import Data.Maybe (catMaybes, fromJust, isJust, mapMaybe, fromMaybe) import Distribution.Package hiding (depends,packageId) import qualified Data.Set as Set import qualified Data.ByteString.Char8 as BS@@ -64,7 +69,6 @@ import IDE.Core.Serializable () import Data.Map (Map(..)) import Control.Exception (SomeException(..), catch)-import Prelude hiding(catch, readFile) import IDE.Utils.ServerConnection(doServerCommand) import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Trans.Class (MonadTrans(..))@@ -75,6 +79,7 @@ import Data.Monoid ((<>)) import qualified Control.Arrow as A (Arrow(..)) import Data.Function (on)+import Distribution.Package (PackageIdentifier)  -- --------------------------------------------------------------------- -- Updating metadata@@ -131,6 +136,19 @@     updateWorkspaceInfo' True $ \ _ ->         void (triggerEventIDE (InfoChanged False)) +getAllPackageIds :: IDEM [PackageIdentifier]+getAllPackageIds = either (const []) id <$> getAllPackageIds'++getAllPackageIds' :: IDEM (Either Text [PackageIdentifier])+getAllPackageIds' = do+    mbWorkspace <- readIDE workspace+    liftIO . getInstalledPackageIds' $ map ipdPackageDir (maybe [] wsAllPackages mbWorkspace)++getAllPackageDBs :: IDEM [[FilePath]]+getAllPackageDBs = do+    mbWorkspace <- readIDE workspace+    liftIO . getPackageDBs $ map ipdPackageDir (maybe [] wsAllPackages mbWorkspace)+ -- -- | Load all infos for all installed and exposed packages --   (see shell command: ghc-pkg list)@@ -138,7 +156,7 @@ loadSystemInfo :: IDEAction loadSystemInfo = do     collectorPath   <-  liftIO getCollectorPath-    mbPackageIds    <-  liftIO getInstalledPackageIds'+    mbPackageIds    <-  getAllPackageIds'     case mbPackageIds of         Left e -> logMessage ("Please check that ghc-pkg is in your PATH and restart leksah:\n    " <> e) ErrorTag         Right packageIds -> do@@ -161,7 +179,7 @@     case wi of         Nothing -> loadSystemInfo         Just (GenScopeC (PackScope psmap psst)) -> do-            mbPackageIds    <-  liftIO getInstalledPackageIds'+            mbPackageIds    <-  getAllPackageIds'             case mbPackageIds of                 Left e -> logMessage ("Please check that ghc-pkg is in your PATH and restart leksah:\n    " <> e) ErrorTag                 Right packageIds -> do@@ -255,35 +273,39 @@                 continuation True     postAsyncIDE $ ideMessage Normal "Finished updating workspace metadata" +-- | Update the metadata on several packages updatePackageInfos :: Bool -> [IDEPackage] -> (Bool -> [PackageDescr] -> IDEAction) -> IDEAction-updatePackageInfos = updatePackageInfos' []+updatePackageInfos rebuild pkgs continuation = do+    -- calculate list of known packages once+    knownPackages   <- getAllPackageIds+    updatePackageInfos' [] knownPackages rebuild pkgs continuation     where-        updatePackageInfos' collector _ [] continuation =  continuation True collector-        updatePackageInfos' collector rebuild (hd:tail) continuation =-            updatePackageInfo rebuild hd $ \ _ packDescr ->-                updatePackageInfos' (packDescr : collector) rebuild tail continuation+        updatePackageInfos' collector _ _ [] continuation =  continuation True collector+        updatePackageInfos' collector knownPackages rebuild (hd:tail) continuation =+            updatePackageInfo knownPackages rebuild hd $ \ _ packDescr ->+                updatePackageInfos' (packDescr : collector) knownPackages rebuild tail continuation -updatePackageInfo :: Bool -> IDEPackage -> (Bool -> PackageDescr -> IDEAction) -> IDEAction-updatePackageInfo rebuild idePack continuation = do+-- | Update the metadata on one package+updatePackageInfo :: [PackageIdentifier] -> Bool -> IDEPackage -> (Bool -> PackageDescr -> IDEAction) -> IDEAction+updatePackageInfo knownPackages rebuild idePack continuation = do     liftIO $ infoM "leksah" ("updatePackageInfo " ++ show rebuild ++ " " ++ show (ipdPackageId idePack))     workspInfoCache'     <- readIDE workspInfoCache     let (packageMap, ic) =  case pi  `Map.lookup` workspInfoCache' of                                 Nothing -> (Map.empty,True)                                 Just m  -> (m,False)     modPairsMb <- liftIO $ mapM (\(modName, bi) -> do-            sf <- case  modName `Map.lookup` packageMap of+            sf <- case  LibModule modName `Map.lookup` packageMap of                         Nothing            -> findSourceFile (srcDirs' bi) haskellSrcExts modName                         Just (_,Nothing,_) -> findSourceFile (srcDirs' bi) haskellSrcExts modName                         Just (_,Just fp,_) -> return (Just fp)-            return (modName, sf))+            return (LibModule modName, sf))                 $ Map.toList $ ipdModules idePack     mainModules <- liftIO $ mapM (\(fn, bi, isTest) -> do                                     mbFn <- findSourceFile' (srcDirs' bi) fn-                                    return (main,mbFn))+                                    return (MainModule (fromMaybe fn mbFn), mbFn))                             (ipdMain idePack)-    let modPairsMb' = case mainModules of-                        [] -> modPairsMb-                        hd:_ -> hd : modPairsMb+    -- we want all Main modules since they may be several with different files+    let modPairsMb' = mainModules ++ modPairsMb     let (modWith,modWithout) = partition (\(x,y) -> isJust y) modPairsMb'     let modWithSources       = map (A.second fromJust) modWith     let modWithoutSources    = map fst modWithout@@ -291,14 +313,14 @@     modToUpdate <- if rebuild                             then return modWithSources                             else liftIO $ figureOutRealSources idePack modWithSources-    liftIO . infoM "leksah" $ "updatePackageInfo modToUpdate " ++ show (map (display.fst) modToUpdate)+    liftIO . infoM "leksah" $ "updatePackageInfo modToUpdate " ++ show (map (displayModuleKey.fst) modToUpdate)     callCollectorWorkspace         rebuild-        (dropFileName (ipdCabalFile idePack))+        (ipdPackageDir idePack)         (ipdPackageId idePack)-        (map (\(x,y) -> (T.pack $ display x,y)) modToUpdate)+        (map (\(x,y) -> (T.pack $ display (moduleKeyToName x),y)) modToUpdate)         (\ b -> do-            buildDepends         <- liftIO $ findFittingPackages (ipdDepends idePack)+            let buildDepends         = findFittingPackages knownPackages (ipdDepends idePack)             collectorPath        <- liftIO getCollectorPath             let packageCollectorPath = collectorPath </> T.unpack (packageIdentifierToString pi)             (moduleDescrs,packageMap, changed, modWithout)@@ -318,29 +340,28 @@         srcDirs' bi =  map (basePath </>) ("dist/build":hsSourceDirs bi)         pi = ipdPackageId idePack -figureOutRealSources :: IDEPackage -> [(ModuleName,FilePath)] -> IO [(ModuleName,FilePath)]+figureOutRealSources :: IDEPackage -> [(ModuleKey,FilePath)] -> IO [(ModuleKey,FilePath)] figureOutRealSources idePack modWithSources = do     collectorPath <- getCollectorPath     let packageCollectorPath = collectorPath </> T.unpack (packageIdentifierToString $ ipdPackageId idePack)     filterM (ff packageCollectorPath) modWithSources     where         ff packageCollectorPath (md ,fp) =  do-                let modId = display md-                let collectorModulePath = packageCollectorPath </> modId <.> leksahMetadataWorkspaceFileExtension-                existCollectorFile <- doesFileExist collectorModulePath-                existSourceFile    <- doesFileExist fp-                if not existSourceFile || not existCollectorFile-                    then return True -- Maybe with preprocessing-                    else do-                        sourceModTime <-  getModificationTime fp-                        collModTime   <-  getModificationTime collectorModulePath-                        return (sourceModTime > collModTime)+            let collectorModulePath = packageCollectorPath </> moduleCollectorFileName md <.> leksahMetadataWorkspaceFileExtension+            existCollectorFile <- doesFileExist collectorModulePath+            existSourceFile    <- doesFileExist fp+            if not existSourceFile || not existCollectorFile+                then return True -- Maybe with preprocessing+                else do+                    sourceModTime <-  getModificationTime fp+                    collModTime   <-  getModificationTime collectorModulePath+                    return (sourceModTime > collModTime)   getModuleDescr :: FilePath-    -> ([ModuleDescr],ModuleDescrCache,Bool,[ModuleName])-    -> (ModuleName, Maybe FilePath)-    -> IO ([ModuleDescr],ModuleDescrCache,Bool,[ModuleName])+    -> ([ModuleDescr],ModuleDescrCache,Bool,[ModuleKey])+    -> (ModuleKey, Maybe FilePath)+    -> IO ([ModuleDescr],ModuleDescrCache,Bool,[ModuleKey]) getModuleDescr packageCollectorPath (modDescrs,packageMap,changed,problemMods) (modName,mbFilePath) =     case modName `Map.lookup` packageMap of         Just (eTime,mbFp,mdescr) -> do@@ -351,7 +372,7 @@                     if modificationTime == eTime                         then return (mdescr:modDescrs,packageMap,changed,problemMods)                         else do-                            liftIO . infoM "leksah" $ "getModuleDescr loadInfo: " ++ display modName+                            liftIO . infoM "leksah" $ "getModuleDescr loadInfo: " ++ displayModuleKey modName                             mbNewDescr <- loadInfosForModule moduleCollectorPath                             case mbNewDescr of                                 Just newDescr -> return (newDescr:modDescrs,@@ -374,7 +395,7 @@                                         modName : problemMods)                 else return (modDescrs,packageMap,changed, modName : problemMods)     where-        moduleCollectorPath = packageCollectorPath </> display modName <.>  leksahMetadataWorkspaceFileExtension+        moduleCollectorPath = packageCollectorPath </> moduleCollectorFileName modName <.>  leksahMetadataWorkspaceFileExtension  -- --------------------------------------------------------------------- -- Low level helpers for loading metadata@@ -454,15 +475,20 @@             sysMessage Normal $ "moduleInfo not found for " <> T.pack filePath             return Nothing -findFittingPackages :: [Dependency] -> IO [PackageIdentifier]-findFittingPackages dependencyList = do-    knownPackages   <-  getInstalledPackageIds-    return (concatMap (fittingKnown knownPackages) dependencyList)+-- | Find the packages fitting the dependencies+findFittingPackages+    :: [PackageIdentifier] -- ^ the list of known packages+    -> [Dependency]  -- ^ the dependencies+    -> [PackageIdentifier] -- ^ the known packages matching the dependencies+findFittingPackages knownPackages =+    concatMap (fittingKnown knownPackages)     where     fittingKnown packages (Dependency dname versionRange) =+        -- find matching packages         let filtered =  filter (\ (PackageIdentifier name version) ->                                     name == dname && withinRange version versionRange)                         packages+        -- take latest version if several versions match         in  if length filtered > 1                 then [maximumBy (compare `on` pkgVersion) filtered]                 else filtered@@ -747,9 +773,10 @@ --  callCollector :: Bool -> Bool -> Bool -> (Bool -> IDEAction) -> IDEAction-callCollector rebuild sources extract cont = do+callCollector scRebuild scSources scExtract cont = do     liftIO $ infoM "leksah" "callCollector"-    doServerCommand command $ \ res ->+    scPackageDBs <- getAllPackageDBs+    doServerCommand SystemCommand {..} $ \ res ->         case res of             ServerOK         -> do                 liftIO $ infoM "leksah" "callCollector finished"@@ -760,10 +787,6 @@             _                -> do                 liftIO $ infoM "leksah" "impossible server answer"                 cont False-    where command = SystemCommand {-            scRebuild = rebuild,-            scSources = sources,-            scExtract = extract}  callCollectorWorkspace :: Bool -> FilePath -> PackageIdentifier -> [(Text,FilePath)] ->     (Bool -> IDEAction) -> IDEAction
src/IDE/OSX.hs view
@@ -57,7 +57,7 @@                 applicationInsertAppMenuItem app sep 1             Nothing   -> return () -        mbPrefs   <- uiManagerGetWidget uiManager ("/ui/menubar/_Configuration/Edit general Preferences" :: Text)+        mbPrefs   <- uiManagerGetWidget uiManager ("/ui/menubar/_Tools/_Preferences" :: Text)         case mbPrefs of             Just prefs -> do                 applicationInsertAppMenuItem app (castToMenuItem prefs) 2
src/IDE/Package.hs view
@@ -77,10 +77,13 @@ import Distribution.Verbosity import System.FilePath import Control.Concurrent-import System.Directory (setCurrentDirectory, doesFileExist, getDirectoryContents)+import System.Directory+       (canonicalizePath, setCurrentDirectory, doesFileExist,+        getDirectoryContents, doesDirectoryExist) import Prelude hiding (catch) import Data.Maybe-       (listToMaybe, fromMaybe, isNothing, isJust, fromJust, catMaybes)+       (mapMaybe, listToMaybe, fromMaybe, isNothing, isJust, fromJust,+        catMaybes) import Control.Exception (SomeException(..), catch)  import IDE.Core.State@@ -93,7 +96,7 @@ import IDE.Utils.FileUtils(getConfigFilePathForLoad) import IDE.LogRef import Distribution.ModuleName (ModuleName(..))-import Data.List (isInfixOf, nub, foldl', delete)+import Data.List (isInfixOf, nub, foldl', delete, find) import IDE.Utils.Tool (ToolOutput(..), runTool, newGhci, ToolState(..), toolline, ProcessHandle, executeGhciCommand) import qualified Data.Set as  Set (fromList) import qualified Data.Map as  Map (empty, fromList)@@ -115,7 +118,8 @@ import System.Log.Logger (debugM) import System.Process.Vado (getMountPoint, vado, readSettings) import qualified Data.Text as T-       (replace, unwords, takeWhile, pack, unpack, isInfixOf)+       (lines, isPrefixOf, stripPrefix, replace, unwords, takeWhile, pack,+        unpack, isInfixOf) import IDE.Utils.ExternalTool (runExternalTool', runExternalTool, isRunning, interruptBuild) import Text.PrinterParser (writeFields) import Data.Text (Text)@@ -195,36 +199,42 @@ packageConfig'  :: IDEPackage -> (Bool -> IDEAction) -> IDEAction packageConfig' package continuation = do     prefs     <- readIDE prefs-    let dir = ipdBuildDir package-    logLaunch <- getDefaultLogLaunch-    showDefaultLogLaunch'+    let dir = ipdPackageDir package+    useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"+    if useStack+        then ideMessage Normal (__ "Leksah is not running \"cabal configure\" because a stack.yaml file was found.")+        else do+            logLaunch <- getDefaultLogLaunch+            showDefaultLogLaunch' -    runExternalTool'        (__ "Configuring")-                            (cabalCommand prefs)-                            ("configure" : ipdConfigFlags package)-                            dir $ do-        mbLastOutput <- C.getZipSink $ const <$> C.ZipSink sinkLast <*> C.ZipSink (logOutput logLaunch)-        lift $ do-            mbPack <- idePackageFromPath (logOutput logLaunch) (ipdCabalFile package)-            case mbPack of-                Just pack -> do-                    changePackage pack-                    triggerEventIDE $ WorkspaceChanged False True-                    continuation (mbLastOutput == Just (ToolExit ExitSuccess))-                    return ()-                Nothing -> do-                    postAsyncIDE $ ideMessage Normal (__ "Can't read package file")-                    continuation False-                    return()+            runExternalTool'        (__ "Configuring")+                                    (cabalCommand prefs)+                                    ("configure" : ipdConfigFlags package)+                                    dir $ do+                mbLastOutput <- C.getZipSink $ const <$> C.ZipSink sinkLast <*> C.ZipSink (logOutput logLaunch)+                lift $ do+                    mbPack <- idePackageFromPath (logOutput logLaunch) (ipdCabalFile package)+                    case mbPack of+                        Just pack -> do+                            changePackage pack+                            triggerEventIDE $ WorkspaceChanged False True+                            continuation (mbLastOutput == Just (ToolExit ExitSuccess))+                            return ()+                        Nothing -> do+                            postAsyncIDE $ ideMessage Normal (__ "Can't read package file")+                            continuation False+                            return()  runCabalBuild :: Bool -> Bool -> Bool -> IDEPackage -> Bool -> (Bool -> IDEAction) -> IDEAction runCabalBuild backgroundBuild jumpToWarnings withoutLinking package shallConfigure continuation = do     prefs <- readIDE prefs-    let dir =  ipdBuildDir package+    let dir =  ipdPackageDir package+    useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"     let args = ["build"]-                ++ ["--with-ld=false" | backgroundBuild && withoutLinking]+                ++ ["--with-ld=false" | not useStack && backgroundBuild && withoutLinking]+                ++ (if useStack && runUnitTests prefs then ["--test", "--haddock"] else [])                 ++ ipdBuildFlags package-    runExternalTool' (__ "Building") (cabalCommand prefs) args dir $ do+    runExternalTool' (__ "Building") (if useStack then "stack" else cabalCommand prefs) args dir $ do         (mbLastOutput, isConfigErr, _) <- C.getZipSink $ (,,)             <$> C.ZipSink sinkLast             <*> C.ZipSink isConfigError@@ -281,7 +291,7 @@             -- TODO check debug package matches active package             ready <- liftIO $ isEmptyMVar (currentToolCommand ghci)             when ready $ do-                let dir = ipdBuildDir package+                let dir = ipdPackageDir package                 when (saveAllBeforeBuild prefs) (do fileSaveAll belongsToWorkspace'; return ())                 (`runDebug` debug) . executeDebugCommand ":reload" $ do                     errs <- logOutputForBuild package backgroundBuild jumpToWarnings@@ -301,12 +311,16 @@ packageDoc' backgroundBuild jumpToWarnings package continuation = do     prefs     <- readIDE prefs     catchIDE (do-        let dir = ipdBuildDir package-        runExternalTool' (__ "Documenting") (cabalCommand prefs) ("haddock" : ipdHaddockFlags package) dir $ do-                mbLastOutput <- C.getZipSink $ const <$> C.ZipSink sinkLast <*> (C.ZipSink $-                    logOutputForBuild package backgroundBuild jumpToWarnings)-                lift $ postAsyncIDE reloadDoc-                lift $ continuation (mbLastOutput == Just (ToolExit ExitSuccess)))+        let dir = ipdPackageDir package+        useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"+        if useStack+            then continuation True+            else+                runExternalTool' (__ "Documenting") (cabalCommand prefs) ("haddock" : ipdHaddockFlags package) dir $ do+                    mbLastOutput <- C.getZipSink $ const <$> C.ZipSink sinkLast <*> (C.ZipSink $+                        logOutputForBuild package backgroundBuild jumpToWarnings)+                    lift $ postAsyncIDE reloadDoc+                    lift $ continuation (mbLastOutput == Just (ToolExit ExitSuccess)))         (\(e :: SomeException) -> print e)  packageClean :: PackageAction@@ -320,9 +334,10 @@     logLaunch <- getDefaultLogLaunch     showDefaultLogLaunch' -    let dir = ipdBuildDir package+    let dir = ipdPackageDir package+    useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"     runExternalTool' (__ "Cleaning")-                    (cabalCommand prefs)+                    (if useStack then "stack" else cabalCommand prefs)                     ["clean"]                     dir $ do         mbLastOutput <- C.getZipSink $ const <$> C.ZipSink sinkLast <*> C.ZipSink (logOutput logLaunch)@@ -342,10 +357,10 @@             case mbDir of                 Nothing -> return ()                 Just fp -> do-                    let dir = ipdBuildDir package+                    let dir = ipdPackageDir package                     runExternalTool' (__ "Copying")                                     (cabalCommand prefs)-                                    ("copy" : ["--destdir=" <> T.pack fp])+                                    ["copy", "--destdir=" <> T.pack fp]                                     dir                                     (logOutput logLaunch))             (\(e :: SomeException) -> print e)@@ -359,7 +374,7 @@          catchIDE (do             prefs <- readIDE prefs-            let dir = ipdBuildDir package+            let dir = ipdPackageDir package             runExternalTool' (__ "Installing") (cabalCommand prefs) (                    (if useCabalDev prefs                         then ["install-deps"]@@ -375,8 +390,12 @@     showDefaultLogLaunch'      catchIDE (do-        let dir = ipdBuildDir package-        runExternalTool' (__ "Copying") (cabalCommand prefs) ("copy" : ipdInstallFlags package) dir $ do+        let dir = ipdPackageDir package+        useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"+        runExternalTool' (__ "Copying")+                         (if useStack then "stack" else cabalCommand prefs)+                         ((if useStack then ("install" : ipdBuildFlags package) else ["copy"]) ++ ipdInstallFlags package)+                         dir $ do                 mbLastOutput <- C.getZipSink $ (const <$> C.ZipSink sinkLast) <*> C.ZipSink (logOutput logLaunch)                 lift $ continuation (mbLastOutput == Just (ToolExit ExitSuccess)))         (\(e :: SomeException) -> print e)@@ -419,11 +438,12 @@             showLog             case maybeDebug of                 Nothing -> do-                    let dir = ipdBuildDir package+                    let dir = ipdPackageDir package+                    useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"                     IDE.Package.runPackage (addLogLaunchData logName logLaunch)                                            (T.pack $ printf (__ "Running %s") (T.unpack logName))-                                           "cabal"-                                           (concat [["run"]+                                           (if useStack then "stack" else "cabal")+                                           (concat [[if useStack then "exec" else "run"]                                                 , ipdBuildFlags package                                                 , map (T.pack . exeName) exe                                                 , ["--"]@@ -479,12 +499,12 @@                 let defaultLogName = T.pack . display . pkgName $ ipdPackageId package                     logName = fromMaybe defaultLogName . listToMaybe $ map (T.pack . exeName) exe                 (logLaunch,logName) <- buildLogLaunchByName logName-                let dir = ipdBuildDir package+                let dir = ipdPackageDir package                 prefs <- readIDE prefs                 case exe ++ executables pd of                     (Executable name _ _ : _) -> liftIDE $ do                         let path = "dist/build" </> name </> name <.> "jsexe" </> "index.html"-                            dir = ipdBuildDir package+                            dir = ipdPackageDir package #ifdef WEBKITGTK                         postAsyncIDE $ do                             loadOutputUri ("file:///" ++ dir </> path)@@ -513,10 +533,13 @@           showDefaultLogLaunch'           catchIDE (do             prefs <- readIDE prefs-            let dir = ipdBuildDir package-            runExternalTool' (__ "Registering") (cabalCommand prefs) ("register" : ipdRegisterFlags package) dir $ do-                    mbLastOutput <- C.getZipSink $ (const <$> C.ZipSink sinkLast) <*> C.ZipSink (logOutput logLaunch)-                    lift $ continuation (mbLastOutput == Just (ToolExit ExitSuccess)))+            let dir = ipdPackageDir package+            useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"+            if useStack+                then continuation True+                else runExternalTool' (__ "Registering") (cabalCommand prefs) ("register" : ipdRegisterFlags package) dir $ do+                        mbLastOutput <- C.getZipSink $ (const <$> C.ZipSink sinkLast) <*> C.ZipSink (logOutput logLaunch)+                        lift $ continuation (mbLastOutput == Just (ToolExit ExitSuccess)))             (\(e :: SomeException) -> print e)         else continuation True @@ -526,14 +549,15 @@     interruptSaveAndRun $ packageTest' False True package True (\ _ -> return ())  packageTest' :: Bool -> Bool -> IDEPackage -> Bool -> (Bool -> IDEAction) -> IDEAction-packageTest' backgroundBuild jumpToWarnings package shallConfigure continuation =-    if "--enable-tests" `elem` ipdConfigFlags package+packageTest' backgroundBuild jumpToWarnings package shallConfigure continuation = do+    let dir = ipdPackageDir package+    useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"+    if not useStack && "--enable-tests" `elem` ipdConfigFlags package         then do           logLaunch <- getDefaultLogLaunch           showDefaultLogLaunch'           catchIDE (do             prefs <- readIDE prefs-            let dir = ipdBuildDir package             removeTestLogRefs dir             runExternalTool' (__ "Testing") (cabalCommand prefs) (["test", "--with-ghc=leksahtrue"]                 ++ ipdBuildFlags package ++ ipdTestFlags package) dir $ do@@ -562,7 +586,7 @@          catchIDE (do             prefs <- readIDE prefs-            let dir = ipdBuildDir package+            let dir = ipdPackageDir package             runExternalTool' (__ "Source Dist") (cabalCommand prefs) ("sdist" : ipdSdistFlags package) dir (logOutput logLaunch))             (\(e :: SomeException) -> print e) @@ -573,11 +597,11 @@      liftIDE $ do         prefs   <- readIDE prefs-        let path = ipdBuildDir package+        let path = ipdPackageDir package                         </> "dist/doc/html"                         </> display (pkgName (ipdPackageId package))                         </> "index.html"-            dir = ipdBuildDir package+            dir = ipdPackageDir package #ifdef WEBKITGTK         loadDoc . T.pack $ "file:///" ++ dir </> path         getDocumentation Nothing  >>= \ p -> displayPane p False@@ -786,7 +810,7 @@         maybeDebug <- readIDE debugState         case maybeDebug of             Nothing -> do-                let dir = ipdBuildDir package+                let dir = ipdPackageDir package                 mbExe <- readIDE activeExe                 ghci <- reifyIDE $ \ideR -> newGhci dir mbExe (interactiveFlags prefs')                     $ reflectIDEI (void (logOutputForBuild package True False)) ideR@@ -929,6 +953,19 @@                     else return packp             return (Just pack) +extractStackPackageList :: Text -> [String]+extractStackPackageList = filter (/= ".") .+                          map (stripQuotes . T.unpack . (\x -> fromMaybe x $ T.stripPrefix "location: " x)) .+                          mapMaybe (T.stripPrefix "- ") .+                          takeWhile ("- " `T.isPrefixOf`) .+                          drop 1 .+                          dropWhile (/= "packages:") .+                          T.lines+  where+    stripQuotes ('\'':rest) | take 1 (reverse rest) == "\'" = init rest+    stripQuotes x = x++ idePackageFromPath :: C.Sink ToolOutput IDEM () -> FilePath -> IDEM (Maybe IDEPackage) idePackageFromPath log filePath = do     mbRootPackage <- idePackageFromPath' filePath@@ -936,16 +973,33 @@         Nothing -> return Nothing         Just rootPackage -> do             mvar <- liftIO newEmptyMVar-            runExternalTool' "" "cabal" ["sandbox", "list-sources"] (takeDirectory filePath) $ do-                output <- CL.consume-                liftIO . putMVar mvar $ case take 1 $ reverse output of-                    [ToolExit ExitSuccess] ->-                        map (T.unpack . toolline) . takeWhile (/= ToolOutput "") . drop 1 $ dropWhile (/= ToolOutput "") output-                    _ -> []-            paths <- liftIO $ takeMVar mvar-            sandboxSources <- concat <$> forM paths (\ path -> do-                contents <- liftIO $ getDirectoryContents path-                return . take 1 . map (path </>) $ filter ((== ".cabal") . takeExtension) contents)+            let dir = takeDirectory filePath+            useStack <- liftIO . doesFileExist $ dir </> "stack.yaml"+            paths <-+                if useStack+                    then liftIO $ map (dir </>) . extractStackPackageList <$> T.readFile (dir </> "stack.yaml")+                    else do+                        runExternalTool' "" "cabal" ["sandbox", "list-sources"] dir $ do+                            output <- CL.consume+                            liftIO . putMVar mvar $ case take 1 $ reverse output of+                                [ToolExit ExitSuccess] ->+                                    map (T.unpack . toolline) . takeWhile (/= ToolOutput "") . drop 1 $ dropWhile (/= ToolOutput "") output+                                _ -> []+                        liftIO $ takeMVar mvar++            sandboxSources <- catMaybes <$> forM paths (\path -> do+                exists <- liftIO (doesDirectoryExist path)+                if exists+                    then do+                        cpath <- liftIO $ canonicalizePath path+                        contents <- liftIO $ getDirectoryContents cpath+                        let mbCabalFile = find ((== ".cabal") . takeExtension) contents+                        when (isNothing mbCabalFile) $+                            ideMessage Normal ("Could not find cabal file of the add-source dependency at " <> T.pack cpath)+                        return (fmap (path </>) mbCabalFile)+                    else do+                        ideMessage Normal ("Path of add-source dependency does not exist: " <> T.pack path)+                        return Nothing)             s <- liftM catMaybes . mapM idePackageFromPath' $ nub sandboxSources             return . Just $ rootPackage {ipdSandboxSources = s} 
src/IDE/Pane/Errors.hs view
@@ -17,118 +17,227 @@ -----------------------------------------------------------------------------  module IDE.Pane.Errors (-    IDEErrors+    ErrorsPane ,   ErrorsState ,   fillErrorList-,   addErrorToList-,   selectError ,   getErrors+,   addErrorToList ,   selectMatchingErrors ) where +import Prelude ()+import Prelude.Compat import Graphics.UI.Gtk import Data.Typeable (Typeable) import IDE.Core.State import IDE.ImportTool-       (addResolveMenuItems, resolveErrors)-import Data.List (elemIndex)+       (resolveErrors, resolveMenuItems)+import Data.List (groupBy, sortBy, elemIndex) import IDE.LogRef (showSourceSpan) import Control.Monad.IO.Class (MonadIO(..))-import IDE.Utils.GUIUtils (getDarkState, treeViewContextMenu, __)-import Data.Text (Text)-import Control.Monad (foldM_, unless, void, when, forM_)+import IDE.Utils.GUIUtils+       (treeViewContextMenu', treeViewContextMenu, __, treeViewToggleRow,+        treeStoreGetForest)+import Data.Text (dropWhileEnd, Text)+import Control.Applicative (Alternative(..))+import Control.Monad (filterM, foldM_, unless, void, when) import qualified Data.Text as T-       (intercalate, lines, takeWhile, length, drop)+       (unlines, dropWhileEnd, unpack, pack, intercalate, lines,+        takeWhile, length, drop) import Data.IORef (writeIORef, readIORef, newIORef, IORef)-import Data.Maybe (isNothing)+import Data.Maybe (isJust, isNothing) import qualified Data.Foldable as F (toList) import qualified Data.Sequence as Seq (null, elemIndexL)+import Data.Monoid ((<>))+import Data.Ord (comparing)+import System.Glib.Properties (newAttrFromMaybeStringProperty)+import Data.Char (isSpace)+import Data.Tree (Forest, Tree(..), Tree)+import Data.Function.Compat ((&))+import System.Log.Logger (debugM)+import Data.Foldable (forM_)   -- | The representation of the Errors pane-data IDEErrors      =   IDEErrors {-    scrolledView    ::   ScrolledWindow-,   treeView        ::   TreeView-,   errorStore      ::   ListStore ErrColumn-,   autoClose       ::   IORef Bool -- ^ If the pane was only displayed to show current error+data ErrorsPane      =   ErrorsPane {+    vbox              :: VBox+,   scrolledView      :: ScrolledWindow+,   treeView          :: TreeView+,   errorStore        :: TreeStore ErrorRecord+,   autoClose         :: IORef Bool -- ^ If the pane was only displayed to show current error+,   errorsButton      :: ToggleButton+,   warningsButton    :: ToggleButton+,   suggestionsButton :: ToggleButton+,   testFailsButton   :: ToggleButton } deriving Typeable   -- | The data for a single row in the Errors pane-data ErrColumn = ErrColumn {-    logRef     :: LogRef,-    background :: Text}-+data ErrorRecord = ERLogRef LogRef+                 | ERPackage IDEPackage Text+                 | ERIDE Text+                 | ERFullMessage Text (Maybe LogRef)+    deriving (Eq)  -- | The additional state used when recovering the pane-data ErrorsState    =   ErrorsState+data ErrorsState = ErrorsState+    {+      showErrors :: Bool+    , showWarnings :: Bool+    , showSuggestions :: Bool+    , showTestFails :: Bool+    }    deriving (Eq,Ord,Read,Show,Typeable)  -instance Pane IDEErrors IDEM+instance Pane ErrorsPane IDEM     where     primPaneName _  =   __ "Errors"-    getTopWidget    =   castToWidget . scrolledView+    getTopWidget    =   castToWidget . vbox     paneId _b       =   "*Errors"  -instance RecoverablePane IDEErrors ErrorsState IDEM where-    saveState _p     =   return (Just ErrorsState)-    recoverState pp ErrorsState = do nb <- getNotebook pp-                                     buildPane pp nb builder+instance RecoverablePane ErrorsPane ErrorsState IDEM where+    saveState ErrorsPane{..} = liftIO $ do+        showErrors      <- get errorsButton toggleButtonActive+        showWarnings    <- get warningsButton toggleButtonActive+        showSuggestions <- get suggestionsButton toggleButtonActive+        showTestFails   <- get testFailsButton toggleButtonActive+        return (Just ErrorsState{..})++    recoverState pp ErrorsState{..} = do+        nb <- getNotebook pp+        mbErrors <- buildPane pp nb builder+        forM_ mbErrors $ \ErrorsPane{..} -> liftIO $ do+            set errorsButton [toggleButtonActive := showErrors]+            set warningsButton [toggleButtonActive := showWarnings]+            set suggestionsButton [toggleButtonActive := showSuggestions]+            set testFailsButton [toggleButtonActive := showTestFails]+        return mbErrors++     builder = builder' --- | Builds an 'IDEErrors' pane together with a list of+-- | Builds an 'ErrorsPane' pane together with a list of --   event 'Connections' builder' :: PanePath ->     Notebook ->     Window ->-    IDEM (Maybe IDEErrors, Connections)+    IDEM (Maybe ErrorsPane, Connections) builder' _pp _nb _windows = reifyIDE $ \ ideR -> do-    errorStore   <- listStoreNew []+    errorStore   <- treeStoreNew []++    vbox         <- vBoxNew False 0++    -- Top box with buttons+    hbox <- hBoxNew False 0+    boxPackStart vbox hbox PackNatural 0+++    errorsButton <- toggleButtonNewWithLabel (__ "Errors")+    warningsButton <- toggleButtonNewWithLabel (__ "Warnings")+    suggestionsButton <- toggleButtonNewWithLabel (__ "Suggestions")+    testFailsButton <- toggleButtonNewWithLabel (__ "Test Failures")+    set suggestionsButton [toggleButtonActive := False]++    forM_ [errorsButton, warningsButton, suggestionsButton, testFailsButton] $ \b -> do+        set b [toggleButtonActive := True]+        boxPackStart hbox b PackNatural 3+        b `on` toggled $ reflectIDE (fillErrorList False) ideR+++    boxPackStart vbox hbox PackNatural 0+++    -- TreeView for bottom part of vbox+     treeView     <- treeViewNew     treeViewSetModel treeView errorStore+    set treeView+        [ treeViewLevelIndentation := 20+        , treeViewRulesHint := True+        , treeViewHeadersVisible := False] -    rendererA    <- cellRendererTextNew-    colA         <- treeViewColumnNew-    treeViewColumnSetTitle colA (__ "Description")-    treeViewColumnSetSizing colA TreeViewColumnAutosize-    treeViewColumnSetResizable colA True-    treeViewColumnSetReorderable colA True-    treeViewAppendColumn treeView colA-    cellLayoutPackStart colA rendererA False-    cellLayoutSetAttributes colA rendererA errorStore-        $ \row -> [cellText := removeIndentation (refDescription (logRef row)),-                   cellTextBackground := background row ]-    rendererB    <- cellRendererTextNew-    colB         <- treeViewColumnNew-    treeViewColumnSetTitle colB (__ "Location")-    treeViewColumnSetSizing colB TreeViewColumnAutosize-    treeViewColumnSetResizable colB True-    treeViewColumnSetReorderable colB True-    treeViewAppendColumn treeView colB-    cellLayoutPackStart colB rendererB False-    cellLayoutSetAttributes colB rendererB errorStore-        $ \row -> [ cellText := showSourceSpan (logRef row),-                   cellTextBackground := background row ]-    treeViewSetHeadersVisible treeView False+    column       <- treeViewColumnNew+    iconRenderer <- cellRendererPixbufNew++    cellLayoutPackStart column iconRenderer False+    cellLayoutSetAttributes column iconRenderer errorStore+                $ \row -> [ newAttrFromMaybeStringProperty "icon-name" := toIcon row]+++    treeViewColumnSetSizing column TreeViewColumnAutosize++    renderer <- cellRendererTextNew+    cellLayoutPackStart column renderer False++    cellLayoutSetAttributeFunc column renderer errorStore $ \iter -> do+        path <- treeModelGetPath errorStore iter+        row <- treeModelGetRow errorStore iter+        expanded <- treeViewRowExpanded treeView path+        set renderer [cellText := toDescription expanded row]++    treeViewAppendColumn treeView column++     selB <- treeViewGetSelection treeView     treeSelectionSetMode selB SelectionMultiple     scrolledView <- scrolledWindowNew Nothing Nothing     scrolledWindowSetShadowType scrolledView ShadowIn     containerAdd scrolledView treeView     scrolledWindowSetPolicy scrolledView PolicyAutomatic PolicyAutomatic+    boxPackStart vbox scrolledView PackGrow 0+     autoClose <- newIORef False-    let pane = IDEErrors {..}++    let pane = ErrorsPane {..}     cid1 <- after treeView focusInEvent $ do         liftIO $ reflectIDE (makeActive pane) ideR         return True-    (cid2, cid3) <- treeViewContextMenu treeView $ errorsContextMenu ideR errorStore treeView-    cid4 <- treeView `on` rowActivated $ errorsSelect ideR errorStore+    (cid2, cid3) <- flip reflectIDE ideR $+        treeViewContextMenu' treeView errorStore contextMenuItems+    cid4 <- treeView `on` rowActivated $ \path col -> do+        record <- treeStoreGetValue errorStore path+        case record of+            ERLogRef logRef -> errorsSelect ideR errorStore path col+            ERFullMessage _ ref -> errorsSelect ideR errorStore path col+            _        -> return ()+     reflectIDE (fillErrorList' pane) ideR     return (Just pane, map ConnectC [cid1, cid2, cid3, cid4])  +toIcon :: ErrorRecord -> Maybe Text+toIcon (ERLogRef logRef) =+    case logRefType logRef of+        ErrorRef       -> Just "ide_error"+        WarningRef     -> Just "ide_warning"+        LintRef        -> Just "ide_suggestion"+        TestFailureRef -> Just "software-update-urgent"+        _              -> Nothing+toIcon (ERPackage _ _) = Just "dialog-error"+toIcon (ERIDE _) = Just "dialog-error"+toIcon (ERFullMessage _ _) = Nothing+++toDescription :: Bool -> ErrorRecord -> Text+toDescription expanded errorRec =+    case errorRec of+        (ERLogRef logRef)   -> formatExpandableMessage (T.pack $ logRefFilePath logRef) (refDescription logRef)+        (ERIDE msg)         -> formatExpandableMessage "" msg+        (ERPackage pkg msg) -> formatExpandableMessage (packageIdentifierToString (ipdPackageId pkg))+                                   (packageIdentifierToString (ipdPackageId pkg) <> ": \n" <> msg)+        (ERFullMessage msg _) -> removeIndentation msg++    where+        formatExpandableMessage location msg+            | expanded  = location+            | otherwise = location <> ": " <> msg & removeIndentation+                                                  & T.lines+                                                  & map removeTrailingWhiteSpace+                                                  & T.intercalate " "++ -- | Removes the unnecessary indentation removeIndentation :: Text -> Text removeIndentation t = T.intercalate "\n" $ map (T.drop minIndent) l@@ -136,9 +245,15 @@     l = T.lines t     minIndent = minimum $ map (T.length . T.takeWhile (== ' ')) l +removeTrailingWhiteSpace :: Text -> Text+removeTrailingWhiteSpace = T.dropWhileEnd isSpace +cutOffAt :: Int -> Text -> Text+cutOffAt n t | T.length t < n = t+             | otherwise      = T.pack (take n (T.unpack t)) <> "..."+ -- | Get the Errors pane-getErrors :: Maybe PanePath -> IDEM IDEErrors+getErrors :: Maybe PanePath -> IDEM ErrorsPane getErrors Nothing    = forceGetPane (Right "*Errors") getErrors (Just pp)  = forceGetPane (Left pp) @@ -151,152 +266,195 @@   -- | Fills the pane with the error list from the IDE state-fillErrorList' :: IDEErrors -> IDEAction+fillErrorList' :: ErrorsPane -> IDEAction fillErrorList' pane = do-    refs <- readIDE errorRefs+    liftIO $ debugM "leksah" "fillErrorList'"+    refs <- F.toList <$> readIDE errorRefs+    visibleRefs <- liftIO $ filterM (isRefVisible pane) refs+     ac   <- liftIO $ readIORef (autoClose pane)-    when (Seq.null refs && ac) . void $ closePane pane-    isDark <- getDarkState+    when (null refs && ac) . void $ closePane pane++    updateFilterButtons pane     liftIO $ do         let store = errorStore pane-        listStoreClear store-        forM_ (zip (F.toList refs) [0..]) $ \ (lr, index) ->-            listStoreInsert store index $ ErrColumn lr (-                (if even index then fst else snd) $-                (if isDark then fst else snd) $-                    case logRefType lr of-                        WarningRef -> (("#282000", "#201900"), ("#FFF1DE", "#FFF5E8"))-                        LintRef    -> (("#003000", "#002800"), ("#DBFFDB", "#EDFFED"))-                        _          -> (("#380000", "#280000"), ("#FFDEDE", "#FFEBEB")))+        let view  = treeView pane+        treeStoreClear store+        forM_ (zip visibleRefs [0..]) $ \(ref, n) -> do+            treeStoreInsert store [] n (ERLogRef ref)+            when (length (T.lines (refDescription ref)) > 1) $ do+                treeStoreInsert store [n] 0 (ERFullMessage (refDescription ref) (Just ref))+                treeViewExpandToPath view [n,0] +-- | Returns whether the `LogRef` should be visible in the errors pane+isRefVisible :: ErrorsPane -> LogRef -> IO Bool+isRefVisible pane ref =+    case logRefType ref of+        ErrorRef       -> toggleButtonGetActive (errorsButton pane)+        WarningRef     -> toggleButtonGetActive (warningsButton pane)+        LintRef        -> toggleButtonGetActive (suggestionsButton pane)+        TestFailureRef -> toggleButtonGetActive (testFailsButton pane)+        _              -> return False  -- | Add any LogRef to the Errors pane at a given index addErrorToList :: Bool -- ^ Whether to display the pane                -> Int  -- ^ The index to insert at-               -> LogRef +               -> LogRef                -> IDEAction addErrorToList False index lr = getPane >>= maybe (return ()) (addErrorToList' index lr) addErrorToList True  index lr = getErrors Nothing  >>= \ p -> addErrorToList' index lr p >> displayPane p False   -- | Add a 'LogRef' at a specific index to the Errors pane-addErrorToList' :: Int -> LogRef -> IDEErrors -> IDEAction-addErrorToList' index lr pane = do---    refs <- readIDE errorRefs-    ac   <- liftIO $ readIORef (autoClose pane)---    when (null refs && ac) . void $ closePane pane-    isDark <- getDarkState+addErrorToList' :: Int -> LogRef -> ErrorsPane -> IDEAction+addErrorToList' unfilteredIndex ref pane = do+    liftIO $ debugM "leksah" "addErrorToList'"+    visible <- liftIO $ isRefVisible pane ref+    updateFilterButtons pane+    when visible $ do+        refs <- F.toList <$> readIDE errorRefs+        index <- liftIO $ length <$> filterM (isRefVisible pane) (take unfilteredIndex refs)+        ac   <- liftIO $ readIORef (autoClose pane)+        liftIO $ do+            let store = errorStore pane+            let view  = treeView pane+            treeStoreInsert store [] index (ERLogRef ref)+            when (length (T.lines (refDescription ref)) > 1) $ do+                treeStoreInsert store [index] 0 (ERFullMessage (refDescription ref) (Just ref))+                treeViewExpandToPath view [index,0]++-- | Updates the filter buttons in the Error Pane+updateFilterButtons :: ErrorsPane -> IDEAction+updateFilterButtons pane = do+    liftIO $ debugM "leksah" "updateFilterButtons"+    let numRefs refType = length . filter ((== refType) . logRefType) . F.toList <$> readIDE errorRefs+    let setLabel name amount button = buttonSetLabel button (name <> " (" <> T.pack (show amount) <> ")" )++    numErrors      <- numRefs ErrorRef+    numWarnings    <- numRefs WarningRef+    numSuggestions <- numRefs LintRef+    numTestFails   <- numRefs TestFailureRef+     liftIO $ do-        let store = errorStore pane---        listStoreClear store---        forM_ (zip (toList refs) [0..]) $ \ (lr, index) ->-        listStoreInsert store index $ ErrColumn lr (-                (if even index then fst else snd) $-                (if isDark then fst else snd) $-                    case logRefType lr of-                        WarningRef -> (("#282000", "#201900"), ("#FFF1DE", "#FFF5E8"))-                        LintRef    -> (("#003000", "#002800"), ("#DBFFDB", "#EDFFED"))-                        _          -> (("#380000", "#280000"), ("#FFDEDE", "#FFEBEB")))+        setLabel "Errors"        numErrors      (errorsButton      pane)+        setLabel "Warnings"      numWarnings    (warningsButton    pane)+        setLabel "Suggestions"   numSuggestions (suggestionsButton pane)+        setLabel "Test Failures" numTestFails   (testFailsButton   pane)+        widgetShowAll (vbox pane)   -- | Get the currently selected error getSelectedError ::  TreeView-    -> ListStore ErrColumn+    -> TreeStore ErrorRecord     -> IO (Maybe LogRef) getSelectedError treeView store = do+    liftIO $ debugM "leksah" "getSelectedError"     treeSelection   <-  treeViewGetSelection treeView     paths           <-  treeSelectionGetSelectedRows treeSelection     case paths of-        [a]:r ->  do-            val     <-  listStoreGetValue store a-            return (Just (logRef val))+        path:_ ->  do+            val     <-  treeStoreGetValue store path+            case val of+                ERLogRef logRef -> return (Just logRef)+                _ -> return Nothing         _  ->  return Nothing --- | Select an error in the Errors pane-selectError :: Maybe LogRef -- ^ When @Nothing@, the first error in the list is selected+-- | Select a 'LogRef' in the Errors pane if it is visible+selectError :: Maybe LogRef -- ^ When @Nothing@, the first row in the list is selected             -> IDEAction selectError mbLogRef = do-    (mbPane :: Maybe IDEErrors) <- getPane-    errorRefs' <- readIDE errorRefs+    liftIO $ debugM "leksah" "selectError"+    (mbPane :: Maybe ErrorsPane) <- getPane     errors     <- getErrors Nothing     when (isNothing mbPane) $ do         liftIO $ writeIORef (autoClose errors) True         displayPane errors False-    liftIO $ do+    reifyIDE $ \ideR -> do         selection <- treeViewGetSelection (treeView errors)         case mbLogRef of             Nothing -> do-                size <- listStoreGetSize (errorStore errors)-                unless (size == 0) $+                empty <- null <$> treeStoreGetTree (errorStore errors) []+                unless empty $                     treeViewScrollToCell (treeView errors) (Just [0]) Nothing Nothing                 treeSelectionUnselectAll selection-            Just lr -> case lr `Seq.elemIndexL` errorRefs' of-                        Nothing  -> return ()-                        Just ind -> do-                            treeViewScrollToCell (treeView errors) (Just [ind]) Nothing Nothing-                            treeSelectionSelectPath selection [ind]+            Just lr -> do+                let store = errorStore errors+                empty <- isNothing <$> treeModelGetIterFirst store+                unless empty $ do+                    forest <- treeStoreGetForest store+                    let mbPath = forestFind forest (ERLogRef lr)+                    forM_ mbPath $ \path -> do+                        treeViewScrollToCell (treeView errors) (Just path) Nothing Nothing+                        treeSelectionSelectPath selection path +    where+        forestFind :: Eq a => Forest a -> a -> Maybe TreePath+        forestFind = forestFind' [0]+            where+                forestFind' path [] _ = Nothing+                forestFind' path (Node x trees : forest) y+                    | x == y    = Just path+                    | otherwise = forestFind' (path ++ [0]) trees y+                                      <|> forestFind' (sibling path) forest y --- | Constructs the context menu for the Errors pane-errorsContextMenu :: IDERef-                  -> ListStore ErrColumn-                  -> TreeView-                  -> Menu-                  -> IO ()-errorsContextMenu ideR store treeView theMenu = do-    mbSel           <-  getSelectedError treeView store-    item0           <-  menuItemNewWithLabel (__ "Resolve Errors")-    item0 `on` menuItemActivate $ reflectIDE resolveErrors ideR-    menuShellAppend theMenu item0-    case mbSel of-        Just sel -> addResolveMenuItems ideR theMenu sel-        Nothing -> return ()+                sibling [n] = [n+1]+                sibling (x:xs) = x:sibling xs+                sibling [] = error "Error in selectError sibling function" +contextMenuItems :: ErrorRecord -> TreePath -> TreeStore ErrorRecord -> IDEM [[(Text, IDEAction)]]+contextMenuItems record path store = return+    [("Resolve Errors", resolveErrors) :+        case record of+               ERLogRef logRef -> resolveMenuItems logRef ++ [clipboardItem (refDescription logRef)]+               ERIDE msg       -> [clipboardItem msg]+               ERPackage _ msg -> [clipboardItem msg]+               _               -> []+    ] ++    where clipboardItem str = ("Copy message to clipboard", liftIO $ clipboardGet selectionClipboard >>= flip clipboardSetText str)++ -- | Highlight an error refered to by the 'TreePath' in the given 'TreeViewColumn' errorsSelect :: IDERef-                -> ListStore ErrColumn+                -> TreeStore ErrorRecord                 -> TreePath                 -> TreeViewColumn                 -> IO ()-errorsSelect ideR store [index] _ = do-    ref <- listStoreGetValue store index-    reflectIDE (setCurrentError (Just (logRef ref))) ideR-errorsSelect _ _ _ _ = return ()+errorsSelect ideR store path _ = do+    liftIO $ debugM "leksah" "errorsSelect"+    record <- treeStoreGetValue store path+    case record of+        ERLogRef logRef -> reflectIDE (setCurrentError (Just logRef)) ideR+        ERFullMessage _ (Just ref) -> reflectIDE (setCurrentError (Just ref)) ideR+        _ -> return ()  --- | Select the matching errors for a 'SrcSpan' in the Errors +-- | Select the matching errors for a 'SrcSpan' in the Errors --   pane, or none at all-selectMatchingErrors :: Maybe SrcSpan -- ^ When @Nothing@, unselects any errors in the pane -                     -> IDEM ()+selectMatchingErrors :: Maybe SrcSpan -- ^ When @Nothing@, unselects any errors in the pane+                     -> IDEAction selectMatchingErrors mbSpan = do+    liftIO $ debugM "leksah" "selectMatchingErrors"     mbErrors <- getPane-    case mbErrors of-        Nothing -> return ()-        Just pane  ->-            liftIO $ do-                treeSel <- treeViewGetSelection (treeView pane)-                case mbSpan of-                    Nothing -> treeSelectionUnselectAll treeSel-                    Just (SrcSpan file lStart cStart lEnd cEnd) -> do-                        size <- listStoreGetSize (errorStore pane)-                        foldM_ (\ haveScrolled n -> do-                            mbIter <- treeModelGetIter (errorStore pane) [n]-                            case mbIter of-                                Nothing -> return False-                                Just iter -> do-                                    ErrColumn {logRef = ref@LogRef{..}} <- listStoreGetValue (errorStore pane) n-                                    isSelected <- treeSelectionIterIsSelected treeSel iter-                                    let shouldBeSel = file == logRefFullFilePath ref-                                                     && (lStart, cStart) <= (srcSpanEndLine     logRefSrcSpan,-                                                                               srcSpanEndColumn   logRefSrcSpan)-                                                     && (lEnd, cEnd)     >= (srcSpanStartLine   logRefSrcSpan,-                                                                               srcSpanStartColumn logRefSrcSpan)-                                    when (isSelected && not shouldBeSel) $ treeSelectionUnselectIter treeSel iter-                                    when (not isSelected && shouldBeSel) $ do-                                        unless haveScrolled $ treeViewScrollToCell (treeView pane) (Just [n]) Nothing Nothing-                                        treeSelectionSelectIter treeSel iter-                                    return $ haveScrolled || shouldBeSel)-                            False (take size [0..])+    forM_ mbErrors $ \pane -> do+        treeSel <- liftIO $ treeViewGetSelection (treeView pane)+        liftIO $ treeSelectionUnselectAll treeSel+        forM_ mbSpan $ \span -> do+            spans <- map logRefSrcSpan . F.toList <$> readIDE errorRefs+            matches <- matchingRefs span . F.toList <$> readIDE errorRefs+            forM_ matches $ \ref ->+                selectError (Just ref) +matchingRefs :: SrcSpan -> [LogRef] -> [LogRef]+matchingRefs span refs =+    -- the path of the SrcSpan in the LogRef absolute, so comparison with the given SrcSpan goes right+    let toAbsolute ref =  ref {logRefSrcSpan = (logRefSrcSpan ref) {srcSpanFilename = logRefFullFilePath ref}}+    in filter (\ref -> filesMatch (logRefSrcSpan (toAbsolute ref)) span && span `insideOf` logRefSrcSpan (toAbsolute ref)) refs+    where+        filesMatch span span' = srcSpanFilename span == srcSpanFilename span' +        -- Test whether the first span is inside of the second+        insideOf (SrcSpan _ lStart cStart lEnd cEnd) (SrcSpan _ lStart' cStart' lEnd' cEnd')+            =  (lStart, cStart) <= (lEnd', cEnd')+            && (lEnd, cEnd)     >= (lStart', cStart')
src/IDE/Pane/Files.hs view
@@ -6,7 +6,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-} --------------------------------------------------------------------------------+--f -- Module      :  IDE.Pane.Files -- Copyright   :  (c) Juergen Nicklisch-Franken, Hamish Mackenzie -- License     :  GNU-GPL@@ -22,101 +22,81 @@ module IDE.Pane.Files (     IDEFiles(..) ,   FilesState(..)-,   getFiles-,   refreshFiles ) where  import Prelude hiding (catch) import Graphics.UI.Gtk-       (scrolledWindowSetShadowType, treeSelectionSelectionChanged,-        treeStoreRemove, treeModelIterNext, treeModelGetRow,-        treeStoreInsert, treeModelIterNthChild, treeModelGetPath, TreeIter,-        treeModelGetIter, TreePath, treeSelectionGetSelectedRows,-        rowActivated, treeStoreGetValue, rowExpanded, on, after,-        focusInEvent, scrolledWindowSetPolicy, containerAdd,-        scrolledWindowNew, treeSelectionSetMode, treeViewGetSelection,-        treeViewSetHeadersVisible, cellText, cellLayoutSetAttributes,-        cellLayoutPackStart, treeViewAppendColumn,-        treeViewColumnSetReorderable, treeViewColumnSetResizable,-        treeViewColumnSetSizing, treeViewColumnSetTitle, treeViewColumnNew,-        cellRendererPixbufNew, cellRendererTextNew, treeViewSetModel,-        treeViewNew, treeStoreNew, castToWidget, TreeStore, TreeView,-        ScrolledWindow, treeViewRowExpanded, treeStoreGetTree)-import Data.Maybe (isJust)+import Data.Maybe (fromMaybe, maybeToList, listToMaybe, isJust) import Control.Monad (forM, void, forM_, when) import Data.Typeable (Typeable) import IDE.Core.State-       (MessageLevel(..), ipdBuildDir, ipdPackageId, wsPackages,-        workspace, readIDE, IDEAction, ideMessage, reflectIDE, reifyIDE,-        IDEM, IDEPackage, ipdSandboxSources)-import IDE.Pane.SourceBuffer-    (goToSourceDefinition')+       (catchIDE, window, getIDE, MessageLevel(..), ipdPackageId,+        wsPackages, workspace, readIDE, IDEAction, ideMessage, reflectIDE,+        reifyIDE, IDEM, IDEPackage, ipdSandboxSources)+import IDE.Pane.SourceBuffer (fileNew, goToSourceDefinition')+import IDE.Sandbox import Control.Applicative ((<$>)) import System.FilePath ((</>), takeFileName, dropFileName) import Distribution.Package (PackageIdentifier(..))-import System.Directory (doesDirectoryExist, getDirectoryContents, getPermissions, readable)+import System.Directory+       (removeDirectoryRecursive, removeDirectory, createDirectory,+        doesFileExist, removeFile, doesDirectoryExist,+        getDirectoryContents, getPermissions, readable) import IDE.Core.CTypes        (Location(..), packageIdentifierToString) import Graphics.UI.Frame.Panes        (RecoverablePane(..), PanePath, RecoverablePane, Pane(..))-import Graphics.UI.Frame.ViewFrame (getNotebook)+import Graphics.UI.Frame.ViewFrame (getMainWindow, getNotebook) import Graphics.UI.Editor.Basics (Connection(..)) import Graphics.UI.Gtk.General.Enums        (ShadowType(..), PolicyType(..), SelectionMode(..),         TreeViewColumnSizing(..))-import System.Glib.Attributes (AttrOp(..))+import System.Glib.Attributes (set, AttrOp(..)) import Control.Monad.IO.Class (MonadIO(..))-import IDE.Utils.GUIUtils (__)-import Control.Exception (catch)+import IDE.Utils.GUIUtils+       (showErrorDialog, showInputDialog, treeViewContextMenu', __,+        showDialogOptions)+import Control.Exception (SomeException(..), catch) import Data.Text (Text)-import qualified Data.Text as T (pack)+import qualified Data.Text as T+       (isPrefixOf, words, isSuffixOf, unpack, pack) import Data.Monoid ((<>))-import Data.List (sortBy, sort)+import IDE.Core.Types+       (ipdLib, WorkspaceAction, Workspace(..), wsAllPackages, WorkspaceM,+        runPackage, runWorkspace, PackageAction, PackageM, IDEPackage(..),+        IDE(..), Prefs(..), MonadIDE(..), ipdPackageDir)+import System.Glib.Properties (newAttrFromMaybeStringProperty)+import System.FilePath+       (addTrailingPathSeparator, takeDirectory, takeExtension,+       makeRelative, splitDirectories)+import Control.Monad.Reader.Class (MonadReader(..))+import IDE.Workspaces+       (makePackage, workspaceAddPackage', workspaceRemovePackage,+        workspaceActivatePackage, workspaceTry, workspaceTryQuiet,+        packageTry)+import Data.List+       (isSuffixOf, find, stripPrefix, isPrefixOf, sortBy, sort) import Data.Ord (comparing)-import Data.Char (toLower)-import IDE.Core.Types (IDEPackage(..), IDE(..), Prefs(..))-import Data.Tree (Tree(..))+import Data.Char (toUpper, toLower) import System.Log.Logger (debugM)------ * A record in the Files Pane---- | The data for a single cell in the file tree-data FileRecord =-    FileRecord FilePath-  | DirRecord FilePath-  | PackageRecord IDEPackage-  | PlaceHolder -- ^ Used as child node of directories that are not yet expanded,-                --   so that the expansion arrow becomes visible-  deriving (Eq)---instance Ord FileRecord where-    -- | The ordering used for displaying the records in the filetree-    compare (DirRecord _) (FileRecord _) = LT-    compare (FileRecord _) (DirRecord _) = GT-    compare (FileRecord p1) (FileRecord p2) = comparing (map toLower) p1 p2-    compare (DirRecord p1) (DirRecord p2) = comparing (map toLower) p1 p2-    compare _ _ = LT---- | The text to show in the file tree for a file record-displayText :: FileRecord -> Text-displayText (FileRecord f) = T.pack $ takeFileName f-displayText (DirRecord f) = T.pack $ takeFileName f-displayText (PackageRecord p) = packageIdentifierToString (ipdPackageId p) <> " " <> T.pack (ipdBuildDir p)-displayText PlaceHolder = ""--+import Data.Tree (Forest, Tree(..))+import Graphics.UI.Gtk.MenuComboToolbar.MenuItem+       (menuItemActivate, menuItemNewWithLabel)+import IDE.Pane.Modules (addModule)+import Graphics.UI.Gtk.Windows.MessageDialog+       (ButtonsType(..), MessageType(..), messageDialogNew)+import Graphics.UI.Gtk.ModelView.CellRenderer+       (CellRendererMode(..), cellMode)+import IDE.Pane.PackageEditor (packageEditText)+import IDE.Utils.GtkBindings (treeViewSetActiveOnSingleClick)+import IDE.Package (packageTest, packageRun, packageClean)   -- * The Files pane  -- | The representation of the Files pane data IDEFiles        =   IDEFiles {-    scrolledView    ::   ScrolledWindow-,   treeView        ::   TreeView-,   fileStore       ::   TreeStore FileRecord+    deprecatedLabel :: Label } deriving Typeable  @@ -128,7 +108,7 @@ instance Pane IDEFiles IDEM where     primPaneName _  =   __ "Files"     getAddedIndex _ =   0-    getTopWidget    =   castToWidget . scrolledView+    getTopWidget    =   castToWidget . deprecatedLabel     paneId b        =   "*Files"  instance RecoverablePane IDEFiles FilesState IDEM where@@ -137,222 +117,5 @@         nb      <-  getNotebook pp         buildPane pp nb builder     builder pp nb windows = reifyIDE $ \ ideR -> do-        fileStore   <-  treeStoreNew []-        treeView    <-  treeViewNew-        treeViewSetModel treeView fileStore--        renderer1    <- cellRendererTextNew-        renderer10   <- cellRendererPixbufNew-        col1         <- treeViewColumnNew-        treeViewColumnSetTitle col1 (__ "File")-        treeViewColumnSetSizing col1 TreeViewColumnAutosize-        treeViewColumnSetResizable col1 True-        treeViewColumnSetReorderable col1 True-        treeViewAppendColumn treeView col1-        cellLayoutPackStart col1 renderer10 False-        cellLayoutPackStart col1 renderer1 True-        cellLayoutSetAttributes col1 renderer1 fileStore-            $ \row -> [ cellText := displayText row]--        treeViewSetHeadersVisible treeView False-        sel <- treeViewGetSelection treeView-        treeSelectionSetMode sel SelectionSingle--        scrolledView <- scrolledWindowNew Nothing Nothing-        scrolledWindowSetShadowType scrolledView ShadowIn-        containerAdd scrolledView treeView-        scrolledWindowSetPolicy scrolledView PolicyAutomatic PolicyAutomatic--        let files = IDEFiles {..}--        cid1 <- after treeView focusInEvent $ do-            liftIO $ reflectIDE (makeActive files) ideR-            return True-        cid2 <- on treeView rowExpanded $ \ iter path -> do-            record <- treeStoreGetValue fileStore path-            reflectIDE (-                case record of-                    DirRecord f     -> refreshDir fileStore path f-                    PackageRecord p -> refreshPackage fileStore path p-                    _               -> ideMessage Normal (__ "Unexpected Expansion in Files Pane")) ideR-        on treeView rowActivated $ \ path col -> do-            record <- treeStoreGetValue fileStore path-            reflectIDE (-                case record of-                    FileRecord f    -> void (goToSourceDefinition' f (Location "" 1 0 1 0))-                    DirRecord f     -> refreshDir fileStore path f-                    PackageRecord p -> refreshPackage fileStore path p-                    _               -> ideMessage Normal (__ "Unexpected Activation in Files Pane")) ideR-        on sel treeSelectionSelectionChanged $ do-            paths <- treeSelectionGetSelectedRows sel-            forM_ paths $ \ path -> do-                record <- treeStoreGetValue fileStore path-                reflectIDE (-                    case record of-                        FileRecord _    -> return ()-                        DirRecord f     -> refreshDir fileStore path f-                        PackageRecord p -> refreshPackage fileStore path p-                        _               -> ideMessage Normal (__ "Unexpected Selection in Files Pane")) ideR--        return (Just files,[ConnectC cid1])---- | Get the Files pane-getFiles :: Maybe PanePath -> IDEM IDEFiles-getFiles Nothing    = forceGetPane (Right "*Files")-getFiles (Just pp)  = forceGetPane (Left pp)----- | Refreshes the Files pane, lists all package directories and synchronizes the expanded--- folders with the file system-refreshFiles :: IDEAction-refreshFiles = do-    files <- getFiles Nothing-    let store = fileStore files-    let view  = treeView files-    mbWS <- readIDE workspace-    let packages = maybe [] wsPackages mbWS-    setDirectories store Nothing $ map PackageRecord packages--    forM_ (zip [0..] packages) $ \(n, package) ->-         refreshRecursively store [n] view---- | Returns the 'FileRecord's at the given 'FilePath'.-dirContents :: FilePath -> IDEM [FileRecord]-dirContents dir = do-   prefs <- readIDE prefs-   contents <- liftIO $ getDirectoryContents dir-                            `catch` \ (e :: IOError) -> return []-   let filtered = if showHiddenFiles prefs-                      then filter (`notElem` [".", ".."]) contents-                      else filter ((/= '.') . head) contents-   records <- forM filtered $ \f -> do-                  let full = dir </> f-                  isDir <- liftIO $ doesDirectoryExist full-                  return $ if isDir then DirRecord full else FileRecord full-   return (sort records)----- | Recursively refreshes the file tree with the given TreePath as root. Only refreshes contents--- of expanded folders.-refreshRecursively :: TreeStore FileRecord -> TreePath -> TreeView -> IDEAction-refreshRecursively store path view = do-    isExpanded <- liftIO $ treeViewRowExpanded view path-    record     <- liftIO $ treeStoreGetValue store path--    when isExpanded $-        case record of-            DirRecord dir -> do-                refreshDir store path dir-                nChildren  <- length . subForest <$> liftIO (treeStoreGetTree store path)-                forM_ [0..nChildren-1] (\n -> refreshRecursively store (path ++ [n]) view)--            PackageRecord package -> do-                refreshPackage store path package-                nChildren  <- length . subForest <$> liftIO (treeStoreGetTree store path)-                forM_ [0..nChildren-1] (\n -> refreshRecursively store (path ++ [n]) view)--            _ -> return ()---- | Refreshes the child nodes of the package node at the given 'TreePath'. Also adds sandbox--- add-source dependencies as a 'PackageRecord'.-refreshPackage :: TreeStore FileRecord -> TreePath -> IDEPackage -> IDEAction-refreshPackage store path p = do-    liftIO $ debugM "leksah" $ "refreshPackage " <> ipdCabalFile p-    let dir = ipdBuildDir p-    mbIter <- liftIO $ treeModelGetIter store path-    when (isJust mbIter) $ do-        contents <- dirContents dir-        setDirectories store mbIter $ map PackageRecord (ipdSandboxSources p) ++ contents----- | Refreshes the child nodes of the node at the given 'TreePath'.-refreshDir :: TreeStore FileRecord -> TreePath -> FilePath -> IDEAction-refreshDir store path dir =  do-    liftIO $ debugM "leksah" $ "refreshPackage " <> dir-    mbIter <- liftIO $ treeModelGetIter store path-    when (isJust mbIter) $ do-        contents <- dirContents dir-        setDirectories store mbIter contents---- | Sets the child nodes of the given 'TreeIter' to the provided list of 'FileRecord's. If a record--- is already present, it is kept in the same (expanded) state.-setDirectories :: TreeStore FileRecord -> Maybe TreeIter -> [FileRecord] -> IDEAction-setDirectories store parent records = liftIO $ do-    parentPath <- case parent of-                Just i -> treeModelGetPath store i-                _      -> return []-    forM_ (zip [0..] records) $ \(n, record) -> do-        mbChild <- treeModelIterNthChild store parent n-        findResult <- find record store mbChild-        case (mbChild, findResult) of-            (_, WhereExpected _) -> return ()-            (Just iter, Found _) -> do-                path <- treeModelGetPath store iter-                removeUntil record store path-            _ -> do-                treeStoreInsert store parentPath n record--                -- Insert placeholder children for dirs and packages so they can-                -- be expanded on clicking, and have the contents loaded "lazily".-                case record of-                    DirRecord _     -> treeStoreInsert store (parentPath++[n]) 0 PlaceHolder-                    PackageRecord _ -> treeStoreInsert store (parentPath++[n]) 0 PlaceHolder-                    _               -> return ()-    removeRemaining store (parentPath++[length records])--data FindResult = WhereExpected TreeIter | Found TreeIter | NotFound---- | Tries to find the given value in the 'TreeStore'. Only looks at the given 'TreeIter' and its--- sibling nodes to the right.--- Returns @WhereExpected iter@ if the records is found at the provided 'TreeIter'--- Returns @Found iter@ if the record is found at a sibling iter--- Returns @NotFound@ otherwise-find :: Eq a => a -> TreeStore a -> Maybe TreeIter -> IO FindResult-find _ _ Nothing = return NotFound-find a store (Just iter) = do-    row <- treeModelGetRow store iter-    if row == a-        then return $ WhereExpected iter-        else treeModelIterNext store iter >>= find'-  where-    find' :: Maybe TreeIter -> IO FindResult-    find' Nothing = return NotFound-    find' (Just iter) = do-        row <- treeModelGetRow store iter-        if row == a-            then return $ Found iter-            else treeModelIterNext store iter >>= find'----- | Starting at the node at the given 'TreePath', removes all sibling nodes to the right---   until the given value is found.-removeUntil :: Eq a => a -> TreeStore a -> TreePath -> IO ()-removeUntil a store path = do-    row <- treeStoreGetValue store path-    when (row /= a) $ do-        found <- treeStoreRemove store path-        when found $ removeUntil a store path----- | Starting at the node at the given 'TreePath', removes all sibling nodes to the right-removeRemaining :: TreeStore a -> TreePath -> IO ()-removeRemaining store path = do-    found <- treeStoreRemove store path-    when found $ removeRemaining store path-----------------+        deprecatedLabel <- labelNew $ Just ("The Files pane is deprecated and has been combined with the Workspace pane"::Text)+        return (Just IDEFiles {..}, [])
src/IDE/Pane/Grep.hs view
@@ -247,7 +247,7 @@             Just active -> active : filter (/= active) (wsAllPackages ws)
             Nothing     -> wsAllPackages ws
     lift $ grepDirectories regexString caseSensitive $
-            map (dropFileName . ipdCabalFile) packages
+            map ipdPackageDir packages
 
 
 -- | Greps a list of directories
src/IDE/Pane/Info.hs view
@@ -69,7 +69,7 @@  instance Pane IDEInfo IDEM     where-    primPaneName _  =   __ "Info"+    primPaneName _  =   __ "Symbol Info"     getAddedIndex _ =   0     getTopWidget    =   castToWidget . sw     paneId b        =   "*Info"
src/IDE/Pane/Modules.hs view
@@ -59,7 +59,7 @@         hasLibs, executables, testSuites, exeName, testName, benchmarks,         benchmarkName, libBuildInfo, library, buildInfo, testBuildInfo,         benchmarkBuildInfo)-import System.FilePath (takeBaseName, (</>),dropFileName)+import System.FilePath (takeBaseName, (</>),dropFileName,makeRelative,takeDirectory) import System.Directory (doesFileExist,createDirectoryIfMissing, removeFile) import Graphics.UI.Editor.MakeEditor (buildEditor,FieldDescription(..),mkField) import Graphics.UI.Editor.Parameters@@ -782,13 +782,26 @@         resultTree        =   foldl' insertPairsInTree defaultRoot modDescrPackDescr         in sortTree resultTree +-- | Insert module and package info into the tre insertPairsInTree :: ModTree -> (ModuleDescr,PackageDescr) -> ModTree insertPairsInTree tree pair =-    let nameArray           =   map T.pack . components . modu . mdModuleId $ fst pair+    let nameArray           =   modTreeName $ fst pair         (startArray,last)   =   splitAt (length nameArray - 1) nameArray         pairedWith          =   map (\ n -> (n, Nothing)) startArray ++ [(head last, Just pair)]     in  insertNodesInTree pairedWith tree-+    where modTreeName modDescr = let+                    modId = mdModuleId modDescr+                    modName = modu modId+                    mFilePath = mdMbSourcePath modDescr+                    -- show relative file path for Main modules+                    -- since we can have several+                    in case (components modName,mFilePath) of+                        (["Main"],Just fp) ->+                            let sfp = case (pdMbSourcePath (snd pair)) of+                                        Nothing -> fp+                                        Just pfp -> makeRelative (takeDirectory pfp) fp+                            in  [T.pack $ "Main ("++sfp++")"]+                        (cmps,_) -> map T.pack cmps  insertNodesInTree :: [ModuleRecord] -> ModTree -> ModTree insertNodesInTree  [p1@(str1,Just pair)] (Node p2@(str2,mbPair) forest2) =@@ -1151,7 +1164,7 @@         []     -> return []         (treePath:_) -> liftIO $ mapM (treeStoreGetValue store . (`take` treePath))                                    [1 .. length treePath]-    addModule categories+    addModule (map fst categories)  -- Includes non buildable allBuildInfo' :: PackageDescription -> [BuildInfo]@@ -1160,15 +1173,16 @@                        ++ [ testBuildInfo tst      | tst <- testSuites pkg_descr ]                        ++ [ benchmarkBuildInfo tst | tst <- benchmarks pkg_descr ] -addModule :: [ModuleRecord] -> PackageAction-addModule categories = do+addModule :: [Text] -> PackageAction+addModule modulePrefix = do     liftIO $ debugM "leksah" "selectIdentifier"     mbPD <- liftIDE getPackageDescriptionAndPath     case mbPD of         Nothing             -> liftIDE $ ideMessage Normal (__ "No package description")         Just (pd,cabalPath) -> let srcPaths = nub $ concatMap hsSourceDirs $ allBuildInfo' pd                                    rootPath = dropFileName cabalPath-                                   modPath  = foldr ((\ a b -> a <> "." <> b) . fst) "" categories+                                   modPath  = foldr (\a b -> a <> "." <> b) ""+                                                    modulePrefix                                in do             window' <- liftIDE getMainWindow             mbResp <- liftIO $ addModuleDialog window' modPath srcPaths (hasLibs pd) $@@ -1181,7 +1195,8 @@                     case simpleParse $ T.unpack modPath of                         Nothing         -> liftIDE $ ideMessage Normal (T.pack $ printf (__ "Not a valid module name : %s") (T.unpack modPath))                         Just moduleName -> do-                            let  target = srcPath </> toFilePath moduleName ++ ".hs"+                            package <- ask+                            let  target = ipdPackageDir package </> srcPath </> toFilePath moduleName ++ ".hs"                             liftIO $ createDirectoryIfMissing True (dropFileName target)                             alreadyExists <- liftIO $ doesFileExist target                             if alreadyExists@@ -1197,8 +1212,7 @@                                     liftIDE $ fileOpenThis target  ---  Yet another stupid little dialog-+-- | The dialog for adding a new module data AddModule = AddModule {     moduleName   :: Text,     sourceRoot   :: FilePath,@@ -1213,7 +1227,13 @@     lib (Just False) = [LibOtherMod]     lib Nothing = [] -addModuleDialog :: Window -> Text -> [FilePath] -> Bool -> [Text] -> IO (Maybe AddModule)+-- | Creates and runs a "new module" dialog+addModuleDialog :: Window -- ^ The parent window+                -> Text   -- ^ Will be set as default value for the module name+                -> [FilePath] -- ^ Possible source directories to add it to+                -> Bool       -- ^ Whether the active package has a library+                -> [Text]     -- ^ The components of the active package+                -> IO (Maybe AddModule) addModuleDialog parent modString sourceRoots hasLib exesTests = do     liftIO $ debugM "leksah" "addModuleDialog"     dia                        <-   dialogNew
src/IDE/Pane/PackageEditor.hs view
@@ -113,6 +113,8 @@ import MyMissing (forceJust) import Language.Haskell.Extension (Language(..)) import Distribution.License (License(..))+import Control.Exception (SomeException(..))+import IDE.Metainfo.Provider (getAllPackageIds)  printf :: PrintfType r => Text -> r printf = S.printf . T.unpack@@ -170,13 +172,13 @@   = chooseDir window (__ "Select root folder for package")  choosePackageFile :: Window -> Maybe FilePath -> IO (Maybe FilePath)-choosePackageFile window-  = chooseFile window (__ "Select cabal package file (.cabal)")+choosePackageFile window mbfp+  = chooseFile window (__ "Select cabal package file (.cabal)") mbfp [("Cabal Package Files", ["*.cabal"])]  packageEdit :: PackageAction packageEdit = do     idePackage <- ask-    let dirName = dropFileName (ipdCabalFile idePackage)+    let dirName = ipdPackageDir idePackage     modules <- liftIO $ allModules dirName     package <- liftIO $ readPackageDescription normal (ipdCabalFile idePackage)     if hasConfigs package@@ -376,7 +378,7 @@ cloneFields :: [PackageId] -> FilePath -> FieldDescription ClonePackageSourceRepo cloneFields packages workspaceDir = VFD emptyParams [         mkField-            (paraName <<<- ParaName (__ "Existing package to clone source repository")+            (paraName <<<- ParaName (__ "Existing package to copy source repository")                     $ emptyParams)             packageToClone             (\ a b -> b{packageToClone = a})@@ -389,17 +391,18 @@             (\ a b -> b{cloneParentDir = a})             (fileEditor (Just workspaceDir) FileChooserActionSelectFolder "Select")] -clonePackageSourceDialog :: Window -> FilePath -> IO (Maybe ClonePackageSourceRepo)+clonePackageSourceDialog :: Window -> FilePath -> IDEM (Maybe ClonePackageSourceRepo) clonePackageSourceDialog parent workspaceDir = do-    packages                   <- getInstalledPackageIds+  packages <- getAllPackageIds+  liftIO $ do     dia                        <-   dialogNew     set dia [ windowTransientFor := parent-            , windowTitle := __ "Clone Package" ]+            , windowTitle := __ "Copy Installed Package" ]     upper                      <-   dialogGetContentArea dia     lower                      <-   dialogGetActionArea dia     (widget,inj,ext,_)         <-   buildEditor (cloneFields packages workspaceDir)                                         (ClonePackageSourceRepo "" workspaceDir)-    okButton <- dialogAddButton dia (__"Clone Package") ResponseOk+    okButton <- dialogAddButton dia (__"Copy Package") ResponseOk     dialogAddButton dia (__"Cancel") ResponseCancel     boxPackStart (castToBox upper) widget PackGrow 7     set okButton [widgetCanDefault := True]@@ -414,9 +417,9 @@         _             -> return Nothing  packageClone :: FilePath -> C.Sink ToolOutput IDEM () -> (FilePath -> IDEAction) -> IDEAction-packageClone workspaceDir log activateAction = do+packageClone workspaceDir log activateAction = flip catchIDE (\(e :: SomeException) -> print e) $ do     windows  <- getWindows-    mbResult <- liftIO $ clonePackageSourceDialog (head windows) workspaceDir+    mbResult <- clonePackageSourceDialog (head windows) workspaceDir     case mbResult of         Nothing -> return ()         Just ClonePackageSourceRepo{..} -> cabalUnpack cloneParentDir packageToClone True Nothing log activateAction@@ -597,7 +600,7 @@         Nothing -> do             pp  <- getBestPathForId "*Package"             nb  <- getNotebook pp-            packageInfos <- liftIO getInstalledPackageIds+            packageInfos <- getAllPackageIds             let packageEd = toEditor packageD             initPackage packagePath packageEd                 (packageDD@@ -622,7 +625,7 @@ initPackage packageDir packageD packageDescr panePath nb modules afterSaveAction origPackageD = do     let fields =  flattenFieldDescription packageDescr     let initialPackagePath = packageDir </> (display . pkgName . package . pd) packageD ++ ".cabal"-    packageInfos <- liftIO getInstalledPackageIds+    packageInfos <- getAllPackageIds     mbP <- buildThisPane panePath nb         (builder' packageDir packageD packageDescr afterSaveAction             initialPackagePath modules packageInfos fields origPackageD)
− src/IDE/Pane/Preferences.hs
@@ -1,936 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE OverloadedStrings #-}------------------------------------------------------------------------------------ Module      :  IDE.Pane.Preferences--- Copyright   :  (c) Juergen Nicklisch-Franken, Hamish Mackenzie--- License     :  GNU-GPL------ Maintainer  :  <maintainer at leksah.org>--- Stability   :  provisional--- Portability :  portable--------- | Module for saving, restoring and editing preferences----------------------------------------------------------------------------------------module IDE.Pane.Preferences (-    IDEPrefs(..)-,   PrefsState-,   readPrefs-,   writePrefs-,   defaultPrefs-,   prefsDescription-,   getPrefs-) where--import Graphics.UI.Gtk-       (buttonBoxSetLayout, boxSetSpacing, widgetDestroy, dialogRun,-        windowWindowPosition, dialogAddButton, messageDialogNew,-        labelSetMarkup, labelNew, widgetSetSensitive, cellText,-        widgetModifyFont, on, buttonActivated, boxPackEnd, boxPackStart,-        buttonNewFromStock, hButtonBoxNew, vBoxNew, castToWidget, VBox,-        ShadowType(..), Packing(..), fontDescriptionFromString, AttrOp(..),-        FileChooserAction(..), Color(..), ResponseId(..))-import qualified Text.PrettyPrint.HughesPJ as PP-import Distribution.Package-import Data.IORef-import Data.Typeable--import Control.Event-import Graphics.UI.Editor.Basics-import IDE.Core.State-import Graphics.UI.Editor.Simple-import Graphics.UI.Editor.Composite-import Graphics.UI.Editor.Parameters-import Graphics.UI.Editor.MakeEditor hiding (parameters)-import Graphics.UI.Editor.DescriptionPP-import Text.PrinterParser hiding (fieldParser,parameters)-import IDE.TextEditor-import IDE.Pane.SourceBuffer-import IDE.Pane.Log-import IDE.Pane.Info (setInfoStyle)-import IDE.Utils.FileUtils-import IDE.Utils.GUIUtils-import IDE.Debug-    (debugSetPrintBindResult,-     debugSetBreakOnError,-     debugSetBreakOnException,-     debugSetPrintEvldWithShow)-import Graphics.UI.Gtk.SourceView-       (sourceStyleSchemeManagerAppendSearchPath,-        sourceStyleSchemeManagerGetSchemeIds, sourceStyleSchemeManagerNew)-import System.Time (getClockTime)-import qualified IDE.StrippedPrefs as SP-import Control.Exception(SomeException,catch)-import Prelude hiding(catch)-import Data.List (isSuffixOf, sortBy)-import Data.Maybe (mapMaybe, catMaybes, fromMaybe, isJust)-import Graphics.UI.Gtk.Windows.MessageDialog-       (ButtonsType(..), MessageType(..))-import System.Glib.Attributes (set)-import Graphics.UI.Gtk.General.Enums-       (ButtonBoxStyle(..), WindowPosition(..))-import Control.Monad.IO.Class (MonadIO(..))-import Control.Monad (void, when)-import System.FilePath ((</>))-import Data.Text (Text)-import qualified Data.Text as T (isSuffixOf, unpack, pack, null)-import Data.Monoid ((<>))-import Control.Applicative ((<$>))-import Distribution.Text (display, simpleParse)-import IDE.Pane.Files (refreshFiles)-import Data.Foldable (forM_)---- ------------------------------------------------------------------------ This needs to be incremented, when the preferences format changes----prefsVersion :: Int-prefsVersion = 3----- | Represents the Preferences pane-data IDEPrefs               =   IDEPrefs {-    prefsBox                ::   VBox-} deriving Typeable----- | The additional state used when recovering the pane-data PrefsState             =   PrefsState-    deriving(Eq,Ord,Read,Show,Typeable)---instance Pane IDEPrefs IDEM-    where-    primPaneName _  =   __ "Prefs"-    getAddedIndex _ =   0-    getTopWidget    =   castToWidget . prefsBox-    paneId b        =   "*Prefs"---instance RecoverablePane IDEPrefs PrefsState IDEM where-    saveState p     =   return Nothing-    recoverState pp st  =  return Nothing-    builder pp nb windows = do-        initialPrefs <- readIDE prefs-        configDir <- liftIO getConfigDir-        lastAppliedPrefsRef <- liftIO $ newIORef initialPrefs-        packageInfos <- liftIO getInstalledPackageIds-        let flatPrefsDesc = flattenFieldDescriptionPP (prefsDescription configDir packageInfos)-        reifyIDE $  \ ideR -> do-            vb      <-  vBoxNew False 0-            bb      <-  hButtonBoxNew-            boxSetSpacing bb 6-            buttonBoxSetLayout bb ButtonboxSpread-            preview   <-  buttonNewFromStock "Preview"-            restore <-  buttonNewFromStock "Restore"-            closeB  <-  buttonNewFromStock "gtk-cancel"-            save    <-  buttonNewFromStock "gtk-save"-            widgetSetSensitive save False-            boxPackStart bb preview PackNatural 0-            boxPackStart bb restore PackNatural 0-            boxPackEnd bb closeB PackNatural 0-            boxPackEnd bb save PackNatural 0-            (widget,injb,ext,notifier) <-  buildEditor-                                (extractFieldDescription $ prefsDescription configDir packageInfos) initialPrefs-            boxPackStart vb widget PackGrow 0-            label   <-  labelNew (Nothing :: Maybe Text)-            boxPackStart vb label PackNatural 0-            boxPackEnd vb bb PackNatural 5-            let prefsPane = IDEPrefs vb--            let applyPrefs newPrefs = do-                    lastAppliedPrefs    <- readIORef lastAppliedPrefsRef-                    reflectIDE (modifyIDE_ (\ide -> ide{prefs = newPrefs})) ideR-                    mapM_ (\f -> reflectIDE (applicator f newPrefs lastAppliedPrefs) ideR) flatPrefsDesc-                    writeIORef lastAppliedPrefsRef newPrefs--            on preview buttonActivated $ do-                mbNewPrefs <- extract initialPrefs [ext]-                forM_ mbNewPrefs applyPrefs--            on restore buttonActivated $ do-                applyPrefs initialPrefs--                -- update the UI-                injb initialPrefs-                markLabel nb (getTopWidget prefsPane) False-                widgetSetSensitive save False---            on save buttonActivated $ do-                mbNewPrefs <- extract initialPrefs [ext]-                case mbNewPrefs of-                    Nothing -> return ()-                    Just newPrefs -> do-                        applyPrefs newPrefs--                        -- save preferences to disk-                        fp   <- getConfigFilePathForSave standardPreferencesFilename-                        writePrefs fp newPrefs-                        fp2  <-  getConfigFilePathForSave strippedPreferencesFilename-                        SP.writeStrippedPrefs fp2-                            SP.Prefs {SP.sourceDirectories = sourceDirectories newPrefs,-                                       SP.unpackDirectory   = unpackDirectory newPrefs,-                                       SP.retrieveURL       = retrieveURL newPrefs,-                                       SP.retrieveStrategy  = retrieveStrategy newPrefs,-                                       SP.serverPort        = serverPort newPrefs,-                                       SP.endWithLastConn   = endWithLastConn newPrefs}--                        -- close the UI-                        reflectIDE (void (closePane prefsPane)) ideR--            on closeB buttonActivated $ do-                mbP <- extract initialPrefs [ext]-                let hasChanged = case mbP of-                                        Nothing -> False-                                        Just p -> p{prefsFormat = 0, prefsSaveTime = ""} /=-                                                  initialPrefs{prefsFormat = 0, prefsSaveTime = ""}-                if not hasChanged-                    then reflectIDE (void (closePane prefsPane)) ideR-                    else do-                        md <- messageDialogNew (Just windows) []-                            MessageQuestion-                            ButtonsYesNo-                            (__ "Unsaved changes. Close anyway?")-                        set md [ windowWindowPosition := WinPosCenterOnParent ]-                        resp <- dialogRun md-                        widgetDestroy md-                        case resp of-                            ResponseYes -> do-                                applyPrefs initialPrefs-                                reflectIDE (void (closePane prefsPane)) ideR-                            _  ->   return ()-            registerEvent notifier FocusIn (\e -> do-                reflectIDE (makeActive prefsPane) ideR-                return (e{gtkReturn=False}))-            registerEvent notifier MayHaveChanged (\ e -> do-                mbP <- extract initialPrefs [ext]-                let hasChanged = case mbP of-                                        Nothing -> False-                                        Just p -> p{prefsFormat = 0, prefsSaveTime = ""} /=-                                                  initialPrefs{prefsFormat = 0, prefsSaveTime = ""}-                when (isJust mbP) $ labelSetMarkup label ("" :: Text)-                markLabel nb (getTopWidget prefsPane) hasChanged-                widgetSetSensitive save hasChanged-                return (e{gtkReturn=False}))-            registerEvent notifier ValidationError (\e -> do-                labelSetMarkup label $ "<span foreground=\"red\" size=\"x-large\">The following fields have invalid values: "-                    <> eventText e <> "</span>"-                return e)-            return (Just prefsPane,[])----- | Get the Preferences pane-getPrefs :: Maybe PanePath -> IDEM IDEPrefs-getPrefs Nothing    = forceGetPane (Right "*Prefs")-getPrefs (Just pp)  = forceGetPane (Left pp)------ --------------------------------------------------------------- * Dialog definition--- ---------------------------------------------------------------- | Description of the preference options-prefsDescription :: FilePath -> [PackageIdentifier] -> FieldDescriptionPP Prefs IDEM-prefsDescription configDir packages = NFDPP [-    (__ "Editor", VFDPP emptyParams [-        mkFieldPP-            (paraName <<<- ParaName (__ "Version number of preferences file format")-                $ paraSynopsis <<<- ParaSynopsis (__ "Integer")-                    $ paraShowLabel <<<- ParaShowLabel False $ emptyParams)-            (PP.text . show)-            intParser-            prefsFormat-            (\ b a -> a{prefsFormat = b})-            (noEditor 0)-            (\b -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Time of last storage")-                $ paraShowLabel <<<- ParaShowLabel False $ emptyParams)-            (PP.text . show)-            stringParser-            prefsSaveTime-            (\ b a -> a{prefsSaveTime = b})-            (noEditor "")-            (\b -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Show line numbers")-                $ paraSynopsis <<<- ParaSynopsis (__ "(True/False)")-                    $ emptyParams)-            (PP.text . show)-            boolParser-            showLineNumbers-            (\ b a -> a{showLineNumbers = b})-            boolEditor-            (\b -> do-                buffers <- allBuffers-                mapM_ (\(IDEBuffer {sourceView = sv}) -> setShowLineNumbers sv b) buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "TextView Font") $ emptyParams)-            (\a -> PP.text (case a of Nothing -> show ""; Just s -> show s))-            (do str <- stringParser-                return (if T.null str then Nothing else Just str))-            textviewFont-            (\ b a -> a{textviewFont = b})-            fontEditor-            (\mbs -> do-                buffers <- allBuffers-                mapM_ (\(IDEBuffer {sourceView = sv}) -> setFont sv mbs) buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Right margin")-                $ paraSynopsis <<<- ParaSynopsis (__ "Size or 0 for no right margin")-                    $ paraShadow <<<- ParaShadow ShadowIn $ emptyParams)-            (PP.text . show)-            readParser-            rightMargin-            (\b a -> a{rightMargin = b})-            (disableEditor (intEditor (1.0, 200.0, 5.0), paraName <<<- ParaName (__ "Position")-                    $ emptyParams)-                    True (__ "Show it ?"))-            (\b -> do-                buffers <- allBuffers-                mapM_ (\(IDEBuffer {sourceView = sv}) -> setRightMargin sv-                                (case b of-                                    (True,v) -> Just v-                                    (False,_) -> Nothing)) buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Tab width") $ emptyParams)-            (PP.text . show)-            intParser-            tabWidth-            (\b a -> a{tabWidth = b})-            (intEditor (1.0, 20.0, 1.0))-            (\i -> do-                buffers <- allBuffers-                mapM_ (\(IDEBuffer {sourceView = sv}) -> setIndentWidth sv i) buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Wrap lines") $ emptyParams)-            (PP.text . show)-            boolParser-            wrapLines-            (\b a -> a{wrapLines = b})-            boolEditor-            (\b -> do-                buffers <- allBuffers-                mapM_ (\(IDEBuffer {sourceView = sv}) -> setWrapMode sv b) buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Use standard line ends even on windows") $ emptyParams)-            (PP.text . show)-            boolParser-            forceLineEnds-            (\b a -> a{forceLineEnds = b})-            boolEditor-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Remove trailing blanks when saving a file") $ emptyParams)-            (PP.text . show)-            boolParser-            removeTBlanks-            (\b a -> a{removeTBlanks = b})-            boolEditor-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Source candy")-                $ paraSynopsis <<<- ParaSynopsis-                    (__ "Empty for do not use or the name of a candy file in a config dir")-                    $ paraShadow <<<- ParaShadow ShadowIn $ emptyParams)-            (PP.text . show)-            readParser-            sourceCandy (\b a -> a{sourceCandy = b})-            (disableEditor (textEditor (not . T.null) True,-                paraName <<<- ParaName (__ "Candy specification")-                                    $ emptyParams)-                    True (__ "Use it ?"))-            (\cs -> case cs of-                        (False,_) -> do-                            setCandyState False-                            editCandy-                        (True,name) -> do-                            setCandyState True-                            editCandy)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Editor Style") $ emptyParams)-            (\a -> PP.text (case a of (False,_) -> show ""; (True, s) -> show s))-            (do str <- stringParser-                return (if T.null str then (False, __ "classic") else (True,str)))-            sourceStyle-            (\b a -> a{sourceStyle = b})-            styleEditor-            (\mbs -> do-                setInfoStyle-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Found Text Background") $ emptyParams)-            (PP.text . show)-            colorParser-            foundBackgroundLight-            (\ b a -> a{foundBackgroundLight = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Selection Match Text Background") $ emptyParams)-            (PP.text . show)-            colorParser-            matchBackgroundLight-            (\ b a -> a{matchBackgroundLight = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Execution Context Text Background") $ emptyParams)-            (PP.text . show)-            colorParser-            contextBackgroundLight-            (\ b a -> a{contextBackgroundLight = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Breakpoint Text Background") $ emptyParams)-            (PP.text . show)-            colorParser-            breakpointBackgroundLight-            (\ b a -> a{breakpointBackgroundLight = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Lint Text Background") $ emptyParams)-            (PP.text . show)-            colorParser-            lintBackgroundLight-            (\ b a -> a{lintBackgroundLight = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Found Text Dark Background") $ emptyParams)-            (PP.text . show)-            colorParser-            foundBackgroundDark-            (\ b a -> a{foundBackgroundDark = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Selection Match Text Dark Background") $ emptyParams)-            (PP.text . show)-            colorParser-            matchBackgroundDark-            (\ b a -> a{matchBackgroundDark = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Execution Context Text Dark Background") $ emptyParams)-            (PP.text . show)-            colorParser-            contextBackgroundDark-            (\ b a -> a{contextBackgroundDark = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Breakpoint Text Dark Background") $ emptyParams)-            (PP.text . show)-            colorParser-            breakpointBackgroundDark-            (\ b a -> a{breakpointBackgroundDark = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Lint Text Dark Background") $ emptyParams)-            (PP.text . show)-            colorParser-            lintBackgroundDark-            (\ b a -> a{lintBackgroundDark = b})-            colorEditor-            (\c -> do-                buffers <- allBuffers-                mapM_ updateStyle' buffers)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Automatically load modified files modified outside of Leksah") $ emptyParams)-            (PP.text . show)-            boolParser-            autoLoad-            (\b a -> a{autoLoad = b})-            boolEditor-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Text Editor") $ emptyParams)-            (PP.text . show)-            stringParser-            textEditorType-            (\b a -> a{textEditorType = b})-            (comboSelectionEditor ["GtkSourceView", "Yi", "CodeMirror"] id)-            (\i -> return ())-    ]),-    (__ "GUI Options", VFDPP emptyParams [-        mkFieldPP-            (paraName <<<- ParaName (__ "LogView Font") $ emptyParams)-            (\a -> PP.text (case a of Nothing -> show ""; Just s -> show s))-            (do str <- stringParser-                return (if T.null str then Nothing else Just str))-            logviewFont-            (\ b a -> a{logviewFont = b})-            fontEditor-            (\mbs -> do-                log <- getLog-                fdesc <- liftIO $fontDescriptionFromString (fromMaybe "" mbs)-                liftIO $widgetModifyFont (castToWidget $ logLaunchTextView log) (Just fdesc))-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Window default size")-                $ paraSynopsis <<<- ParaSynopsis-                    (__ "Default size of the main ide window specified as pair (int,int)")-                    $ paraShadow <<<- ParaShadow ShadowIn $ emptyParams)-            (PP.text.show)-            (pairParser intParser)-            defaultSize (\(c,d) a -> a{defaultSize = (c,d)})-            (pairEditor (intEditor (0.0, 3000.0, 25.0),-                            paraName <<<- ParaName "X" $ emptyParams)-                        (intEditor (0.0, 3000.0, 25.0),-                            paraName <<<- ParaName "Y" $ emptyParams))-            (\a -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Show hidden files in file tree") $ emptyParams)-            (PP.text . show)-            boolParser-            showHiddenFiles-            (\b a -> a {showHiddenFiles = b})-            boolEditor-            (const refreshFiles)-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Use ctrl Tab for Notebook flipper") $ emptyParams)-            (PP.text . show)-            boolParser-            useCtrlTabFlipping-            (\b a -> a{useCtrlTabFlipping = b})-            boolEditor-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Complete only on Hotkey") $ emptyParams)-            (PP.text . show)-            boolParser-            completeRestricted-            (\b a -> a{completeRestricted = b})-            boolEditor-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Name of the keymap")-                $ paraSynopsis <<<- ParaSynopsis-                    (__ "The name of a keymap file in a config dir")-                    $ paraDirection <<<- ParaDirection Horizontal $ emptyParams)-            (PP.text . T.unpack)-            identifier-            keymapName-            (\b a -> a{keymapName = b})-            (textEditor (not . T.null) True)-            (\ a -> return ())-    ]),-    (__ "Initial Pane positions", VFDPP emptyParams [-        mkFieldPP-            (paraName <<<- ParaName-                (__ "Categories for panes")-                $ paraShadow <<<- ParaShadow ShadowIn-                     $ paraDirection <<<- ParaDirection Vertical-                        $ paraMinSize <<<- ParaMinSize (-1,130)-                            $ emptyParams)-            (PP.text . show)-            readParser-            categoryForPane-            (\b a -> a{categoryForPane = b})-            (multisetEditor-                (ColumnDescr True [(__ "Pane Id", \ (n, _) -> [cellText := n])-                                   ,(__ "Pane Category", \ (_, v) -> [cellText := v])])-                (pairEditor-                    (textEditor (not . T.null) True, emptyParams)-                    (textEditor (not . T.null) True, emptyParams), emptyParams)-                (Just (sortBy (\(a,_) (a2,_) -> compare a a2)))-                (Just (\(a,_) (a2,_) -> a == a2)))-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName-                (__ "Pane path for category")-                $ paraShadow <<<- ParaShadow ShadowIn-                     $ paraDirection <<<- ParaDirection Vertical-                        $ paraMinSize <<<- ParaMinSize (-1,130)-                            $ emptyParams)-            (PP.text . show)-            readParser-            pathForCategory-            (\b a -> a{pathForCategory = b})-            (multisetEditor-                (ColumnDescr True [(__ "Pane category", \ (n, _) -> [cellText := n])-                                   ,(__ "Pane path", \ (_, v) -> [cellText := T.pack $ show v])])-                (pairEditor (textEditor (not . T.null) True, emptyParams)-                    (genericEditor, emptyParams),-                  emptyParams)-                (Just (sortBy (\(a,_) (a2,_) -> compare a a2)))-                (Just (\(a,_) (a2,_) -> a == a2)))-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Default pane path") $ emptyParams)-            (PP.text . show)-            readParser-            defaultPath-            (\b a -> a{defaultPath = b})-            genericEditor-            (\i -> return ())-    ]),-    (__ "Metadata", VFDPP emptyParams [-        mkFieldPP-            (paraName <<<- ParaName-                (__ "Paths under which haskell sources for packages may be found")-                        $ paraMinSize <<<- ParaMinSize (-1,100)-                            $ emptyParams)-            (PP.text . show)-            readParser-            sourceDirectories-            (\b a -> a{sourceDirectories = b})-            (filesEditor Nothing FileChooserActionSelectFolder (__ "Select folder"))-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Unpack source for cabal packages to") $ emptyParams)-            (PP.text . show)-            readParser-            unpackDirectory-            (\b a -> a{unpackDirectory = b})-            (maybeEditor (stringEditor (const True) True,emptyParams) True "")-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "URL from which to download prebuilt metadata") $ emptyParams)-            (PP.text . show)-            stringParser-            retrieveURL-            (\b a -> a{retrieveURL = b})-            (textEditor (const True) True)-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Strategy for downloading prebuilt metadata") $ emptyParams)-            (PP.text . show)-            readParser-            retrieveStrategy-            (\b a -> a{retrieveStrategy = b})-            (enumEditor [__ "Try to download and then build locally if that fails",-                         __ "Try to build locally and then download if that fails",-                         __ "Never download (just try to build locally)"])-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Update metadata at startup") $ emptyParams)-            (PP.text . show)-            boolParser-            collectAtStart-            (\b a -> a{collectAtStart = b})-            boolEditor-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Port number for leksah to comunicate with leksah-server") $ emptyParams)-            (PP.text . show)-            intParser-            serverPort-            (\b a -> a{serverPort = b})-            (intEditor (1.0, 65535.0, 1.0))-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "IP address for leksah to comunicate with leksah-server") $ emptyParams)-            (PP.text . show)-            stringParser-            serverIP-            (\b a -> a{serverIP = b})-            (textEditor (not . T.null) True)-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "Stop the leksah-server process when leksah disconnects") $ emptyParams)-            (PP.text . show)-            boolParser-            endWithLastConn-            (\b a -> a{endWithLastConn = b})-            boolEditor-            (\i -> return ())-    ]),-    (__ "Blacklist", VFDPP emptyParams [-        mkFieldPP-            (paraName <<<- ParaName-                (__ "Packages which are excluded from the modules pane")-                        $ paraMinSize <<<- ParaMinSize (-1,200)-                            $ emptyParams)-            (PP.text . show . map display)-            (fmap (mapMaybe simpleParse) readParser)-            packageBlacklist-            (\b a -> a{packageBlacklist = b})-            (dependenciesEditor packages)-            (\i -> return ())-    ]),-    (__ "Build", VFDPP emptyParams [-         mkFieldPP-            (paraName <<<- ParaName (__ "Automatically save all files before building") $ emptyParams)-            (PP.text . show)-            boolParser-            saveAllBeforeBuild-            (\b a -> a{saveAllBeforeBuild = b})-            boolEditor-            (\i -> return ())-         , mkFieldPP-            (paraName <<<- ParaName (__ "Select first warning if built without errors") $ emptyParams)-            (PP.text . show)-            boolParser-            jumpToWarnings-            (\b a -> a{jumpToWarnings = b})-            boolEditor-            (\i -> return ())-         , mkFieldPP-            (paraName <<<- ParaName (__ "Background build") $ emptyParams)-            (PP.text . show)-            boolParser-            backgroundBuild-            (\b a -> a{backgroundBuild = b})-            boolEditor-            (\i -> return ())-         , mkFieldPP-            (paraName <<<- ParaName (__ "Run unit tests when building") $ emptyParams)-            (PP.text . show)-            boolParser-            runUnitTests-            (\b a -> a{runUnitTests = b})-            boolEditor-            (\i -> return ())-         , mkFieldPP-            (paraName <<<- ParaName (__ "Make mode") $ emptyParams)-            (PP.text . show)-            boolParser-            makeMode-            (\b a -> a{makeMode = b})-            (boolEditor2 (__ "Single mode"))-            (\i -> return ())--         , mkFieldPP-            (paraName <<<- ParaName (__ "Single build without linking") $ emptyParams)-            (PP.text . show)-            boolParser-            singleBuildWithoutLinking-            (\b a -> a{singleBuildWithoutLinking = b})-            boolEditor-            (\i -> return ())-         , mkFieldPP-            (paraName <<<- ParaName (__ "Don't install last package") $ emptyParams)-            (PP.text . show)-            boolParser-            dontInstallLast-            (\b a -> a{dontInstallLast = b})-            boolEditor-            (\i -> return ())--        , mkFieldPP-            (paraName <<<- ParaName (__ "Use vado to run commands on the remote machine") $ emptyParams)-            (PP.text . show)-            boolParser-            useVado-            (\b a -> a{useVado = b})-            boolEditor-            (\i -> return ())--        , mkFieldPP-            (paraName <<<- ParaName (__ "Use cabal-dev") $ emptyParams)-            (PP.text . show)-            boolParser-            useCabalDev-            (\b a -> a{useCabalDev = b})-            boolEditor-            (\i -> return ())-    ]),-    (__ "Debug", VFDPP emptyParams [-           mkFieldPP-            (paraName <<<- ParaName (__ "Enable usage of Show instances in :print") $ emptyParams)-            (PP.text . show)-            boolParser-            printEvldWithShow-            (\b a -> a{printEvldWithShow = b})-            boolEditor-            debugSetPrintEvldWithShow-         , mkFieldPP-            (paraName <<<- ParaName (__ "Break on any exception thrown") $ emptyParams)-            (PP.text . show)-            boolParser-            breakOnException-            (\b a -> a{breakOnException = b})-            boolEditor-            debugSetBreakOnException-         , mkFieldPP-            (paraName <<<- ParaName (__ "Break on uncaught exceptions and errors") $ emptyParams)-            (PP.text . show)-            boolParser-            breakOnError-            (\b a -> a{breakOnError = b})-            boolEditor-            debugSetBreakOnError-         , mkFieldPP-            (paraName <<<- ParaName (__ "Turn on printing of binding results in GHCi") $ emptyParams)-            (PP.text . show)-            boolParser-            printBindResult-            (\b a -> a{printBindResult = b})-            boolEditor-            debugSetPrintBindResult-    ]),-    (__ "Help", VFDPP emptyParams [-        mkFieldPP-            (paraName <<<- ParaName (__ "Browser") $ emptyParams)-            (PP.text . show)-            stringParser-            browser-            (\b a -> a{browser = b})-            (textEditor (not . T.null) True)-            (\i -> return ())-    ,   mkFieldPP-            (paraName <<<- ParaName (__ "URL for searching documentation") $-                paraSynopsis <<<- ParaSynopsis-                    ("e.g https://www.haskell.org/hoogle/?q= or " <>-                        "Hayoo: http://hayoo.fh-wedel.de/?query=")-                        $ emptyParams)-            (PP.text . show)-            stringParser-            docuSearchURL-            (\b a -> a{docuSearchURL = b})-            (textEditor (not . T.null) True)-            (\i -> return ())-    ])]---- | Editor for enabling a different syntax stylesheet-styleEditor :: Editor (Bool, Text)-styleEditor p n = do-    styleManager <- sourceStyleSchemeManagerNew-    dataDir <- getDataDir-    sourceStyleSchemeManagerAppendSearchPath styleManager $ dataDir </> "data/styles"-    ids          <- sourceStyleSchemeManagerGetSchemeIds styleManager-    let notDarkIds = filter (not . T.isSuffixOf "-dark") ids-    disableEditor (comboSelectionEditor notDarkIds id, p) True (__ "Select a special style?") p n----- | The default preferences-defaultPrefs = Prefs {-        prefsFormat         =   prefsVersion-    ,   prefsSaveTime       =   ""-    ,   showLineNumbers     =   True-    ,   rightMargin         =   (True,100)-    ,   tabWidth            =   4-    ,   wrapLines           =   False-    ,   sourceCandy         =   (False,"candy")-    ,   keymapName          =   "keymap"-    ,   forceLineEnds       =   True-    ,   removeTBlanks       =   True-    ,   textviewFont        =   Nothing-    ,   sourceStyle         =   (True,"leksah")-    ,   foundBackgroundLight      = Color 65535 65535 32768-    ,   matchBackgroundLight      = Color 42064 55923 28520-    ,   contextBackgroundLight    = Color 65535 46529 46529-    ,   breakpointBackgroundLight = Color 64879 51921 28114-    ,   lintBackgroundLight       = Color 60000 65535 60000-    ,   foundBackgroundDark       = Color 30364 29149     0-    ,   matchBackgroundDark       = Color 18021 29927  6384-    ,   contextBackgroundDark     = Color 20000 16000 16000-    ,   breakpointBackgroundDark  = Color 15000  5000  5000-    ,   lintBackgroundDark        = Color     0 15000     0-    ,   textEditorType      =   "GtkSourceView"-    ,   autoLoad            =   False-    ,   logviewFont         =   Nothing-    ,   defaultSize         =   (1024,800)-    ,   browser             =   "firefox"-    ,   sourceDirectories   =   []-    ,   packageBlacklist    =   []-    ,   pathForCategory     =   [   ("EditorCategory",[SplitP LeftP])-                                ,   ("LogCategory",[SplitP RightP, SplitP BottomP])-                                ,   ("ToolCategory",[SplitP RightP, SplitP TopP])-                                ]-    ,   defaultPath         =   [SplitP LeftP]-    ,   categoryForPane     =   [   ("*ClassHierarchy","ToolCategory")-                                ,   ("*Breakpoints","LogCategory")-                                ,   ("*Browser","ToolCategory")-                                ,   ("*Debug","ToolCategory")-                                ,   ("*Errors","ToolCategory")-                                ,   ("*Files","ToolCategory")-                                ,   ("*Flags","ToolCategory")-                                ,   ("*Grep","ToolCategory")-                                ,   ("*HLint","ToolCategory")-                                ,   ("*Doc","ToolCategory")-                                ,   ("*Info","LogCategory")-                                ,   ("*Log","LogCategory")-                                ,   ("*Inspect","LogCategory")-                                ,   ("*Modules","ToolCategory")-                                ,   ("*Out","ToolCategory")-                                ,   ("*Package","EditorCategory")-                                ,   ("*Prefs","EditorCategory")-                                ,   ("*Search","ToolCategory")-                                ,   ("*Trace","LogCategory")-                                ,   ("*Variables","LogCategory")-                                ,   ("*Workspace","LogCategory")]-    ,   collectAtStart      =   True-    ,   unpackDirectory     =   Just ("~" </> configDirName </> "packageSources")-    ,   retrieveURL         =   "http://www.leksah.org"-    ,   retrieveStrategy    =   SP.RetrieveThenBuild-    ,   useCtrlTabFlipping  =   True-    ,   docuSearchURL       =   "https://www.haskell.org/hoogle/?q="-    ,   completeRestricted  =   False-    ,   saveAllBeforeBuild  =   True-    ,   jumpToWarnings      =   True-    ,   useVado             =   False-    ,   useCabalDev         =   False-    ,   backgroundBuild     =   True-    ,   runUnitTests        =   False-    ,   makeMode            =   True-    ,   singleBuildWithoutLinking  = False-    ,   dontInstallLast     =   False-    ,   printEvldWithShow   =   True-    ,   breakOnException    =   True-    ,   breakOnError        =   True-    ,   printBindResult     =   False-    ,   serverPort          =   11111-    ,   serverIP            =   "127.0.0.1"-    ,   endWithLastConn     =   True-    ,   showHiddenFiles     =   False-    }---- --------------------------------------------------------------- * Parsing--- ---------------------------------------------------------------- | Read the preference file-readPrefs :: FilePath -> IO Prefs-readPrefs fn = catch (do-    configDir <- getConfigDir-    readFields fn (flattenFieldDescriptionPPToS (prefsDescription configDir [])) defaultPrefs)-        (\ (e :: SomeException) -> do-            sysMessage Normal (T.pack $ show e)-            return defaultPrefs)--- --------------------------------------------------------------- * Printing--- ---------------------------------------------------------------- | Write the preference file-writePrefs :: FilePath -> Prefs -> IO ()-writePrefs fpath prefs = do-    timeNow         <- liftIO getClockTime-    configDir <- getConfigDir-    let newPrefs    =   prefs {prefsSaveTime = T.pack $ show timeNow, prefsFormat = prefsVersion}-    writeFields fpath newPrefs (flattenFieldDescriptionPPToS (prefsDescription configDir []))--
src/IDE/Pane/SourceBuffer.hs view
@@ -6,6 +6,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE MultiWayIf #-} {-# OPTIONS_GHC -fwarn-unused-imports #-} ----------------------------------------------------------------------------- --@@ -61,7 +62,7 @@ ,   editToCandy ,   editFromCandy ,   editKeystrokeCandy-,   editCandy+,   switchBuffersCandy  ,   updateStyle ,   updateStyle'@@ -79,6 +80,7 @@  ,   selectedText ,   selectedTextOrCurrentLine+,   selectedTextOrCurrentIdentifier ,   insertTextAfterSelection ,   selectedModuleName ,   selectedLocation@@ -108,6 +110,7 @@ import IDE.Core.State import IDE.Utils.GUIUtils import IDE.Utils.FileUtils+import IDE.Utils.DirectoryUtils import IDE.SourceCandy import IDE.SymbolNavigation import IDE.Completion as Completion (complete,cancel)@@ -137,12 +140,12 @@ import IDE.BufferMode import Control.Monad.Trans.Reader (ask) import Control.Monad.IO.Class (MonadIO(..))-import Control.Monad (filterM, void, unless, when, liftM)+import Control.Monad (filterM, void, unless, when, liftM, forM_) import Control.Exception as E (catch, SomeException)  import qualified IDE.Command.Print as Print import Control.Monad.Trans.Class (MonadTrans(..))-import System.Log.Logger (debugM)+import System.Log.Logger (errorM, warningM, debugM) import Data.Text (Text) import qualified Data.Text as T        (length, findIndex, replicate, lines,@@ -158,6 +161,7 @@ -- import Data.Time.Clock.POSIX (getPOSIXTime) import qualified Data.Sequence as Seq import Data.Sequence (ViewR(..), (|>))+import Data.Time.Clock (addUTCTime, diffUTCTime)  --time :: MonadIO m => String -> m a -> m a --time name action = do@@ -193,7 +197,7 @@                     iter    <- getIterAtOffset gtkBuf i                     placeCursor gtkBuf iter                     mark    <- getInsertMark gtkBuf-                    scrollToMark v mark 0.0 (Just (0.3,0.3))+                    scrollToMark v mark 0.0 (Just (1.0,0.3))                     liftIO $ debugM "leksah" "SourceBuffer recoverState done"                 return mbbuf             Nothing -> return Nothing@@ -211,7 +215,7 @@                     iter     <-  getIterAtOffset gtkBuf i                     placeCursor gtkBuf iter                     mark     <-  getInsertMark gtkBuf-                    scrollToMark v mark 0.0 (Just (0.3,0.3))+                    scrollToMark v mark 0.0 (Just (1.0,0.3))                     liftIO $ debugM "leksah" "SourceBuffer recoverState done"                 return (Just buf)             Nothing -> return Nothing@@ -328,7 +332,7 @@                     liftIO $ debugM "lekash" "goToSourceDefinition triggered selectRange"                     selectRange ebuf iter iter2                     liftIO $ debugM "lekash" "goToSourceDefinition triggered scrollToIter"-                    scrollToIter sv iter 0.0 (Just (0.3,0.3))+                    scrollToIter sv iter 0.0 (Just (1.0,0.3))                 return ()         Nothing -> return ()     return mbBuf@@ -491,7 +495,7 @@             lineStart <- backwardToLineStartC iter             createMark sv (logRefType logRef) lineStart $ refDescription logRef             applyTagByName ebuf tagName iter iter2-        when scrollTo . postAsyncIDE $ do+        when scrollTo $ do             liftIO $ debugM "lekash" "markRefInSourceBuf triggered placeCursor"             placeCursor ebuf iter             mark <- getInsertMark ebuf@@ -520,7 +524,7 @@     where buildPane contents mModTime = do             nb      <-  getNotebook panePath             prefs   <-  readIDE prefs-            bs      <-  getCandyState+            let bs = candyState prefs             ct      <-  readIDE candy             (ind,rbn) <- figureOutPaneName bn 0             buildThisPane panePath nb (builder' bs mbfn ind bn rbn ct prefs contents mModTime)@@ -627,6 +631,7 @@                 case mbfn of                     Just fn -> Just (SrcSpan fn lStart cStart lEnd cEnd)                     Nothing -> Nothing+             let tagName = "match"             hasSelection <- hasSelection buffer             m <- liftIO $ readIORef hasMatch@@ -737,11 +742,13 @@     mbPrevCharCat <- getCharacterCategory <$> (backwardCharC sel >>= getChar)     return $ isNothing currentChar || currentChar == Just '\n' || mbStartCharCat /= mbPrevCharCat && (mbStartCharCat == SyntaxCharacter || mbStartCharCat == IdentifierCharacter) +-- | Get an iterator pair (start,end) delimiting the identifier currently under the cursor getIdentifierUnderCursor :: forall editor. TextEditor editor => EditorBuffer editor -> IDEM (EditorIter editor, EditorIter editor) getIdentifierUnderCursor buffer = do     (startSel, endSel) <- getSelectionBounds buffer     getIdentifierUnderCursorFromIter (startSel, endSel) +-- | Get an iterator pair (start,end) delimiting the identifier currently contained inside the provided iterator pair getIdentifierUnderCursorFromIter :: TextEditor editor => (EditorIter editor, EditorIter editor) -> IDEM (EditorIter editor, EditorIter editor) getIdentifierUnderCursorFromIter (startSel, endSel) = do     let isIdent a = isAlphaNum a || a == '\'' || a == '_'@@ -987,14 +994,58 @@             let text' = if removeTBlanks                             then T.unlines $ map (T.dropWhileEnd $ \c -> c == ' ') $ T.lines text                             else text+            alreadyExists <- liftIO $ doesFileExist fn+            mbModTimeBefore <- if alreadyExists+                then liftIO $ Just <$> getModificationTime fn+                else return Nothing             succ <- liftIO $ E.catch (do T.writeFile fn text'; return True)                 (\(e :: SomeException) -> do                     sysMessage Normal . T.pack $ show e                     return False)-            setModified buf (not succ)-            markLabelAsChanged nb ideBuf-            triggerEventIDE_ $ SavedFile fn +            -- Truely horrible hack to work around HFS+ only having 1sec resolution+            -- and ghc ignoring files unless the modifiction time has moved forward.+            -- The limitation means we can do at most 1 reload a second, but+            -- this hack allows us to take an advance of up to 30 reloads (by+            -- moving the modidification time up to 30s into the future).+            modTimeChanged <- liftIO $ case mbModTimeBefore of+                Nothing -> return True+                Just modTime -> do+                    newModTime <- getModificationTime fn+                    let diff = diffUTCTime modTime newModTime+                    if+                        | (newModTime > modTime) -> return True -- All good mode time has moved on+                        | diff < 30 -> do+                             setModificationTimeOnOSX fn (addUTCTime 1 modTime)+                             updatedModTime <- getModificationTime fn+                             return (updatedModTime > modTime)+                        | diff < 32 -> do+                             -- Reached our limit of how far in the future we want to set the modifiction time.+                             -- Using 32 instead of 31 in case NTP or something is adjusting the clock back.+                             warningM "leksah" $ "Modification time for " <> fn+                                <> " was already " <> show (diffUTCTime modTime newModTime)+                                <> " in the future"+                             -- We still want to keep the modification time the same though.+                             -- If it went back the future date ghc has might cause it to+                             -- continue to ignore the file.+                             setModificationTimeOnOSX fn modTime+                             return False+                        | otherwise -> do+                             -- This should never happen unless something else is messing+                             -- with the modification time or the clock.+                             -- If it does happen we will leave the modifiction time alone.+                             errorM "leksah" $ "Modification time for " <> fn+                                <> " was already " <> show (diffUTCTime modTime newModTime)+                                <> " in the future"+                             return True++            -- Only consider the file saved if the modification time changed+            -- otherwise another save is really needed to trigger ghc.+            when modTimeChanged $ do+                setModified buf (not succ)+                markLabelAsChanged nb ideBuf+                triggerEventIDE_ $ SavedFile fn+ fileSave :: Bool -> IDEM Bool fileSave query = inActiveBufContext False $ fileSaveBuffer query @@ -1085,7 +1136,7 @@  fileCloseAllButPackage :: IDEAction fileCloseAllButPackage = do-    mbActivePath    <-  fmap ipdBuildDir <$> readIDE activePack+    mbActivePath    <-  fmap ipdPackageDir <$> readIDE activePack     bufs            <-  allBuffers     case mbActivePath of         Just p -> mapM_ (close' p) bufs@@ -1225,19 +1276,22 @@                 Nothing   -> return ()  editUndo :: IDEAction-editUndo = inActiveBufContext () $ \_ _ buf _ _ -> do+editUndo = inActiveBufContext () $ \_ view buf _ _ -> do     can <- canUndo buf-    when can $ undo buf+    when can $ do+        undo buf+        scrollToCursor view  editRedo :: IDEAction-editRedo = inActiveBufContext () $ \_ _ buf _ _ -> do+editRedo = inActiveBufContext () $ \_ view buf _ _ -> do     can <- canRedo buf     when can $ redo buf+    scrollToCursor view  editDelete :: IDEAction-editDelete = inActiveBufContext ()  $ \_ _ ebuf _ _ ->  do+editDelete = inActiveBufContext ()  $ \_ view ebuf _ _ ->  do     deleteSelection ebuf-    return ()+    scrollToCursor view  editSelectAll :: IDEAction editSelectAll = inActiveBufContext () $ \_ _ ebuf _ _ -> do@@ -1251,9 +1305,10 @@     cutClipboard ebuf clip True  editCopy :: IDEAction-editCopy = inActiveBufContext () $ \_ _ ebuf _ _ -> do+editCopy = inActiveBufContext () $ \_ view ebuf _ _ -> do     clip <- liftIO $ clipboardGet selectionClipboard     copyClipboard ebuf clip+    scrollToCursor view  editPaste :: IDEAction editPaste = inActiveBufContext () $ \_ _ ebuf _ _ -> do@@ -1344,6 +1399,7 @@         triggerEventIDE UpdateRecent         return () +-- | Get the currently selected text or Nothing is no text is selected selectedText :: IDEM (Maybe Text) selectedText = do     candy' <- readIDE candy@@ -1356,6 +1412,7 @@                 return $ Just text             else return Nothing +-- | Get the currently selected text, or, if none, the current line text selectedTextOrCurrentLine :: IDEM (Maybe Text) selectedTextOrCurrentLine = do     candy' <- readIDE candy@@ -1371,6 +1428,21 @@                 return (iStart, iEnd)         Just <$> getCandylessPart candy' ebuf i1 i2 +-- | Get the currently selected text, or, if none, tries to selected the current identifier (the one under the cursor)+selectedTextOrCurrentIdentifier :: IDEM (Maybe Text)+selectedTextOrCurrentIdentifier = do+    st <- selectedText+    case st of+        Just t -> return $ Just t+        Nothing -> do+            candy' <- readIDE candy+            inActiveBufContext Nothing $ \_ _ ebuf currentBuffer _ -> do+                        (l,r)   <- getIdentifierUnderCursor ebuf+                        t <- getCandylessPart candy' ebuf l r+                        return $ if T.null t+                                                then Nothing+                                                else Just t+ selectedLocation :: IDEM (Maybe (Int, Int)) selectedLocation = do     candy'      <- readIDE candy@@ -1433,15 +1505,17 @@  useCandyFor :: MonadIDE m => IDEBuffer -> m Bool useCandyFor aBuffer = do-    use <- liftIDE getCandyState-    return (use && isHaskellMode (mode aBuffer))+    prefs <- readIDE prefs+    return (candyState prefs && isHaskellMode (mode aBuffer)) -editCandy = do-    use <- liftIDE getCandyState+switchBuffersCandy :: IDEAction+switchBuffersCandy = do+    prefs <- readIDE prefs     buffers <- allBuffers-    if use-        then mapM_ (\b -> modeEditToCandy (mode b)-            (modeEditInCommentOrString (mode b))) buffers-        else mapM_ (modeEditFromCandy . mode) buffers+    forM_ buffers $ \b@IDEBuffer{sourceView=sv} -> do+        buf <- getBuffer sv+        if candyState prefs+            then modeTransformToCandy (mode b) (modeEditInCommentOrString (mode b)) buf+            else modeTransformFromCandy (mode b) buf  
src/IDE/Pane/WebKit/Documentation.hs view
@@ -120,7 +120,6 @@             liftIO $ reflectIDE (makeActive docs) ideR             return True -        webView `set` [webViewZoomLevel := 2.0]         cid2 <- webView `on` keyPressEvent $ do             key <- eventKeyName             mod <- eventModifier
src/IDE/Pane/WebKit/Output.hs view
@@ -148,7 +148,7 @@             liftIO $ reflectIDE (makeActive out) ideR             return True -        webView `set` [webViewZoomLevel := 2.0]+--        webView `set` [webViewZoomLevel := 2.0]         cid2 <- on webView keyPressEvent $ do             key <- eventKeyName             mod <- eventModifier
src/IDE/Pane/Workspace.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-} ----------------------------------------------------------------------------- --@@ -15,247 +16,700 @@ -- Portability : -- -- | The pane of the IDE that shows the cabal packages in the workspace---   and their build targets+--   and their components, source dependencies and files -- -----------------------------------------------------------------------------  module IDE.Pane.Workspace (     WorkspaceState(..)-,   IDEWorkspace-,   updateWorkspace-,   getWorkspace-,   showWorkspace+,   WorkspacePane+,   getWorkspacePane+,   showWorkspacePane+,   refreshWorkspacePane+,   rebuildWorkspacePane ) where -import Graphics.UI.Gtk hiding (get)-import Graphics.UI.Gtk.Gdk.EventM+import Prelude hiding (catch)+import Graphics.UI.Gtk+       (treeSelectionSelectIter, treeStoreLookup,+        cellLayoutSetAttributeFunc, treeViewRowActivated, treeStoreClear,+        treeModelGetIterFirst, treeViewLevelIndentation,+        treeViewShowExpanders, treeViewCollapseRow, treeViewExpandRow,+        treeSelectionUnselectAll, cellLayoutPackEnd, cellTextMarkup,+        cellPixbufStockId, scrolledWindowSetShadowType,+        treeSelectionSelectionChanged, treeStoreRemove, treeModelIterNext,+        treeModelGetRow, treeStoreInsert, treeModelIterNthChild,+        treeModelGetPath, TreeIter, treeModelGetIter, TreePath,+        treeSelectionGetSelectedRows, rowActivated, treeStoreGetValue,+        rowExpanded, on, after, focusInEvent, scrolledWindowSetPolicy,+        containerAdd, scrolledWindowNew, treeSelectionSetMode,+        treeViewGetSelection, treeViewSetHeadersVisible, cellText,+        cellLayoutSetAttributes, cellLayoutPackStart, treeViewAppendColumn,+        treeViewColumnSetReorderable, treeViewColumnSetResizable,+        treeViewColumnSetSizing, treeViewColumnSetTitle, treeViewColumnNew,+        cellRendererPixbufNew, cellRendererTextNew, treeViewSetModel,+        treeViewNew, treeStoreNew, castToWidget, TreeStore, TreeView,+        ScrolledWindow, treeViewRowExpanded, treeStoreGetTree, Menu(..),+        MenuItem(..), treeStoreSetValue) import Data.Maybe-import Data.Typeable+       (fromJust, fromMaybe, maybeToList, listToMaybe, isJust)+import Control.Monad (forM, void, when)+import Data.Foldable (forM_)+import Data.Typeable (Typeable) import IDE.Core.State-import IDE.Workspaces-import qualified Data.Map as Map (empty)-import Data.List (sortBy)-import IDE.Pane.Files (refreshFiles)-import Control.Monad (when)+       (catchIDE, window, getIDE, MessageLevel(..), ipdPackageId,+        wsPackages, workspace, readIDE, IDEAction, ideMessage, reflectIDE,+        reifyIDE, IDEM, IDEPackage, ipdSandboxSources)+import IDE.Pane.SourceBuffer (fileNew, goToSourceDefinition')+import IDE.Sandbox+import Control.Applicative ((<$>))+import System.FilePath ((</>), takeFileName, dropFileName)+import Distribution.Package (PackageIdentifier(..))+import System.Directory+       (removeDirectoryRecursive, removeDirectory, createDirectory,+        doesFileExist, removeFile, doesDirectoryExist,+        getDirectoryContents, getPermissions, readable)+import IDE.Core.CTypes+       (Location(..), packageIdentifierToString)+import Graphics.UI.Frame.Panes+       (RecoverablePane(..), PanePath, RecoverablePane, Pane(..))+import Graphics.UI.Frame.ViewFrame (getMainWindow, getNotebook)+import Graphics.UI.Editor.Basics (Connection(..))+import Graphics.UI.Gtk.General.Enums+       (ShadowType(..), PolicyType(..), SelectionMode(..),+        TreeViewColumnSizing(..))+import System.Glib.Attributes (set, AttrOp(..)) import Control.Monad.IO.Class (MonadIO(..))-import IDE.Utils.GUIUtils (treeViewContextMenu, __)+import IDE.Utils.GUIUtils+       (showErrorDialog, showInputDialog, treeViewContextMenu', __,+        showDialogOptions, treeViewToggleRow)+import Control.Exception (SomeException(..), catch)+import Data.Text (Text)+import qualified Data.Text as T+       (isPrefixOf, words, isSuffixOf, unpack, pack)+import Data.Monoid ((<>))+import IDE.Core.Types+       (ipdLib, WorkspaceAction, Workspace(..), wsAllPackages, WorkspaceM,+        runPackage, runWorkspace, PackageAction, PackageM, IDEPackage(..),+        IDE(..), Prefs(..), MonadIDE(..), ipdPackageDir) import System.Glib.Properties (newAttrFromMaybeStringProperty)-import Data.Tree (Tree(..))+import System.FilePath+       (addTrailingPathSeparator, takeDirectory, takeExtension,+       makeRelative, splitDirectories)+import Control.Monad.Reader.Class (MonadReader(..))+import IDE.Workspaces+       (makePackage, workspaceAddPackage', workspaceRemovePackage,+        workspaceActivatePackage, workspaceTry, workspaceTryQuiet,+        packageTry)+import Data.List+       (isSuffixOf, find, stripPrefix, isPrefixOf, sortBy, sort)+import Data.Ord (comparing)+import Data.Char (toUpper, toLower) import System.Log.Logger (debugM)-import qualified Data.Function as F (on)-import System.FilePath (takeDirectory, takeBaseName, takeFileName)-import Data.Text (Text)-import qualified Data.Text as T (pack)+import Data.Tree (Forest, Tree(..))+import Graphics.UI.Gtk.MenuComboToolbar.MenuItem+       (menuItemActivate, menuItemNewWithLabel)+import IDE.Pane.Modules (addModule)+import Graphics.UI.Gtk.Windows.MessageDialog+       (ButtonsType(..), MessageType(..), messageDialogNew)+import Graphics.UI.Gtk.ModelView.CellRenderer+       (CellRendererMode(..), cellMode)+import IDE.Pane.PackageEditor (packageEditText)+import IDE.Utils.GtkBindings (treeViewSetActiveOnSingleClick)+import IDE.Package (packageTest, packageRun, packageClean)+import Control.Monad.Trans.Class (MonadTrans(..)) --- | Workspace pane state--- --- | The data in a row displays a package or an---   executable of that package (in the first case---   the path to the package is also stored)-type WorkspaceRecord = (IDEPackage, Maybe Text)+-- | The data for a single record in the Workspace Pane+data WorkspaceRecord =+    FileRecord FilePath+  | DirRecord FilePath+              Bool -- Whether it is a source directory+  | PackageRecord IDEPackage+  | AddSourcesRecord+  | AddSourceRecord IDEPackage+  | ComponentsRecord+  | ComponentRecord Text+  deriving (Eq) +instance Ord WorkspaceRecord where+    -- | The ordering used for displaying the records+    compare (DirRecord _ _) (FileRecord _) = LT+    compare (FileRecord _) (DirRecord _ _) = GT+    compare (FileRecord p1) (FileRecord p2) = comparing (map toLower) p1 p2+    compare (DirRecord p1 _) (DirRecord p2 _) = comparing (map toLower) p1 p2+    compare (PackageRecord p1) (PackageRecord p2) = comparing (map toLower . ipdPackageDir) p1 p2+    compare (AddSourceRecord p1) (AddSourceRecord p2) = comparing (map toLower . ipdPackageDir) p1 p2+    compare (ComponentRecord t1) (ComponentRecord t2) = comparing (map toLower . T.unpack) t1 t2+    compare _ _ = LT --- | The representation of the workspace pane-data IDEWorkspace   =   IDEWorkspace {-    scrolledView        ::   ScrolledWindow-,   treeViewC           ::   TreeView-,   workspaceStore      ::   TreeStore (Bool, WorkspaceRecord)-,   topBox              ::   VBox-} deriving Typeable -instance Pane IDEWorkspace IDEM+-- | The markup to show for a record+toMarkup :: WorkspaceRecord+         -> IDEPackage+         -> IDEM Text+toMarkup record pkg = do+    mbActivePackage   <- readIDE activePack+    mbActiveComponent <- readIDE activeExe++    return . size $ case record of+     (PackageRecord p) ->+        let active = Just pkg == mbActivePackage+            pkgText = (if active then bold else id)+                          (packageIdentifierToString (ipdPackageId p))+            mbLib   = ipdLib p+            componentText = if active+                                then maybe (if isJust mbLib then "(library)" else "")+                                           (\comp -> "(" <> comp <> ")") mbActiveComponent+                                else ""+            pkgDir = gray . T.pack $ ipdPackageDir p+        in (pkgText <> " " <> componentText <> " " <> pkgDir)+     (FileRecord f) -> T.pack $ takeFileName f+     (DirRecord f _) | ipdPackageDir pkg == f -> "Files"+                     | otherwise -> T.pack $ last (splitDirectories f)+     AddSourcesRecord -> "Source Dependencies"+     (AddSourceRecord p) -> do+        let pkgText = packageIdentifierToString (ipdPackageId p)+            dirText = gray (T.pack (ipdPackageDir p))+        pkgText <> " " <> dirText+     ComponentsRecord -> "Components"+     (ComponentRecord comp) -> do+        let active = Just pkg == mbActivePackage &&+                         (mbActiveComponent == Nothing && comp == "library"+                             ||+                          Just comp == mbActiveComponent)+        (if active then bold else id) comp     where-    primPaneName _  =   __ "Workspace"-    getAddedIndex _ =   0-    getTopWidget    =   castToWidget . topBox-    paneId b        =   "*Workspace"+        bold str = "<b>" <> str <> "</b>"+        italic str = "<i>" <> str <> "</i>"+        gray str = "<span foreground=\"#999999\">" <> str <> "</span>"+        size str = "<span font=\"9\">" <> str <> "</span>" ++-- | The icon to show for a record+toIcon :: WorkspaceRecord -> Maybe Text+toIcon record = case record of+    FileRecord path+        | takeExtension path == ".hs"    -> Just "ide_source"+        | takeExtension path == ".cabal" -> Just "ide_cabal_file"+    DirRecord p isSrc+        | isSrc     -> Just "ide_source_folder"+        | otherwise -> Just "ide_folder"+    PackageRecord _ -> Just "ide_package"+    ComponentsRecord -> Just "ide_component"+    AddSourcesRecord -> Just "ide_source_dependency"+    AddSourceRecord _ -> Just "ide_package"+    _ -> Nothing+++-- | Gets the package to which a node in the tree belongs+iterToPackage :: TreeStore WorkspaceRecord -> TreeIter -> IDEM (Maybe IDEPackage)+iterToPackage store iter = do+    path <- liftIO $ treeModelGetPath store iter+    treePathToPackage store path++-- | Gets the package to which a node in the tree belongs+treePathToPackage :: TreeStore WorkspaceRecord -> TreePath -> IDEM (Maybe IDEPackage)+treePathToPackage store (n:_) = do+    record <- liftIO $ treeStoreGetValue store [n]+    case record of+        (PackageRecord pkg) -> return (Just pkg)+        _                     -> do+            liftIO $ debugM "leksah" "treePathToPackage: Unexpected entry at root forest"+            return Nothing+treePathToPackage _ _ = do+    liftIO $ debugM "leksah" "treePathToPackage is called with empty path"+    return Nothing+++-- | Determines whether the 'WorkspaceRecord' can expand, i.e. whether+-- it should get an expander.+canExpand :: WorkspaceRecord -> IDEPackage -> IDEM Bool+canExpand record pkg = case record of+    (PackageRecord _) -> return True+    (DirRecord fp _)     -> do+        mbWs <- readIDE workspace+        case mbWs of+            Just ws -> not . null <$> (flip runWorkspace ws . flip runPackage pkg $ dirRecords fp)+            Nothing -> return False+    ComponentsRecord    -> return . not . null $ components+    AddSourcesRecord    -> return . not . null $ ipdSandboxSources pkg+    (AddSourceRecord _) -> return True+    _                   -> return False++    where components = maybeToList (ipdLib pkg) ++ ipdExes pkg ++ ipdTests pkg ++ ipdBenchmarks pkg++-- * The Workspace pane++-- | The representation of the Workspace pane+data WorkspacePane        =   WorkspacePane {+    scrolledView    ::   ScrolledWindow+,   treeView        ::   TreeView+,   recordStore     ::   TreeStore WorkspaceRecord+} deriving Typeable++ -- | The additional state used when recovering the pane---   (none, the packages and their targets come from the IDE state)-data WorkspaceState           =   WorkspaceState+--   (none)+data WorkspaceState = WorkspaceState     deriving(Eq,Ord,Read,Show,Typeable) -instance RecoverablePane IDEWorkspace WorkspaceState IDEM where+instance Pane WorkspacePane IDEM where+    primPaneName _  =   __ "Workspace"+    getAddedIndex _ =   0+    getTopWidget    =   castToWidget . scrolledView+    paneId b        =   "*Workspace"++instance RecoverablePane WorkspacePane WorkspaceState IDEM where     saveState p     =   return (Just WorkspaceState)     recoverState pp WorkspaceState =   do         nb      <-  getNotebook pp         buildPane pp nb builder-    buildPane pp nb builder  =   do-        res <- buildThisPane pp nb builder-        when (isJust res) $ updateWorkspace True False-        return res-    builder pp nb windows = reifyIDE $ \ideR -> do-        treeStore   <-  treeStoreNew []+    builder pp nb windows = reifyIDE $ \ ideR -> do+        recordStore   <-  treeStoreNew []         treeView    <-  treeViewNew-        treeViewSetModel treeView treeStore+        treeViewSetModel treeView recordStore -        renderer0    <- cellRendererPixbufNew-        set renderer0 [ newAttrFromMaybeStringProperty "stock-id"  := (Nothing :: Maybe Text) ] -        renderer1   <- cellRendererTextNew-        col1        <- treeViewColumnNew-        treeViewColumnSetTitle col1 (__ "Package")++        col1         <- treeViewColumnNew         treeViewColumnSetSizing col1 TreeViewColumnAutosize         treeViewColumnSetResizable col1 True         treeViewColumnSetReorderable col1 True         treeViewAppendColumn treeView col1-        cellLayoutPackStart col1 renderer0 False-        cellLayoutPackStart col1 renderer1 True-        cellLayoutSetAttributes col1 renderer0 treeStore-            $ \row -> [newAttrFromMaybeStringProperty "stock-id" :=-                        if fst row-                            then Just stockYes-                            else Nothing]-        cellLayoutSetAttributes col1 renderer1 treeStore-            $ \row -> [ cellText := name row ] -        renderer2   <- cellRendererTextNew-        col2        <- treeViewColumnNew-        treeViewColumnSetTitle col2 (__ "File path")-        treeViewColumnSetSizing col2 TreeViewColumnAutosize-        treeViewColumnSetResizable col2 True-        treeViewColumnSetReorderable col2 True-        treeViewAppendColumn treeView col2-        cellLayoutPackStart col2 renderer2 True-        cellLayoutSetAttributes col2 renderer2 treeStore-            $ \row -> [ cellText := T.pack $ file row ] -        treeViewSetHeadersVisible treeView True+        prefs <- reflectIDE (readIDE prefs) ideR+        when (showWorkspaceIcons prefs) $ do+            renderer2    <- cellRendererPixbufNew+            cellLayoutPackStart col1 renderer2 False+            set renderer2 [ newAttrFromMaybeStringProperty "stock-id"  := (Nothing :: Maybe Text) ]+            cellLayoutSetAttributes col1 renderer2 recordStore+                $ \record -> [ newAttrFromMaybeStringProperty "stock-id" := toIcon record]++        renderer1    <- cellRendererTextNew+        cellLayoutPackStart col1 renderer1 True+        cellLayoutSetAttributeFunc col1 renderer1 recordStore $ \iter -> do+            record <- treeModelGetRow recordStore iter+            mbPkg  <- flip reflectIDE ideR $ iterToPackage recordStore iter+            forM_ mbPkg $ \pkg -> do+                -- The cellrenderer is stateful, so it knows which cell this markup will be for (the cell at iter)+                markup <- flip reflectIDE ideR $ toMarkup record pkg+                forM_ mbPkg $ \pkg -> set renderer1 [ cellTextMarkup := Just markup]++        -- treeViewSetActiveOnSingleClick treeView True+        treeViewSetHeadersVisible treeView False         sel <- treeViewGetSelection treeView-        treeSelectionSetMode sel SelectionSingle+        -- treeSelectionSetMode sel SelectionSingle -        sw <- scrolledWindowNew Nothing Nothing-        scrolledWindowSetShadowType sw ShadowIn-        containerAdd sw treeView-        scrolledWindowSetPolicy sw PolicyAutomatic PolicyAutomatic-        box             <-  vBoxNew False 2-        boxPackEnd box sw PackGrow 0-        let workspacePane = IDEWorkspace sw treeView treeStore box-        widgetShowAll box-        cid1 <- treeView `after` focusInEvent $ do-            liftIO $ reflectIDE (makeActive workspacePane) ideR+        scrolledView <- scrolledWindowNew Nothing Nothing+        scrolledWindowSetShadowType scrolledView ShadowIn+        containerAdd scrolledView treeView+        scrolledWindowSetPolicy scrolledView PolicyAutomatic PolicyAutomatic++        let wsPane = WorkspacePane {..}++        cid1 <- after treeView focusInEvent $ do+            liftIO $ reflectIDE (makeActive wsPane) ideR             return True-        (cid2, cid3) <- treeViewContextMenu treeView $ workspaceContextMenu ideR workspacePane-        cid4 <- treeView `on` rowActivated $ workspaceSelect ideR workspacePane-        return (Just workspacePane, map ConnectC [cid1, cid2, cid3, cid4])-      where-        name (_, (_, Just exe)) = exe-        name (_, (pack, Nothing)) = packageIdentifierToString $ ipdPackageId pack-        file (_, (_, Just _)) = ""-        file (_, (pack, _)) = ipdCabalFile pack --- | Get the workspace pane-getWorkspace :: Maybe PanePath -> IDEM IDEWorkspace-getWorkspace Nothing = forceGetPane (Right "*Workspace")-getWorkspace (Just pp)  = forceGetPane (Left pp)+        on treeView rowExpanded $ \iter path -> do+            record <- treeStoreGetValue recordStore path+            mbPkg  <- flip reflectIDE ideR $ iterToPackage recordStore iter+            forM_ mbPkg $ \pkg -> do+                flip reflectIDE ideR $ do+                    workspaceTryQuiet $ do+                        runPackage (refreshPackageTreeFrom recordStore treeView path) pkg --- | Show the workspace pane-showWorkspace :: IDEAction-showWorkspace = do-    l <- getWorkspace Nothing+        on treeView rowActivated $ \path col -> do+            record <- treeStoreGetValue recordStore path+            mbPkg    <- flip reflectIDE ideR $ treePathToPackage recordStore path+            forM_ mbPkg $ \pkg -> do+                expandable <- flip reflectIDE ideR $ canExpand record pkg+                case record of+                        FileRecord f  -> void . flip reflectIDE ideR $+                                             goToSourceDefinition' f (Location "" 1 0 1 0)+                        ComponentRecord name -> flip reflectIDE ideR $ workspaceTryQuiet $+                                                          workspaceActivatePackage pkg (Just name)+                        _ -> when expandable $ do+                                 void $ treeViewToggleRow treeView path++        (cid3, cid4) <- reflectIDE (treeViewContextMenu' treeView recordStore contextMenuItems) ideR+        reflectIDE (refresh wsPane) ideR++        return (Just wsPane, map ConnectC [cid1, cid3, cid4])++-- | Get the Workspace pane+getWorkspacePane :: IDEM WorkspacePane+getWorkspacePane = forceGetPane (Right "*Workspace")+++-- | Show the Workspace pane+showWorkspacePane :: IDEAction+showWorkspacePane = do+    l <- getWorkspacePane     displayPane l False --- | Try to get the current selected record and whether---   it is selected-getSelectionTree ::  TreeView-    -> TreeStore (Bool, WorkspaceRecord)-    -> IO (Maybe (Bool, IDEPackage, Maybe Text))-getSelectionTree treeView treeStore = do-    liftIO $ debugM "leksah" "getSelectionTree"-    treeSelection <- treeViewGetSelection treeView-    rows          <- treeSelectionGetSelectedRows treeSelection-    case rows of-        [path]  ->  do-            val     <-  treeStoreGetValue treeStore path-            case val of-                (active, (p, exe)) -> return $ Just (active, p, exe)-        _       ->  return Nothing +-- | Deletes the Workspace pane and rebuilds it (used when enabling/disabling+-- icons, since it requires extra/fewer cellrenderers)+rebuildWorkspacePane :: IDEAction+rebuildWorkspacePane = do+    mbWsPane <- getPane :: IDEM (Maybe WorkspacePane)+    forM_ mbWsPane closePane+    getOrBuildPane (Right "*Workspace") :: IDEM (Maybe WorkspacePane)+    return () --- | Construct the context menu for the pane-workspaceContextMenu :: IDERef-                     -> IDEWorkspace-                     -> Menu-                     -> IO ()-workspaceContextMenu ideR workspacePane theMenu = do-    item1 <- menuItemNewWithLabel (__ "Activate Package")-    item2 <- menuItemNewWithLabel (__ "Add Package")-    item3 <- menuItemNewWithLabel (__ "Remove Package")-    item1 `on` menuItemActivate $ do-        sel <- getSelectionTree (treeViewC workspacePane)-                                (workspaceStore workspacePane)-        case sel of-            Just (_, ideP,mbExe) -> reflectIDE (workspaceTry $ workspaceActivatePackage ideP mbExe) ideR-            otherwise     -> return ()-    item2 `on` menuItemActivate $ reflectIDE (workspaceTry workspaceAddPackage) ideR-    item3 `on` menuItemActivate $ do-        sel <- getSelectionTree (treeViewC workspacePane)-                                (workspaceStore workspacePane)-        case sel of-            Just (_,ideP,_) -> reflectIDE (workspaceTry $ workspaceRemovePackage ideP) ideR-            otherwise     -> return ()-    menuShellAppend theMenu item1-    menuShellAppend theMenu item2-    menuShellAppend theMenu item3 +-- | Searches the workspace packages if it is part of any of them+fileGetPackage :: FilePath -> WorkspaceM (Maybe IDEPackage)+fileGetPackage path = do+    packages <- wsAllPackages <$> ask+    let dirs     = [p | p <- packages, takeDirectory (ipdCabalFile p) `isPrefixOf` path]+    return (listToMaybe dirs) --- | Try to activate the package pointed to by the given 'TreePath'---   by modifying the given IDE state-workspaceSelect :: IDERef-                -> IDEWorkspace-                -> TreePath-                -> TreeViewColumn-                -> IO ()-workspaceSelect ideR workspacePane path _ = do-    liftIO $ debugM "leksah" "workspaceSelect"-    (_,(ideP,mbExe)) <- treeStoreGetValue (workspaceStore workspacePane) path-    reflectIDE (workspaceTry $ workspaceActivatePackage ideP mbExe) ideR  --- | Repopulates the workspace pane with the current packages---   (if the pane is open)-updateWorkspace :: Bool -- ^ Show the pane if it is open and a workspace is loaded-                -> Bool -- ^ Empty the 'bufferProjCache'-                -> IDEAction-updateWorkspace showPane updateFileCache = do-    liftIO $ debugM "leksah" "updateWorkspace"-    mbWs <- readIDE workspace-    when updateFileCache $ modifyIDE_ (\ide -> ide{bufferProjCache = Map.empty})-    mbMod <- getPane-    case mbWs of-        Nothing -> do-            case mbMod of-                Nothing -> return ()-                Just (p :: IDEWorkspace) -> do-                    liftIO $ treeStoreClear (workspaceStore p)-                    when showPane $ displayPane p False-            refreshFiles-        Just ws -> do-            case mbMod of-                Nothing -> return ()-                Just (p :: IDEWorkspace) -> do-                    liftIO $ do-                        treeStoreClear (workspaceStore p)-                        treeStoreInsertForest (workspaceStore p) [] 0 (buildForest ws)-                    when showPane $ displayPane p False-            refreshFiles+-- * Actions for refreshing the Workspace pane++++-- | Refreshes the Workspace pane, lists all packages and synchronizes the expanded+-- nodes with the file system and workspace+refreshWorkspacePane :: IDEAction+refreshWorkspacePane = do+    liftIO $ debugM "leksah" "refreshWorkspacePane"+    workspace <- getWorkspacePane+    refresh workspace++-- | Needed when building the pane, since getWorkspacePane does not+-- work before the building is finished+refresh :: WorkspacePane -> IDEAction+refresh pane = do+    let store = recordStore pane+    let view  = treeView pane++    workspaceTryQuiet $ do+        packages <- sort . wsPackages <$> ask+        setChildren Nothing store view [] (map PackageRecord packages)+++-- | Mutates the 'TreeStore' with the given TreePath as root to attach new+-- entries to. Walks the directory tree recursively when refreshing directories.+refreshPackageTreeFrom :: TreeStore WorkspaceRecord -> TreeView -> TreePath -> PackageAction+refreshPackageTreeFrom store view path = do+    record     <- liftIO $ treeStoreGetValue store path+    Just pkg   <- liftIDE $ treePathToPackage store path+    expandable <- liftIDE $ canExpand record pkg++    kids     <- children record+    lift $ setChildren (Just pkg) store view path kids++-- | Returns the children of the 'WorkspaceRecord'.+children :: WorkspaceRecord -> PackageM [WorkspaceRecord]+children record = case record of+    DirRecord dir _     -> dirRecords dir+    ComponentsRecord    -> componentsRecords+    AddSourcesRecord    -> addSourcesRecords+    AddSourceRecord pkg -> return []+    PackageRecord pkg   -> do+        p <- ask+        return [ ComponentsRecord+               , AddSourcesRecord+               , DirRecord (ipdPackageDir p) False]+    _                   -> return []+++-- | Gets the direct children, the add source dependencies+addSourcesRecords :: PackageM [WorkspaceRecord]+addSourcesRecords = do+    pkg <- ask+    return $ sort $ map AddSourceRecord (ipdSandboxSources pkg)+++-- | Returns the contents at the given 'FilePath' as 'WorkspaceRecord's.+-- Runs in the PackageM monad to determine if directories are+-- source directories (as specified in the cabal file)+dirRecords :: FilePath -> PackageM [WorkspaceRecord]+dirRecords dir = do+   prefs    <- readIDE prefs+   contents <- liftIO $ getDirectoryContents dir+                            `catch` \(e :: IOError) -> return []+   let filtered = if showHiddenFiles prefs+                      then filter (`notElem` [".", ".."]) contents+                      else filter ((/= '.') . head) contents+   records <- forM filtered $ \f -> do+                  let full = dir </> f+                  isDir <- liftIO $ doesDirectoryExist full+                  if isDir+                      then do+                          -- find out if it is a source directory of the project+                          pkgDir <- (addTrailingPathSeparator . takeDirectory . ipdCabalFile) <$> ask+                          case stripPrefix pkgDir full of+                              Just relativeToPackage -> do+                                  srcDirs <- ipdSrcDirs <$> ask+                                  return $ DirRecord full (relativeToPackage `elem` srcDirs)+                              Nothing -> do+                                  -- It's not a descendant of the package directory (e.g. in a source dependency)+                                  return $ DirRecord full False+                      else return $ FileRecord full+   return (sort records)+++-- | Get the components for a specific package+componentsRecords :: PackageM [WorkspaceRecord]+componentsRecords = do+    package         <- ask+    mbActivePackage <- readIDE activePack+    activeComponent <- readIDE activeExe++    return $ sort $ map (\comp -> ComponentRecord comp) (components package)+     where-        -- | Given a workspace, constructs the forest of-        --   packages and their targets-        buildForest ws =-            let sorted = sortBy (compare `F.on` ipdPackageId) $ wsPackages ws-            in  map (buildPackageTree ws) sorted+        components package = maybeToList (ipdLib package)+                          ++ ipdExes package+                          ++ ipdTests package+                          ++ ipdBenchmarks package -        -- | Given an ide package, constructs the tree with the-        --   package as root node, and its targets as children-        buildPackageTree ws ideP =-            let isActive = Just (ipdCabalFile ideP) == wsActivePackFile ws-                sandboxChildren = map (\pack -> Node (False, (pack, Nothing)) [])-                                      (ipdSandboxSources ideP)-                targetsChildren = map (\test -> Node (-                                           Just (ipdCabalFile ideP) == wsActivePackFile ws &&-                                           Just test == wsActiveExe ws, (ideP, Just test)) [])-                                      (ipdExes ideP ++ ipdTests ideP ++ ipdBenchmarks ideP)-            in  Node (isActive, (ideP, Nothing))-                     (sandboxChildren ++ targetsChildren)++-- | Recursively sets the children of the given 'TreePath' to the provided tree of 'WorkspaceRecord's. If a record+-- is already present, it is kept in the same (expanded) state.+-- If a the parent record is not expanded just makes sure at least one of+-- the chldren is added.+setChildren :: Maybe IDEPackage -> TreeStore WorkspaceRecord -> TreeView -> TreePath -> [WorkspaceRecord] -> WorkspaceAction+setChildren _ store _ [] [] = liftIO $ treeStoreClear store+setChildren mbPkg store view parentPath kids = do+    -- We only need to get all the children right when they are visible+    expanded <- if null parentPath+                    then return True+                    else liftIO $ treeViewRowExpanded view parentPath++    let kidsToAdd = (if expanded+                            then id+                            else take 1) kids++    forM_ (zip [0..] kidsToAdd) $ \(n, record) -> do+      liftIO $ do+        mbParentIter <- treeModelGetIter store parentPath+        mbChildIter <- treeModelIterNthChild store mbParentIter n+        let compare rec1 rec2 = case (rec1, rec2) of+                (PackageRecord p1, PackageRecord p2) -> ipdCabalFile p1 == ipdCabalFile p2+                _ -> rec1 == rec2+        findResult <- searchToRight compare record store mbChildIter+        case (mbChildIter, findResult) of+            (_, WhereExpected iter) -> do -- it's already there+                path <- treeModelGetPath store iter+                treeStoreSetValue store path record+            (Just iter, Found _) -> do -- it's already there at a later sibling+                path <- treeModelGetPath store iter+                removeUntil record store path+            _ -> do+                treeStoreInsert store parentPath n record++      let pkg = case record of+                        PackageRecord p -> p+                        _               -> fromJust mbPkg+      -- Only update the grand kids if they are visible+      when expanded $ do+          grandKids <- (`runPackage` pkg) $ children record+          setChildren (Just pkg) store view (parentPath ++ [n]) grandKids++    liftIO $ if null kids+        then treeStoreRemoveChildren store parentPath+        else when expanded . void $ removeRemaining store (parentPath++[length kids])+++-- * Context menu++contextMenuItems :: WorkspaceRecord -> TreePath -> TreeStore WorkspaceRecord -> IDEM [[(Text, IDEAction)]]+contextMenuItems record path store = do+    case record of+        (FileRecord fp) -> do+            let onDeleteFile = flip catchIDE (\(e :: SomeException) -> print e) $ reifyIDE $ \ideRef -> do+                    showDialogOptions+                        ("Are you sure you want to delete " <> T.pack (takeFileName fp) <> "?")+                        MessageQuestion+                        [ ("Delete File", removeFile fp >> reflectIDE refreshWorkspacePane ideRef)+                        , ("Cancel", return ())+                        ]+                        (Just 0)+            return [[("Open File...", void $ goToSourceDefinition' fp (Location "" 1 0 1 0))]+                   ,[("Delete File...", onDeleteFile)]]++        DirRecord fp _ -> do++            let onNewModule = flip catchIDE (\(e :: SomeException) -> print e) $ do+                    mbPkg <- treePathToPackage store path+                    forM_ mbPkg $ \pkg -> do+                        mbWs <- readIDE workspace+                        forM_ mbWs $ \ws -> do+                            mbModulePath <- flip runWorkspace ws $ runPackage (dirToModulePath fp) pkg+                            let modulePrefix = fromMaybe [] mbModulePath+                            packageTry $ addModule modulePrefix+                            refreshWorkspacePane++            let onNewTextFile = flip catchIDE (\(e :: SomeException) -> print e) $ reifyIDE $ \ideRef -> do+                    mbText <- showInputDialog "File name:" ""+                    case mbText of+                        Just t  -> do+                            let path = fp </> T.unpack t+                            exists <- doesFileExist path+                            if exists+                                then showErrorDialog "File already exists"+                                else do+                                    writeFile path ""+                                    void $ reflectIDE (refreshWorkspacePane >> goToSourceDefinition' path (Location "" 1 0 1 0)) ideRef+                        Nothing -> return ()++            let onNewDir = flip catchIDE (\(e :: SomeException) -> print e) $ reifyIDE $ \ideRef -> do+                    mbText <- showInputDialog "Directory name:" ""+                    case mbText of+                        Just t  -> do+                            let path = fp </> T.unpack t+                            exists <- doesDirectoryExist path+                            if exists+                                then showErrorDialog "Directory already exists"+                                else do+                                    createDirectory path+                                    void $ reflectIDE refreshWorkspacePane ideRef+                        Nothing -> return ()++            let onDeleteDir = flip catchIDE (\(e :: SomeException) -> print e) $ reifyIDE $ \ideRef -> do+                    showDialogOptions+                        ("Are you sure you want to delete " <> T.pack (takeFileName fp) <> "?")+                        MessageQuestion+                        [ ("Delete directory", removeDirectoryRecursive fp >> reflectIDE refreshWorkspacePane ideRef)+                        , ("Cancel", return ())+                        ]+                        (Just 0)++            return [ [ ("New Module...", onNewModule)+                     , ("New Text File...", onNewTextFile)+                     , ("New Directory...", onNewDir)+                     ]+                   , [ ("Delete Directory...", onDeleteDir)+                     ]+                   ]++        PackageRecord p -> do++            let onSetActive = workspaceTryQuiet $ workspaceActivatePackage p Nothing+                onAddModule = workspaceTryQuiet $ runPackage (addModule []) p+                onOpenCabalFile = workspaceTryQuiet $ runPackage packageEditText p+                onRemoveFromWs = workspaceTryQuiet $ do+                    workspaceRemovePackage p+                    liftIDE refreshWorkspacePane++            return [ [ ("New Module...", onAddModule)+                     , ("Set As Active Package", onSetActive)++                     ]+                   , [ ("Build", workspaceTryQuiet $ runPackage makePackage p)+                     , ("Run", workspaceTryQuiet $ runPackage packageRun p)+                     , ("Test", workspaceTryQuiet $ runPackage packageTest p)+                     , ("Clean", workspaceTryQuiet $ runPackage packageClean p)+                     , ("Open Package File", onOpenCabalFile)+                     ]+                   , [+                     ("Remove From Workspace", onRemoveFromWs)+                     ]+                   ]++        ComponentRecord comp -> do+            Just pkg <- treePathToPackage store path+            let onSetActive = workspaceTryQuiet $+                                  workspaceActivatePackage pkg (Just comp)+            return [[ ("Activate component", onSetActive) ]]++        AddSourcesRecord -> do+            Just pkg <- treePathToPackage store path+            let onAddSource snapshot = workspaceTryQuiet $ flip runPackage pkg (sandboxAddSource snapshot)+            return [ [ ("Add Source Dependency...", onAddSource False >> refreshWorkspacePane)+                     , ("Add Source Dependency Snapshot...", onAddSource True >> refreshWorkspacePane)+                     ]+                   ]+++        AddSourceRecord p -> do+            Just pkg <- treePathToPackage store path+            let onRemoveSourceDependency  = do+                    workspaceTryQuiet $ flip runPackage pkg (sandboxDeleteSource (ipdPackageDir p))+                onAddSourceDependencyToWs = workspaceTryQuiet . void $+                    workspaceAddPackage' (ipdCabalFile p)++            return [ [ ("Add Package To Workspace", onAddSourceDependencyToWs >> refreshWorkspacePane)+                     ]+                   , [ ("Delete Source Dependency", onRemoveSourceDependency >> refreshWorkspacePane)+                     ]+                   ]+        _ -> return []+++-- | Searches the source folders to determine what the corresponding+--   module path is+dirToModulePath :: FilePath -> PackageM (Maybe [Text])+dirToModulePath fp = do+    pkgDir <- ipdPackageDir <$> ask+    srcDirs <- map (pkgDir <>) . ipdSrcDirs <$> ask+    return $ do+        srcDir <- find (`isPrefixOf` fp) srcDirs+        let suffix = if srcDir == fp then "" else makeRelative srcDir fp+        let dirs   = map (T.pack . capitalize) (splitDirectories suffix)+        return dirs+    where+        capitalize (x:xs) = toUpper x : xs+        capitalize [] = []+++-- * Utility functions for operating on 'TreeStore'++++leaf :: a -> Tree a+leaf x = Node x []++treeStoreRemoveChildren :: TreeStore a -> TreePath -> IO ()+treeStoreRemoveChildren store path = do+    Node record children <- treeStoreGetTree store path+    forM_ (zip [0..] children) $ \_ -> do+        treeStoreRemove store (path ++ [0]) -- this works because mutation ...++data FindResult = WhereExpected TreeIter | Found TreeIter | NotFound++-- | Tries to find the given value in the 'TreeStore'. Only looks at the given 'TreeIter' and its+-- sibling nodes to the right.+-- Returns @WhereExpected iter@ if the records is found at the provided 'TreeIter'+-- Returns @Found iter@ if the record is found at a sibling iter+-- Returns @NotFound@ otherwise+searchToRight :: (a -> a -> Bool) -> a -> TreeStore a -> Maybe TreeIter -> IO FindResult+searchToRight compare _ _ Nothing = return NotFound+searchToRight compare a store (Just iter) = do+    row <- treeModelGetRow store iter+    if compare row a+        then return $ WhereExpected iter+        else treeModelIterNext store iter >>= find'+  where+    find' :: Maybe TreeIter -> IO FindResult+    find' Nothing = return NotFound+    find' (Just iter) = do+        row <- treeModelGetRow store iter+        if compare row a+            then return $ Found iter+            else treeModelIterNext store iter >>= find'+++-- | Starting at the node at the given 'TreePath', removes all sibling nodes to the right+--   until the given value is found.+removeUntil :: Eq a => a -> TreeStore a -> TreePath -> IO ()+removeUntil a store path = do+    row <- treeStoreGetValue store path+    when (row /= a) $ do+        found <- treeStoreRemove store path+        when found $ removeUntil a store path+++-- | Starting at the node at the given 'TreePath', removes all sibling nodes to the right+removeRemaining :: TreeStore a -> TreePath -> IO ()+removeRemaining store path = do+    found <- treeStoreRemove store path+    when found $ removeRemaining store path
src/IDE/PaneGroups.hs view
@@ -43,7 +43,7 @@ import IDE.Pane.Breakpoints (IDEBreakpoints(..)) import IDE.Pane.Variables (IDEVariables(..)) import IDE.Pane.Trace (IDETrace(..))-import IDE.Pane.Workspace (IDEWorkspace(..))+import IDE.Pane.Workspace (WorkspacePane(..)) import Control.Monad.IO.Class (MonadIO(..)) import IDE.Pane.WebKit.Output (IDEOutput(..)) @@ -88,7 +88,7 @@     getOrBuildBrowserPanes upperP lowerP topP = do         moveOrBuildPane upperP :: IDEM (Maybe IDEModules)         moveOrBuildPane lowerP :: IDEM (Maybe IDEInfo)-        moveOrBuildPane topP :: IDEM (Maybe IDEWorkspace)+        moveOrBuildPane topP :: IDEM (Maybe WorkspacePane)         return ()  setSensitivityDebugger :: Bool -> IDEAction
+ src/IDE/Preferences.hs view
@@ -0,0 +1,965 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-}+-----------------------------------------------------------------------------+--+-- Module      :  IDE.Preferences+-- Copyright   :  2007-2014 Juergen Nicklisch-Franken, Hamish Mackenzie+-- License     :  GPL+--+-- Maintainer  :  maintainer@leksah.org+-- Stability   :  provisional+-- Portability :  Definition of the Preferences dialog+--+-- |+--+-----------------------------------------------------------------------------+++module IDE.Preferences (+  runPreferencesDialog+, applyInterfaceTheme+, readPrefs+, writePrefs+, defaultPrefs+) where++import Graphics.UI.Gtk+import Graphics.UI.Gtk.General.Settings+import qualified Text.PrettyPrint.HughesPJ as PP+import Distribution.Package+import Data.IORef+import Data.Typeable++import Control.Event+import Graphics.UI.Editor.Basics+import IDE.Core.State+import Graphics.UI.Editor.Simple+import Graphics.UI.Editor.Composite+import Graphics.UI.Editor.Parameters+import Graphics.UI.Editor.MakeEditor hiding (parameters)+import Graphics.UI.Editor.DescriptionPP+import Text.PrinterParser hiding (fieldParser,parameters)+import IDE.TextEditor+import IDE.Pane.SourceBuffer+import IDE.Pane.Log+import IDE.Pane.Info (setInfoStyle)+import IDE.Utils.FileUtils+import IDE.Utils.GUIUtils+import IDE.Pane.Workspace+import IDE.Debug+    (debugSetPrintBindResult,+     debugSetBreakOnError,+     debugSetBreakOnException,+     debugSetPrintEvldWithShow)+import Graphics.UI.Gtk.SourceView+       (sourceStyleSchemeManagerAppendSearchPath,+        sourceStyleSchemeManagerGetSchemeIds, sourceStyleSchemeManagerNew)+import System.Time (getClockTime)+import qualified IDE.StrippedPrefs as SP+import Control.Exception(SomeException,catch)+import Prelude hiding(catch)+import Data.List (isSuffixOf, sortBy)+import Data.Maybe (mapMaybe, catMaybes, fromMaybe, isJust)+import Graphics.UI.Gtk.Windows.MessageDialog+       (ButtonsType(..), MessageType(..))+import System.Glib.Attributes (set)+import Graphics.UI.Gtk.General.Enums+       (ButtonBoxStyle(..), WindowPosition(..))+import Control.Monad.IO.Class (MonadIO(..))+import Control.Monad (void, when)+import System.FilePath ((</>))+import Data.Text (Text)+import qualified Data.Text as T (isSuffixOf, unpack, pack, null)+import Data.Monoid ((<>))+import Control.Applicative ((<$>))+import Distribution.Text (display, simpleParse)+import Data.Foldable (forM_)+import IDE.Pane.Errors (fillErrorList)+import GHC.IO (evaluate)+import IDE.Metainfo.Provider (getAllPackageIds)+++-- | This needs to be incremented when the preferences format changes+prefsVersion :: Int+prefsVersion = 7++runPreferencesDialog :: IDEAction+runPreferencesDialog = do+  packageInfos <- getAllPackageIds+  initialPrefs <- readIDE prefs+  parent <- getMainWindow+  reifyIDE $ \ideR -> do+    dialog <-   dialogNew+    set dialog [ windowTransientFor := parent+            , windowTitle := __ "Preferences" ]+    windowSetDefaultSize dialog 800 500++    configDir    <- getConfigDir+    (widget, inj, ext, notifier) <- buildEditor (extractFieldDescription $ prefsDescription configDir packageInfos) initialPrefs++    bb      <-  hButtonBoxNew+    boxSetSpacing bb 6+    buttonBoxSetLayout bb ButtonboxSpread+    load    <-  buttonNewWithLabel (__ "Load")+    save    <-  buttonNewWithLabel (__ "Save")+    preview <-  buttonNewWithLabel (__ "Preview")+    cancel  <-  buttonNewFromStock "gtk-cancel"+    apply      <-  buttonNewFromStock "gtk-apply"+    forM_ [preview, cancel, apply] $ \but ->+        boxPackEnd bb but PackNatural 0++++    upper <-   dialogGetContentArea dialog+    boxPackStart (castToBox upper) widget PackGrow 0+    errorLabel <-  labelNew (Nothing :: Maybe Text)+    boxPackStart (castToBox upper) errorLabel PackNatural 0+    lower <-   dialogGetActionArea dialog+    boxPackEnd (castToBox lower) bb PackNatural 5++    -- Keep an IO ref to the last applied preferences+    -- so it can be restored+    lastAppliedPrefsRef <- liftIO $ newIORef initialPrefs+    let flatPrefsDesc = flattenFieldDescriptionPP (prefsDescription configDir packageInfos)+    let applyPrefs newPrefs = do+            lastAppliedPrefs <- readIORef lastAppliedPrefsRef+            reflectIDE (modifyIDE_ (\ide -> ide{prefs = newPrefs})) ideR+            mapM_ (\f -> reflectIDE (applicator f newPrefs lastAppliedPrefs) ideR) flatPrefsDesc+            writeIORef lastAppliedPrefsRef newPrefs+++    on preview buttonActivated $ do+            mbNewPrefs <- extract initialPrefs [ext]+            forM_ mbNewPrefs applyPrefs+++    on apply buttonActivated $ do+        mbNewPrefs <- extract initialPrefs [ext]+        forM_ mbNewPrefs $ \newPrefs -> do+            applyPrefs newPrefs++            -- save preferences to disk+            fp   <- getConfigFilePathForSave standardPreferencesFilename+            writePrefs fp newPrefs+            fp2  <-  getConfigFilePathForSave strippedPreferencesFilename+            SP.writeStrippedPrefs fp2+                SP.Prefs {SP.sourceDirectories = sourceDirectories newPrefs,+                           SP.unpackDirectory   = unpackDirectory newPrefs,+                           SP.retrieveURL       = retrieveURL newPrefs,+                           SP.retrieveStrategy  = retrieveStrategy newPrefs,+                           SP.serverPort        = serverPort newPrefs,+                           SP.endWithLastConn   = endWithLastConn newPrefs}++        dialogResponse dialog ResponseOk++    let onClose = do+            mbP <- extract initialPrefs [ext]+            let hasChanged = case mbP of+                                    Nothing -> False+                                    Just p -> p{prefsFormat = 0, prefsSaveTime = ""} /=+                                              initialPrefs{prefsFormat = 0, prefsSaveTime = ""}+            when hasChanged (applyPrefs initialPrefs)+            dialogResponse dialog ResponseCancel++    on cancel buttonActivated onClose+    on dialog response $ \resp -> do+        case resp of+            ResponseDeleteEvent -> onClose+            _ -> return ()++    registerEvent notifier MayHaveChanged (\ e -> do+        mbP <- extract initialPrefs [ext]+        let hasChanged = case mbP of+                                Nothing -> False+                                Just p -> p{prefsFormat = 0, prefsSaveTime = ""} /=+                                          initialPrefs{prefsFormat = 0, prefsSaveTime = ""}+        when (isJust mbP) $ labelSetMarkup errorLabel ("" :: Text)+        return (e{gtkReturn=False}))++    registerEvent notifier ValidationError $ \e -> do+        labelSetMarkup errorLabel $ "<span foreground=\"red\" size=\"x-large\">The following fields have invalid values: "+            <> eventText e <> "</span>"+        widgetSetSensitive apply False+        return e+++    set apply [widgetCanDefault := True]+    widgetGrabDefault apply+    widgetShowAll dialog+    resp  <- dialogRun dialog+    widgetDestroy dialog+    return ()+++-- | Represents the Preferences dialog+data PreferencesDialog = PreferencesDialog {+    editorsBox ::   VBox+} deriving Typeable+++-- ------------------------------------------------------------+-- * Dialog definition+-- ------------------------------------------------------------++-- | Description of the preference options+prefsDescription :: FilePath -> [PackageIdentifier] -> FieldDescriptionPP Prefs IDEM+prefsDescription configDir packages = NFDPP [+    (__ "Editor", VFDPP emptyParams [+        mkFieldPP+            (paraName <<<- ParaName (__ "Version number of preferences file format")+                $ paraSynopsis <<<- ParaSynopsis (__ "Integer")+                    $ paraShowLabel <<<- ParaShowLabel False $ emptyParams)+            (PP.text . show)+            intParser+            prefsFormat+            (\ b a -> a{prefsFormat = b})+            (noEditor 0)+            (\b -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Time of last storage")+                $ paraShowLabel <<<- ParaShowLabel False $ emptyParams)+            (PP.text . show)+            stringParser+            prefsSaveTime+            (\ b a -> a{prefsSaveTime = b})+            (noEditor "")+            (\b -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Show line numbers")+                $ paraSynopsis <<<- ParaSynopsis (__ "(True/False)")+                    $ emptyParams)+            (PP.text . show)+            boolParser+            showLineNumbers+            (\ b a -> a{showLineNumbers = b})+            boolEditor+            (\b -> do+                buffers <- allBuffers+                mapM_ (\(IDEBuffer {sourceView = sv}) -> setShowLineNumbers sv b) buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "TextView Font") $ emptyParams)+            (\a -> PP.text (case a of Nothing -> show ""; Just s -> show s))+            (do str <- stringParser+                return (if T.null str then Nothing else Just str))+            textviewFont+            (\ b a -> a{textviewFont = b})+            fontEditor+            (\mbs -> do+                buffers <- allBuffers+                mapM_ (\(IDEBuffer {sourceView = sv}) -> setFont sv mbs) buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Right margin")+                $ paraSynopsis <<<- ParaSynopsis (__ "Size or 0 for no right margin")+                    $ paraShadow <<<- ParaShadow ShadowIn $ emptyParams)+            (PP.text . show)+            readParser+            rightMargin+            (\b a -> a{rightMargin = b})+            (disableEditor (intEditor (1.0, 200.0, 5.0), paraName <<<- ParaName (__ "Position")+                    $ emptyParams)+                    True (__ "Show it ?"))+            (\b -> do+                buffers <- allBuffers+                mapM_ (\(IDEBuffer {sourceView = sv}) -> setRightMargin sv+                                (case b of+                                    (True,v) -> Just v+                                    (False,_) -> Nothing)) buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Tab width") $ emptyParams)+            (PP.text . show)+            intParser+            tabWidth+            (\b a -> a{tabWidth = b})+            (intEditor (1.0, 20.0, 1.0))+            (\i -> do+                buffers <- allBuffers+                mapM_ (\(IDEBuffer {sourceView = sv}) -> setIndentWidth sv i) buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Wrap lines") $ emptyParams)+            (PP.text . show)+            boolParser+            wrapLines+            (\b a -> a{wrapLines = b})+            boolEditor+            (\b -> do+                buffers <- allBuffers+                mapM_ (\(IDEBuffer {sourceView = sv}) -> setWrapMode sv b) buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Use standard line ends even on windows") $ emptyParams)+            (PP.text . show)+            boolParser+            forceLineEnds+            (\b a -> a{forceLineEnds = b})+            boolEditor+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Remove trailing blanks when saving a file") $ emptyParams)+            (PP.text . show)+            boolParser+            removeTBlanks+            (\b a -> a{removeTBlanks = b})+            boolEditor+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Source candy")+                $ paraSynopsis <<<- ParaSynopsis+                    (__ "Empty for do not use or the name of a candy file in a config dir")+                    $ paraShadow <<<- ParaShadow ShadowIn $ emptyParams)+            (PP.text . show)+            readParser+            sourceCandy (\b a -> a{sourceCandy = b})+            (disableEditor (textEditor (not . T.null) True,+                paraName <<<- ParaName (__ "Candy specification")+                                    $ emptyParams)+                    True (__ "Use it ?"))+            (\_ -> switchBuffersCandy)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Editor Style") $ emptyParams)+            (\a -> PP.text (case a of (False,_) -> show ""; (True, s) -> show s))+            (do str <- stringParser+                return (if T.null str then (False, __ "classic") else (True,str)))+            sourceStyle+            (\b a -> a{sourceStyle = b})+            styleEditor+            (\mbs -> do+                setInfoStyle+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Found Text Background") $ emptyParams)+            (PP.text . show)+            colorParser+            foundBackgroundLight+            (\ b a -> a{foundBackgroundLight = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Selection Match Text Background") $ emptyParams)+            (PP.text . show)+            colorParser+            matchBackgroundLight+            (\ b a -> a{matchBackgroundLight = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Execution Context Text Background") $ emptyParams)+            (PP.text . show)+            colorParser+            contextBackgroundLight+            (\ b a -> a{contextBackgroundLight = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Breakpoint Text Background") $ emptyParams)+            (PP.text . show)+            colorParser+            breakpointBackgroundLight+            (\ b a -> a{breakpointBackgroundLight = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Lint Text Background") $ emptyParams)+            (PP.text . show)+            colorParser+            lintBackgroundLight+            (\ b a -> a{lintBackgroundLight = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Found Text Dark Background") $ emptyParams)+            (PP.text . show)+            colorParser+            foundBackgroundDark+            (\ b a -> a{foundBackgroundDark = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Selection Match Text Dark Background") $ emptyParams)+            (PP.text . show)+            colorParser+            matchBackgroundDark+            (\ b a -> a{matchBackgroundDark = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Execution Context Text Dark Background") $ emptyParams)+            (PP.text . show)+            colorParser+            contextBackgroundDark+            (\ b a -> a{contextBackgroundDark = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Breakpoint Text Dark Background") $ emptyParams)+            (PP.text . show)+            colorParser+            breakpointBackgroundDark+            (\ b a -> a{breakpointBackgroundDark = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Lint Text Dark Background") $ emptyParams)+            (PP.text . show)+            colorParser+            lintBackgroundDark+            (\ b a -> a{lintBackgroundDark = b})+            colorEditor+            (\c -> do+                buffers <- allBuffers+                mapM_ updateStyle' buffers)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Automatically load modified files modified outside of Leksah") $ emptyParams)+            (PP.text . show)+            boolParser+            autoLoad+            (\b a -> a{autoLoad = b})+            boolEditor+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Text Editor") $ emptyParams)+            (PP.text . show)+            stringParser+            textEditorType+            (\b a -> a{textEditorType = b})+            (comboSelectionEditor ["GtkSourceView", "Yi", "CodeMirror"] id)+            (\i -> return ())+    ]),+    (__ "User Interface", VFDPP emptyParams [+        mkFieldPP+            -- TODO: be able to load different gtk themes+            (paraName <<<- ParaName (__ "User interface theme") $ emptyParams)+            (PP.text . show)+            stringParser+            (\prefs -> if darkUserInterface prefs then "Dark" else "Light")+            (\str a -> a {darkUserInterface = str == "Dark"})+            (comboSelectionEditor ["Dark", "Light"] id)+            (\_ -> applyInterfaceTheme)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "LogView Font") $ emptyParams)+            (\a -> PP.text (case a of Nothing -> show ""; Just s -> show s))+            (do str <- stringParser+                return (if T.null str then Nothing else Just str))+            logviewFont+            (\ b a -> a{logviewFont = b})+            fontEditor+            (\mbs -> do+                log <- getLog+                fdesc <- liftIO $fontDescriptionFromString (fromMaybe "" mbs)+                liftIO $widgetModifyFont (castToWidget $ logLaunchTextView log) (Just fdesc))+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Window default size")+                $ paraSynopsis <<<- ParaSynopsis+                    (__ "Default size of the main ide window specified as pair")+                $ paraShadow <<<- ParaShadow ShadowIn $ emptyParams)+            (PP.text.show)+            (pairParser intParser)+            defaultSize (\(c,d) a -> a{defaultSize = (c,d)})+            (pairEditor (intEditor (0.0, 3000.0, 25.0),+                            paraName <<<- ParaName "X" $ emptyParams)+                        (intEditor (0.0, 3000.0, 25.0),+                            paraName <<<- ParaName "Y" $ emptyParams))+            (\a -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Show hidden files in workspace") $ emptyParams)+            (PP.text . show)+            boolParser+            showHiddenFiles+            (\b a -> a {showHiddenFiles = b})+            boolEditor+            (\_ -> refreshWorkspacePane)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Show icons in the Workspace pane") $ emptyParams)+            (PP.text . show)+            boolParser+            showWorkspaceIcons+            (\b a -> a {showWorkspaceIcons = b})+            boolEditor+            (\_ -> rebuildWorkspacePane)+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Use ctrl Tab for Notebook flipper") $ emptyParams)+            (PP.text . show)+            boolParser+            useCtrlTabFlipping+            (\b a -> a{useCtrlTabFlipping = b})+            boolEditor+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Complete only on Hotkey") $ emptyParams)+            (PP.text . show)+            boolParser+            completeRestricted+            (\b a -> a{completeRestricted = b})+            boolEditor+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Name of the keymap")+                $ paraSynopsis <<<- ParaSynopsis+                    (__ "The name of a keymap file in a config dir")+                    $ paraDirection <<<- ParaDirection Horizontal $ emptyParams)+            (PP.text . T.unpack)+            identifier+            keymapName+            (\b a -> a{keymapName = b})+            (textEditor (not . T.null) True)+            (\ a -> return ())+    ]),+    (__ "Sessions", VFDPP emptyParams [+         mkFieldPP+            (paraName <<<- ParaName (__ "Save the session (open files, pane positioning and sizing, etc) before closing a workspace") $+                paraSynopsis <<<- ParaSynopsis+                    (__ "Save the session (open files, pane positioning and sizing, etc) before closing a workspace")+                    $ paraShadow <<<- ParaShadow ShadowIn  $ emptyParams)+            (PP.text . show)+            boolParser+            saveSessionOnClose+            (\b a -> a{saveSessionOnClose = b})+            boolEditor+            (\_ -> return ())+    ]),+    (__ "Initial Pane positions", VFDPP emptyParams [+        mkFieldPP+            (paraName <<<- ParaName+                (__ "Categories for panes")+                $ paraShadow <<<- ParaShadow ShadowIn+                     $ paraDirection <<<- ParaDirection Vertical+                        $ paraMinSize <<<- ParaMinSize (-1,130)+                            $ emptyParams)+            (PP.text . show)+            readParser+            categoryForPane+            (\b a -> a{categoryForPane = b})+            (multisetEditor+                (ColumnDescr True [(__ "Pane Id", \ (n, _) -> [cellText := n])+                                   ,(__ "Pane Category", \ (_, v) -> [cellText := v])])+                (pairEditor+                    (textEditor (not . T.null) True, emptyParams)+                    (textEditor (not . T.null) True, emptyParams), emptyParams)+                (Just (sortBy (\(a,_) (a2,_) -> compare a a2)))+                (Just (\(a,_) (a2,_) -> a == a2)))+            (\i -> return ())+       ,mkFieldPP+            (paraName <<<- ParaName+                (__ "Pane path for category")+                $ paraShadow <<<- ParaShadow ShadowIn+                     $ paraDirection <<<- ParaDirection Vertical+                        $ paraMinSize <<<- ParaMinSize (-1,130)+                            $ emptyParams)+            (PP.text . show)+            readParser+            pathForCategory+            (\b a -> a{pathForCategory = b})+            (multisetEditor+                (ColumnDescr True [(__ "Pane category", \ (n, _) -> [cellText := n])+                                   ,(__ "Pane path", \ (_, v) -> [cellText := T.pack $ show v])])+                (pairEditor (textEditor (not . T.null) True, emptyParams)+                    (genericEditor, emptyParams),+                  emptyParams)+                (Just (sortBy (\(a,_) (a2,_) -> compare a a2)))+                (Just (\(a,_) (a2,_) -> a == a2)))+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Default pane path") $ emptyParams)+            (PP.text . show)+            readParser+            defaultPath+            (\b a -> a{defaultPath = b})+            genericEditor+            (\i -> return ())+    ]),+    (__ "Metadata", VFDPP emptyParams [+        mkFieldPP+            (paraName <<<- ParaName+                (__ "Paths under which haskell sources for packages may be found")+                        $ paraMinSize <<<- ParaMinSize (-1,100)+                            $ emptyParams)+            (PP.text . show)+            readParser+            sourceDirectories+            (\b a -> a{sourceDirectories = b})+            (filesEditor Nothing FileChooserActionSelectFolder (__ "Select folder"))+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Unpack source for cabal packages to") $ emptyParams)+            (PP.text . show)+            readParser+            unpackDirectory+            (\b a -> a{unpackDirectory = b})+            (maybeEditor (stringEditor (const True) True,emptyParams) True "")+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "URL from which to download prebuilt metadata") $ emptyParams)+            (PP.text . show)+            stringParser+            retrieveURL+            (\b a -> a{retrieveURL = b})+            (textEditor (const True) True)+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Strategy for downloading prebuilt metadata") $ emptyParams)+            (PP.text . show)+            readParser+            retrieveStrategy+            (\b a -> a{retrieveStrategy = b})+            (enumEditor [__ "Try to download and then build locally if that fails",+                         __ "Try to build locally and then download if that fails",+                         __ "Never download (just try to build locally)"])+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Update metadata at startup") $ emptyParams)+            (PP.text . show)+            boolParser+            collectAtStart+            (\b a -> a{collectAtStart = b})+            boolEditor+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Port number for leksah to comunicate with leksah-server") $ emptyParams)+            (PP.text . show)+            intParser+            serverPort+            (\b a -> a{serverPort = b})+            (intEditor (1.0, 65535.0, 1.0))+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "IP address for leksah to comunicate with leksah-server") $ emptyParams)+            (PP.text . show)+            stringParser+            serverIP+            (\b a -> a{serverIP = b})+            (textEditor (not . T.null) True)+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "Stop the leksah-server process when leksah disconnects") $ emptyParams)+            (PP.text . show)+            boolParser+            endWithLastConn+            (\b a -> a{endWithLastConn = b})+            boolEditor+            (\i -> return ())+    ]),+    (__ "Blacklist", VFDPP emptyParams [+        mkFieldPP+            (paraName <<<- ParaName+                (__ "Packages which are excluded from the modules pane")+                        $ paraMinSize <<<- ParaMinSize (-1,200)+                            $ emptyParams)+            (PP.text . show . map display)+            (fmap (mapMaybe simpleParse) readParser)+            packageBlacklist+            (\b a -> a{packageBlacklist = b})+            (dependenciesEditor packages)+            (\i -> return ())+    ]),+    (__ "Build", VFDPP emptyParams [+         mkFieldPP+            (paraName <<<- ParaName (__ "Automatically save all files before building") $ emptyParams)+            (PP.text . show)+            boolParser+            saveAllBeforeBuild+            (\b a -> a{saveAllBeforeBuild = b})+            boolEditor+            (\i -> return ())+         , mkFieldPP+               (paraName <<<- ParaName (__ "Run HLint when saving a source file") $ emptyParams)+               (PP.text . show)+               boolParser+               hlintOnSave+               (\b a -> a{hlintOnSave = b})+               boolEditor+               (\i -> return ())+         , mkFieldPP+            (paraName <<<- ParaName (__ "Select first warning if built without errors") $ emptyParams)+            (PP.text . show)+            boolParser+            jumpToWarnings+            (\b a -> a{jumpToWarnings = b})+            boolEditor+            (\i -> return ())+         , mkFieldPP+            (paraName <<<- ParaName (__ "Background build") $ emptyParams)+            (PP.text . show)+            boolParser+            backgroundBuild+            (\b a -> a{backgroundBuild = b})+            boolEditor+            (\i -> return ())+         , mkFieldPP+            (paraName <<<- ParaName (__ "Run unit tests when building") $ emptyParams)+            (PP.text . show)+            boolParser+            runUnitTests+            (\b a -> a{runUnitTests = b})+            boolEditor+            (\i -> return ())+         , mkFieldPP+            (paraName <<<- ParaName (__ "Make mode") $ emptyParams)+            (PP.text . show)+            boolParser+            makeMode+            (\b a -> a{makeMode = b})+            (boolEditor2 (__ "Single mode"))+            (\i -> return ())++         , mkFieldPP+            (paraName <<<- ParaName (__ "Single build without linking") $ emptyParams)+            (PP.text . show)+            boolParser+            singleBuildWithoutLinking+            (\b a -> a{singleBuildWithoutLinking = b})+            boolEditor+            (\i -> return ())+         , mkFieldPP+            (paraName <<<- ParaName (__ "Don't install last package") $ emptyParams)+            (PP.text . show)+            boolParser+            dontInstallLast+            (\b a -> a{dontInstallLast = b})+            boolEditor+            (\i -> return ())++        , mkFieldPP+            (paraName <<<- ParaName (__ "Use vado to run commands on the remote machine") $ emptyParams)+            (PP.text . show)+            boolParser+            useVado+            (\b a -> a{useVado = b})+            boolEditor+            (\i -> return ())++        , mkFieldPP+            (paraName <<<- ParaName (__ "Use cabal-dev") $ emptyParams)+            (PP.text . show)+            boolParser+            useCabalDev+            (\b a -> a{useCabalDev = b})+            boolEditor+            (\i -> return ())+    ]),+    (__ "Debug", VFDPP emptyParams [+           mkFieldPP+            (paraName <<<- ParaName (__ "Enable usage of Show instances in :print") $ emptyParams)+            (PP.text . show)+            boolParser+            printEvldWithShow+            (\b a -> a{printEvldWithShow = b})+            boolEditor+            debugSetPrintEvldWithShow+         , mkFieldPP+            (paraName <<<- ParaName (__ "Break on any exception thrown") $ emptyParams)+            (PP.text . show)+            boolParser+            breakOnException+            (\b a -> a{breakOnException = b})+            boolEditor+            debugSetBreakOnException+         , mkFieldPP+            (paraName <<<- ParaName (__ "Break on uncaught exceptions and errors") $ emptyParams)+            (PP.text . show)+            boolParser+            breakOnError+            (\b a -> a{breakOnError = b})+            boolEditor+            debugSetBreakOnError+         , mkFieldPP+            (paraName <<<- ParaName (__ "Turn on printing of binding results in GHCi") $ emptyParams)+            (PP.text . show)+            boolParser+            printBindResult+            (\b a -> a{printBindResult = b})+            boolEditor+            debugSetPrintBindResult+    ]),+    (__ "Help", VFDPP emptyParams [+        mkFieldPP+            (paraName <<<- ParaName (__ "Browser") $ emptyParams)+            (PP.text . show)+            stringParser+            browser+            (\b a -> a{browser = b})+            (textEditor (not . T.null) True)+            (\i -> return ())+    ,   mkFieldPP+            (paraName <<<- ParaName (__ "URL for searching documentation") $+                paraSynopsis <<<- ParaSynopsis+                    ("e.g https://www.haskell.org/hoogle/?q= or " <>+                        "Hayoo: http://hayoo.fh-wedel.de/?query=")+                        $ emptyParams)+            (PP.text . show)+            stringParser+            docuSearchURL+            (\b a -> a{docuSearchURL = b})+            (textEditor (not . T.null) True)+            (\i -> return ())+    ])]++getActiveSettings :: PaneMonad alpha => alpha (Maybe Settings)+getActiveSettings = do+    mbScreen <- getActiveScreen+    case mbScreen of+        Nothing -> return Nothing+        Just screen -> liftIO $ Just <$> settingsGetForScreen screen++applyInterfaceTheme :: IDEAction+applyInterfaceTheme = do+    setInfoStyle+    fillErrorList False+    prefs <- readIDE prefs+    buffers <- allBuffers+    mapM_ updateStyle' buffers+    mbSettings <- getActiveSettings+    case mbSettings of+        Just settings -> liftIO $ settingsSetLongProperty+                            settings+                            ("gtk-application-prefer-dark-theme" :: Text)+                            (if darkUserInterface prefs then 1 else 0)+                            "Leksah"+        Nothing -> return ()+    menuDarkState <- getDarkState+    when (menuDarkState /= darkUserInterface prefs) $+        setDarkState (darkUserInterface prefs)++-- | Editor for enabling a different syntax stylesheet+styleEditor :: Editor (Bool, Text)+styleEditor p n = do+    styleManager <- sourceStyleSchemeManagerNew+    dataDir <- getDataDir+    sourceStyleSchemeManagerAppendSearchPath styleManager $ dataDir </> "data/styles"+    ids          <- sourceStyleSchemeManagerGetSchemeIds styleManager+    let notDarkIds = filter (not . T.isSuffixOf "-dark") ids+    disableEditor (comboSelectionEditor notDarkIds id, p) True (__ "Select a special style?") p n+++-- | The default preferences+defaultPrefs = Prefs {+        prefsFormat         =   prefsVersion+    ,   prefsSaveTime       =   ""+    ,   showLineNumbers     =   True+    ,   rightMargin         =   (True,100)+    ,   tabWidth            =   4+    ,   wrapLines           =   False+    ,   sourceCandy         =   (False,"candy")+    ,   darkUserInterface   = False+    ,   saveSessionOnClose  = True+    ,   keymapName          =   "keymap"+    ,   forceLineEnds       =   True+    ,   removeTBlanks       =   True+    ,   textviewFont        =   Nothing+    ,   sourceStyle         =   (True,"leksah")+    ,   foundBackgroundLight      = Color 65535 65535 32768+    ,   matchBackgroundLight      = Color 42064 55923 28520+    ,   contextBackgroundLight    = Color 65535 46529 46529+    ,   breakpointBackgroundLight = Color 64879 51921 28114+    ,   lintBackgroundLight       = Color 60000 65535 60000+    ,   foundBackgroundDark       = Color 30364 29149     0+    ,   matchBackgroundDark       = Color 18021 29927  6384+    ,   contextBackgroundDark     = Color 20000 16000 16000+    ,   breakpointBackgroundDark  = Color 15000  5000  5000+    ,   lintBackgroundDark        = Color     0 15000     0+    ,   textEditorType      =   "GtkSourceView"+    ,   autoLoad            =   False+    ,   logviewFont         =   Nothing+    ,   defaultSize         =   (1024,800)+    ,   browser             =   "firefox"+    ,   sourceDirectories   =   []+    ,   packageBlacklist    =   []+    ,   pathForCategory     =   [   ("EditorCategory",[SplitP LeftP])+                                ,   ("LogCategory",[SplitP RightP, SplitP BottomP])+                                ,   ("ToolCategory",[SplitP RightP, SplitP TopP])+                                ]+    ,   defaultPath         =   [SplitP LeftP]+    ,   categoryForPane     =   [   ("*ClassHierarchy","ToolCategory")+                                ,   ("*Breakpoints","LogCategory")+                                ,   ("*Browser","ToolCategory")+                                ,   ("*Debug","ToolCategory")+                                ,   ("*Errors","ToolCategory")+                                ,   ("*Files","ToolCategory")+                                ,   ("*Flags","ToolCategory")+                                ,   ("*Grep","ToolCategory")+                                ,   ("*HLint","ToolCategory")+                                ,   ("*Doc","ToolCategory")+                                ,   ("*Info","LogCategory")+                                ,   ("*Log","LogCategory")+                                ,   ("*Inspect","LogCategory")+                                ,   ("*Modules","ToolCategory")+                                ,   ("*Out","ToolCategory")+                                ,   ("*Package","EditorCategory")+                                ,   ("*Prefs","EditorCategory")+                                ,   ("*Search","ToolCategory")+                                ,   ("*Trace","LogCategory")+                                ,   ("*Variables","LogCategory")+                                ,   ("*Workspace","LogCategory")]+    ,   collectAtStart      =   True+    ,   unpackDirectory     =   Just ("~" </> configDirName </> "packageSources")+    ,   retrieveURL         =   "http://www.leksah.org"+    ,   retrieveStrategy    =   SP.RetrieveThenBuild+    ,   useCtrlTabFlipping  =   True+    ,   docuSearchURL       =   "https://www.haskell.org/hoogle/?q="+    ,   completeRestricted  =   False+    ,   saveAllBeforeBuild  =   True+    ,   jumpToWarnings      =   True+    ,   useVado             =   False+    ,   useCabalDev         =   False+    ,   backgroundBuild     =   True+    ,   runUnitTests        =   False+    ,   makeMode            =   True+    ,   singleBuildWithoutLinking  = False+    ,   dontInstallLast     =   False+    ,   printEvldWithShow   =   True+    ,   breakOnException    =   True+    ,   breakOnError        =   True+    ,   printBindResult     =   False+    ,   serverPort          =   11111+    ,   serverIP            =   "127.0.0.1"+    ,   endWithLastConn     =   True+    ,   showHiddenFiles     =   False+    ,   showWorkspaceIcons       =   True+    ,   hlintOnSave = True+    }++-- ------------------------------------------------------------+-- * Parsing+-- ------------------------------------------------------------++-- | Read the preference file+readPrefs :: FilePath -> IO Prefs+readPrefs fn = catch (do+    configDir <- getConfigDir+    readFields fn (flattenFieldDescriptionPPToS (prefsDescription configDir [])) defaultPrefs)+        (\ (e :: SomeException) -> do+            sysMessage Normal (T.pack $ show e)+            return defaultPrefs)+-- ------------------------------------------------------------+-- * Printing+-- ------------------------------------------------------------++-- | Write the preference file+writePrefs :: FilePath -> Prefs -> IO ()+writePrefs fpath prefs = do+    timeNow         <- liftIO getClockTime+    configDir <- getConfigDir+    let newPrefs    =   prefs {prefsSaveTime = T.pack $ show timeNow, prefsFormat = prefsVersion}+    writeFields fpath newPrefs (flattenFieldDescriptionPPToS (prefsDescription configDir []))++
src/IDE/Sandbox.hs view
@@ -18,6 +18,7 @@ , sandboxInitShared , sandboxDelete , sandboxAddSource+, sandboxDeleteSource ) where  import Graphics.UI.Gtk (Window)@@ -31,9 +32,11 @@ import qualified Data.Conduit as C (Sink, ZipSink(..), getZipSink) import qualified Data.Conduit.List as CL (fold) import IDE.Utils.Tool (ToolOutput(..))-import IDE.Utils.GUIUtils (__, chooseDir)-import IDE.Core.State (PackageAction, readIDE, prefs, ipdBuildDir, getMainWindow,-            Workspace, wsFile, liftIDE, IDEPackage, IDEM, runPackage, LogLaunch)+import IDE.Utils.GUIUtils (showDialogOptions, __, chooseDir)+import IDE.Core.State+       (reflectIDE, reifyIDE, PackageAction, readIDE, prefs,+        ipdPackageDir, getMainWindow, Workspace, wsFile, liftIDE,+        IDEPackage, IDEM, runPackage, LogLaunch) import IDE.Pane.Log (getDefaultLogLaunch) import IDE.Utils.ExternalTool (runExternalTool') import IDE.LogRef (logOutput)@@ -42,10 +45,35 @@ import IDE.Package (refreshPackage) import Data.Monoid ((<>)) import qualified Data.Text as T (pack)+import IDE.Core.Types (runWorkspace, IDE(..), PackageM)+import System.Directory (doesFileExist)+import System.FilePath.Windows ((</>))+import Graphics.UI.Gtk.Windows.MessageDialog (MessageType(..))  -- | Get the last item sinkLast = CL.fold (\_ a -> Just a) Nothing +sandboxTry :: PackageAction -> PackageAction+sandboxTry action = do+    sandbox <- hasSandbox+    pkg <- ask+    if sandbox then action else do+        reifyIDE $ \ideRef -> do+            Just ws <- reflectIDE (readIDE workspace) ideRef+            let packageToIO = flip reflectIDE ideRef . flip runWorkspace ws . flip runPackage pkg+            showDialogOptions+                "This action requires a sandboxed package database. Would you like to initialize a sandbox for this package?"+                MessageQuestion+                [ ("Initialize New Sandbox", packageToIO $ sandboxInit >> action)+                , ("Use Existing Sandbox", packageToIO $ sandboxInitShared >> action)+                , ("Cancel", return ())]+                (Just 0)++hasSandbox :: PackageM Bool+hasSandbox = do+    pkg <- ask+    liftIO $ doesFileExist (ipdPackageDir pkg </> "cabal.sandbox.config")+ logSandbox :: IDEPackage -> LogLaunch -> C.Sink ToolOutput IDEM () logSandbox package logLaunch = do     let log = logOutput logLaunch@@ -59,7 +87,7 @@     logLaunch <- getDefaultLogLaunch     runExternalTool' (__ "Sandbox Init")         "cabal" ["sandbox", "init"]-        (ipdBuildDir package) (logSandbox package logLaunch)+        (ipdPackageDir package) (logSandbox package logLaunch)  chooseSandboxDir :: Window -> Maybe FilePath -> IO (Maybe FilePath) chooseSandboxDir window = chooseDir window (__ "Select sandbox folder")@@ -76,21 +104,21 @@             logLaunch <- getDefaultLogLaunch             runExternalTool' (__ "Sandbox Init")                 "cabal" ["sandbox", "init", "--sandbox=" <> T.pack dir]-                (ipdBuildDir package) (logSandbox package logLaunch)+                (ipdPackageDir package) (logSandbox package logLaunch)  sandboxDelete :: PackageAction-sandboxDelete = do+sandboxDelete = sandboxTry $  do     package <- ask     logLaunch <- getDefaultLogLaunch     runExternalTool' (__ "Sandbox Delete")         "cabal" ["sandbox", "delete"]-        (ipdBuildDir package) (logSandbox package logLaunch)+        (ipdPackageDir package) (logSandbox package logLaunch)  chooseSandboxSourceDir :: Window -> Maybe FilePath -> IO (Maybe FilePath) chooseSandboxSourceDir window = chooseDir window (__ "Select source folder")  sandboxAddSource :: Bool -> PackageAction-sandboxAddSource snapshot = do+sandboxAddSource snapshot = sandboxTry $ do     package <- ask     ws <- lift ask     let path = dropFileName (wsFile ws)@@ -102,5 +130,13 @@             logLaunch <- getDefaultLogLaunch             runExternalTool' (__ "Sandbox Add Source")                 "cabal" (["sandbox", "add-source", T.pack fp] ++ ["--snapshot" | snapshot])-                (ipdBuildDir package) (logSandbox package logLaunch)+                (ipdPackageDir package) (logSandbox package logLaunch)++sandboxDeleteSource :: FilePath -> PackageAction+sandboxDeleteSource dir = sandboxTry $ do+    package <- ask+    logLaunch <- getDefaultLogLaunch+    runExternalTool' (__ "Sandbox Delete Source")+        "cabal" ["sandbox", "delete-source", T.pack dir]+        (ipdPackageDir package) (logSandbox package logLaunch) 
src/IDE/Session.hs view
@@ -24,7 +24,6 @@ ,   loadSession ,   loadSessionPrompt ,   viewFullScreen-,   viewDark ) where  import Prelude hiding (catch)@@ -49,7 +48,6 @@ import IDE.Pane.SourceBuffer import IDE.Pane.Info (InfoState(..), setInfoStyle) import IDE.Pane.Log (LogState(..))-import IDE.Pane.Preferences import IDE.Pane.PackageFlags import IDE.Pane.Search import IDE.Pane.Grep@@ -76,12 +74,13 @@ import qualified Data.Text as T (pack) import Data.Traversable (forM) import Data.Foldable (forM_)+import IDE.Preferences (applyInterfaceTheme)  -- --------------------------------------------------------------------- -- This needs to be incremented, when the session format changes -- theSessionVersion :: Int-theSessionVersion = 1+theSessionVersion = 2  -- --------------------------------------------------------------------- -- All pane types must be in here !@@ -91,7 +90,6 @@                     |   LogSt LogState                     |   InfoSt InfoState                     |   ModulesSt ModulesState-                    |   PrefsSt PrefsState                     |   FlagsSt FlagsState                     |   SearchSt SearchState                     |   FilesSt FilesState@@ -112,7 +110,6 @@ asPaneState s | isJust (cast s :: Maybe LogState)         =   LogSt (fromJust $ cast s) asPaneState s | isJust (cast s :: Maybe InfoState)        =   InfoSt (fromJust $ cast s) asPaneState s | isJust (cast s :: Maybe ModulesState)     =   ModulesSt (fromJust $ cast s)-asPaneState s | isJust (cast s :: Maybe PrefsState)       =   PrefsSt (fromJust $ cast s) asPaneState s | isJust (cast s :: Maybe FlagsState)       =   FlagsSt (fromJust $ cast s) asPaneState s | isJust (cast s :: Maybe SearchState)      =   SearchSt (fromJust $ cast s) asPaneState s | isJust (cast s :: Maybe FilesState)       =   FilesSt (fromJust $ cast s)@@ -133,7 +130,6 @@ recover pp (LogSt p)            =   void (recoverState pp p) recover pp (InfoSt p)           =   void (recoverState pp p) recover pp (ModulesSt p)        =   void (recoverState pp p)-recover pp (PrefsSt p)          =   void (recoverState pp p) recover pp (FlagsSt p)          =   void (recoverState pp p) recover pp (SearchSt p)         =   void (recoverState pp p) recover pp (FilesSt p)          =   void (recoverState pp p)@@ -171,7 +167,6 @@     ,   population          ::   [(Maybe PaneState,PanePath)]     ,   windowSize          ::   (Int,Int)     ,   fullScreen          ::   Bool-    ,   dark                ::   Bool     ,   completionSize      ::   (Int,Int)     ,   workspacePath       ::   Maybe FilePath     ,   activePaneN         ::   Maybe Text@@ -235,7 +230,6 @@                                 , (Just (WorkspaceSt WorkspaceState),[SplitP RightP,SplitP BottomP])]     ,   windowSize          =   (1024,768)     ,   fullScreen          =   False-    ,   dark                =   False     ,   completionSize      =   (750,400)     ,   workspacePath       =   Nothing     ,   activePaneN         =   Nothing@@ -293,12 +287,6 @@             fullScreen             (\b a -> a{fullScreen = b})     ,   mkFieldS-            (paraName <<<- ParaName "Dark" $ emptyParams)-            (PP.text . show)-            readParser-            dark-            (\b a -> a{dark = b})-    ,   mkFieldS             (paraName <<<- ParaName "Completion size" $ emptyParams)             (PP.text . show)             (pairParser intParser)@@ -357,55 +345,49 @@  saveSessionAs :: FilePath -> Maybe FilePath ->  IDEAction saveSessionAs sessionPath mbSecondPath = do-    forget          <- getForgetSession-    if forget-        then ideMessage Normal (__ "Forget this session")-        else do-            sysMessage Normal (__ "Now saving session")-            bufs <- allBuffers-            case filter (\b -> bufferName b == "_Eval.hs") bufs of-                [IDEBuffer{sourceView = sv}] -> do-                    ebuf <- getBuffer sv-                    setModified ebuf False-                _     -> return ()-            wdw             <-  getMainWindow-            layout          <-  mkLayout-            population      <-  getPopulation-            size            <-  liftIO $ windowGetSize wdw-            fullScreen      <-  getFullScreenState-            dark            <-  getDarkState-            (completionSize,_) <- readIDE completion-            mbWs            <-  readIDE workspace-            activePane'     <-  getActivePane-            let activeP =   case activePane' of-                                Nothing -> Nothing-                                Just (s,_) -> Just s-            (toolbarVisible,_)  <- readIDE toolbar-            findState       <- getFindState-            (findbarVisible,_)  <- readIDE findbar-            timeNow         <- liftIO getClockTime-            recentFiles'      <- readIDE recentFiles-            recentWorkspaces' <- readIDE recentWorkspaces-            let state = SessionState {-                sessionVersion      =   theSessionVersion-            ,   saveTime            =   T.pack $ show timeNow-            ,   layoutS             =   layout-            ,   population          =   population-            ,   windowSize          =   size-            ,   fullScreen          =   fullScreen-            ,   dark                =   dark-            ,   completionSize      =   completionSize-            ,   workspacePath       =   case mbWs of-                                            Nothing -> Nothing-                                            Just ws -> Just (wsFile ws)-            ,   activePaneN         =   activeP-            ,   toolbarVisibleS     =   toolbarVisible-            ,   findbarState        =   (findbarVisible,findState)-            ,   recentOpenedFiles   =   recentFiles'-            ,   recentOpenedWorksp  =   recentWorkspaces'}-            liftIO $ writeFields sessionPath state sessionDescr-            when (isJust mbSecondPath) $-                liftIO $ writeFields (fromJust mbSecondPath) state sessionDescr+    sysMessage Normal (__ "Now saving session")+    bufs <- allBuffers+    case filter (\b -> bufferName b == "_Eval.hs") bufs of+        [IDEBuffer{sourceView = sv}] -> do+            ebuf <- getBuffer sv+            setModified ebuf False+        _     -> return ()+    wdw             <-  getMainWindow+    layout          <-  mkLayout+    population      <-  getPopulation+    size            <-  liftIO $ windowGetSize wdw+    fullScreen      <-  getFullScreenState+    (completionSize,_) <- readIDE completion+    mbWs            <-  readIDE workspace+    activePane'     <-  getActivePane+    let activeP =   case activePane' of+                        Nothing -> Nothing+                        Just (s,_) -> Just s+    (toolbarVisible,_)  <- readIDE toolbar+    findState       <- getFindState+    (findbarVisible,_)  <- readIDE findbar+    timeNow         <- liftIO getClockTime+    recentFiles'      <- readIDE recentFiles+    recentWorkspaces' <- readIDE recentWorkspaces+    let state = SessionState {+        sessionVersion      =   theSessionVersion+    ,   saveTime            =   T.pack $ show timeNow+    ,   layoutS             =   layout+    ,   population          =   population+    ,   windowSize          =   size+    ,   fullScreen          =   fullScreen+    ,   completionSize      =   completionSize+    ,   workspacePath       =   case mbWs of+                                    Nothing -> Nothing+                                    Just ws -> Just (wsFile ws)+    ,   activePaneN         =   activeP+    ,   toolbarVisibleS     =   toolbarVisible+    ,   findbarState        =   (findbarVisible,findState)+    ,   recentOpenedFiles   =   recentFiles'+    ,   recentOpenedWorksp  =   recentWorkspaces'}+    liftIO $ writeFields sessionPath state sessionDescr+    when (isJust mbSecondPath) $+        liftIO $ writeFields (fromJust mbSecondPath) state sessionDescr  saveSessionAsPrompt :: IDEAction saveSessionAsPrompt = do@@ -583,8 +565,7 @@                                         recentWorkspaces = recentOpenedWorksp sessionSt})         setFullScreenState (fullScreen sessionSt)         viewFullScreen-        setDarkState (dark sessionSt)-        viewDark+        applyInterfaceTheme         liftIO $ debugM "leksah" "recoverSession done"         return (toolbarVisibleS sessionSt, (fst . findbarState) sessionSt))         (\ (e :: SomeException) -> do@@ -654,31 +635,4 @@         (Nothing, _)         -> return ()         (Just window, True)  -> liftIO $ windowFullscreen window         (Just window, False) -> liftIO $ windowUnfullscreen window--viewDark :: IDEAction-viewDark = getDarkState >>= setDark--getActiveSettings :: PaneMonad alpha => alpha (Maybe Settings)-getActiveSettings = do-    mbScreen <- getActiveScreen-    case mbScreen of-        Nothing -> return Nothing-        Just screen -> liftIO $ Just <$> settingsGetForScreen screen--setDark :: Bool -> IDEM ()-setDark dark = do-    setInfoStyle-    fillErrorList False-    prefs <- readIDE prefs-    buffers <- allBuffers-    mapM_ updateStyle' buffers-    mbSettings <- getActiveSettings-    case mbSettings of-        Just settings -> liftIO $ settingsSetLongProperty-                            settings-                            ("gtk-application-prefer-dark-theme" :: Text)-                            (if dark then 1 else 0)-                            "Leksah"-        Nothing -> return ()- 
src/IDE/TextEditor/Class.hs view
@@ -17,11 +17,12 @@     TextEditor(..)   , EditorStyle(..)   , updateStyle+  , scrollToCursor ) where  import IDE.Core.Types        (LogRefType, IDE(..), IDERef, IDEM, IDEEventM, EditorStyle(..),-        IDEAction(..), editorStyle)+        IDEAction(..), Prefs (..), editorStyle) import Graphics.UI.Editor.Basics (Connection) import Control.Monad.Reader (ReaderT(..)) import Graphics.UI.Gtk@@ -34,14 +35,19 @@ import System.Glib.Signals (on) import Data.Text (Text) import IDE.Core.State (readIDE)-import IDE.Utils.GUIUtils (getDarkState)  updateStyle :: TextEditor editor => EditorBuffer editor -> IDEAction updateStyle ebuf = do     prefs <- readIDE prefs-    preferDark <- getDarkState-    setStyle ebuf $ editorStyle preferDark prefs+    setStyle ebuf $ editorStyle (darkUserInterface prefs) prefs +-- | Scrolls the editor to the cursor if necessary+scrollToCursor :: TextEditor editor => EditorView editor -> IDEAction+scrollToCursor view = do+    buf  <- getBuffer view+    iter <- getInsertIter buf+    scrollToIter view iter 0.0 Nothing+ class TextEditor editor where     data EditorBuffer editor     data EditorView editor@@ -131,11 +137,12 @@                     -> Double                     -> Maybe (Double, Double)                     -> IDEM ()-    scrollToIter :: EditorView editor-                    -> EditorIter editor-                    -> Double-                    -> Maybe (Double, Double)-                    -> IDEM ()+    -- | Scrolls the editor to the given `EditorIter`+    scrollToIter :: EditorView editor -- ^ The editor view+                 -> EditorIter editor -- ^ The iter+                 -> Double            -- ^ Margin+                 -> Maybe (Double, Double) -- ^ Alignment of the iter, @Just (0,0) is left-top, Just (1.0, 1.0) is right-bottom+                 -> IDEM ()     setFont :: EditorView editor -> Maybe Text -> IDEM ()     setIndentWidth :: EditorView editor -> Int -> IDEM ()     setWrapMode :: EditorView editor -> Bool -> IDEM ()
src/IDE/TextEditor/CodeMirror.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE DeriveDataTypeable #-}@@ -54,6 +55,8 @@ import Data.Eq (Eq(..)) import GHC.Float (Double) import qualified Data.Text as T (pack)+import Control.Lens.Getter (to)+import Control.Monad (liftM, (=<<))  #ifdef LEKSAH_WITH_CODE_MIRROR import Control.Monad (unless)@@ -62,9 +65,9 @@ import Graphics.UI.Gtk.WebKit.Types (WebView(..)) import Control.Monad.Reader (ReaderT(..)) import Language.Javascript.JSaddle-       (valToObject, (#), JSContextRef, JSObjectRef, jsg, (<#), obj, js2,-        js, JSM, js1, valToText, valToStr, js3, js0, MakeValueRef(..), MakeStringRef(..),-        JSStringRef, JSValueRef, valToBool, strToText, valToNumber, MakeObjectRef)+       (valToObject, (#), JSContextRef, Object, jsg, jsg2, (<#), obj, js2, jss,+        js, JSM, js1, valToText, valToStr, js3, js0, ToJSVal(..), ToJSString(..),+        JSString, JSVal, valToBool, strToText, valToNumber, MakeObject(..)) import Control.Applicative ((<$>)) import Control.Monad.Reader.Class (MonadReader(..)) import Control.Concurrent (putMVar, newEmptyMVar, takeMVar, MVar, tryTakeMVar)@@ -104,11 +107,11 @@  data CodeMirrorState = CodeMirrorState {     cmContext        :: JSContextRef-  , cmObject         :: JSObjectRef }+  , cmObject         :: Object } type CM = ReaderT (WebView, CodeMirrorState) JSM webView :: CM WebView webView = fst <$> ask-codeMirror :: CM JSObjectRef+codeMirror :: CM Object codeMirror = cmObject . snd <$> ask runCM :: CodeMirrorRef -> CM a -> IDEM a runCM (v, mvar) f = liftIO $ do@@ -138,59 +141,60 @@  type CodeMirrorRef = (WebView, MVar CodeMirrorState) --+gCodeMirror x y   = jsg2 "CodeMirror" x y >>= valToObject body              = js  "body"-value             = js  "value"+setValue v        = jss "value" v setSize           = js2 "setSize"-mode              = js  "mode"-line              = js  "line"-ch                = js  "ch"-left              = js  "left"-top               = js  "top"-right             = js  "right"-bottom            = js  "bottom"-lastLine          = js0 "lastLine"-getRange          = js2 "getRange"-setValue          = js1 "setValue"+setMode m         = jss "mode" m+line              = js  "line" . to valToNumber+setLine l         = jss "line" l+ch                = js  "ch" . to valToNumber+setCh c           = jss "ch" c+setLeft l         = jss "left" l+setTop t          = jss "top" t+left              = js  "left" . to valToNumber+top               = js  "top" . to valToNumber+right             = js  "right" . to valToNumber+bottom            = js  "bottom" . to valToNumber+lastLine          = js0 "lastLine" . to valToNumber+getRange x y      = js2 "getRange" x y . to valToStr+callSetValue      = js1 "setValue" setBookmark'      = js2 "setBookmark"-find              = js0 "find"-from              = js  "from"-getCursor :: (MakeValueRef a0, MakeObjectRef o) => a0 -> IndexPreservingGetter o (JSM JSValueRef)-getCursor         = js1 "getCursor"-isClean           = js0 "isClean"+find              = js0 "find" . to valToObject+from              = js  "from" . to valToObject+getCursor x       = js1 "getCursor" x . to valToObject+isClean           = js0 "isClean" . to valToBool markText          = js3 "markText"-className         = js  "className"+className         = "className" clearHistory      = js0 "clearHistory" callUndo          = js0 "undo"-undo'             = js  "undo"+undo'             = js  "undo" . to valToBool callRedo          = js0 "redo"-redo'             = js  "redo"+redo'             = js  "redo" . to valToBool historySize       = js0 "historySize" replaceRange      = js3 "replaceRange" insertAt          = js2 "replaceRange" replaceSelection  = js1 "replaceSelection"-posFromIndex      = js1 "posFromIndex"-lineCount         = js0 "lineCount"-somethingSelected = js0 "somethingSelected"+posFromIndex x    = js1 "posFromIndex" x . to valToObject+lineCount         = js0 "lineCount" . to valToNumber+somethingSelected = js0 "somethingSelected" . to valToBool setSelection      = js2 "setSelection" placeCursorAt     = js1 "setSelection" markClean         = js0 "markClean"-coordsChar        = js2 "coordsChar"+coordsChar pos n  = js2 "coordsChar" pos n . to valToObject charCoords        = js2 "charCoords" scrollIntoView    = js2 "scrollIntoView" getAllMarks       = js0 "getAllMarks"-indexFromPos      = js1 "indexFromPos"-getLineText :: (MakeValueRef a0, MakeObjectRef o) => a0 -> IndexPreservingGetter o (JSM JSValueRef)-getLineText       = js1 "getLine"-jsLength          = js  "length"+indexFromPos p    = js1 "indexFromPos" p . to valToNumber+getLineText l     = js1 "getLine" l+jsLength          = js  "length" . to valToNumber  cmIter :: CodeMirrorRef -> Int -> Int -> CM (EditorIter CodeMirror)-cmIter cm l c = do+cmIter cm l c =     lift $ do         i <- obj-        i ^. line <# (fromIntegral l :: Double)-        i ^. ch   <# (fromIntegral c :: Double)+        i ^. setLine (fromIntegral l :: Double)+        i ^. setCh   (fromIntegral c :: Double)         return $ CMIter cm i  newCMBuffer :: Maybe FilePath -> Text -> IDEM (EditorBuffer CodeMirror)@@ -211,11 +215,10 @@              runjs $ do                 document   <- jsg "document"-                codeMirror <- jsg "CodeMirror"                 code <- obj-                code ^. value <# contents-                code ^. mode <# "haskell"-                cmObject <- codeMirror # (document ^. body, code) >>= valToObject+                code ^. setValue contents+                code ^. setMode "haskell"+                cmObject <- gCodeMirror (document ^. body) code                  cmObject ^. setSize "100%" "100%"                 liftIO $ debugM "leksah" "newCMBuffer loaded"@@ -237,8 +240,8 @@ instance TextEditor CodeMirror where     data EditorBuffer CodeMirror = CMBuffer CodeMirrorRef     data EditorView CodeMirror = CMView CodeMirrorRef-    data EditorMark CodeMirror = CMMark JSObjectRef | CMCursor JSValueRef-    data EditorIter CodeMirror = CMIter CodeMirrorRef JSObjectRef+    data EditorMark CodeMirror = CMMark Object | CMCursor JSVal+    data EditorIter CodeMirror = CMIter CodeMirrorRef Object     data EditorTagTable CodeMirror = CMTagTable CodeMirrorRef     data EditorTag CodeMirror = CMTag @@ -247,17 +250,17 @@         m <- codeMirror         lift $ do             o <- obj-            o ^. className <# name+            (o <# className) name             m ^. markText first last o             return ()     beginNotUndoableAction (CMBuffer cm) = return () -- TODO     beginUserAction (CMBuffer cm) = return () -- TODO     canRedo (CMBuffer cm) = runCM cm $ do         m <- codeMirror-        lift $ (m ^. historySize ^. redo') >>= valToBool+        lift $ m ^. historySize ^. redo'     canUndo (CMBuffer cm) = runCM cm $ do         m <- codeMirror-        lift $ (m ^. historySize ^. undo') >>= valToBool+        lift $ m ^. historySize ^. undo'     copyClipboard (CMBuffer cm) _ = return () -- TODO     createMark (CMView cm) _refType (CMIter _ i) _tooltip = runCM cm $ do         m <- codeMirror@@ -284,46 +287,46 @@         lift $ do             i <- obj             l <- m ^. lastLine-            i ^. line <# l-            i ^. ch   <# m ^. getLineText l ^. jsLength+            i ^. setLine l+            i ^. setCh (m ^. getLineText l ^. jsLength)             return $ CMIter cm i-    getInsertMark (CMBuffer cm) = runCM cm . lift $ CMCursor <$> makeValueRef "head"+    getInsertMark (CMBuffer cm) = runCM cm . lift $ CMCursor <$> toJSVal "head"     getIterAtLine (CMBuffer cm) line = runCM cm $ cmIter cm line 0-    getIterAtMark (CMBuffer cm) (CMMark mark) = runCM cm $ do-        lift $ CMIter cm <$> (mark ^. find ^. from >>= valToObject)+    getIterAtMark (CMBuffer cm) (CMMark mark) = runCM cm $+        lift $ CMIter cm <$> mark ^. find ^. from     getIterAtMark (CMBuffer cm) (CMCursor c) = runCM cm $ do         m <- codeMirror-        lift $ CMIter cm <$> ((m ^. getCursor c) >>= valToObject)+        lift $ CMIter cm <$> m ^. getCursor c     getIterAtOffset (CMBuffer cm) offset = runCM cm $ do         m <- codeMirror-        lift $ CMIter cm <$> ((m ^. posFromIndex (fromIntegral offset :: Double)) >>= valToObject)+        lift $ CMIter cm <$> m ^. posFromIndex (fromIntegral offset :: Double)     getLineCount (CMBuffer cm) = runCM cm $ do         m <- codeMirror-        lift $ round <$> ((m ^. lineCount) >>= valToNumber)+        lift $ round <$> m ^. lineCount     getModified (CMBuffer cm) = runCM cm $ do         m <- codeMirror-        lift $ not <$> ((m ^. isClean) >>= valToBool)-    getSelectionBoundMark (CMBuffer cm) = runCM cm . lift $ CMCursor <$> makeValueRef "anchor"+        lift $ not <$> m ^. isClean+    getSelectionBoundMark (CMBuffer cm) = runCM cm . lift $ CMCursor <$> toJSVal "anchor"     getSelectionBounds (CMBuffer cm) = runCM cm $ do         m <- codeMirror         lift $ do-            start <- (m ^. getCursor "start") >>= valToObject-            end   <- (m ^. getCursor "end") >>= valToObject+            start <- m ^. getCursor "start"+            end   <- m ^. getCursor "end"             return (CMIter cm start, CMIter cm end)     getInsertIter (CMBuffer cm) = runCM cm $ do         m <- codeMirror-        lift $ CMIter cm <$> (m ^. getCursor "head" >>= valToObject)+        lift $ CMIter cm <$> m ^. getCursor "head"     getSlice (CMBuffer cm) (CMIter _ first) (CMIter _ last) includeHidenChars = runCM cm $ do         m <- codeMirror-        lift $ m ^. getRange first last >>= valToText+        lift $ m ^. getRange first last >>= strToText     getStartIter (CMBuffer cm) = runCM cm $ cmIter cm 0 0     getTagTable (CMBuffer cm) = return $ CMTagTable cm     getText (CMBuffer cm) (CMIter _ first) (CMIter _ last) includeHidenChars = runCM cm $ do         m <- codeMirror-        lift $ m ^. getRange first last >>= valToText+        lift $ m ^. getRange first last >>= strToText     hasSelection (CMBuffer cm) = runCM cm $ do         m <- codeMirror-        lift $ (m ^. somethingSelected) >>= valToBool+        lift $ m ^. somethingSelected     insert (CMBuffer cm) (CMIter _ p) text = runCM cm $ do         m <- codeMirror         lift $ m ^. insertAt text p >> return ()@@ -351,7 +354,7 @@     setStyle (CMBuffer cm) _style = return () -- TODO     setText (CMBuffer cm) text = runCM cm $ do         m <- codeMirror-        lift $ m ^. setValue text+        lift $ m ^. callSetValue text         return ()     undo (CMBuffer cm) = runCM cm $ do         m <- codeMirror@@ -367,17 +370,17 @@         m <- codeMirror         lift $ do             pos <- obj-            pos ^. left <# (fromIntegral x :: Double)-            pos ^. top  <# (fromIntegral y :: Double)-            CMIter cm <$> (m ^. coordsChar pos "window" >>= valToObject)+            pos ^. setLeft (fromIntegral x :: Double)+            pos ^. setTop (fromIntegral y :: Double)+            CMIter cm <$> (m ^. coordsChar pos "window")     getIterLocation (CMView cm) (CMIter _ i) = runCM cm $ do         m <- codeMirror         lift $ do-            rect <- (m ^. charCoords i "window" >>= valToObject)-            l <- rect ^. left   >>= valToNumber-            r <- rect ^. right  >>= valToNumber-            t <- rect ^. top    >>= valToNumber-            b <- rect ^. bottom >>= valToNumber+            rect <- m ^. charCoords i "window"+            l <- rect ^. left+            r <- rect ^. right+            t <- rect ^. top+            b <- rect ^. bottom             return $ Rectangle (round l) (round t) (round $ r - l) (round $ b - t)     getOverwrite (CMView cm) = return False -- TODO     getScrolledWindow (CMView (v,_)) = liftIO . fmap (castToScrolledWindow . fromJust) $ widgetGetParent v@@ -400,7 +403,7 @@     backwardCharC (CMIter cm i) = runCM cm $ do         m <- codeMirror         lift $ do-            n <- m ^. indexFromPos i >>= valToNumber+            n <- m ^. indexFromPos i             i2 <- m ^. posFromIndex (n - 1)             return (CMIter cm i2)     backwardFindCharC (CMIter cm i) pred mbLimit = return Nothing -- TODO@@ -409,20 +412,21 @@         m <- codeMirror         lift $ do             i2 <- obj-            i2 ^. line <# i ^. line-            i2 ^. ch <# (0 :: Double)+            l <- i ^. line+            i2 ^. setLine l+            i2 ^. setCh (0 :: Double)             return $ CMIter cm i2     endsWord (CMIter cm i) = return False -- TODO     forwardCharC (CMIter cm i) = runCM cm $ do         m <- codeMirror         lift $ do-            n <- m ^. indexFromPos i >>= valToNumber+            n <- m ^. indexFromPos i             i2 <- m ^. posFromIndex (n + 1)             return (CMIter cm i2)     forwardCharsC (CMIter cm i) d = runCM cm $ do         m <- codeMirror         lift $ do-            n <- m ^. indexFromPos i >>= valToNumber+            n <- m ^. indexFromPos i             i2 <- m ^. posFromIndex (n + fromIntegral d)             return (CMIter cm i2)     forwardFindCharC (CMIter cm i) pred mbLimit = return Nothing -- TODO@@ -431,22 +435,22 @@         m <- codeMirror         lift $ do             i2 <- obj-            l <- i ^. line >>= makeValueRef-            i2 ^. line <# l-            i2 ^. ch   <# m ^. getLineText l ^. jsLength+            l <- i ^. line+            i2 ^. setLine l+            i2 ^. setCh (m ^. getLineText l ^. jsLength)             return $ CMIter cm i2     forwardWordEndC (CMIter cm i) = return Nothing -- TODO     getChar (CMIter cm i) = return Nothing -- TODO     getCharsInLine (CMIter cm i) = runCM cm $ do         m <- codeMirror-        lift $ round <$> (m ^. getLineText (i ^. line) ^. jsLength >>= valToNumber)-    getLine (CMIter cm i) = runCM cm $ do-        lift $ round <$> (i ^. line >>= valToNumber)-    getLineOffset (CMIter cm i) = runCM cm $ do-        lift $ round <$> (i ^. ch >>= valToNumber)+        lift $ round <$> m ^. getLineText (i ^. line) ^. jsLength+    getLine (CMIter cm i) = runCM cm $+        lift $ round <$> i ^. line+    getLineOffset (CMIter cm i) = runCM cm $+        lift $ round <$> i ^. ch     getOffset (CMIter cm i) = runCM cm $ do         m <- codeMirror-        lift $ round <$> (m ^. indexFromPos i >>= valToNumber)+        lift $ round <$> m ^. indexFromPos i     isStart i@(CMIter cm _) = do         start <- getStartIter (CMBuffer cm)         iterEqual start i@@ -454,13 +458,13 @@         end <- getEndIter (CMBuffer cm)         iterEqual end i     iterEqual (CMIter cm i1) (CMIter _ i2) = runCM cm . lift $ do-        l1 <- i1 ^. line >>= valToNumber-        l2 <- i2 ^. line >>= valToNumber+        l1 <- i1 ^. line+        l2 <- i2 ^. line         if l1 /= l2             then return False             else do-                c1 <- i1 ^. ch >>= valToNumber-                c2 <- i2 ^. ch >>= valToNumber+                c1 <- i1 ^. ch+                c2 <- i2 ^. ch                 return $ c1 == c2     startsLine i = (== 0) <$> getLineOffset i     startsWord (CMIter cm i) = return False -- TODO@@ -469,15 +473,16 @@         m <- codeMirror         lift $ do             i2 <- obj-            i2 ^. line <# (fromIntegral l :: Double)-            i2 ^. ch <# (0 :: Double)+            i2 ^. setLine (fromIntegral l :: Double)+            i2 ^. setCh (0 :: Double)             return $ CMIter cm i2     atLineOffset (CMIter cm i) column = runCM cm $ do         m <- codeMirror         lift $ do             i2 <- obj-            i2 ^. line <# i ^. line-            i2 ^. ch <# (fromIntegral column :: Double)+            l <- i ^. line+            i2 ^. setLine l+            i2 ^. setCh (fromIntegral column :: Double)             return $ CMIter cm i2     atOffset (CMIter cm _ ) offset = getIterAtOffset (CMBuffer cm) offset     atStart (CMIter cm _) = getStartIter (CMBuffer cm)@@ -517,7 +522,7 @@         liftIO $ do             v `widgetAddEvents` [ButtonReleaseMask]             id1 <- (`reflectIDE` ideR) $ v `onIDE` buttonReleaseEvent $ do-                mod <- lift $ eventModifier+                mod <- lift eventModifier                 case mod of                     [Control] -> f >> return True                     _             -> return False
src/IDE/TextEditor/GtkSourceView.hs view
@@ -262,10 +262,10 @@             forM_ [minBound..maxBound] $ \ refType -> do                 let cat = T.pack $ show refType                     icon = case refType of-                            ErrorRef       -> "dialog-error"-                            WarningRef     -> "dialog-warning"+                            ErrorRef       -> "ide_error"+                            WarningRef     -> "ide_warning"                             TestFailureRef -> "software-update-urgent"-                            LintRef        -> "emblem-generic"+                            LintRef        -> "ide_suggestion"                             BreakpointRef  -> "media-playback-pause"                             ContextRef     -> "media-playback-start"                 attributes <- sourceMarkAttributesNew
+ src/IDE/Utils/DirectoryUtils.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE CPP #-}+-----------------------------------------------------------------------------+--+-- Module      :  IDE.Utils.DirectoryUtils+-- Copyright   :  2007-2014 Juergen Nicklisch-Franken, Hamish Mackenzie+-- License     :  GPL+--+-- Maintainer  :  maintainer@leksah.org+-- Stability   :  provisional+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++module IDE.Utils.DirectoryUtils (+    setModificationTimeOnOSX+) where++import Data.Time.Clock (UTCTime(..))+#ifdef darwin_HOST_OS+import Data.Tuple (swap)+import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds)+import System.IO.Error (modifyIOError, ioeSetLocation, ioeSetFileName)+import System.FilePath (normalise)+import System.Posix.Files as Posix (getFileStatus)+# if MIN_VERSION_unix(2, 7, 0)+import System.Posix.Files as Posix (setFileTimesHiRes, accessTimeHiRes, modificationTimeHiRes)+#endif+#endif++-- HFS+ has a 1s resolution so we may need to fudge the mtime+-- This code is copied from the directory package to+-- avoid depending on the latest version.  Once we no longer+-- support ghc 7.10 we should remove it and use+-- setModificationTime from directory instead.+#ifdef darwin_HOST_OS+setModificationTimeOnOSX :: FilePath -> UTCTime -> IO ()+setModificationTimeOnOSX path =+  modifyIOError (`ioeSetLocation` "setModificationTime") .+  setFileTime True path++setFileTime :: Bool -> FilePath -> UTCTime -> IO ()+setFileTime isMtime path = modifyIOError (`ioeSetFileName` path) .+                           setTime . utcTimeToPOSIXSeconds+  where+    path'  = normalise path             -- handle empty paths+    setTime time = do+      stat <- Posix.getFileStatus path'+      uncurry (setFileTimes path') $+        swapIf isMtime (convertTime time, otherTime stat)+# if MIN_VERSION_unix(2, 7, 0)+    setFileTimes = Posix.setFileTimesHiRes+    convertTime  = id+    otherTime    = if isMtime+                   then Posix.accessTimeHiRes+                   else Posix.modificationTimeHiRes+#  else+    setFileTimes = Posix.setFileTimes+    convertTime  = fromInteger . truncate+    otherTime    = if isMtime+                   then Posix.accessTime+                   else Posix.modificationTime+# endif++swapIf :: Bool -> (a, a) -> (a, a)+swapIf True  = swap+swapIf False = id++#else++setModificationTimeOnOSX :: FilePath -> UTCTime -> IO ()+setModificationTimeOnOSX _path _time = return ()++#endif
src/IDE/Utils/GUIUtils.hs view
@@ -19,14 +19,13 @@ ,   openBrowser ,   showDialog ,   showErrorDialog+,   showDialogOptions+,   showInputDialog -,   getCandyState-,   setCandyState ,   getFullScreenState ,   setFullScreenState ,   getDarkState ,   setDarkState-,   getForgetSession  ,   getBackgroundBuildToggled ,   setBackgroundBuildToggled@@ -43,7 +42,10 @@  ,   stockIdFromType ,   mapControlCommand+,   treeViewToggleRow ,   treeViewContextMenu+,   treeViewContextMenu'+,   treeStoreGetForest  ,   __ @@ -52,8 +54,9 @@  import Graphics.UI.Gtk import IDE.Utils.Tool (runProcess)-import Data.Maybe (fromJust, isJust)-import Control.Monad+import Data.Maybe+       (listToMaybe, fromMaybe, catMaybes, fromJust, isJust)+import Control.Monad (void, when, unless) import IDE.Core.State --import Graphics.UI.Gtk.Selectors.FileChooser --    (FileChooserAction(..))@@ -68,6 +71,11 @@                                , pack #endif                                 )+import Control.Applicative ((<$>))+import Data.List (intercalate)+import Data.Foldable (forM_)+import Data.Tree (Tree(..), Forest)+ #ifdef LOCALIZATION  import Text.I18N.GetText@@ -101,8 +109,13 @@             return Nothing         _                   -> return Nothing -chooseFile :: Window -> Text -> Maybe FilePath -> IO (Maybe FilePath)-chooseFile window prompt mbFolder = do+-- | Launch a "choose file" dialog+chooseFile :: Window+           -> Text                   -- ^ Window title+           -> Maybe FilePath         -- ^ Start location+           -> [(String, [String])]   -- ^ File filters, e.g. [("Music Files", ["*.mp3", "*.wav"])]+           -> IO (Maybe FilePath)+chooseFile window prompt mbFolder filters = do     dialog <- fileChooserDialogNew                     (Just prompt)                     (Just window)@@ -111,7 +124,9 @@                 ,ResponseCancel)                 ,("gtk-open"                 ,ResponseAccept)]-    when (isJust mbFolder) $ void (fileChooserSetCurrentFolder dialog (fromJust mbFolder))+    forM_ mbFolder $ \folder ->+        void (fileChooserSetCurrentFolder dialog folder)+    forM_ filters (addFilter dialog)     widgetShow dialog     response <- dialogRun dialog     case response of@@ -127,6 +142,13 @@             return Nothing         _                   -> return Nothing +    where+        addFilter dialog (description, exts) = do+            ff <- fileFilterNew+            fileFilterSetName ff description+            forM_ exts (fileFilterAddPattern ff)+            fileChooserAddFilter dialog ff+ chooseSaveFile :: Window -> Text -> Maybe FilePath -> IO (Maybe FilePath) chooseSaveFile window prompt mbFolder = do     dialog <- fileChooserDialogNew@@ -158,7 +180,7 @@             (\ (_ :: SomeException) -> sysMessage Normal ("Can't find browser executable " <> browser prefs')))     return () -+-- | Show a text dialog with an Ok button and a specific messagetype showDialog :: Text -> MessageType -> IO () showDialog msg msgType = do     dialog <- messageDialogNew Nothing [] msgType ButtonsOk msg@@ -166,21 +188,68 @@     widgetDestroy dialog     return () ++-- | Show an error dialog with an Ok button showErrorDialog :: Text -> IO () showErrorDialog msg = showDialog msg MessageError --- get widget elements (menu & toolbar) -getCandyState :: PaneMonad alpha => alpha Bool-getCandyState = do-    ui <- getUIAction "ui/menubar/_Configuration/Source Candy" castToToggleAction-    liftIO $toggleActionGetActive ui+-- | Show a dialog with custom buttons and callbacks+showDialogOptions :: Text             -- ^ the message+                  -> MessageType      -- ^ type of dialog+                  -> [(Text, IO ())]  -- ^ button text and corresponding actions+                  -> Maybe Int        -- ^ index of button that has default focus (0-based)+                  -> IO ()+showDialogOptions msg msgType buttons mbIndex = do+    dialog <- messageDialogNew Nothing [] msgType ButtonsNone msg -setCandyState :: PaneMonad alpha => Bool -> alpha ()-setCandyState b = do-    ui <- getUIAction "ui/menubar/_Configuration/Source Candy" castToToggleAction-    liftIO $toggleActionSetActive ui b+    forM_ (zip [0..] buttons) $ \(n,(text, _)) -> do+        dialogAddButton dialog text (ResponseUser n) +    dialogSetDefaultResponse dialog (ResponseUser (fromMaybe 0 mbIndex))+    set dialog [ windowWindowPosition := WinPosCenterOnParent ]+    res <- dialogRun dialog+    widgetHide dialog+    case res of+        ResponseUser n | n >= 0 && n < length buttons -> map snd buttons !! n+        _ -> return ()+++-- | Show a simple dialog that asks the user for some text+showInputDialog :: Text -- ^ The message text+                -> Text -- ^ The default value+                -> IO (Maybe Text)+showInputDialog msg def = do+    dialog <- dialogNew -- Nothing [] MessageQuestion ButtonsOkCancel msg+    vbox   <- castToBox <$> dialogGetContentArea dialog+    label <- labelNew (Just msg)+    entry <- entryNew+    set entry [entryText := def]+    boxPackStart vbox label PackNatural 0+    boxPackStart vbox entry PackNatural 0+    widgetShowAll vbox++    -- Can't use messageDialog because of https://github.com/gtk2hs/gtk2hs/issues/114+    dialogAddButton dialog ("Cancel" :: Text) ResponseCancel+    dialogAddButton dialog ("Ok" :: Text) ResponseOk+    dialogSetDefaultResponse dialog ResponseOk++    res <- dialogRun dialog+    widgetHide dialog++    case res of+        ResponseOk -> do+            text <- get entry entryText+            widgetDestroy dialog+            return (Just text)+        _ -> widgetDestroy dialog >> return Nothing+++++-- get widget elements (menu & toolbar)++ getFullScreenState :: PaneMonad alpha => alpha Bool getFullScreenState = do     ui <- getUIAction "ui/menubar/_View/_Full Screen" castToToggleAction@@ -193,19 +262,14 @@  getDarkState :: PaneMonad alpha => alpha Bool getDarkState = do-    ui <- getUIAction "ui/menubar/_View/Dark" castToToggleAction+    ui <- getUIAction "ui/menubar/_View/_Use Dark Interface" castToToggleAction     liftIO $toggleActionGetActive ui  setDarkState :: PaneMonad alpha => Bool -> alpha () setDarkState b = do-    ui <- getUIAction "ui/menubar/_View/Dark" castToToggleAction+    ui <- getUIAction "ui/menubar/_View/_Use Dark Interface" castToToggleAction     liftIO $toggleActionSetActive ui b -getForgetSession :: PaneMonad alpha => alpha Bool-getForgetSession = do-    ui <- getUIAction "ui/menubar/_Configuration/Forget Session" castToToggleAction-    liftIO $toggleActionGetActive ui- getMenuItem :: Text -> IDEM MenuItem getMenuItem path = do     uiManager' <- getUiManager@@ -255,8 +319,10 @@     liftIO $ toggleActionSetActive ui b  getRecentFiles , getRecentWorkspaces, getVCS :: IDEM MenuItem-getRecentFiles    = getMenuItem "ui/menubar/_File/Open _Recent"-getRecentWorkspaces = getMenuItem "ui/menubar/_Workspace/Open _Recent"+getRecentFiles    = getMenuItem "ui/menubar/_File/Recent Files"+++getRecentWorkspaces = getMenuItem "ui/menubar/_File/Recent Workspaces" getVCS = getMenuItem "ui/menubar/Version Con_trol" --this could fail, try returning Menu if it does -- (toolbar) @@ -272,11 +338,76 @@ stockIdFromType Method          =   "ide_method" stockIdFromType _               =   "ide_other" ++treeStoreGetForest :: TreeStore a -> IO (Forest a)+treeStoreGetForest store = subForest <$> (treeStoreGetTree store [])++-- | Toggles a row in a `TreeView`+treeViewToggleRow treeView path = do+    expanded <- treeViewRowExpanded treeView path+    if expanded+        then treeViewCollapseRow treeView path+        else treeViewExpandRow   treeView path False+ -- maps control key for Macos #if defined(darwin_HOST_OS) mapControlCommand Alt = Control #endif mapControlCommand a = a++-- | Sets the context menu for a treeView widget+treeViewContextMenu' :: TreeViewClass treeView+                     => treeView                 -- ^ The view+                     -> TreeStore a              -- ^ The model+                     -> (a -> TreePath -> TreeStore a -> IDEM [[(Text, IDEAction)]]) -- ^ Produces the menu items for the selected values when right clicking+                                                                                     -- The lists are seperated by a seperator+                     -> IDEM (ConnectId treeView, ConnectId treeView)+treeViewContextMenu' view store itemsFor = reifyIDE $ \ideRef -> do+    cid1 <- view `on` popupMenuSignal $ do+        showMenu Nothing ideRef+    cid2 <- view `on` buttonPressEvent $ do+        button    <- eventButton+        click     <- eventClick+        timestamp <- eventTime+        (x, y)    <- eventCoordinates+        case (button, click) of+            (RightButton, SingleClick) -> liftIO $ do+                sel <- treeViewGetSelection view+                selCount <- treeSelectionCountSelectedRows sel+                when (selCount <= 1) $ do+                    pathInfo <- treeViewGetPathAtPos view (floor x, floor y)+                    case pathInfo of+                        Just (path, _, _) -> do+                            treeSelectionUnselectAll sel+                            treeSelectionSelectPath sel path+                        _ -> return ()+                showMenu (Just (button, timestamp)) ideRef+            _ -> return False+    return (cid1, cid2)+  where+    showMenu buttonEventDetails ideRef = do++        selPaths  <- treeViewGetSelection view >>= treeSelectionGetSelectedRows+        selValues <- mapM (treeStoreGetValue store) selPaths+        theMenu   <- menuNew+        menuAttachToWidget theMenu view+        forM_ (listToMaybe $ zip selValues selPaths) $ \(val, path) -> do+            itemsPerSection     <- flip reflectIDE ideRef $ itemsFor val path store+            menuItemsPerSection <- mapM (mapM (liftIO . menuItemNewWithLabel . fst)) itemsPerSection+++            forM_ (zip itemsPerSection menuItemsPerSection) $ \(section, itemsSection) -> do+                forM_ (zip section itemsSection) $ \((_, onActivated), m) -> do+                    m `on` menuItemActivated $ reflectIDE onActivated ideRef++            unless (null itemsPerSection) $ do+                itemsAndSeparators <- sequence $+                    intercalate [fmap castToMenuItem separatorMenuItemNew]+                                (map (map (return . castToMenuItem)) menuItemsPerSection)+                mapM_ (menuShellAppend theMenu) itemsAndSeparators+                menuPopup theMenu buttonEventDetails+                widgetShowAll theMenu+        return True  treeViewContextMenu :: TreeViewClass treeView                     => treeView
+ src/IDE/Utils/GtkBindings.hs view
@@ -0,0 +1,32 @@+-----------------------------------------------------------------------------+--+-- Module      :  IDE.Utils.GtkBindings+-- Copyright   :  2007-2014 Juergen Nicklisch-Franken, Hamish Mackenzie+-- License     :  GPL+--+-- Maintainer  :  maintainer@leksah.org+-- Stability   :  provisional+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++module IDE.Utils.GtkBindings (+    treeViewSetActiveOnSingleClick+) where++import Foreign.Ptr (Ptr)+import Graphics.UI.Gtk (toToolbar, TreeViewClass, TreeView)+import Foreign.ForeignPtr (withForeignPtr)+import Graphics.UI.GtkInternals (toTreeView, unTreeView)+import Foreign.C.Types (CInt(..))+import Foreign.Marshal.Utils (fromBool)++foreign import ccall safe "gtk_tree_view_set_activate_on_single_click"+    gtk_tree_view_set_activate_on_single_click :: Ptr TreeView -> CInt -> IO ()++treeViewSetActiveOnSingleClick :: TreeViewClass self => self -> Bool -> IO ()+treeViewSetActiveOnSingleClick self singleClick =+  withForeignPtr (unTreeView $ toTreeView self) $+      \selfPtr -> gtk_tree_view_set_activate_on_single_click selfPtr (fromIntegral $ fromBool singleClick)
src/IDE/Workspaces.hs view
@@ -42,7 +42,7 @@ import IDE.Core.State import Graphics.UI.Editor.Parameters     (Parameter(..), (<<<-), paraName, emptyParams)-import Control.Monad (void, unless, when, liftM)+import Control.Monad (filterM, void, unless, when, liftM) import Data.Maybe (isJust, fromJust, catMaybes) import IDE.Utils.GUIUtils     (chooseFile, chooseSaveFile, __)@@ -69,8 +69,8 @@        (getModuleTemplate, getPackageDescriptionAndPath, activatePackage,         deactivatePackage, idePackageFromPath, idePackageFromPath) import System.Directory-       (getDirectoryContents, getHomeDirectory, createDirectoryIfMissing,-        doesFileExist)+       (doesDirectoryExist, getDirectoryContents, getHomeDirectory,+        createDirectoryIfMissing, doesFileExist) import System.Time (getClockTime) import Graphics.UI.Gtk.Windows.MessageDialog     (ButtonsType(..), MessageType(..))@@ -190,7 +190,7 @@                 _  -> return ()  chooseWorkspaceFile :: Window -> IO (Maybe FilePath)-chooseWorkspaceFile window = chooseFile window (__ "Select leksah workspace file (.lkshw)") Nothing+chooseWorkspaceFile window = chooseFile window (__ "Select leksah workspace file (.lkshw)") Nothing [("Leksah Workspace Files", ["*.lkshw"])]  workspaceOpenThis :: Bool -> Maybe FilePath -> IDEAction workspaceOpenThis askForSession mbFilePath =@@ -240,7 +240,9 @@         Just ws -> do             VCSWS.onWorkspaceClose             let oldActivePackFile = wsActivePackFile ws-            triggerEventIDE (SaveSession (dropExtension (wsFile ws) ++ leksahSessionFileExtension))+            prefs <- readIDE prefs+            when (saveSessionOnClose prefs) $+                triggerEventIDE_ (SaveSession (dropExtension (wsFile ws) ++ leksahSessionFileExtension))             addRecentlyUsedWorkspace (wsFile ws)             Writer.setWorkspace Nothing             when (isJust oldActivePackFile) $ do@@ -594,7 +596,9 @@     findCabalFile :: FilePath -> IO (Maybe FilePath)     findCabalFile fp = (do             let dir = takeDirectory fp-            cabal <- filter ((== ".cabal") . takeExtension) <$> getDirectoryContents dir+            contents <- getDirectoryContents dir+            files    <- filterM (\f -> not <$> doesDirectoryExist (dir </> f)) contents+            let cabal = filter ((== ".cabal") . takeExtension) files             case cabal of                 (c:_) -> return . Just $ dir </> c                 _ | fp == dir -> return Nothing
tests/IDE/TextEditor/Tests.hs view
@@ -35,7 +35,7 @@ import IDE.Utils.FileUtils (getConfigFilePathForLoad) import IDE.Utils.Utils        (leksahKeymapFileExtension, leksahCandyFileExtension)-import IDE.Pane.Preferences (defaultPrefs)+import IDE.Preferences (defaultPrefs) import IDE.Keymap (Keymap(..)) import IDE.Command (mkActions) import qualified IDE.YiConfig as Yi (start)@@ -55,15 +55,8 @@ import Data.Text (Text) import Data.Monoid ((<>)) import qualified Data.Text as T (unpack, pack)+import Data.Sequence (empty) -testEditors :: IO Bool-testEditors = do-    result <- newEmptyMVar-    postGUIAsync $ do-        $quickCheckAll >>= putMVar result-        mainQuit-    mainGUI-    takeMVar result  testIDE :: IDEM Bool -> IO Bool testIDE f = do@@ -105,7 +98,7 @@               ,   activePack        =   Nothing               ,   activeExe         =   Nothing               ,   bufferProjCache   =   Map.empty-              ,   allLogRefs        =   []+              ,   allLogRefs        =   empty               ,   currentHist       =   0               ,   currentEBC        =   (Nothing, Nothing, Nothing)               ,   systemInfo        =   Nothing@@ -128,6 +121,8 @@               ,   logLaunches       =   Map.empty               ,   autoCommand       =   return ()               ,   autoURI           =   Nothing+              ,   hlintQueue        =   Nothing+              ,   serverQueue       =   Nothing               }     ideR <- newIORef ide     (`reflectIDE` ideR) f >>= putMVar result@@ -168,4 +163,17 @@         out <- getText buffer first last True         return $ T.pack input == out)     assert result++-- workaround for issue with $quickcheckall+-- see https://hackage.haskell.org/package/QuickCheck-2.4.2/docs/Test-QuickCheck-All.html+return []++testEditors :: IO Bool+testEditors = do+    result <- newEmptyMVar+    postGUIAsync $ do+        $quickCheckAll >>= putMVar result+        mainQuit+    mainGUI+    takeMVar result 
tests/Tests.hs view
@@ -46,6 +46,9 @@ 
 prop_parseHiddenModule2 = parseHiddenModule testString2 == Just HiddenModuleResult {hiddenModule = "Data.Attoparsec.Lazy", missingPackage = PackageIdentifier {pkgName = PackageName "attoparsec", pkgVersion = Version {versionBranch = [0,10,2,0], versionTags = []}}}
 +-- workaround for issue with $quickcheckall+-- see https://hackage.haskell.org/package/QuickCheck-2.4.2/docs/Test-QuickCheck-All.html+return [] main = do     result <- newEmptyMVar     forkIO $ do