    {-# LANGUAGE CPP #-}
    {-# LANGUAGE Rank2Types #-}
    {-# OPTIONS_GHC -fno-warn-duplicate-exports #-}
    {-# OPTIONS_HADDOCK show-extensions #-}

    -- |
    -- Module      :  Yi.Config.Simple
    -- License     :  GPL-2
    -- Maintainer  :  yi-devel@googlegroups.com
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- A simplified configuration interface for Yi.
    --
    -- This module provides a simple configuration API, allowing users to
    -- start with an initial configuration and imperatively (monadically)
    -- modify it. Some common actions (keybindings, selecting modes,
    -- choosing the frontend) have been given special commands
    -- ('globalBindKeys', 'setFrontendPreferences', 'addMode', and so on).
    --
    -- A simple configuration might look like the following:
    --
    -- @
    -- import Yi.Config.Simple
    -- import Yi.Boot
    -- import qualified Yi.Mode.Haskell as Haskell
    -- -- note: don't import "Yi", or else there will be name clashes
    --
    -- main = 'configMain' 'defaultEmacsConfig' $ do
    --   'fontSize' '%=' 'Just' 10
    --   'modeBindKeys' Haskell.cleverMode ('metaCh' \'q\' '?>>!' 'reload')
    --   'globalBindKeys' ('metaCh' \'r\' '?>>!' 'reload')
    -- @
    --
    -- A lot of the fields here are specified with the 'Field' type. To write
    -- a field, use ('%='). To read, use 'get'. For modification, use
    -- ('modify'). For example, the functions @foo@ and @bar@ are equivalent:
    --
    -- @
    -- foo = 'modify' 'layoutManagers' 'reverse'
    -- bar = do
    --  lms <- 'get' 'layoutManagers'
    --  'layoutManagers' '%=' 'reverse' lms
    -- @

    module Yi.Config.Simple (
      -- * The main interface
      ConfigM,
      Field,
      -- * Modes, commands, and keybindings
      globalBindKeys,
      modeBindKeys,
      modeBindKeysByName,
      addMode,
      modifyMode,
      modifyModeByName,
      -- * Evaluation of commands
      evaluator,
    #ifdef HINT
      ghciEvaluator,
    #endif
      publishedActionsEvaluator,
      publishAction,
      publishedActions,
      -- * Appearance
      fontName,
      fontSize,
      scrollWheelAmount,
      scrollStyle,
      ScrollStyle(..),
      cursorStyle,
      CursorStyle(..),
      Side(..),
      scrollBarSide,
      autoHideScrollBar,
      autoHideTabBar,
      lineWrap,
      windowFill,
      theme,
      lineNumbers,
      -- ** Layout
      layoutManagers,
      -- * Debugging
      debug,
      -- * Startup hooks
      runOnStartup,
      runAfterStartup,
      -- * Advanced
      -- $advanced
      startActions,
      initialActions,
      defaultKm,
      inputPreprocess,
      modes,
      regionStyle,
      killringAccumulate,
      bufferUpdateHandler,
      -- * Module exports

      -- we can't just export 'module Yi', because then we would get
      -- clashes with Yi.Config
      module Yi.Buffer,
      module Yi.Core,
      module Yi.Dired,
      module Yi.Editor,
      module Yi.File,
      module Yi.Config,
      module Yi.Config.Default,
      module Yi.Keymap,
      module Yi.Keymap.Keys,
      module Yi.Layout,
      module Yi.Search,
      module Yi.Style,
      module Yi.Style.Library,
      module Yi.Misc,
     ) where

    import           Lens.Micro.Platform (Lens', (%=), (%~), use, lens)
    import qualified Data.Text as T
    import qualified Data.Sequence as S
    import           Text.Printf(printf)
    import           Yi.Buffer hiding (modifyMode)
    import           Yi.Config.Default
    import           Yi.Config.Misc
    import           Yi.Config.Simple.Types
    import           Yi.Core
    import           Yi.Dired
    import           Yi.Editor
    import           Yi.Eval
    import           Yi.File
    import           Yi.Keymap
    import           Yi.Keymap.Keys
    import           Yi.Layout
    import           Yi.Misc
    import           Yi.Search
    import           Yi.Style
    import           Yi.Style.Library
    import           Yi.Utils

    -- we do explicit imports because we reuse a lot of the names
    import           Yi.Config(Config, UIConfig, startFrontEndA, configUIA,
                               startActionsA, initialActionsA, defaultKmA,
                               configInputPreprocessA, modeTableA, debugModeA,
                               configRegionStyleA, configKillringAccumulateA,
                               bufferUpdateHandlerA, configFontNameA,
                               configFontSizeA, configScrollWheelAmountA,
                               configScrollStyleA, configCursorStyleA,
                               CursorStyle(..), configLeftSideScrollBarA,
                               configAutoHideScrollBarA, configAutoHideTabBarA,
                               configLineWrapA, configWindowFillA, configThemeA,
                               layoutManagersA, configVarsA, configLineNumbersA
                               )

    --------------- Main interface
    -- newtype ConfigM a   (imported)

    ------------------------- Modes, commands, and keybindings
    -- | Adds the given key bindings to the `global keymap'. The bindings
    -- will override existing bindings in the case of a clash.
    globalBindKeys :: Keymap -> ConfigM ()
    globalBindKeys :: Keymap -> ConfigM ()
    globalBindKeys Keymap
    a = ((KeymapSet -> Identity KeymapSet) -> Config -> Identity Config
    Lens' Config KeymapSet
    defaultKmA ((KeymapSet -> Identity KeymapSet) -> Config -> Identity Config)
    -> ((Keymap -> Identity Keymap) -> KeymapSet -> Identity KeymapSet)
    -> (Keymap -> Identity Keymap)
    -> Config
    -> Identity Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Keymap -> Identity Keymap) -> KeymapSet -> Identity KeymapSet
    Lens' KeymapSet Keymap
    topKeymapA) ((Keymap -> Identity Keymap) -> Config -> Identity Config)
    -> (Keymap -> Keymap) -> ConfigM ()
    forall s (m :: * -> *) a b.
    MonadState s m =>
    ASetter s s a b -> (a -> b) -> m ()
    %= (Keymap -> Keymap -> Keymap
    forall (f :: * -> *) w e a.
    MonadInteract f w e =>
    f a -> f a -> f a
    ||> Keymap
    a)

    -- | @modeBindKeys mode keys@ adds the keybindings in @keys@ to all
    -- modes with the same name as @mode@.
    --
    -- As with 'modifyMode', a mode by the given name must already be
    -- registered, or the function will have no effect, and issue a
    -- command-line warning.
    modeBindKeys :: Mode syntax -> Keymap -> ConfigM ()
    modeBindKeys :: forall syntax. Mode syntax -> Keymap -> ConfigM ()
    modeBindKeys Mode syntax
    mode Keymap
    keys =
      String -> Text -> ConfigM () -> ConfigM ()
    ensureModeRegistered String
    "modeBindKeys" (Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    mode) ConfigM ()
    boundKeys
      where
        boundKeys :: ConfigM ()
    boundKeys = Text -> Keymap -> ConfigM ()
    modeBindKeysByName (Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    mode) Keymap
    keys

    -- | @modeBindKeysByName name keys@ adds the keybindings in @keys@ to
    -- all modes with name @name@ (if it is registered). Consider using
    -- 'modeBindKeys' instead.
    modeBindKeysByName :: T.Text -> Keymap -> ConfigM ()
    modeBindKeysByName :: Text -> Keymap -> ConfigM ()
    modeBindKeysByName Text
    name Keymap
    k =
      String -> Text -> ConfigM () -> ConfigM ()
    ensureModeRegistered String
    "modeBindKeysByName" Text
    name ConfigM ()
    modMode
      where
        f :: (KeymapSet -> KeymapSet) -> KeymapSet -> KeymapSet
        f :: (KeymapSet -> KeymapSet) -> KeymapSet -> KeymapSet
    f KeymapSet -> KeymapSet
    mkm KeymapSet
    km = (Keymap -> Identity Keymap) -> KeymapSet -> Identity KeymapSet
    Lens' KeymapSet Keymap
    topKeymapA ((Keymap -> Identity Keymap) -> KeymapSet -> Identity KeymapSet)
    -> (Keymap -> Keymap) -> KeymapSet -> KeymapSet
    forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
    %~ (Keymap -> Keymap -> Keymap
    forall (f :: * -> *) w e a.
    MonadInteract f w e =>
    f a -> f a -> f a
    ||> Keymap
    k) (KeymapSet -> KeymapSet) -> KeymapSet -> KeymapSet
    forall a b. (a -> b) -> a -> b
    $ KeymapSet -> KeymapSet
    mkm KeymapSet
    km

        modMode :: ConfigM ()
    modMode = Text -> (forall syntax. Mode syntax -> Mode syntax) -> ConfigM ()
    modifyModeByName Text
    name (((KeymapSet -> KeymapSet) -> Identity (KeymapSet -> KeymapSet))
    -> Mode syntax -> Identity (Mode syntax)
    forall syntax (f :: * -> *).
    Functor f =>
    ((KeymapSet -> KeymapSet) -> f (KeymapSet -> KeymapSet))
    -> Mode syntax -> f (Mode syntax)
    modeKeymapA (((KeymapSet -> KeymapSet) -> Identity (KeymapSet -> KeymapSet))
     -> Mode syntax -> Identity (Mode syntax))
    -> ((KeymapSet -> KeymapSet) -> KeymapSet -> KeymapSet)
    -> Mode syntax
    -> Mode syntax
    forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
    %~ (KeymapSet -> KeymapSet) -> KeymapSet -> KeymapSet
    f)

    -- | Register the given mode. It will be preferred over any modes
    -- already defined.
    addMode :: Mode syntax -> ConfigM ()
    addMode :: forall syntax. Mode syntax -> ConfigM ()
    addMode Mode syntax
    m = ([AnyMode] -> Identity [AnyMode]) -> Config -> Identity Config
    Lens' Config [AnyMode]
    modeTableA (([AnyMode] -> Identity [AnyMode]) -> Config -> Identity Config)
    -> ([AnyMode] -> [AnyMode]) -> ConfigM ()
    forall s (m :: * -> *) a b.
    MonadState s m =>
    ASetter s s a b -> (a -> b) -> m ()
    %= (Mode syntax -> AnyMode
    forall syntax. Mode syntax -> AnyMode
    AnyMode Mode syntax
    m AnyMode -> [AnyMode] -> [AnyMode]
    forall a. a -> [a] -> [a]
    :)

    -- | @modifyMode mode f@ modifies all modes with the same name as
    -- @mode@, using the function @f@.
    --
    -- Note that the @mode@ argument is only used by its 'modeName'. In
    -- particular, a mode by the given name must already be registered, or
    -- this function will have no effect, and issue a command-line
    -- warning.
    --
    -- @'modifyMode' mode f = 'modifyModeByName' ('modeName' mode) f@
    modifyMode :: Mode syntax
               -> (forall syntax'. Mode syntax' -> Mode syntax')
               -> ConfigM ()
    modifyMode :: forall syntax.
    Mode syntax
    -> (forall syntax. Mode syntax -> Mode syntax) -> ConfigM ()
    modifyMode Mode syntax
    mode forall syntax. Mode syntax -> Mode syntax
    f = String -> Text -> ConfigM () -> ConfigM ()
    ensureModeRegistered String
    "modifyMode" (Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    mode) ConfigM ()
    modMode
      where
        modMode :: ConfigM ()
    modMode = Text -> (forall syntax. Mode syntax -> Mode syntax) -> ConfigM ()
    modifyModeByName (Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    mode) Mode syntax -> Mode syntax
    forall syntax. Mode syntax -> Mode syntax
    f

    -- | @modifyModeByName name f@ modifies the mode with name @name@
    -- using the function @f@. Consider using 'modifyMode' instead.
    modifyModeByName :: T.Text
                     -> (forall syntax. Mode syntax -> Mode syntax)
                     -> ConfigM ()
    modifyModeByName :: Text -> (forall syntax. Mode syntax -> Mode syntax) -> ConfigM ()
    modifyModeByName Text
    name forall syntax. Mode syntax -> Mode syntax
    f =
        String -> Text -> ConfigM () -> ConfigM ()
    ensureModeRegistered String
    "modifyModeByName" Text
    name (ConfigM () -> ConfigM ()) -> ConfigM () -> ConfigM ()
    forall a b. (a -> b) -> a -> b
    $ ([AnyMode] -> Identity [AnyMode]) -> Config -> Identity Config
    Lens' Config [AnyMode]
    modeTableA (([AnyMode] -> Identity [AnyMode]) -> Config -> Identity Config)
    -> ([AnyMode] -> [AnyMode]) -> ConfigM ()
    forall s (m :: * -> *) a b.
    MonadState s m =>
    ASetter s s a b -> (a -> b) -> m ()
    %= (AnyMode -> AnyMode) -> [AnyMode] -> [AnyMode]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((forall syntax. Mode syntax -> Mode syntax) -> AnyMode -> AnyMode
    onMode Mode syntax -> Mode syntax
    forall syntax. Mode syntax -> Mode syntax
    g)
            where
                g :: forall syntax. Mode syntax -> Mode syntax
                g :: forall syntax. Mode syntax -> Mode syntax
    g Mode syntax
    m | Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    m Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    name = Mode syntax -> Mode syntax
    forall syntax. Mode syntax -> Mode syntax
    f Mode syntax
    m
                    | Bool
    otherwise          = Mode syntax
    m

    -- helper functions
    warn :: String -> String -> ConfigM ()
    warn :: String -> String -> ConfigM ()
    warn String
    caller String
    msg = IO () -> ConfigM ()
    forall (m :: * -> *) a. MonadBase IO m => IO a -> m a
    io (IO () -> ConfigM ()) -> IO () -> ConfigM ()
    forall a b. (a -> b) -> a -> b
    $ String -> IO ()
    putStrLn (String -> IO ()) -> String -> IO ()
    forall a b. (a -> b) -> a -> b
    $ String -> String -> String -> String
    forall r. PrintfType r => String -> r
    printf String
    "Warning: %s: %s" String
    caller String
    msg
    -- the putStrLn shouldn't be necessary, but it doesn't print anything
    -- if it's not there...

    isModeRegistered :: T.Text -> ConfigM Bool
    isModeRegistered :: Text -> ConfigM Bool
    isModeRegistered Text
    name =
      (AnyMode -> Bool) -> [AnyMode] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (\(AnyMode Mode syntax
    mode) -> Mode syntax -> Text
    forall syntax. Mode syntax -> Text
    modeName Mode syntax
    mode Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    name) ([AnyMode] -> Bool) -> ConfigM [AnyMode] -> ConfigM Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Getting [AnyMode] Config [AnyMode] -> ConfigM [AnyMode]
    forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
    use Getting [AnyMode] Config [AnyMode]
    Lens' Config [AnyMode]
    modeTableA

    -- ensure the given mode is registered, and if it is, then run the given action.
    ensureModeRegistered :: String -> T.Text -> ConfigM () -> ConfigM ()
    ensureModeRegistered :: String -> Text -> ConfigM () -> ConfigM ()
    ensureModeRegistered String
    caller Text
    name ConfigM ()
    m = do
      isRegistered <- Text -> ConfigM Bool
    isModeRegistered Text
    name
      if isRegistered
       then m
       else warn caller (printf "mode \"%s\" is not registered." (T.unpack name))

    --------------------- Appearance
    -- | 'Just' the font name, or 'Nothing' for default.
    fontName :: Field (Maybe String)
    fontName :: Field (Maybe String)
    fontName = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Maybe String -> f (Maybe String)) -> UIConfig -> f UIConfig)
    -> (Maybe String -> f (Maybe String))
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Maybe String -> f (Maybe String)) -> UIConfig -> f UIConfig
    Lens' UIConfig (Maybe String)
    configFontNameA

    -- | 'Just' the font size, or 'Nothing' for default.
    fontSize :: Field (Maybe Int)
    fontSize :: Field (Maybe Int)
    fontSize = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Maybe Int -> f (Maybe Int)) -> UIConfig -> f UIConfig)
    -> (Maybe Int -> f (Maybe Int))
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Maybe Int -> f (Maybe Int)) -> UIConfig -> f UIConfig
    Lens' UIConfig (Maybe Int)
    configFontSizeA

    -- | Amount to move the buffer when using the scroll wheel.
    scrollWheelAmount :: Field Int
    scrollWheelAmount :: Field Int
    scrollWheelAmount = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Int -> f Int) -> UIConfig -> f UIConfig)
    -> (Int -> f Int)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int -> f Int) -> UIConfig -> f UIConfig
    Lens' UIConfig Int
    configScrollWheelAmountA

    -- | 'Just' the scroll style, or 'Nothing' for default.
    scrollStyle :: Field (Maybe ScrollStyle)
    scrollStyle :: Field (Maybe ScrollStyle)
    scrollStyle = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Maybe ScrollStyle -> f (Maybe ScrollStyle))
        -> UIConfig -> f UIConfig)
    -> (Maybe ScrollStyle -> f (Maybe ScrollStyle))
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Maybe ScrollStyle -> f (Maybe ScrollStyle))
    -> UIConfig -> f UIConfig
    Lens' UIConfig (Maybe ScrollStyle)
    configScrollStyleA

    -- | See 'CursorStyle' for documentation.
    cursorStyle :: Field CursorStyle
    cursorStyle :: Field CursorStyle
    cursorStyle = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((CursorStyle -> f CursorStyle) -> UIConfig -> f UIConfig)
    -> (CursorStyle -> f CursorStyle)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (CursorStyle -> f CursorStyle) -> UIConfig -> f UIConfig
    Lens' UIConfig CursorStyle
    configCursorStyleA

    data Side = LeftSide | RightSide

    -- | Which side to display the scroll bar on.
    scrollBarSide :: Field Side
    scrollBarSide :: Field Side
    scrollBarSide = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Side -> f Side) -> UIConfig -> f UIConfig)
    -> (Side -> f Side)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Bool -> f Bool) -> UIConfig -> f UIConfig
    Lens' UIConfig Bool
    configLeftSideScrollBarA ((Bool -> f Bool) -> UIConfig -> f UIConfig)
    -> ((Side -> f Side) -> Bool -> f Bool)
    -> (Side -> f Side)
    -> UIConfig
    -> f UIConfig
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Side -> f Side) -> Bool -> f Bool
    Lens' Bool Side
    fromBool
      where
        fromBool :: Lens' Bool Side
        fromBool :: Lens' Bool Side
    fromBool = (Bool -> Side) -> (Bool -> Side -> Bool) -> Lens' Bool Side
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens (\Bool
    b -> if Bool
    b then Side
    LeftSide else Side
    RightSide)
                        (\Bool
    _ Side
    s -> case Side
    s of { Side
    LeftSide -> Bool
    True; Side
    RightSide -> Bool
    False })

    -- | Should the scroll bar autohide?
    autoHideScrollBar :: Field Bool
    autoHideScrollBar :: Field Bool
    autoHideScrollBar = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Bool -> f Bool) -> UIConfig -> f UIConfig)
    -> (Bool -> f Bool)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Bool -> f Bool) -> UIConfig -> f UIConfig
    Lens' UIConfig Bool
    configAutoHideScrollBarA

    -- | Should the tab bar autohide?
    autoHideTabBar :: Field Bool
    autoHideTabBar :: Field Bool
    autoHideTabBar = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Bool -> f Bool) -> UIConfig -> f UIConfig)
    -> (Bool -> f Bool)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Bool -> f Bool) -> UIConfig -> f UIConfig
    Lens' UIConfig Bool
    configAutoHideTabBarA

    -- | Should lines be wrapped?
    lineWrap :: Field Bool
    lineWrap :: Field Bool
    lineWrap = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Bool -> f Bool) -> UIConfig -> f UIConfig)
    -> (Bool -> f Bool)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Bool -> f Bool) -> UIConfig -> f UIConfig
    Lens' UIConfig Bool
    configLineWrapA

    -- | The character with which to fill empty window space. Usually
    -- \'~\' for vi-like editors, \' \' for everything else.
    windowFill :: Field Char
    windowFill :: Field Char
    windowFill = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Char -> f Char) -> UIConfig -> f UIConfig)
    -> (Char -> f Char)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> f Char) -> UIConfig -> f UIConfig
    Lens' UIConfig Char
    configWindowFillA

    -- | UI colour theme.
    theme :: Field Theme
    theme :: Field Theme
    theme = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Theme -> f Theme) -> UIConfig -> f UIConfig)
    -> (Theme -> f Theme)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Theme -> f Theme) -> UIConfig -> f UIConfig
    Lens' UIConfig Theme
    configThemeA

    -- | Line numbers.
    lineNumbers :: Field Bool
    lineNumbers :: Field Bool
    lineNumbers = (UIConfig -> f UIConfig) -> Config -> f Config
    Lens' Config UIConfig
    configUIA ((UIConfig -> f UIConfig) -> Config -> f Config)
    -> ((Bool -> f Bool) -> UIConfig -> f UIConfig)
    -> (Bool -> f Bool)
    -> Config
    -> f Config
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Bool -> f Bool) -> UIConfig -> f UIConfig
    Lens' UIConfig Bool
    configLineNumbersA

    ---------- Layout
    -- | List of registered layout managers. When cycling through layouts,
    -- this list will be consulted.
    layoutManagers :: Field [AnyLayoutManager]
    layoutManagers :: Field [AnyLayoutManager]
    layoutManagers = ([AnyLayoutManager] -> f [AnyLayoutManager]) -> Config -> f Config
    Field [AnyLayoutManager]
    layoutManagersA

    ------------------------ Debugging
    -- | Produce a .yi.dbg file with debugging information?
    debug :: Field Bool
    debug :: Field Bool
    debug = (Bool -> f Bool) -> Config -> f Config
    Field Bool
    debugModeA

    ----------- Startup hooks
    -- | Run when the editor is started (this is run after all actions
    -- which have already been registered)
    runOnStartup :: Action -> ConfigM ()
    runOnStartup :: Action -> ConfigM ()
    runOnStartup Action
    action = [Action] -> ConfigM ()
    runManyOnStartup [Action
    action]

    -- | List version of 'runOnStartup'.
    runManyOnStartup :: [Action] -> ConfigM ()
    runManyOnStartup :: [Action] -> ConfigM ()
    runManyOnStartup [Action]
    actions = ([Action] -> Identity [Action]) -> Config -> Identity Config
    Field [Action]
    startActions (([Action] -> Identity [Action]) -> Config -> Identity Config)
    -> ([Action] -> [Action]) -> ConfigM ()
    forall s (m :: * -> *) a b.
    MonadState s m =>
    ASetter s s a b -> (a -> b) -> m ()
    %= ([Action] -> [Action] -> [Action]
    forall a. [a] -> [a] -> [a]
    ++ [Action]
    actions)

    -- | Run after the startup actions have completed, or on reload (this
    -- is run after all actions which have already been registered)
    runAfterStartup :: Action -> ConfigM ()
    runAfterStartup :: Action -> ConfigM ()
    runAfterStartup Action
    action = [Action] -> ConfigM ()
    runManyAfterStartup [Action
    action]

    -- | List version of 'runAfterStartup'.
    runManyAfterStartup :: [Action] -> ConfigM ()
    runManyAfterStartup :: [Action] -> ConfigM ()
    runManyAfterStartup [Action]
    actions = ([Action] -> Identity [Action]) -> Config -> Identity Config
    Field [Action]
    initialActions (([Action] -> Identity [Action]) -> Config -> Identity Config)
    -> ([Action] -> [Action]) -> ConfigM ()
    forall s (m :: * -> *) a b.
    MonadState s m =>
    ASetter s s a b -> (a -> b) -> m ()
    %= ([Action] -> [Action] -> [Action]
    forall a. [a] -> [a] -> [a]
    ++ [Action]
    actions)

    ------------------------ Advanced
    {- $advanced

    These fields are here for completeness -- that is, to expose all the
    functionality of the "Yi.Config" module. However, most users probably
    need not use these fields, typically because they provide advanced
    functionality, or because a simpler interface for the common case is
    available above.

    -}

    -- | Actions to run when the editor is started. Consider using
    -- 'runOnStartup' or 'runManyOnStartup' instead.
    startActions :: Field [Action]
    startActions :: Field [Action]
    startActions = ([Action] -> f [Action]) -> Config -> f Config
    Field [Action]
    startActionsA

    -- | Actions to run after startup or reload. Consider using
    -- 'runAfterStartup' or 'runManyAfterStartup' instead.
    initialActions :: Field [Action]
    initialActions :: Field [Action]
    initialActions = ([Action] -> f [Action]) -> Config -> f Config
    Field [Action]
    initialActionsA

    -- | Default keymap to use.
    defaultKm :: Field KeymapSet
    defaultKm :: Lens' Config KeymapSet
    defaultKm = (KeymapSet -> f KeymapSet) -> Config -> f Config
    Lens' Config KeymapSet
    defaultKmA

    -- | ?
    inputPreprocess :: Field (P Event Event)
    inputPreprocess :: Field (P Event Event)
    inputPreprocess = (P Event Event -> f (P Event Event)) -> Config -> f Config
    Field (P Event Event)
    configInputPreprocessA

    -- | List of modes by order of preference. Consider using 'addMode',
    -- 'modeBindKeys', or 'modifyMode' instead.
    modes :: Field [AnyMode]
    modes :: Lens' Config [AnyMode]
    modes = ([AnyMode] -> f [AnyMode]) -> Config -> f Config
    Lens' Config [AnyMode]
    modeTableA

    -- | Set to 'Exclusive' for an emacs-like behaviour. Consider starting
    -- with 'defaultEmacsConfig', 'defaultVimConfig', or
    -- 'defaultCuaConfig' to instead.
    regionStyle :: Field RegionStyle
    regionStyle :: Field RegionStyle
    regionStyle = (RegionStyle -> f RegionStyle) -> Config -> f Config
    Field RegionStyle
    configRegionStyleA

    -- | Set to 'True' for an emacs-like behaviour, where all deleted text
    -- is accumulated in a killring. Consider starting with
    -- 'defaultEmacsConfig', 'defaultVimConfig', or 'defaultCuaConfig'
    -- instead.
    killringAccumulate :: Field Bool
    killringAccumulate :: Field Bool
    killringAccumulate = (Bool -> f Bool) -> Config -> f Config
    Field Bool
    configKillringAccumulateA

    -- | ?
    bufferUpdateHandler :: Field (S.Seq (S.Seq Update -> BufferM ()))
    bufferUpdateHandler :: Field (Seq (Seq Update -> BufferM ()))
    bufferUpdateHandler = (Seq (Seq Update -> BufferM ())
     -> f (Seq (Seq Update -> BufferM ())))
    -> Config -> f Config
    Field (Seq (Seq Update -> BufferM ()))
    bufferUpdateHandlerA