3Module : Idris.CmdOptions
4Description : A parser for the CmdOptions for the Idris executable.
6Maintainer : The Idris Community.
11module Idris.CmdOptions
12 ( opt, getClient, getPkg, getPkgCheck, getPkgClean, getPkgMkDoc,
13 getPkgREPL, getPkgTest, getPort, getIBCSubDir,
14 pureArgParser, execArgParserPure, runArgParser
17import Idris.Info (getIdrisVersion)
19import IRTS.CodegenCommon
21import qualified Control.Monad.Fail as Fail
22import Control.Monad.Trans (lift)
23import Control.Monad.Trans.Except (throwE)
24import Control.Monad.Trans.Reader (ask)
27import Data.Monoid ((<>))
28import Options.Applicative
29import Options.Applicative.Arrows
30import Options.Applicative.Types (ReadM(..))
32import Text.ParserCombinators.ReadP hiding (many, option)
35import qualified Text.PrettyPrint.ANSI.Leijen as PP
37runArgParser :: IO [Opt]
38runArgParser = do opts <- execParser $ info parser
40 <> headerDoc (Just idrisHeader)
41 <> progDescDoc (Just idrisProgDesc)
42 <> footerDoc (Just idrisFooter)
44 return $ preProcOpts opts
46 idrisHeader = PP.hsep [PP.text "Idris version", PP.text getIdrisVersion, PP.text ", (C) The Idris Community 2016"]
47 idrisProgDesc = PP.vsep [PP.empty,
48 PP.text "Idris is a general purpose pure functional programming language with dependent",
49 PP.text "types. Dependent types allow types to be predicated on values, meaning that",
50 PP.text "some aspects of a program's behaviour can be specified precisely in the type.",
51 PP.text "It is compiled, with eager evaluation. Its features are influenced by Haskell",
54 PP.vsep $ map (PP.indent 4 . PP.text) [
55 "+ Full dependent types with dependent pattern matching",
56 "+ Simple case expressions, where-clauses, with-rule",
57 "+ Pattern matching let- and lambda-bindings",
58 "+ Overloading via Interfaces (Type class-like), Monad comprehensions",
59 "+ do-notation, idiom brackets",
60 "+ Syntactic conveniences for lists, tuples, dependent pairs",
61 "+ Totality checking",
62 "+ Coinductive types",
63 "+ Indentation significant syntax, Extensible syntax",
64 "+ Tactic based theorem proving (influenced by Coq)",
65 "+ Cumulative universes",
66 "+ Simple Foreign Function Interface",
67 "+ Hugs style interactive environment"
69 idrisFooter = PP.vsep [PP.text "It is important to note that Idris is first and foremost a research tool",
70 PP.text "and project. Thus the tooling provided and resulting programs created",
71 PP.text "should not necessarily be seen as production ready nor for industrial use.",
73 PP.text "More details over Idris can be found online here:",
75 PP.indent 4 (PP.text "https://www.idris-lang.org/")]
77execArgParserPure :: [String] -> ParserResult [Opt]
78execArgParserPure args = preProcOpts <$> execParserPure (prefs idm) (info parser idm) args
80pureArgParser :: [String] -> [Opt]
81pureArgParser args = case getParseResult (execArgParserPure args) of
82 Just opts -> preProcOpts opts
86parser = runA $ proc () -> do
87 flags <- asA parseFlags -< ()
88 files <- asA (many $ argument (fmap Filename str) (metavar "FILES")) -< ()
89 A parseVersion >>> A helper -< (flags ++ files)
91parseFlags :: Parser [Opt]
93 flag' NoBanner (long "nobanner" <> help "Suppress the banner")
94 <|> flag' Quiet (short 'q' <> long "quiet" <> help "Quiet verbosity")
96 -- IDE Mode Specific Flags
97 <|> flag' Idemode (long "ide-mode" <> help "Run the Idris REPL with machine-readable syntax")
98 <|> flag' IdemodeSocket (long "ide-mode-socket" <> help "Choose a socket for IDE mode to listen on")
101 <|> Client <$> strOption (long "client")
104 <|> OLogging <$> option auto (long "log" <> metavar "LEVEL" <> help "Debugging log level")
105 <|> OLogCats <$> option (str >>= parseLogCats)
106 (long "logging-categories"
108 <> help "Colon separated logging categories. Use --listlogcats to see list.")
111 <|> flag' NoBasePkgs (long "nobasepkgs" <> help "Do not use the given base package")
112 <|> flag' NoPrelude (long "noprelude" <> help "Do not use the given prelude")
113 <|> flag' NoBuiltins (long "nobuiltins" <> help "Do not use the builtin functions")
115 <|> flag' NoREPL (long "check" <> help "Typecheck only, don't start the REPL")
117 <|> Output <$> strOption (short 'o' <> long "output" <> metavar "FILE" <> help "Specify output file")
119 -- <|> flag' TypeCase (long "typecase")
120 <|> flag' Interface (long "interface" <> help "Generate interface files from ExportLists")
121 <|> flag' TypeInType (long "typeintype" <> help "Turn off Universe checking")
122 <|> flag' DefaultTotal (long "total" <> help "Require functions to be total by default")
123 <|> flag' DefaultPartial (long "partial")
124 <|> flag' WarnPartial (long "warnpartial" <> help "Warn about undeclared partial functions")
125 <|> flag' WarnReach (long "warnreach" <> help "Warn about reachable but inaccessible arguments")
126 <|> flag' AuditIPkg (long "warnipkg" <> help "Warn about possible incorrect package specifications")
127 <|> flag' NoCoverage (long "nocoverage")
128 <|> flag' ErrContext (long "errorcontext")
131 <|> flag' ShowAll (long "info" <> help "Display information about installation.")
132 <|> flag' ShowLoggingCats (long "listlogcats" <> help "Display logging categories")
133 <|> flag' ShowLibs (long "link" <> help "Display link flags")
134 <|> flag' ShowPkgs (long "listlibs" <> help "Display installed libraries")
135 <|> flag' ShowLibDir (long "libdir" <> help "Display library directory")
136 <|> flag' ShowDocDir (long "docdir" <> help "Display idrisdoc install directory")
137 <|> flag' ShowIncs (long "include" <> help "Display the includes flags")
139 <|> flag' (Verbose 3) (long "V2" <> help "Loudest verbosity")
140 <|> flag' (Verbose 2) (long "V1" <> help "Louder verbosity")
141 <|> flag' (Verbose 1) (short 'V' <> long "V0" <>long "verbose" <> help "Loud verbosity")
143 <|> IBCSubDir <$> strOption (long "ibcsubdir" <> metavar "FILE" <> help "Write IBC files into sub directory")
144 <|> ImportDir <$> strOption (short 'i' <> long "idrispath" <> help "Add directory to the list of import paths")
145 <|> SourceDir <$> strOption (long "sourcepath" <> help "Add directory to the list of source search paths")
147 <|> flag' WarnOnly (long "warn")
149 <|> Pkg <$> strOption (short 'p' <> long "package" <> help "Add package as a dependency")
150 <|> Port <$> option portReader (long "port" <> metavar "PORT" <> help "REPL TCP port - pass \"none\" to not bind any port")
153 <|> PkgBuild <$> strOption (long "build" <> metavar "IPKG" <> help "Build package")
154 <|> PkgInstall <$> strOption (long "install" <> metavar "IPKG" <> help "Install package")
155 <|> PkgREPL <$> strOption (long "repl" <> metavar "IPKG" <> help "Launch REPL, only for executables")
156 <|> PkgClean <$> strOption (long "clean" <> metavar "IPKG" <> help "Clean package")
157 <|> (PkgDocBuild <$> strOption (long "mkdoc" <> metavar "IPKG" <> help "Generate IdrisDoc for package"))
158 <|> PkgDocInstall <$> strOption (long "installdoc" <> metavar "IPKG" <> help "Install IdrisDoc for package")
159 <|> PkgCheck <$> strOption (long "checkpkg" <> metavar "IPKG" <> help "Check package only")
160 <|> PkgTest <$> strOption (long "testpkg" <> metavar "IPKG" <> help "Run tests for package")
162 -- Interactive Editing Flags
163 <|> IndentWith <$> option auto (long "indent-with"
165 <> help "Indentation to use with :makewith (default 2)")
166 <|> IndentClause <$> option auto (long "indent-clause"
168 <> help "Indentation to use with :addclause (default 2)")
171 <|> BCAsm <$> strOption (long "bytecode")
173 <|> flag' (OutputTy Raw) (short 'S' <> long "codegenonly" <> help "Do no further compilation of code generator output")
174 <|> flag' (OutputTy Object) (short 'c' <> long "compileonly" <> help "Compile to object files rather than an executable")
176 <|> DumpDefun <$> strOption (long "dumpdefuns")
177 <|> DumpCases <$> strOption (long "dumpcases")
179 <|> (UseCodegen . parseCodegen) <$> strOption (long "codegen"
181 <> help "Select code generator: C, Javascript, Node and bytecode are bundled with Idris")
183 <|> ((UseCodegen . Via JSONFormat) <$> strOption (long "portable-codegen"
185 <> help "Pass the name of the code generator. This option is for codegens that take JSON formatted IR."))
187 <|> CodegenArgs <$> strOption (long "cg-opt"
189 <> help "Arguments to pass to code generator")
191 <|> EvalExpr <$> strOption (long "eval"
194 <> help "Evaluate an expression without loading the REPL")
196 <|> flag' (InterpretScript "Main.main") (long "execute" <> help "Execute as idris")
197 <|> InterpretScript <$> strOption (long "exec" <> metavar "EXPR" <> help "Execute as idris")
199 <|> ((Extension . getExt) <$> strOption (long "extension"
202 <> help "Turn on language extension (TypeProviders or ErrorReflection)"))
204 -- Optimisation Levels
205 <|> flag' (OptLevel 3) (long "O3")
206 <|> flag' (OptLevel 2) (long "O2")
207 <|> flag' (OptLevel 1) (long "O1")
208 <|> flag' (OptLevel 0) (long "O0")
210 <|> flag' (AddOpt PETransform) (long "partial-eval")
211 <|> flag' (RemoveOpt PETransform) (long "no-partial-eval" <> help "Switch off partial evaluation, mainly for debugging purposes")
213 <|> flag' (AddOpt GeneralisedNatHack) (
214 long "optimise-nat-like-types"
215 <> long "optimize-nat-like-types"
216 <> help "Enable compilation of Nat-like types to bigints"
218 <|> flag' (RemoveOpt GeneralisedNatHack) (
219 long "no-optimise-nat-like-types"
220 <> long "no-optimize-nat-like-types"
221 <> help "Disable compilation of Nat-like types to bigints"
224 <|> OptLevel <$> option auto (short 'O' <> long "level")
226 <|> TargetTriple <$> strOption (long "target" <> metavar "TRIPLE" <> help "If supported the codegen will target the named triple.")
227 <|> TargetCPU <$> strOption (long "cpu" <> metavar "CPU" <> help "If supported the codegen will target the named CPU e.g. corei7 or cortex-m3")
230 <|> flag' (ColourREPL True) (long "colour" <> long "color" <> help "Force coloured output")
231 <|> flag' (ColourREPL False) (long "nocolour" <> long "nocolor" <> help "Disable coloured output")
233 <|> (UseConsoleWidth <$> option (str >>= parseConsoleWidth) (long "consolewidth" <> metavar "WIDTH" <> help "Select console width: auto, infinite, nat"))
235 <|> flag' DumpHighlights (long "highlight" <> help "Emit source code highlighting")
237 <|> flag' NoOldTacticDeprecationWarnings (long "no-tactic-deprecation-warnings" <> help "Disable deprecation warnings for the old tactic sublanguage")
238 <|> flag' AllowCapitalizedPatternVariables (long "allow-capitalized-pattern-variables" <> help "Allow pattern variables to be capitalized")
241 getExt :: String -> LanguageExt
242 getExt s = fromMaybe (error ("Unknown extension " ++ s)) (maybeRead s)
243 maybeRead :: String -> Maybe LanguageExt
244 maybeRead = fmap fst . listToMaybe . reads
245 portReader :: ReadM REPLPort
247 ((ListenPort . fromIntegral) <$> auto) <|>
248 (ReadM $ do opt <- ask
249 if map toLower opt == "none"
250 then return $ DontListen
251 else lift $ throwE $ ErrorMsg $
252 "got " <> opt <> " expected port number or \"none\"")
254parseVersion :: Parser (a -> a)
255parseVersion = infoOption getIdrisVersion (short 'v' <> long "version" <> help "Print version information")
257preProcOpts :: [Opt] -> [Opt]
258preProcOpts (NoBuiltins : xs) = NoBuiltins : NoPrelude : preProcOpts xs
259preProcOpts (Output s : xs) = Output s : NoREPL : preProcOpts xs
260preProcOpts (BCAsm s : xs) = BCAsm s : NoREPL : preProcOpts xs
261preProcOpts (x:xs) = x : preProcOpts xs
264parseCodegen :: String -> Codegen
265parseCodegen "bytecode" = Bytecode
266parseCodegen cg = Via IBCFormat (map toLower cg)
268parseLogCats :: Fail.MonadFail m => String -> m [LogCat]
270 case lastMay (readP_to_S doParse s) of
271 Just (xs, _) -> return xs
272 _ -> fail "Incorrect categories specified"
274 doParse :: ReadP [LogCat]
276 cs <- sepBy1 parseLogCat (char ':')
280 parseLogCat :: ReadP [LogCat]
281 parseLogCat = (string (strLogCat IParse) *> return parserCats)
282 <|> (string (strLogCat IElab) *> return elabCats)
283 <|> (string (strLogCat ICodeGen) *> return codegenCats)
284 <|> (string (strLogCat ICoverage) *> return [ICoverage])
285 <|> (string (strLogCat IIBC) *> return [IIBC])
286 <|> (string (strLogCat IErasure) *> return [IErasure])
289 parseLogCatBad :: ReadP [LogCat]
292 fail $ "Category: " ++ s ++ " is not recognised."
294parseConsoleWidth :: Fail.MonadFail m => String -> m ConsoleWidth
295parseConsoleWidth "auto" = return AutomaticWidth
296parseConsoleWidth "infinite" = return InfinitelyWide
298 case lastMay (readP_to_S integerReader s) of
299 Just (r, _) -> return $ ColsWide r
300 _ -> fail $ "Cannot parse: " ++ s
302integerReader :: ReadP Int
304 digits <- many1 $ satisfy isDigit
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list