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 +3/−2
- data/keymap.lkshk +1/−1
- data/leksah-welcome/src/Main.hs +2/−2
- data/leksah.menu +39/−32
- leksah.cabal +21/−10
- osx/launcher.sh +0/−1
- osx/leksah.bundle +0/−8
- osx/makedmg.sh +0/−3
- osx/makedmgs.sh +6/−6
- pics/ide_cabal_file.png binary
- pics/ide_component.png binary
- pics/ide_error.png binary
- pics/ide_folder.png binary
- pics/ide_package.png binary
- pics/ide_source.png binary
- pics/ide_source_dependency.png binary
- pics/ide_source_folder.png binary
- pics/ide_suggestion.png binary
- pics/ide_warning.png binary
- src/IDE/BufferMode.hs +9/−1
- src/IDE/Command.hs +118/−84
- src/IDE/Completion.hs +0/−1
- src/IDE/Core/State.hs +1/−1
- src/IDE/Core/Types.hs +31/−10
- src/IDE/Find.hs +64/−60
- src/IDE/HLint.hs +7/−7
- src/IDE/ImportTool.hs +9/−0
- src/IDE/Leksah.hs +1/−2
- src/IDE/LogRef.hs +5/−5
- src/IDE/Metainfo/Provider.hs +72/−49
- src/IDE/OSX.hs +1/−1
- src/IDE/Package.hs +121/−67
- src/IDE/Pane/Errors.hs +309/−151
- src/IDE/Pane/Files.hs +50/−287
- src/IDE/Pane/Grep.hs +1/−1
- src/IDE/Pane/Info.hs +1/−1
- src/IDE/Pane/Modules.hs +31/−11
- src/IDE/Pane/PackageEditor.hs +15/−12
- src/IDE/Pane/Preferences.hs +0/−936
- src/IDE/Pane/SourceBuffer.hs +100/−26
- src/IDE/Pane/WebKit/Documentation.hs +0/−1
- src/IDE/Pane/WebKit/Output.hs +1/−1
- src/IDE/Pane/Workspace.hs +648/−194
- src/IDE/PaneGroups.hs +2/−2
- src/IDE/Preferences.hs +965/−0
- src/IDE/Sandbox.hs +45/−9
- src/IDE/Session.hs +46/−92
- src/IDE/TextEditor/Class.hs +16/−9
- src/IDE/TextEditor/CodeMirror.hs +99/−94
- src/IDE/TextEditor/GtkSourceView.hs +3/−3
- src/IDE/Utils/DirectoryUtils.hs +75/−0
- src/IDE/Utils/GUIUtils.hs +158/−27
- src/IDE/Utils/GtkBindings.hs +32/−0
- src/IDE/Workspaces.hs +10/−6
- tests/IDE/TextEditor/Tests.hs +18/−10
- tests/Tests.hs +3/−0
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)
@@ -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