{-# Language OverloadedStrings, TemplateHaskell #-}
{-|
Module      : Client.Commands.Window
Description : Window command implementations
Copyright   : (c) Eric Mertens, 2016-2020
License     : ISC
Maintainer  : emertens@gmail.com
-}

module Client.Commands.Window (windowCommands, parseFocus, focusNames) where

import Client.Commands.Arguments.Spec
import Client.Commands.Docs (windowDocs, cmdDoc)
import Client.Commands.TabCompletion
import Client.Commands.Types
import Client.Commands.WordCompletion (plainWordCompleteMode)
import Client.Mask (buildMask)
import Client.State
import Client.State.EditBox qualified as Edit
import Client.State.Focus
import Client.State.Network (csChannels)
import Client.State.Channel (chanJoined)
import Client.State.Window (windowClear, wlText, winMessages, winHidden, winActivityFilter, winName, activityFilterStrings, readActivityFilter)
import Control.Applicative (liftA2)
import Control.Exception (SomeException, Exception(displayException), try)
import Control.Lens
import Data.Foldable (Foldable(foldl', toList))
import Data.HashMap.Strict qualified as HashMap
import Data.HashSet (HashSet)
import Data.List ((\\), nub)
import Data.List.NonEmpty (NonEmpty((:|)))
import Data.Map qualified as Map
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Lazy qualified as LText
import Data.Text.Lazy.IO qualified as LText
import Irc.Identifier (Identifier, idText, mkId)

windowCommands :: CommandSection
windowCommands :: CommandSection
windowCommands = Text -> [Command] -> CommandSection
CommandSection Text
"Window management"
  ------------------------------------------------------------------------

  [ NonEmpty Text
-> Args ArgsContext (String, Maybe String)
-> Text
-> CommandImpl (String, Maybe String)
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"focus")
      ((String -> Maybe String -> (String, Maybe String))
-> Ap (Arg ArgsContext) String
-> Ap (Arg ArgsContext) (Maybe String)
-> Args ArgsContext (String, Maybe String)
forall a b c.
(a -> b -> c)
-> Ap (Arg ArgsContext) a
-> Ap (Arg ArgsContext) b
-> Ap (Arg ArgsContext) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"network") (Ap (Arg ArgsContext) String -> Ap (Arg ArgsContext) (Maybe String)
forall r a. Args r a -> Args r (Maybe a)
optionalArg (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"[target]")))
      $(windowDocs `cmdDoc` "focus")
    (CommandImpl (String, Maybe String) -> Command)
-> CommandImpl (String, Maybe String) -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand (String, Maybe String)
-> (Bool -> ClientCommand String)
-> CommandImpl (String, Maybe String)
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand (String, Maybe String)
cmdFocus Bool -> ClientCommand String
tabFocus

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text
"c" Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text
"channel"])
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"focus")
      $(windowDocs `cmdDoc` "channel")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand String
-> (Bool -> ClientCommand String) -> CommandImpl String
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand String
cmdChannel Bool -> ClientCommand String
tabChannel

  , NonEmpty Text
-> Args ArgsContext (Maybe (String, Maybe String))
-> Text
-> CommandImpl (Maybe (String, Maybe String))
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"clear")
      (Args ArgsContext (String, Maybe String)
-> Args ArgsContext (Maybe (String, Maybe String))
forall r a. Args r a -> Args r (Maybe a)
optionalArg ((String -> Maybe String -> (String, Maybe String))
-> Ap (Arg ArgsContext) String
-> Ap (Arg ArgsContext) (Maybe String)
-> Args ArgsContext (String, Maybe String)
forall a b c.
(a -> b -> c)
-> Ap (Arg ArgsContext) a
-> Ap (Arg ArgsContext) b
-> Ap (Arg ArgsContext) c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"[network]") (Ap (Arg ArgsContext) String -> Ap (Arg ArgsContext) (Maybe String)
forall r a. Args r a -> Args r (Maybe a)
optionalArg (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"[channel]"))))
      $(windowDocs `cmdDoc` "clear")
    (CommandImpl (Maybe (String, Maybe String)) -> Command)
-> CommandImpl (Maybe (String, Maybe String)) -> Command
forall a b. (a -> b) -> a -> b
$ WindowCommand (Maybe (String, Maybe String))
-> (Bool -> WindowCommand String)
-> CommandImpl (Maybe (String, Maybe String))
forall a.
WindowCommand a -> (Bool -> WindowCommand String) -> CommandImpl a
WindowCommand WindowCommand (Maybe (String, Maybe String))
cmdClear (\Bool
rev Focus
_ -> Bool -> ClientCommand String
tabFocus Bool
rev)

  , NonEmpty Text
-> Ap (Arg ArgsContext) (Maybe String)
-> Text
-> CommandImpl (Maybe String)
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"windows")
      (Ap (Arg ArgsContext) String -> Ap (Arg ArgsContext) (Maybe String)
forall r a. Args r a -> Args r (Maybe a)
optionalArg (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"[kind]"))
      $(windowDocs `cmdDoc` "windows")
    (CommandImpl (Maybe String) -> Command)
-> CommandImpl (Maybe String) -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand (Maybe String)
-> (Bool -> ClientCommand String) -> CommandImpl (Maybe String)
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand (Maybe String)
cmdWindows Bool -> ClientCommand String
tabWindows

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text
"splits" Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text
"s"])
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
remainingArg String
"focuses")
      $(windowDocs `cmdDoc` "splits")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand String
-> (Bool -> ClientCommand String) -> CommandImpl String
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand String
cmdSplits Bool -> ClientCommand String
tabSplits

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text
"splits+" Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text
"s+"])
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
remainingArg String
"focuses")
      $(windowDocs `cmdDoc` "splits")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand String
-> (Bool -> ClientCommand String) -> CommandImpl String
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand String
cmdSplitsAdd Bool -> ClientCommand String
tabSplits

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text
"splits-" Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text
"s-"])
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
remainingArg String
"focuses")
      $(windowDocs `cmdDoc` "splits")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand String
-> (Bool -> ClientCommand String) -> CommandImpl String
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand String
cmdSplitsDel Bool -> ClientCommand String
tabActiveSplits

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"ignore")
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
remainingArg String
"masks")
      $(windowDocs `cmdDoc` "ignore")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand String
-> (Bool -> ClientCommand String) -> CommandImpl String
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand String
cmdIgnore Bool -> ClientCommand String
tabIgnore

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text
"grep" Text -> [Text] -> NonEmpty Text
forall a. a -> [a] -> NonEmpty a
:| [Text
"g"])
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
remainingArg String
"regular-expression")
      $(windowDocs `cmdDoc` "grep")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand String
-> (Bool -> ClientCommand String) -> CommandImpl String
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand String
cmdGrep Bool -> ClientCommand String
simpleClientTab

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"dump")
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"filename")
      $(windowDocs `cmdDoc` "dump")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ WindowCommand String
-> (Bool -> WindowCommand String) -> CommandImpl String
forall a.
WindowCommand a -> (Bool -> WindowCommand String) -> CommandImpl a
WindowCommand WindowCommand String
cmdDump (\Bool
rev Focus
_ -> Bool -> ClientCommand String
simpleClientTab Bool
rev)

  , NonEmpty Text
