packages feed

yi-dynamic-configuration 0.15.0 → 0.16.0

raw patch · 3 files changed

+308/−2 lines, 3 filesdep +data-defaultdep ~yi-corePVP ok

version bump matches the API change (PVP)

Dependencies added: data-default

Dependency ranges changed: yi-core

API changes (from Hackage documentation)

+ Yi.Main: ConsoleConfig :: [String] -> Bool -> IO FilePath -> ConsoleConfig
+ Yi.Main: [ghcOptions] :: ConsoleConfig -> [String]
+ Yi.Main: [selfCheck] :: ConsoleConfig -> Bool
+ Yi.Main: [userConfigDir] :: ConsoleConfig -> IO FilePath
+ Yi.Main: data ConsoleConfig
+ Yi.Main: do_args :: Bool -> Config -> [String] -> Either OptionError (Config, ConsoleConfig)
+ Yi.Main: main :: (Config, ConsoleConfig) -> Maybe Editor -> IO ()
+ Yi.Option: OptionError :: Text -> ExitCode -> OptionError
+ Yi.Option: consYiOption :: YiOptionDescr -> Config -> Config
+ Yi.Option: consYiOptions :: [YiOptionDescr] -> Config -> Config
+ Yi.Option: data OptionError
+ Yi.Option: data YiOptions
+ Yi.Option: instance Data.Default.Class.Default Yi.Option.YiOptions
+ Yi.Option: instance Yi.Types.YiConfigVariable Yi.Option.YiOptions
+ Yi.Option: type YiOption = Config -> Either OptionError Config
+ Yi.Option: type YiOptionDescr = OptDescr YiOption
+ Yi.Option: yiActionFlagOption :: Action -> ArgDescr YiOption
+ Yi.Option: yiActionOption :: IsString a => (a -> Action) -> String -> ArgDescr YiOption
+ Yi.Option: yiActionOption' :: IsString a => (a -> Either OptionError Action) -> String -> ArgDescr YiOption
+ Yi.Option: yiBoolOption :: Lens' Config Bool -> ArgDescr YiOption
+ Yi.Option: yiCustomOptions :: Lens' Config [YiOptionDescr]
+ Yi.Option: yiFlagOption :: Lens' Config a -> (a -> a) -> ArgDescr YiOption
+ Yi.Option: yiStringOption :: IsString a => Lens' Config a -> String -> ArgDescr YiOption
+ Yi.Option: yiStringOption' :: IsString a => Lens' Config (Maybe a) -> String -> ArgDescr YiOption

Files

