    --
    -- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons
    -- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)
    --
    -- Syntactic sugar for developing plugins.
    -- Simplifies import lists, and abstracts over common patterns
    --
    module Lambdabot.Plugin
        ( Module(..)
        , ModuleT
        , newModule

        , LB
        , MonadLB(..)
        , lim80
        , ios80

        , ChanName
        , mkCN
        , getCN

        , Nick(..)
        , ircPrivmsg

        , module Lambdabot.Config
        , module Lambdabot.Config.Core
        , module Lambdabot.Command
        , module Lambdabot.State
        , module Lambdabot.File
        , module Lambdabot.Util.Serial
        ) where

    import Lambdabot.Bot
    import Lambdabot.ChanName
    import Lambdabot.Config
    import Lambdabot.Config.Core
    import Lambdabot.Command hiding (runCommand, execCmd)
    import Lambdabot.File
    import Lambdabot.Module
    import Lambdabot.Monad
    import Lambdabot.Nick
    import Lambdabot.State
    import Lambdabot.Util
    import Lambdabot.Util.Serial

    import Codec.Binary.UTF8.String
    import Control.Monad
    import Control.Monad.Trans
    import Data.Char

    lim80 :: Monad m => m String -> Cmd m ()
    lim80 :: forall (m :: * -> *). Monad m => m String -> Cmd m ()
    lim80 m String
    action = do
        to <- Cmd m Nick
    forall (m :: * -> *). Monad m => Cmd m Nick
    getTarget
        let lim = case Nick -> String
    nName Nick
    to of
                      (Char
    '#':String
    _) -> Int -> [String] -> [String]
    forall a. Int -> [a] -> [a]
    take Int
    3 ([String] -> [String])
    -> ([String] -> [String]) -> [String] -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int -> String -> String
    limitStr Int
    80) -- message to channel: be nice
                      String
    _       -> [String] -> [String]
    forall a. a -> a
    id          -- private message: get everything
            spaceOut = [String] -> String
    unlines ([String] -> String) -> (String -> [String]) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> [String]
    lim ([String] -> [String])
    -> (String -> [String]) -> String -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (Char
    ' 'Char -> String -> String
    forall a. a -> [a] -> [a]
    :) ([String] -> [String])
    -> (String -> [String]) -> String -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> [String]
    lines
            removeControl = (Char -> Bool) -> String -> String
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\Char
    x -> Char -> Bool
    isSpace Char
    x Bool -> Bool -> Bool
    || Bool -> Bool
    not (Char -> Bool
    isControl Char
    x))
        (say =<<) . lift $ liftM (encodeString . spaceOut . removeControl . decodeString) action

    -- | convenience, similar to ios but also cut output to channel to 80 characters
    -- usage:  @process _ _ to _ s = ios80 to (plugs s)@
    ios80 :: MonadIO m => IO String -> Cmd m ()
    ios80 :: forall (m :: * -> *). MonadIO m => IO String -> Cmd m ()
    ios80 = m String -> Cmd m ()
    forall (m :: * -> *). Monad m => m String -> Cmd m ()
    lim80 (m String -> Cmd m ())
    -> (IO String -> m String) -> IO String -> Cmd m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO String -> m String
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    io