-> Args ArgsContext () -> Text -> CommandImpl () -> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"mentions")
      (() -> Args ArgsContext ()
forall a. a -> Ap (Arg ArgsContext) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
      $(windowDocs `cmdDoc` "mentions")
    (CommandImpl () -> Command) -> CommandImpl () -> Command
forall a b. (a -> b) -> a -> b
$ ClientCommand ()
-> (Bool -> ClientCommand String) -> CommandImpl ()
forall a.
ClientCommand a -> (Bool -> ClientCommand String) -> CommandImpl a
ClientCommand ClientCommand ()
cmdMentions Bool -> ClientCommand String
noClientTab

  , NonEmpty Text
-> Ap (Arg ArgsContext) String
-> Text
-> CommandImpl String
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"setwindow")
      (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken (String
"hide|show" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (String -> String) -> [String] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Char
'|'Char -> String -> String
forall a. a -> [a] -> [a]
:) [String]
activityFilterStrings))
      $(windowDocs `cmdDoc` "setwindow")
    (CommandImpl String -> Command) -> CommandImpl String -> Command
forall a b. (a -> b) -> a -> b
$ WindowCommand String
-> (Bool -> WindowCommand String) -> CommandImpl String
forall a.
WindowCommand a -> (Bool -> WindowCommand String) -> CommandImpl a
WindowCommand WindowCommand String
cmdSetWindow Bool -> WindowCommand String
tabSetWindow

  , NonEmpty Text
-> Ap (Arg ArgsContext) (Maybe String)
-> Text
-> CommandImpl (Maybe String)
-> Command
forall a.
NonEmpty Text
-> Args ArgsContext a -> Text -> CommandImpl a -> Command
Command
      (Text -> NonEmpty Text
forall a. a -> NonEmpty a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"setname")
      (Ap (Arg ArgsContext) String -> Ap (Arg ArgsContext) (Maybe String)
forall r a. Args r a -> Args r (Maybe a)
optionalArg (String -> Ap (Arg ArgsContext) String
forall r. String -> Args r String
simpleToken String
"[letter]"))
      $(windowDocs `cmdDoc` "setname")
    (CommandImpl (Maybe String) -> Command)
-> CommandImpl (Maybe String) -> Command
forall a b. (a -> b) -> a -> b
$ WindowCommand (Maybe String)
-> (Bool -> WindowCommand String) -> CommandImpl (Maybe String)
forall a.
WindowCommand a -> (Bool -> WindowCommand String) -> CommandImpl a
WindowCommand WindowCommand (Maybe String)
cmdSetWindowName (\Bool
rev Focus
_ -> Bool -> ClientCommand String
noClientTab Bool
rev)
  ]

cmdSetWindowName :: WindowCommand (Maybe String)
cmdSetWindowName :: WindowCommand (Maybe String)
cmdSetWindowName Focus
focus ClientState
st Maybe String
arg =
  -- unset current name so that it becomes available
  let mbSt1 :: Maybe ClientState
mbSt1 = LensLike
  ((,) Any) ClientState ClientState (Maybe Char) (Maybe Char)
-> (Maybe Char -> Maybe Char) -> ClientState -> Maybe ClientState
forall (m :: * -> *) s t a b.
Alternative m =>
LensLike ((,) Any) s t a b -> (a -> b) -> s -> m t
failover ((Map Focus Window -> (Any, Map Focus Window))
-> ClientState -> (Any, ClientState)
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> (Any, Map Focus Window))
 -> ClientState -> (Any, ClientState))
-> ((Maybe Char -> (Any, Maybe Char))
    -> Map Focus Window -> (Any, Map Focus Window))
-> LensLike
     ((,) Any) ClientState ClientState (Maybe Char) (Maybe Char)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
focus ((Window -> (Any, Window))
 -> Map Focus Window -> (Any, Map Focus Window))
-> ((Maybe Char -> (Any, Maybe Char)) -> Window -> (Any, Window))
-> (Maybe Char -> (Any, Maybe Char))
-> Map Focus Window
-> (Any, Map Focus Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Char -> (Any, Maybe Char)) -> Window -> (Any, Window)
Lens' Window (Maybe Char)
winName) (\Maybe Char
_ -> Maybe Char
forall a. Maybe a
Nothing) ClientState
st in
  case Maybe ClientState
mbSt1 of
    Maybe ClientState
Nothing -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
"no current window" ClientState
st
    Just ClientState
st1 ->
      let next :: Char
next = Maybe WindowHint -> ClientState -> Char
clientNextWindowName (Focus -> ClientState -> Maybe WindowHint
clientWindowHint Focus
focus ClientState
st) ClientState
st
          mbName :: Either Text Char
mbName =
            case Maybe String
arg of
              Just [Char
n] | Char
n Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ClientState -> String
clientWindowNames ClientState
st -> Char -> Either Text Char
forall a b. b -> Either a b
Right Char
n
              Just String
_ -> Text -> Either Text Char
forall a b. a -> Either a b
Left Text
"invalid name"
              Maybe String
Nothing
                | Char
next Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\0' -> Char -> Either Text Char
forall a b. b -> Either a b
Right Char
next
                | Bool
otherwise -> Text -> Either Text Char
forall a b. a -> Either a b
Left Text
"no free names" in
      case Either Text Char
mbName of
        Left Text
e -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
e ClientState
st
        Right Char
name ->
          let unset :: Maybe Char -> Maybe Char
unset Maybe Char
n = if Maybe Char
n Maybe Char -> Maybe Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char -> Maybe Char
forall a. a -> Maybe a
Just Char
name then Maybe Char
forall a. Maybe a
Nothing else Maybe Char
n in
          ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess
            (ClientState -> IO CommandResult)
-> ClientState -> IO CommandResult
forall a b. (a -> b) -> a -> b
$ ASetter ClientState ClientState (Maybe Char) (Maybe Char)
-> Maybe Char -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> b -> s -> t
set  ((Map Focus Window -> Identity (Map Focus Window))
-> ClientState -> Identity ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Identity (Map Focus Window))
 -> ClientState -> Identity ClientState)
-> ((Maybe Char -> Identity (Maybe Char))
    -> Map Focus Window -> Identity (Map Focus Window))
-> ASetter ClientState ClientState (Maybe Char) (Maybe Char)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
focus ((Window -> Identity Window)
 -> Map Focus Window -> Identity (Map Focus Window))
-> ((Maybe Char -> Identity (Maybe Char))
    -> Window -> Identity Window)
-> (Maybe Char -> Identity (Maybe Char))
-> Map Focus Window
-> Identity (Map Focus Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Char -> Identity (Maybe Char)) -> Window -> Identity Window
Lens' Window (Maybe Char)
winName) (Char -> Maybe Char
forall a. a -> Maybe a
Just Char
name)
            (ClientState -> ClientState) -> ClientState -> ClientState