+ src/Yi/Main.hs view
@@ -0,0 +1,178 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings #-}++-- | This is the main module of Yi, called with configuration from the user.+-- Here we mainly process command line arguments.++module Yi.Main (+                -- * Static main+                main,+                -- * Command line processing+                do_args,+                ConsoleConfig(..),+               ) where++import Control.Monad+import Data.Char+import Data.Monoid+import qualified Data.Text as T+import Data.List (intercalate)+import Data.Version (showVersion)+import Lens.Micro.Platform (view)+import System.Console.GetOpt+import System.Exit+#ifndef HLINT+#include "ghcconfig.h"+#endif++import Yi.Buffer+import Yi.Config+import Yi.Core (startEditor)+import Yi.Debug+import Yi.Editor+import Yi.File+import Yi.Keymap+import Yi.Option (YiOption, OptionError(..), yiCustomOptions)+import Yi.Paths (getConfigDir)+import Paths_yi_core++-- | Configuration information which can be set in the command-line, but not+-- in the user's configuration file.+data ConsoleConfig =+  ConsoleConfig {+     ghcOptions :: [String],+     selfCheck :: Bool,+     userConfigDir :: IO FilePath+  }++defaultConsoleConfig :: ConsoleConfig+defaultConsoleConfig =+  ConsoleConfig {+                  ghcOptions = [],+                  selfCheck = False,+                  userConfigDir = Yi.Paths.getConfigDir+                }++-- ---------------------------------------------------------------------+-- | Argument parsing. Pretty standard.++data Opts = Help+          | Version+          | LineNo String+          | EditorNm String+          | File String+          | Frontend String+          | ConfigFile String+          | SelfCheck+          | GhcOption String+          | Debug+          | OpenInTabs+          | CustomNoArg YiOption+          | CustomReqArg (String -> YiOption) String+          | CustomOptArg (Maybe String -> YiOption) (Maybe String)++-- | List of editors for which we provide an emulation.+editors :: [(String,Config -> Config)]+editors = []++builtinOptions :: [OptDescr Opts]+builtinOptions =+  [ Option []     ["self-check"]  (NoArg  SelfCheck)             "Run self-checks"+  , Option ['f']  ["frontend"]    (ReqArg Frontend   "FRONTEND") frontendHelp+  , Option ['y']  ["config-file"] (ReqArg ConfigFile "PATH")     "Specify a folder containing a configuration yi.hs file"+  , Option ['V']  ["version"]     (NoArg  Version)               "Show version information"+  , Option ['h']  ["help"]        (NoArg  Help)                  "Show this help"+  , Option []     ["debug"]       (NoArg  Debug)                 "Write debug information in a log file"+  , Option ['l']  ["line"]        (ReqArg LineNo     "NUM")      "Start on line number"+  , Option []     ["as"]          (ReqArg EditorNm   "EDITOR")   editorHelp+  , Option []     ["ghc-option"]  (ReqArg GhcOption  "OPTION")   "Specify option to pass to ghc when compiling configuration file"+  , Option [openInTabsShort] [openInTabsLong] (NoArg  OpenInTabs)  "Open files in tabs"+  ] where frontendHelp = "Select frontend"+          editorHelp   = "Start with editor keymap, where editor is one of:\n" ++ (intercalate ", " . fmap fst) editors++convertCustomOption :: OptDescr YiOption -> OptDescr Opts+convertCustomOption (Option short long desc help) = Option short long desc' help+    where desc' = convertCustomArgDesc desc++convertCustomArgDesc :: ArgDescr YiOption -> ArgDescr Opts+convertCustomArgDesc (NoArg o) = NoArg (CustomNoArg o)+convertCustomArgDesc (ReqArg f s) = ReqArg (CustomReqArg f) s+convertCustomArgDesc (OptArg f s) = OptArg (CustomOptArg f) s++customOptions :: Config -> [OptDescr Opts]+customOptions = fmap convertCustomOption . view yiCustomOptions++openInTabsShort :: Char+openInTabsShort = 'p'++openInTabsLong :: String+openInTabsLong = "open-in-tabs"++-- | usage string.+usage :: [OptDescr Opts] -> T.Text+usage opts = T.pack $ usageInfo "Usage: yi [option...] [file]" opts++versinfo :: T.Text+versinfo = "yi " <> T.pack (showVersion version)++-- | Transform the config with options+do_args :: Bool -> Config -> [String] -> Either OptionError (Config, ConsoleConfig)+do_args ignoreUnknown cfg args = let options = customOptions cfg ++ builtinOptions in+    case getOpt' (ReturnInOrder File) options args of+        (os, [], [], []) -> handle options os+        (os, _, u:us, []) -> if ignoreUnknown+                                    then handle options os+                                    else fail $ "unknown arguments: " ++ intercalate ", " (u:us)+        (_os, _ex, _ey, errs) -> fail (concat errs)+    where+        shouldOpenInTabs = ("--" ++ openInTabsLong) `elem` args+                         || ('-':[openInTabsShort]) `elem` args+        handle options os = foldM (getConfig options shouldOpenInTabs) (cfg, defaultConsoleConfig) (reverse os)++-- | Update the default configuration based on a command-line option.+getConfig :: [OptDescr Opts] -> Bool -> (Config, ConsoleConfig) -> Opts -> Either OptionError (Config, ConsoleConfig)+getConfig options shouldOpenInTabs (cfg, cfgcon) opt =+    case opt of+      Frontend _    -> fail "Panic: frontend not found"+      Help          -> Left $ OptionError (usage options) ExitSuccess+      Version       -> Left $ OptionError versinfo ExitSuccess+      Debug         -> return (cfg { debugMode = True }, cfgcon)+      LineNo l      -> case startActions cfg of+                         x : xs -> return (cfg { startActions = x:makeAction (gotoLn (read l)):xs }, cfgcon)+                         []     -> fail "The `-l' option must come after a file argument"++      File filename -> if shouldOpenInTabs && not (null (startActions cfg)) then+                         prependActions [YiA $ openNewFile filename, EditorA newTabE]+                       else+                         prependAction $ openNewFile filename++      EditorNm emul -> case lookup (fmap toLower emul) editors of+             Just modifyCfg -> return (modifyCfg cfg, cfgcon)+             Nothing -> fail $ "Unknown emulation: " ++ show emul+      GhcOption ghcOpt -> return (cfg, cfgcon { ghcOptions = ghcOptions cfgcon ++ [ghcOpt] })+      ConfigFile f -> return (cfg, cfgcon { userConfigDir = return f })+      CustomNoArg o -> do+          cfg' <- o cfg+          return (cfg', cfgcon)+      CustomReqArg f s -> do+          cfg' <- f s cfg+          return (cfg', cfgcon)+      CustomOptArg f s -> do+          cfg' <- f s cfg+          return (cfg', cfgcon)+      _ -> return (cfg, cfgcon)+  where+    prependActions as = return (cfg { startActions = fmap makeAction as ++ startActions cfg }, cfgcon)+    prependAction a = return (cfg { startActions = makeAction a : startActions cfg}, cfgcon)++-- ---------------------------------------------------------------------+-- | Static main. This is the front end to the statically linked+-- application, and the real front end, in a sense. 'dynamic_main' calls+-- this after setting preferences passed from the boot loader.+--+main :: (Config, ConsoleConfig) -> Maybe Editor -> IO ()+main (cfg, _cfgcon) state = do+  when (debugMode cfg) $ initDebug ".yi.dbg"+  startEditor cfg state
+ src/Yi/Option.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE Rank2Types #-}+{-# OPTIONS_HADDOCK show-extensions #-}++-- |+-- Module      :  Yi.Option+-- License     :  GPL-2+-- Maintainer  :  yi-devel@googlegroups.com+-- Stability   :  experimental+-- Portability :  portable+--+-- Command-line options++module Yi.Option+    (+    -- * Types+      YiOption+    , YiOptionDescr+    , YiOptions+    , OptionError(..)++    -- * Core+    , yiCustomOptions+    , consYiOption+    , consYiOptions++    -- * Argument-less options+    , yiBoolOption+    , yiFlagOption+    , yiActionFlagOption++    -- * Argument-taking options+    , yiStringOption+    , yiStringOption'+    , yiActionOption+    , yiActionOption'+    )+where++import           Data.Default          (Default)+import qualified Data.Text             as T (Text)+import           Data.Typeable         (Typeable)+import           Data.String           (IsString, fromString)+import           Lens.Micro.Platform   (Lens', makeLenses, over, set)+import           System.Exit           (ExitCode)+import           System.Console.GetOpt (OptDescr, ArgDescr(..))+import           Yi.Config.Lens        (configVariable, startActionsA)+import           Yi.Types              (Action, Config, YiConfigVariable)++data OptionError = OptionError T.Text ExitCode++-- | An option is a function that attempts to change the configuration of the+-- editor at runtime.+type YiOption = Config -> Either OptionError Config++type YiOptionDescr = OptDescr YiOption++-- | Custom options that should be accepted. Provided in user configuration.+--+-- The general flow is that the user adds options to his configuration. Options+-- are essentially functions describing how to modify the configuration at runtime.+-- When an option is called, it gets the current config and may modify it (to encode+-- its value)+newtype YiOptions = YiOptions { _yiOptions :: [YiOptionDescr] }+    deriving (Default, Typeable)++instance YiConfigVariable YiOptions++makeLenses ''YiOptions++-- | Lens for accessing the list of custom options.+--+-- You can pretty much create whatever types of options you want with this.+-- But most cases are taken care of by one of the helper functions in this module.+yiCustomOptions :: Lens' Config [YiOptionDescr]+yiCustomOptions = configVariable . yiOptions++-- | Includes an extra option in the configuration. Small wrapper around 'yiCustomOptions'+consYiOption :: YiOptionDescr -> Config -> Config+consYiOption opt = over yiCustomOptions (opt:)++-- | Like 'consYiOption' but supports multiple options. Convenient for keymaps which might+-- want to install lots of options.+consYiOptions :: [YiOptionDescr] -> Config -> Config+consYiOptions opts = over yiCustomOptions (opts++)++-- | An argument which sets some configuration value to 'True'.+yiBoolOption :: Lens' Config Bool -> ArgDescr YiOption+yiBoolOption lens = NoArg $ Right . set lens True++-- | An argument which applies a function transforming some inner value of+-- the configuration.+yiFlagOption :: Lens' Config a -> (a -> a) -> ArgDescr YiOption+yiFlagOption lens f = NoArg $ Right . over lens f++-- | Flag that appends an action to the startup actions.+yiActionFlagOption :: Action -> ArgDescr YiOption+yiActionFlagOption action = NoArg f+    where f config = Right $ over startActionsA (++[action]) config+ +-- | Sets the value of an option which is any string type (hopefully text...)+--+-- This is not meant to be fully applied. By only passing in the lens you+-- will obtain a value suitable for use in OptDescr.+yiStringOption :: IsString a => Lens' Config a -> String -> ArgDescr YiOption+yiStringOption lens desc = ReqArg f desc+    where f string config = Right $ set lens (fromString string) config++-- | Just like 'yiStringOption', except it applies a 'Just'. Useful for setting+-- string-like values whose default is 'None'.+yiStringOption' :: IsString a => Lens' Config (Maybe a) -> String -> ArgDescr YiOption+yiStringOption' lens desc = ReqArg f desc+    where f string config = Right $ set lens (Just $ fromString string) config++-- | Option that appends a parameterized action to the startup actions.+yiActionOption :: IsString a => (a -> Action) -> String -> ArgDescr YiOption+yiActionOption action desc = ReqArg f desc+    where f string config = Right $ over startActionsA (++[action (fromString string)]) config++yiActionOption' :: IsString a => (a -> Either OptionError Action) -> String -> ArgDescr YiOption+yiActionOption' action desc = ReqArg f desc+    where f string config = do+            action' <- action (fromString string)+            return $ over startActionsA (++[action']) config
yi-dynamic-configuration.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           yi-dynamic-configuration-version:        0.15.0+version:        0.16.0 synopsis:       Dynamic configuration support for Yi category:       Yi homepage:       https://github.com/yi-editor/yi#readme@@ -22,8 +22,9 @@       src   build-depends:       base >= 4.8 && < 5+    , data-default     , dyre >= 0.8.11-    , yi-core >= 0.15.0+    , yi-core >= 0.16.0     , transformers-base     , mtl >= 0.1.0.1     , microlens-platform@@ -32,6 +33,8 @@   exposed-modules:       Yi.Boot       Yi.Boot.Internal+      Yi.Main+      Yi.Option   other-modules:       Paths_yi_dynamic_configuration   default-language: Haskell2010