Optparse-applicative

This commit is contained in:
Nikolay Yakimov
2015-12-05 23:55:12 +03:00
parent bff86be69f
commit ad16b739eb
11 changed files with 534 additions and 505 deletions

View File

@@ -12,7 +12,7 @@ import Language.Haskell.GhcMod.Modules
boot :: IOish m => GhcModT m String
boot = concat <$> sequence ms
where
ms = [modules, languages, flags, concat <$> mapM browse preBrowsedModules]
ms = [modules False, languages, flags, concat <$> mapM (browse (BrowseOpts False False False)) preBrowsedModules]
preBrowsedModules :: [String]
preBrowsedModules = [

View File

@@ -1,5 +1,6 @@
module Language.Haskell.GhcMod.Browse (
browse
browse,
BrowseOpts(..)
) where
import Control.Applicative
@@ -14,7 +15,6 @@ import Language.Haskell.GhcMod.Convert
import Language.Haskell.GhcMod.Doc (showPage, styleUnqualified)
import Language.Haskell.GhcMod.Gap as Gap
import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Logging
import Name (getOccString)
import Outputable
@@ -25,13 +25,20 @@ import Prelude
----------------------------------------------------------------
data BrowseOpts = BrowseOpts {
optBrowseOperators :: Bool
, optBrowseDetailed :: Bool
, optBrowseQualified :: Bool
}
-- | Getting functions, classes, etc from a module.
-- If 'detailed' is 'True', their types are also obtained.
-- If 'operators' is 'True', operators are also returned.
browse :: forall m. IOish m
=> String -- ^ A module name. (e.g. \"Data.List\", "base:Prelude")
=> BrowseOpts
-> String -- ^ A module name. (e.g. \"Data.List\", "base:Prelude")
-> GhcModT m String
browse pkgmdl = do
browse opts pkgmdl = do
convert' . sort =<< go
where
-- TODO: Add API to Gm.Target to check if module is home module without
@@ -43,13 +50,11 @@ browse pkgmdl = do
gmLog GmException "browse" $ showDoc ex
goPkgModule = do
opt <- options
runGmPkgGhc $
processExports opt =<< tryModuleInfo =<< G.findModule mdlname mpkgid
processExports opts =<< tryModuleInfo =<< G.findModule mdlname mpkgid
goHomeModule = runGmlT [Right mdlname] $ do
opt <- options
processExports opt =<< tryModuleInfo =<< G.findModule mdlname Nothing
processExports opts =<< tryModuleInfo =<< G.findModule mdlname Nothing
tryModuleInfo m = fromJust <$> G.getModuleInfo m
@@ -80,31 +85,31 @@ isNotOp (h:_) = isAlpha h || (h == '_')
isNotOp _ = error "isNotOp"
processExports :: (G.GhcMonad m, MonadIO m, ExceptionMonad m)
=> Options -> ModuleInfo -> m [String]
=> BrowseOpts -> ModuleInfo -> m [String]
processExports opt minfo = do
let
removeOps
| optOperators opt = id
| optBrowseOperators opt = id
| otherwise = filter (isNotOp . getOccString)
mapM (showExport opt minfo) $ removeOps $ G.modInfoExports minfo
showExport :: forall m. (G.GhcMonad m, MonadIO m, ExceptionMonad m)
=> Options -> ModuleInfo -> Name -> m String
=> BrowseOpts -> ModuleInfo -> Name -> m String
showExport opt minfo e = do
mtype' <- mtype
return $ concat $ catMaybes [mqualified, Just $ formatOp $ getOccString e, mtype']
where
mqualified = (G.moduleNameString (G.moduleName $ G.nameModule e) ++ ".") `justIf` optQualified opt
mqualified = (G.moduleNameString (G.moduleName $ G.nameModule e) ++ ".") `justIf` optBrowseQualified opt
mtype :: m (Maybe String)
mtype
| optDetailed opt = do
| optBrowseDetailed opt = do
tyInfo <- G.modInfoLookupName minfo e
-- If nothing found, load dependent module and lookup global
tyResult <- maybe (inOtherModule e) (return . Just) tyInfo
dflag <- G.getSessionDynFlags
return $ do
typeName <- tyResult >>= showThing dflag
(" :: " ++ typeName) `justIf` optDetailed opt
(" :: " ++ typeName) `justIf` optBrowseDetailed opt
| otherwise = return Nothing
formatOp nm
| null nm = error "formatOp"

View File

@@ -5,22 +5,23 @@ import Control.Exception (SomeException(..))
import Language.Haskell.GhcMod.Logger (checkErrorPrefix)
import Language.Haskell.GhcMod.Convert
import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.Types
import Language.Haskell.HLint (hlint)
import Language.Haskell.GhcMod.Utils (withMappedFile)
import Data.List (stripPrefix)
data LintOpts = LintOpts { optLintHlintOpts :: [String] }
-- | Checking syntax of a target file using hlint.
-- Warnings and errors are returned.
lint :: IOish m
=> FilePath -- ^ A target file.
=> LintOpts
-> FilePath -- ^ A target file.
-> GhcModT m String
lint file = do
opt <- options
lint opt file =
withMappedFile file $ \tempfile ->
liftIO (hlint $ tempfile : "--quiet" : optHlintOpts opt)
liftIO (hlint $ tempfile : "--quiet" : optLintHlintOpts opt)
>>= mapM (replaceFileName tempfile)
>>= ghandle handler . pack
where

View File

@@ -14,13 +14,12 @@ import qualified GHC as G
----------------------------------------------------------------
-- | Listing installed modules.
modules :: (IOish m, Gm m) => m String
modules = do
Options { optDetailed } <- options
modules :: (IOish m, Gm m) => Bool -> m String
modules detailed = do
df <- runGmPkgGhc G.getSessionDynFlags
let mns = listVisibleModuleNames df
pmnss = map (first moduleNameString) $ zip mns (modulePkg df `map` mns)
convert' $ nub [ if optDetailed then pkg ++ " " ++ mn else mn
convert' $ nub [ if detailed then pkg ++ " " ++ mn else mn
| (mn, pkgs) <- pmnss, pkg <- pkgs ]
where
modulePkg df = lookupModulePackageInAllPackages df

View File

@@ -102,13 +102,6 @@ data Options = Options {
, optPrograms :: Programs
-- | GHC command line options set on the @ghc-mod@ command line
, optGhcUserOptions :: [GHCOption]
-- | If 'True', 'browse' also returns operators.
, optOperators :: Bool
-- | If 'True', 'browse' also returns types.
, optDetailed :: Bool
-- | If 'True', 'browse' will return fully qualified name
, optQualified :: Bool
, optHlintOpts :: [String]
, optFileMappings :: [(FilePath, Maybe FilePath)]
} deriving (Show)
@@ -128,10 +121,6 @@ defaultOptions = Options {
, stackProgram = "stack"
}
, optGhcUserOptions = []
, optOperators = False
, optDetailed = False
, optQualified = False
, optHlintOpts = []
, optFileMappings = []
}