forall a b. (a -> b) -> a -> b
$ ASetter ClientState ClientState (Maybe Char) (Maybe Char)
-> (Maybe Char -> Maybe Char) -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ((Map Focus Window -> Identity (Map Focus Window))
-> ClientState -> Identity ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Identity (Map Focus Window))
 -> ClientState -> Identity ClientState)
-> ((Maybe Char -> Identity (Maybe Char))
    -> Map Focus Window -> Identity (Map Focus Window))
-> ASetter ClientState ClientState (Maybe Char) (Maybe Char)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Window -> Identity Window)
-> Map Focus Window -> Identity (Map Focus Window)
forall s t a b. Each s t a b => Traversal s t a b
Traversal (Map Focus Window) (Map Focus Window) Window Window
each     ((Window -> Identity Window)
 -> Map Focus Window -> Identity (Map Focus Window))
-> ((Maybe Char -> Identity (Maybe Char))
    -> Window -> Identity Window)
-> (Maybe Char -> Identity (Maybe Char))
-> Map Focus Window
-> Identity (Map Focus Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Char -> Identity (Maybe Char)) -> Window -> Identity Window
Lens' Window (Maybe Char)
winName) Maybe Char -> Maybe Char
unset
            (ClientState -> ClientState) -> ClientState -> ClientState
forall a b. (a -> b) -> a -> b
$ ClientState
st1

cmdSetWindow :: WindowCommand String
cmdSetWindow :: WindowCommand String
cmdSetWindow Focus
focus ClientState
st String
cmd =
  case Maybe (Window -> Window)
mbFun of
    Maybe (Window -> Window)
Nothing -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
"bad window setting" ClientState
st
    Just Window -> Window
f ->
      case LensLike ((,) Any) ClientState ClientState Window Window
-> (Window -> Window) -> ClientState -> Maybe ClientState
forall (m :: * -> *) s t a b.
Alternative m =>
LensLike ((,) Any) s t a b -> (a -> b) -> s -> m t
failover ((Map Focus Window -> (Any, Map Focus Window))
-> ClientState -> (Any, ClientState)
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> (Any, Map Focus Window))
 -> ClientState -> (Any, ClientState))
-> ((Window -> (Any, Window))
    -> Map Focus Window -> (Any, Map Focus Window))
-> LensLike ((,) Any) ClientState ClientState Window Window
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
focus) Window -> Window
f ClientState
st of
        Maybe ClientState
Nothing -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
"no such window" ClientState
st
        Just ClientState
st' -> ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess ClientState
st'
  where
    mbFun :: Maybe (Window -> Window)
mbFun =
      case String
cmd of
        String
"show"    -> (Window -> Window) -> Maybe (Window -> Window)
forall a. a -> Maybe a
Just (ASetter Window Window Bool Bool -> Bool -> Window -> Window
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Window Window Bool Bool
Lens' Window Bool
winHidden Bool
False)
        String
"hide"    -> (Window -> Window) -> Maybe (Window -> Window)
forall a. a -> Maybe a
Just (((Maybe Char -> Identity (Maybe Char))
 -> Window -> Identity Window)
-> Maybe Char -> Window -> Window
forall s t a b. ASetter s t a b -> b -> s -> t
set (Maybe Char -> Identity (Maybe Char)) -> Window -> Identity Window
Lens' Window (Maybe Char)
winName Maybe Char
forall a. Maybe a
Nothing (Window -> Window) -> (Window -> Window) -> Window -> Window
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ASetter Window Window Bool Bool -> Bool -> Window -> Window
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Window Window Bool Bool
Lens' Window Bool
winHidden Bool
True)
        String
other     -> ASetter Window Window ActivityFilter ActivityFilter
-> ActivityFilter -> Window -> Window
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter Window Window ActivityFilter ActivityFilter
Lens' Window ActivityFilter
winActivityFilter (ActivityFilter -> Window -> Window)
-> Maybe ActivityFilter -> Maybe (Window -> Window)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Maybe ActivityFilter
readActivityFilter String
other

tabSetWindow :: Bool {- ^ reversed -} -> WindowCommand String
tabSetWindow :: Bool -> WindowCommand String
tabSetWindow Bool
isReversed Focus
_ ClientState
st String
_ =
  WordCompletionMode
-> [Text] -> [Text] -> Bool -> ClientState -> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
plainWordCompleteMode [] [Text]
completions Bool
isReversed ClientState
st
  where
    completions :: [Text]
completions = Text
"hide"Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:Text
"show"Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (String -> Text) -> [String] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map String -> Text
Text.pack [String]
activityFilterStrings

-- | Implementation of @/grep@
cmdGrep :: ClientCommand String
cmdGrep :: ClientCommand String
cmdGrep ClientState
st String
str
  | String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
str  = ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (ASetter ClientState ClientState (Maybe Matcher) (Maybe Matcher)
-> Maybe Matcher -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter ClientState ClientState (Maybe Matcher) (Maybe Matcher)
Lens' ClientState (Maybe Matcher)
clientRegex Maybe Matcher
forall a. Maybe a
Nothing ClientState
st)
  | Bool
otherwise =
      case String -> Maybe Matcher
buildMatcher String
str of
        Maybe Matcher
Nothing -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
"bad grep" ClientState
st
        Just  Matcher
r -> ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (ASetter ClientState ClientState (Maybe Matcher) (Maybe Matcher)
-> Maybe Matcher -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter ClientState ClientState (Maybe Matcher) (Maybe Matcher)
Lens' ClientState (Maybe Matcher)
clientRegex (Matcher -> Maybe Matcher
forall a. a -> Maybe a
Just Matcher
r) ClientState
st)

-- | Implementation of @/windows@ command. Set subfocus to Windows.
cmdWindows :: ClientCommand (Maybe String)
cmdWindows :: ClientCommand (Maybe String)
cmdWindows ClientState
st Maybe String
arg =
  case Maybe String
arg of
    Maybe String
Nothing         -> WindowsFilter -> IO CommandResult
forall {m :: * -> *}. Monad m => WindowsFilter -> m CommandResult
success WindowsFilter
AllWindows
    Just String
"networks" -> WindowsFilter -> IO CommandResult
forall {m :: * -> *}. Monad m => WindowsFilter -> m CommandResult
success WindowsFilter
NetworkWindows
    Just String
"channels" -> WindowsFilter -> IO CommandResult
forall {m :: * -> *}. Monad m => WindowsFilter -> m CommandResult
success WindowsFilter
ChannelWindows
    Just String
"users"    -> WindowsFilter -> IO CommandResult
forall {m :: * -> *}. Monad m => WindowsFilter -> m CommandResult
success WindowsFilter
UserWindows
    Maybe String
_               -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
errmsg ClientState
st
  where
    errmsg :: Text
errmsg = Text
"/windows expected networks, channels, or users"
    success :: WindowsFilter -> m CommandResult
success WindowsFilter
x =
      ClientState -> m CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Subfocus -> ClientState -> ClientState
changeSubfocus (WindowsFilter -> Subfocus
FocusWindows WindowsFilter
x) ClientState
st)

