    {-# LANGUAGE OverloadedStrings #-}
    {-# OPTIONS_HADDOCK show-extensions #-}

    -- |
    -- Module      :  Yi.Keymap.Vim.Ex.Commands.Number
    -- License     :  GPL-2
    -- Maintainer  :  yi-devel@googlegroups.com
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- Toggles line numbers.

    module Yi.Keymap.Vim.Ex.Commands.Number (parse) where

    import qualified Data.Attoparsec.Text             as P (string)
    import           Data.Monoid                      ((<>))
    import           Yi.Editor                        (printMsg, withCurrentBuffer)
    import           Yi.Keymap                        (Action (BufferA, EditorA))
    import           Yi.Keymap.Vim.Common             (EventString)
    import           Yi.Keymap.Vim.Ex.Commands.Common (BoolOptionAction (..), parseBoolOption, pureExCommand)
    import qualified Yi.Keymap.Vim.Ex.Commands.Common as Ex (parse)
    import           Yi.Keymap.Vim.Ex.Types           (ExCommand (..), evStringToExCommand)
    import           Yi.String                        (showT)
    import           Yi.UI.LineNumbers                (getDisplayLineNumbersLocal, setDisplayLineNumbersLocal)

    -- | Defines the following commands:
    -- - :set [no]number        (toggle buffer-local line numbers)
    -- - :unset number          (make the current buffer use the global setting)
    parse :: EventString -> Maybe ExCommand
    parse :: EventString -> Maybe ExCommand
    parse = [EventString -> Maybe ExCommand] -> EventString -> Maybe ExCommand
    evStringToExCommand
      [ Text
    -> (BoolOptionAction -> Action) -> EventString -> Maybe ExCommand
    parseBoolOption Text
    "number" BoolOptionAction -> Action
    actionSet
      , EventString -> Maybe ExCommand
    parseUnset
      ]

    actionSet :: BoolOptionAction -> Action
    actionSet :: BoolOptionAction -> Action
    actionSet BoolOptionAction
    BoolOptionAsk = EditorM () -> Action
    forall a. Show a => EditorM a -> Action
    EditorA (EditorM () -> Action) -> EditorM () -> Action
    forall a b. (a -> b) -> a -> b
    $ do
      mb <- BufferM (Maybe Bool) -> EditorM (Maybe Bool)
    forall (m :: * -> *) a. MonadEditor m => BufferM a -> m a
    withCurrentBuffer BufferM (Maybe Bool)
    getDisplayLineNumbersLocal
      printMsg $ "number = " <> case mb of
        Maybe Bool
    Nothing -> Text
    "<unset>"
        Just Bool
    b  -> Bool -> Text
    forall a. Show a => a -> Text
    showT Bool
    b
    actionSet (BoolOptionSet Bool
    b) = BufferM () -> Action
    forall a. Show a => BufferM a -> Action
    BufferA (BufferM () -> Action) -> BufferM () -> Action
    forall a b. (a -> b) -> a -> b
    $ Maybe Bool -> BufferM ()
    setDisplayLineNumbersLocal (Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    b)
    actionSet BoolOptionAction
    BoolOptionInvert = BufferM () -> Action
    forall a. Show a => BufferM a -> Action
    BufferA (BufferM () -> Action) -> BufferM () -> Action
    forall a b. (a -> b) -> a -> b
    $ do
      b <- BufferM (Maybe Bool)
    getDisplayLineNumbersLocal
      setDisplayLineNumbersLocal (fmap not b)

    parseUnset :: EventString -> Maybe ExCommand
    parseUnset :: EventString -> Maybe ExCommand
    parseUnset = Parser ExCommand -> EventString -> Maybe ExCommand
    Ex.parse (Parser ExCommand -> EventString -> Maybe ExCommand)
    -> Parser ExCommand -> EventString -> Maybe ExCommand
    forall a b. (a -> b) -> a -> b
    $ do
      _ <- Text -> Parser Text
    P.string Text
    "unset number"
      return $ pureExCommand
        { cmdShow = "unset number"
        , cmdAction = BufferA $ setDisplayLineNumbersLocal Nothing
        }