-- | Implementation of @/mentions@ command. Set subfocus to Mentions.
cmdMentions :: ClientCommand ()
cmdMentions :: ClientCommand ()
cmdMentions ClientState
st ()
_ = ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Subfocus -> ClientState -> ClientState
changeSubfocus Subfocus
FocusMentions ClientState
st)

cmdIgnore :: ClientCommand String
cmdIgnore :: ClientCommand String
cmdIgnore ClientState
st String
rest =
  case Text -> Identifier
mkId (Text -> Identifier) -> [Text] -> [Identifier]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [Text]
Text.words (String -> Text
Text.pack String
rest) of
    [] -> ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Subfocus -> ClientState -> ClientState
changeSubfocus Subfocus
FocusIgnoreList ClientState
st)
    [Identifier]
xs -> ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess ClientState
st2
      where
        (HashSet Identifier
newIgnores, ClientState
st1) = ((HashSet Identifier -> (HashSet Identifier, HashSet Identifier))
-> ClientState -> (HashSet Identifier, ClientState)
Lens' ClientState (HashSet Identifier)
clientIgnores ((HashSet Identifier -> (HashSet Identifier, HashSet Identifier))
 -> ClientState -> (HashSet Identifier, ClientState))
-> (HashSet Identifier -> HashSet Identifier)
-> ClientState
-> (HashSet Identifier, ClientState)
forall b s t a. LensLike ((,) b) s t a b -> (a -> b) -> s -> (b, t)
<%~ HashSet Identifier -> HashSet Identifier
updateIgnores) ClientState
st
        st2 :: ClientState
st2 = ASetter ClientState ClientState Mask Mask
-> Mask -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> b -> s -> t
set ASetter ClientState ClientState Mask Mask
Lens' ClientState Mask
clientIgnoreMask ([Identifier] -> Mask
buildMask (HashSet Identifier -> [Identifier]
forall a. HashSet a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList HashSet Identifier
newIgnores)) ClientState
st1

        updateIgnores :: HashSet Identifier -> HashSet Identifier
        updateIgnores :: HashSet Identifier -> HashSet Identifier
updateIgnores HashSet Identifier
s = (HashSet Identifier -> Identifier -> HashSet Identifier)
-> HashSet Identifier -> [Identifier] -> HashSet Identifier
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' HashSet Identifier -> Identifier -> HashSet Identifier
HashSet Identifier
-> Index (HashSet Identifier) -> HashSet Identifier
forall {t}. Contains t => t -> Index t -> t
updateIgnore HashSet Identifier
s [Identifier]
xs

        updateIgnore :: t -> Index t -> t
updateIgnore t
s Index t
x = ASetter t t Bool Bool -> (Bool -> Bool) -> t -> t
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (Index t -> Lens' t Bool
forall m. Contains m => Index m -> Lens' m Bool
contains Index t
x) Bool -> Bool
not t
s

-- | Complete the nickname at the current cursor position using the
-- userlist for the currently focused channel (if any)
tabIgnore :: Bool {- ^ reversed -} -> ClientCommand String
tabIgnore :: Bool -> ClientCommand String
tabIgnore Bool
isReversed ClientState
st String
_ =
  WordCompletionMode
-> [Identifier]
-> [Identifier]
-> Bool
-> ClientState
-> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
mode [Identifier]
hint [Identifier]
completions Bool
isReversed ClientState
st
  where
    hint :: [Identifier]
hint          = ClientState -> [Identifier]
activeNicks ClientState
st
    completions :: [Identifier]
completions   = ClientState -> [Identifier]
currentCompletionList ClientState
st [Identifier] -> [Identifier] -> [Identifier]
forall a. [a] -> [a] -> [a]
++ LensLike' (Const [Identifier]) ClientState (HashSet Identifier)
-> (HashSet Identifier -> [Identifier])
-> ClientState
-> [Identifier]
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const [Identifier]) ClientState (HashSet Identifier)
Lens' ClientState (HashSet Identifier)
clientIgnores HashSet Identifier -> [Identifier]
forall a. HashSet a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList ClientState
st
    mode :: WordCompletionMode
mode          = ClientState -> WordCompletionMode
currentNickCompletionMode ClientState
st

-- | Implementation of @/splits@
cmdSplits :: ClientCommand String
cmdSplits :: ClientCommand String
cmdSplits ClientState
st String
str =
  ClientState
-> String
-> ([(Focus, Subfocus)] -> IO CommandResult)
-> IO CommandResult
withSplitFocuses ClientState
st String
str (([(Focus, Subfocus)] -> IO CommandResult) -> IO CommandResult)
-> ([(Focus, Subfocus)] -> IO CommandResult) -> IO CommandResult
forall a b. (a -> b) -> a -> b
$ \[(Focus, Subfocus)]
args ->
    ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess ([(Focus, Subfocus)] -> ClientState -> ClientState
setExtraFocus ([(Focus, Subfocus)] -> [(Focus, Subfocus)]
forall a. Eq a => [a] -> [a]
nub [(Focus, Subfocus)]
args) ClientState
st)


-- | Implementation of @/splits+@. When no focuses are provided
-- the current focus is used instead.
cmdSplitsAdd :: ClientCommand String
cmdSplitsAdd :: ClientCommand String
cmdSplitsAdd ClientState
st String
str =
  ClientState
-> String
-> ([(Focus, Subfocus)] -> IO CommandResult)
-> IO CommandResult
withSplitFocuses ClientState
st String
str (([(Focus, Subfocus)] -> IO CommandResult) -> IO CommandResult)
-> ([(Focus, Subfocus)] -> IO CommandResult) -> IO CommandResult
forall a b. (a -> b) -> a -> b
$ \[(Focus, Subfocus)]
args ->
    let args' :: [(Focus, Subfocus)]
args'
          | [(Focus, Subfocus)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Focus, Subfocus)]
args = [(Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st, Getting Subfocus ClientState Subfocus -> ClientState -> Subfocus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Subfocus ClientState Subfocus
Lens' ClientState Subfocus
clientSubfocus ClientState
st)]
          | Bool
otherwise = [(Focus, Subfocus)]
args
        extras :: [(Focus, Subfocus)]
extras = [(Focus, Subfocus)] -> [(Focus, Subfocus)]
forall a. Eq a => [a] -> [a]
nub ([(Focus, Subfocus)]
args' [(Focus, Subfocus)] -> [(Focus, Subfocus)] -> [(Focus, Subfocus)]
forall a. [a] -> [a] -> [a]
++ Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
-> ClientState -> [(Focus, Subfocus)]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
Lens' ClientState [(Focus, Subfocus)]
clientExtraFocus ClientState
st)

    in ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess ([(Focus, Subfocus)] -> ClientState -> ClientState
setExtraFocus [(Focus, Subfocus)]
extras ClientState
st)

-- | Implementation of @/splits-@. When no focuses are provided
-- the current focus is used instead.
cmdSplitsDel :: ClientCommand String
cmdSplitsDel :: ClientCommand String
cmdSplitsDel ClientState
st String
str =
  ClientState
-> String
-> ([(Focus, Subfocus)] -> IO CommandResult)
-> IO CommandResult
withSplitFocuses ClientState
st String
str (([(Focus, Subfocus)] -> IO CommandResult) -> IO CommandResult)
-> ([(Focus, Subfocus)] -> IO CommandResult) -> IO CommandResult
forall a b. (a -> b) -> a -> b
$ \[(Focus, Subfocus)]
args ->
    let args' :: [(Focus, Subfocus)]
args'
          | [(Focus, Subfocus)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Focus, Subfocus)]
args = [(Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st, Getting Subfocus ClientState Subfocus -> ClientState -> Subfocus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Subfocus ClientState Subfocus
Lens' ClientState Subfocus
clientSubfocus ClientState
st)]
          | Bool
otherwise = [(Focus, Subfocus)]
args
        extras :: [(Focus, Subfocus)]
extras = Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
-> ClientState -> [(Focus, Subfocus)]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
Lens' ClientState [(Focus, Subfocus)]
clientExtraFocus ClientState
st [(Focus, Subfocus)] -> [(Focus, Subfocus)] -> [(Focus, Subfocus)]
forall a. Eq a => [a] -> [a] -> [a]
\\ [(Focus, Subfocus)]
args'

    in ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess ([(Focus, Subfocus)] -> ClientState -> ClientState
setExtraFocus [(Focus, Subfocus)]
extras ClientState
st)

withSplitFocuses ::
  ClientState                   ->
  String                        ->
  ([(Focus, Subfocus)] -> IO CommandResult) ->
  IO CommandResult
withSplitFocuses :: ClientState
-> String
-> ([(Focus, Subfocus)] -> IO CommandResult)
-> IO CommandResult
withSplitFocuses ClientState
st String
str [(Focus, Subfocus)] -> IO CommandResult
k =
  case Maybe [Focus]
mb of
    Maybe [Focus]
Nothing   -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
"unable to parse arguments" ClientState
st
    Just [Focus]
args -> [(Focus, Subfocus)] -> IO CommandResult
k [(Focus
x, Subfocus
FocusMessages) | Focus
x <- [Focus]
args]
  where
    mb :: Maybe [Focus]
mb = (String -> Maybe Focus) -> [String] -> Maybe [Focus]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse
           (Maybe Text -> String -> Maybe Focus
parseFocus (LensLike' (Const (Maybe Text)) ClientState Focus
-> (Focus -> Maybe Text) -> ClientState -> Maybe Text
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const (Maybe Text)) ClientState Focus
Lens' ClientState Focus
clientFocus Focus -> Maybe Text
focusNetwork ClientState
st))
           (String -> [String]
words String
str)

cmdFocus :: ClientCommand (String, Maybe String)
cmdFocus :: ClientCommand (String, Maybe String)
cmdFocus ClientState
st (String
network, Maybe String
mbChannel)
  | String
network String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"*" = ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Focus -> ClientState -> ClientState
changeFocus Focus
Unfocused ClientState
st)
  | Bool
otherwise =
     case Maybe String
mbChannel of
       Maybe String
Nothing ->
         let focus :: Focus
focus = Text -> Focus
NetworkFocus (String -> Text
Text.pack String
network) in
         ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Focus -> ClientState -> ClientState
changeFocus Focus
focus ClientState
st)
       Just String
channel ->
         let focus :: Focus
focus = Text -> Identifier -> Focus
ChannelFocus (String -> Text
Text.pack String
network) (Text -> Identifier
mkId (String -> Text
Text.pack String
channel)) in
         ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess
           (ClientState -> IO CommandResult)
-> ClientState -> IO CommandResult
forall a b. (a -> b) -> a -> b
$ Focus -> ClientState -> ClientState
changeFocus Focus
focus ClientState
st

tabWindows :: Bool -> ClientCommand String
tabWindows :: Bool -> ClientCommand String
tabWindows Bool
isReversed ClientState
st String
_ =
  WordCompletionMode
-> [Text] -> [Text] -> Bool -> ClientState -> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
plainWordCompleteMode [] [Text]
completions Bool
isReversed ClientState
st
  where
    completions :: [Text]
completions = [Text
"networks",Text
"channels",Text
"users"] :: [Text]

-- | Tab completion for @/splits-@. This completes only from the list of active
-- entries in the splits list.
tabActiveSplits :: Bool -> ClientCommand String
tabActiveSplits :: Bool -> ClientCommand String
tabActiveSplits Bool
isReversed ClientState
st String
_ =
  WordCompletionMode
-> [Text] -> [Text] -> Bool -> ClientState -> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
plainWordCompleteMode [] [Text]
completions Bool
isReversed ClientState
st
  where
    completions :: [Text]
completions = [Text]
currentNetSplits [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> [Text]
currentSplits
    currentSplits :: [Text]
currentSplits = [Focus -> Text
renderSplitFocus Focus
x | (Focus
x, Subfocus
FocusMessages) <- Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
-> ClientState -> [(Focus, Subfocus)]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
Lens' ClientState [(Focus, Subfocus)]
clientExtraFocus ClientState
st]
    currentNetSplits :: [Text]
currentNetSplits =
      [ Identifier -> Text
idText Identifier
chan
        | (ChannelFocus Text
net Identifier
chan, Subfocus
FocusMessages) <- Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
-> ClientState -> [(Focus, Subfocus)]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
Lens' ClientState [(Focus, Subfocus)]
clientExtraFocus ClientState
st
        , LensLike' (Const (Maybe Text)) ClientState Focus
-> (Focus -> Maybe Text) -> ClientState -> Maybe Text
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const (Maybe Text)) ClientState Focus
Lens' ClientState Focus
clientFocus Focus -> Maybe Text
focusNetwork ClientState
st Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just Text
net
        ]

-- | When used on a channel that the user is currently
-- joined to this command will clear the messages but
-- preserve the window. When used on a window that the
-- user is not joined to this command will delete the window.
cmdClear :: WindowCommand (Maybe (String, Maybe String))
cmdClear :: WindowCommand (Maybe (String, Maybe String))
cmdClear Focus
focusDefault ClientState
st Maybe (String, Maybe String)
args =
  case Maybe (String, Maybe String)
args of
    Maybe (String, Maybe String)
Nothing                      -> Focus -> IO CommandResult
forall {m :: * -> *}. Monad m => Focus -> m CommandResult
clearFocus Focus
focusDefault
    Just (String
"*",     Maybe String
Nothing     ) -> Focus -> IO CommandResult
forall {m :: * -> *}. Monad m => Focus -> m CommandResult
clearFocus Focus
Unfocused
    Just (String
network, Maybe String
Nothing     ) -> Focus -> IO CommandResult
forall {m :: * -> *}. Monad m => Focus -> m CommandResult
clearFocus (Text -> Focus
NetworkFocus (String -> Text
Text.pack String
network))
    Just (String
network, Just String
"*"    ) -> String -> IO CommandResult
forall {m :: * -> *}. Monad m => String -> m CommandResult
clearNetworkWindows String
network
    Just (String
network, Just String
channel) -> Focus -> IO CommandResult
forall {m :: * -> *}. Monad m => Focus -> m CommandResult
clearFocus (Text -> Identifier -> Focus
ChannelFocus (String -> Text
Text.pack String
network) (Text -> Identifier
mkId (String -> Text
Text.pack String
channel)))
  where
    clearNetworkWindows :: String -> m CommandResult
clearNetworkWindows String
network
      = ClientState -> m CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess
      (ClientState -> m CommandResult) -> ClientState -> m CommandResult
forall a b. (a -> b) -> a -> b
$ (ClientState -> Focus -> ClientState)
-> ClientState -> [Focus] -> ClientState
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((Focus -> ClientState -> ClientState)
-> ClientState -> Focus -> ClientState
forall a b c. (a -> b -> c) -> b -> a -> c
flip Focus -> ClientState -> ClientState
clearFocus1) ClientState
st
      ([Focus] -> ClientState) -> [Focus] -> ClientState
forall a b. (a -> b) -> a -> b
$ (Focus -> Bool) -> [Focus] -> [Focus]
forall a. (a -> Bool) -> [a] -> [a]
filter (\Focus
x -> Focus -> Maybe Text
focusNetwork Focus
x Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Maybe Text
forall a. a -> Maybe a
Just (String -> Text
Text.pack String
network))
      ([Focus] -> [Focus]) -> [Focus] -> [Focus]
forall a b. (a -> b) -> a -> b
$ LensLike' (Const [Focus]) ClientState (Map Focus Window)
-> (Map Focus Window -> [Focus]) -> ClientState -> [Focus]
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const [Focus]) ClientState (Map Focus Window)
Lens' ClientState (Map Focus Window)
clientWindows Map Focus Window -> [Focus]
forall k a. Map k a -> [k]
Map.keys ClientState
st

    clearFocus :: Focus -> m CommandResult
clearFocus Focus
focus = ClientState -> m CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Focus -> ClientState -> ClientState
clearFocus1 Focus
focus ClientState
st)

    clearFocus1 :: Focus -> ClientState -> ClientState
clearFocus1 Focus
focus ClientState
st' = ClientState -> ClientState
channelEffect (ClientState -> ClientState
focusEffect (ClientState -> ClientState
windowEffect ClientState
st'))
      where
        channelEffect :: ClientState -> ClientState
channelEffect =
          case Focus
focus of
            ChannelFocus Text
network Identifier
channel | Bool -> Bool
not Bool
isActive ->
              ASetter
  ClientState
  ClientState
  (HashMap Identifier ChannelState)
  (HashMap Identifier ChannelState)
-> (HashMap Identifier ChannelState
    -> HashMap Identifier ChannelState)
-> ClientState
-> ClientState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (Text -> LensLike' Identity ClientState NetworkState
forall (f :: * -> *).
Applicative f =>
Text -> LensLike' f ClientState NetworkState
clientConnection Text
network LensLike' Identity ClientState NetworkState
-> ((HashMap Identifier ChannelState
     -> Identity (HashMap Identifier ChannelState))
    -> NetworkState -> Identity NetworkState)
-> ASetter
     ClientState
     ClientState
     (HashMap Identifier ChannelState)
     (HashMap Identifier ChannelState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap Identifier ChannelState
 -> Identity (HashMap Identifier ChannelState))
-> NetworkState -> Identity NetworkState
Lens' NetworkState (HashMap Identifier ChannelState)
csChannels) (Index (HashMap Identifier ChannelState)
-> HashMap Identifier ChannelState
-> HashMap Identifier ChannelState
forall m. At m => Index m -> m -> m
sans Identifier
Index (HashMap Identifier ChannelState)
channel)
            Focus
_ -> ClientState -> ClientState
forall a. a -> a
id

        -- clear or delete the window buffer
        windowEffect :: ClientState -> ClientState
windowEffect = ASetter ClientState ClientState (Maybe Window) (Maybe Window)
-> (Maybe Window -> Maybe Window) -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ((Map Focus Window -> Identity (Map Focus Window))
-> ClientState -> Identity ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Identity (Map Focus Window))
 -> ClientState -> Identity ClientState)
-> ((Maybe Window -> Identity (Maybe Window))
    -> Map Focus Window -> Identity (Map Focus Window))
-> ASetter ClientState ClientState (Maybe Window) (Maybe Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Lens' (Map Focus Window) (Maybe (IxValue (Map Focus Window)))
forall m. At m => Index m -> Lens' m (Maybe (IxValue m))
at Index (Map Focus Window)
Focus
focus)
                           (if Bool
isActive then (Window -> Window) -> Maybe Window -> Maybe Window
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Window -> Window
windowClear else Maybe Window -> Maybe Window -> Maybe Window
forall a b. a -> b -> a
const Maybe Window
forall a. Maybe a
Nothing)

        -- stay on the current focus or find a new one
        focusEffect :: ClientState -> ClientState
focusEffect
          | Bool
noChangeNeeded    = ClientState -> ClientState
forall a. a -> a
id
          | Bool
prevExists        = Focus -> ClientState -> ClientState
changeFocus Focus
prev
          | Bool
otherwise         = ClientState -> ClientState
advanceFocus
          where
            noChangeNeeded :: Bool
noChangeNeeded    = Bool
isActive Bool -> Bool -> Bool
|| Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientFocus ClientState
st' Focus -> Focus -> Bool
forall a. Eq a => a -> a -> Bool
/= Focus
focus
            prevExists :: Bool
prevExists        = Getting Any ClientState Window -> ClientState -> Bool
forall s a. Getting Any s a -> s -> Bool
has ((Map Focus Window -> Const Any (Map Focus Window))
-> ClientState -> Const Any ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Const Any (Map Focus Window))
 -> ClientState -> Const Any ClientState)
-> ((Window -> Const Any Window)
    -> Map Focus Window -> Const Any (Map Focus Window))
-> Getting Any ClientState Window
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
prev) ClientState
st'

            prev :: Focus
prev              = Getting Focus ClientState Focus -> ClientState -> Focus
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Focus ClientState Focus
Lens' ClientState Focus
clientPrevFocus ClientState
st

        -- active windows are cleared instead of deleted
        isActive :: Bool
isActive =
          case Focus
focus of
            Focus
Unfocused -> Bool
False
            NetworkFocus Text
network -> Getting Any ClientState NetworkState -> ClientState -> Bool
forall s a. Getting Any s a -> s -> Bool
has (Text -> Getting Any ClientState NetworkState
forall (f :: * -> *).
Applicative f =>
Text -> LensLike' f ClientState NetworkState
clientConnection Text
network) ClientState
st'
            ChannelFocus Text
network Identifier
channel ->
              Getting Any ClientState Bool -> ClientState -> Bool
forall s. Getting Any s Bool -> s -> Bool
orOf (Text -> Getting Any ClientState NetworkState
forall (f :: * -> *).
Applicative f =>
Text -> LensLike' f ClientState NetworkState
clientConnection Text
network Getting Any ClientState NetworkState
-> ((Bool -> Const Any Bool)
    -> NetworkState -> Const Any NetworkState)
-> Getting Any ClientState Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HashMap Identifier ChannelState
 -> Const Any (HashMap Identifier ChannelState))
-> NetworkState -> Const Any NetworkState
Lens' NetworkState (HashMap Identifier ChannelState)
csChannels ((HashMap Identifier ChannelState
  -> Const Any (HashMap Identifier ChannelState))
 -> NetworkState -> Const Any NetworkState)
-> ((Bool -> Const Any Bool)
    -> HashMap Identifier ChannelState
    -> Const Any (HashMap Identifier ChannelState))
-> (Bool -> Const Any Bool)
-> NetworkState
-> Const Any NetworkState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (HashMap Identifier ChannelState)
-> Traversal'
     (HashMap Identifier ChannelState)
     (IxValue (HashMap Identifier ChannelState))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Identifier
Index (HashMap Identifier ChannelState)
channel ((ChannelState -> Const Any ChannelState)
 -> HashMap Identifier ChannelState
 -> Const Any (HashMap Identifier ChannelState))
-> ((Bool -> Const Any Bool)
    -> ChannelState -> Const Any ChannelState)
-> (Bool -> Const Any Bool)
-> HashMap Identifier ChannelState
-> Const Any (HashMap Identifier ChannelState)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Const Any Bool) -> ChannelState -> Const Any ChannelState
Lens' ChannelState Bool
chanJoined) ClientState
st'

-- | Tab completion for @/splits[+]@. When given no arguments this
-- populates the current list of splits, otherwise it tab completes
-- all of the currently available windows.
tabSplits :: Bool -> ClientCommand String
tabSplits :: Bool -> ClientCommand String
tabSplits Bool
isReversed ClientState
st String
rest

  -- If no arguments, populate the current splits
  | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Char
' 'Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==) String
rest =
     let cmd :: String
cmd = [String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ String
"/splits"
                       String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [Text -> String
Text.unpack (Focus -> Text
renderSplitFocus Focus
x) | (Focus
x, Subfocus
FocusMessages) <- Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
-> ClientState -> [(Focus, Subfocus)]
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting [(Focus, Subfocus)] ClientState [(Focus, Subfocus)]
Lens' ClientState [(Focus, Subfocus)]
clientExtraFocus ClientState
st]
         newline :: Line
newline = String -> Line
Edit.endLine String
cmd
     in ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (ASetter ClientState ClientState Line Line
-> Line -> ClientState -> ClientState
forall s t a b. ASetter s t a b -> b -> s -> t
set ((EditBox -> Identity EditBox)
-> ClientState -> Identity ClientState
Lens' ClientState EditBox
clientTextBox ((EditBox -> Identity EditBox)
 -> ClientState -> Identity ClientState)
-> ((Line -> Identity Line) -> EditBox -> Identity EditBox)
-> ASetter ClientState ClientState Line Line
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Line -> Identity Line) -> EditBox -> Identity EditBox
forall c. HasLine c => Lens' c Line
Lens' EditBox Line
Edit.line) Line
newline ClientState
st)

  -- Tab complete the available windows. Accepts either fully qualified
  -- window names or current network names without the ':'
  | Bool
otherwise =
     let completions :: [Text]
completions = [Text]
currentNet [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> [Text]
allWindows
         allWindows :: [Text]
allWindows  = Focus -> Text
renderSplitFocus (Focus -> Text) -> [Focus] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LensLike' (Const [Focus]) ClientState (Map Focus Window)
-> (Map Focus Window -> [Focus]) -> ClientState -> [Focus]
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const [Focus]) ClientState (Map Focus Window)
Lens' ClientState (Map Focus Window)
clientWindows Map Focus Window -> [Focus]
forall k a. Map k a -> [k]
Map.keys ClientState
st
         currentNet :: [Text]
currentNet  = case LensLike' (Const (Maybe Text)) ClientState Focus
-> (Focus -> Maybe Text) -> ClientState -> Maybe Text
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const (Maybe Text)) ClientState Focus
Lens' ClientState Focus
clientFocus Focus -> Maybe Text
focusNetwork ClientState
st of
                         Just Text
net -> Identifier -> Text
idText (Identifier -> Text) -> [Identifier] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> ClientState -> [Identifier]
channelWindowsOnNetwork Text
net ClientState
st
                         Maybe Text
Nothing  -> []
     in WordCompletionMode
-> [Text] -> [Text] -> Bool -> ClientState -> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
plainWordCompleteMode [] [Text]
completions Bool
isReversed ClientState
st

-- | Render a entry from splits back to the textual format.
renderSplitFocus :: Focus -> Text
renderSplitFocus :: Focus -> Text
renderSplitFocus Focus
Unfocused          = Text
"*"
renderSplitFocus (NetworkFocus Text
x)   = Text
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":"
renderSplitFocus (ChannelFocus Text
x Identifier
y) = Text
x Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Identifier -> Text
idText Identifier
y

focusNames :: ClientState -> [Text]
focusNames :: ClientState -> [Text]
focusNames ClientState
st = [Text]
currentNet [Text] -> [Text] -> [Text]
forall a. Semigroup a => a -> a -> a
<> [Text]
allWindows
  where
    allWindows :: [Text]
allWindows  = Focus -> Text
renderSplitFocus (Focus -> Text) -> [Focus] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LensLike' (Const [Focus]) ClientState (Map Focus Window)
-> (Map Focus Window -> [Focus]) -> ClientState -> [Focus]
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const [Focus]) ClientState (Map Focus Window)
Lens' ClientState (Map Focus Window)
clientWindows Map Focus Window -> [Focus]
forall k a. Map k a -> [k]
Map.keys ClientState
st
    currentNet :: [Text]
currentNet  = case LensLike' (Const (Maybe Text)) ClientState Focus
-> (Focus -> Maybe Text) -> ClientState -> Maybe Text
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const (Maybe Text)) ClientState Focus
Lens' ClientState Focus
clientFocus Focus -> Maybe Text
focusNetwork ClientState
st of
                    Just Text
net -> Identifier -> Text
idText (Identifier -> Text) -> [Identifier] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> ClientState -> [Identifier]
channelWindowsOnNetwork Text
net ClientState
st
                    Maybe Text
Nothing  -> []

-- | When tab completing the first parameter of the focus command
-- the current networks are used.
tabFocus :: Bool -> ClientCommand String
tabFocus :: Bool -> ClientCommand String
tabFocus Bool
isReversed ClientState
st String
_ =
  WordCompletionMode
-> [Identifier]
-> [Identifier]
-> Bool
-> ClientState
-> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
plainWordCompleteMode [] [Identifier]
completions Bool
isReversed ClientState
st
  where
    networks :: [Identifier]
networks   = (Text -> Identifier) -> [Text] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Identifier
mkId ([Text] -> [Identifier]) -> [Text] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ HashMap Text NetworkState -> [Text]
forall k v. HashMap k v -> [k]
HashMap.keys (HashMap Text NetworkState -> [Text])
-> HashMap Text NetworkState -> [Text]
forall a b. (a -> b) -> a -> b
$ Getting
  (HashMap Text NetworkState) ClientState (HashMap Text NetworkState)
-> ClientState -> HashMap Text NetworkState
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting
  (HashMap Text NetworkState) ClientState (HashMap Text NetworkState)
Lens' ClientState (HashMap Text NetworkState)
clientConnections ClientState
st
    params :: [String]
params     = String -> [String]
words (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ (Int -> String -> String) -> (Int, String) -> String
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> String -> String
forall a. Int -> [a] -> [a]
take ((Int, String) -> String) -> (Int, String) -> String
forall a b. (a -> b) -> a -> b
$ ClientState -> (Int, String)
clientLine ClientState
st

    completions :: [Identifier]
completions =
      case [String]
params of
        [String
_cmd,String
_net]      -> [Identifier]
networks
        [String
_cmd,String
net,String
_chan] -> Text -> ClientState -> [Identifier]
channelWindowsOnNetwork (String -> Text
Text.pack String
net) ClientState
st
        [String]
_                -> []

-- | @/channel@ command. Takes a channel or nickname and switches
-- focus to that target on the current network.
cmdChannel :: ClientCommand String
cmdChannel :: ClientCommand String
cmdChannel ClientState
st String
channel =
  case Maybe Text -> String -> Maybe Focus
parseFocus (LensLike' (Const (Maybe Text)) ClientState Focus
-> (Focus -> Maybe Text) -> ClientState -> Maybe Text
forall s (m :: * -> *) r a.
MonadReader s m =>
LensLike' (Const r) s a -> (a -> r) -> m r
views LensLike' (Const (Maybe Text)) ClientState Focus
Lens' ClientState Focus
clientFocus Focus -> Maybe Text
focusNetwork ClientState
st) String
channel of
    Just Focus
focus -> ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess (Focus -> ClientState -> ClientState
changeFocus Focus
focus ClientState
st)
    Maybe Focus
Nothing    -> Text -> ClientState -> IO CommandResult
commandFailureMsg Text
"No current network" ClientState
st

-- | Tab completion for @/channel@. Tab completion uses pre-existing
-- windows.
tabChannel ::
  Bool {- ^ reversed order -} ->
  ClientCommand String
tabChannel :: Bool -> ClientCommand String
tabChannel Bool
isReversed ClientState
st String
_ =
  WordCompletionMode
-> [Text] -> [Text] -> Bool -> ClientState -> IO CommandResult
forall a.
Prefix a =>
WordCompletionMode
-> [a] -> [a] -> Bool -> ClientState -> IO CommandResult
simpleTabCompletion WordCompletionMode
plainWordCompleteMode [] (ClientState -> [Text]
focusNames ClientState
st) Bool
isReversed ClientState
st

-- | Return the list of identifiers for open channel windows on
-- the given network name.
channelWindowsOnNetwork ::
  Text         {- ^ network              -} ->
  ClientState  {- ^ client state         -} ->
  [Identifier] {- ^ open channel windows -}
channelWindowsOnNetwork :: Text -> ClientState -> [Identifier]
channelWindowsOnNetwork Text
network ClientState
st =
  [ Identifier
chan | ChannelFocus Text
net Identifier
chan <- Map Focus Window -> [Focus]
forall k a. Map k a -> [k]
Map.keys (Getting (Map Focus Window) ClientState (Map Focus Window)
-> ClientState -> Map Focus Window
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Map Focus Window) ClientState (Map Focus Window)
Lens' ClientState (Map Focus Window)
clientWindows ClientState
st)
         , Text
net Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
network ]

-- | Implementation of @/dump@. Writes detailed contents of focused buffer
-- to the given filename.
cmdDump :: WindowCommand String
cmdDump :: WindowCommand String
cmdDump Focus
focus ClientState
st String
fp =
  do Either SomeException ()
res <- IO () -> IO (Either SomeException ())
forall e a. Exception e => IO a -> IO (Either e a)
try (String -> Text -> IO ()
LText.writeFile String
fp ([Text] -> Text
LText.unlines [Text]
outputLines))
     case Either SomeException ()
res of
       Left SomeException
e  -> Text -> ClientState -> IO CommandResult
commandFailureMsg (String -> Text
Text.pack (SomeException -> String
forall e. Exception e => e -> String
displayException (SomeException
e :: SomeException))) ClientState
st
       Right{} -> ClientState -> IO CommandResult
forall (m :: * -> *). Monad m => ClientState -> m CommandResult
commandSuccess ClientState
st

  where
    outputLines :: [Text]
outputLines
      = [Text] -> [Text]
forall a. [a] -> [a]
reverse
      ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ ClientState -> (Text -> Text) -> [Text] -> [Text]
forall a. ClientState -> (a -> Text) -> [a] -> [a]
clientFilter ClientState
st Text -> Text
forall a. a -> a
id
      ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Getting (Endo [Text]) ClientState Text -> ClientState -> [Text]
forall a s. Getting (Endo [a]) s a -> s -> [a]
toListOf ((Map Focus Window -> Const (Endo [Text]) (Map Focus Window))
-> ClientState -> Const (Endo [Text]) ClientState
Lens' ClientState (Map Focus Window)
clientWindows ((Map Focus Window -> Const (Endo [Text]) (Map Focus Window))
 -> ClientState -> Const (Endo [Text]) ClientState)
-> ((Text -> Const (Endo [Text]) Text)
    -> Map Focus Window -> Const (Endo [Text]) (Map Focus Window))
-> Getting (Endo [Text]) ClientState Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Focus Window)
-> Traversal' (Map Focus Window) (IxValue (Map Focus Window))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Map Focus Window)
Focus
focus ((Window -> Const (Endo [Text]) Window)
 -> Map Focus Window -> Const (Endo [Text]) (Map Focus Window))
-> ((Text -> Const (Endo [Text]) Text)
    -> Window -> Const (Endo [Text]) Window)
-> (Text -> Const (Endo [Text]) Text)
-> Map Focus Window
-> Const (Endo [Text]) (Map Focus Window)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WindowLines -> Const (Endo [Text]) WindowLines)
-> Window -> Const (Endo [Text]) Window
Lens' Window WindowLines
winMessages ((WindowLines -> Const (Endo [Text]) WindowLines)
 -> Window -> Const (Endo [Text]) Window)
-> ((Text -> Const (Endo [Text]) Text)
    -> WindowLines -> Const (Endo [Text]) WindowLines)
-> (Text -> Const (Endo [Text]) Text)
-> Window
-> Const (Endo [Text]) Window
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WindowLine -> Const (Endo [Text]) WindowLine)
-> WindowLines -> Const (Endo [Text]) WindowLines
forall s t a b. Each s t a b => Traversal s t a b
Traversal WindowLines WindowLines WindowLine WindowLine
each ((WindowLine -> Const (Endo [Text]) WindowLine)
 -> WindowLines -> Const (Endo [Text]) WindowLines)
-> ((Text -> Const (Endo [Text]) Text)
    -> WindowLine -> Const (Endo [Text]) WindowLine)
-> (Text -> Const (Endo [Text]) Text)
-> WindowLines
-> Const (Endo [Text]) WindowLines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const (Endo [Text]) Text)
-> WindowLine -> Const (Endo [Text]) WindowLine
Getter WindowLine Text
wlText) ClientState
st