module Yi.Tab
(
Tab,
TabRef,
tabWindowsA,
tabLayoutManagerA,
tabDividerPositionA,
tkey,
tabMiniWindows,
tabFocus,
forceTab,
mapWindows,
tabLayout,
tabFoldl,
makeTab,
makeTab1,
) where
import Prelude hiding (foldl, foldr)
import Lens.Micro.Platform (Lens', lens, over, (^.))
import qualified Data.Binary as Binary (Binary, get, put)
import Data.Default (def)
import Data.Foldable (foldl, foldr, toList)
import qualified Data.List.PointedList as PL (PointedList, singleton, _focus)
import Data.Typeable (Typeable)
import Yi.Buffer.Basic (WindowRef)
import Yi.Layout
import Yi.Window (Window, isMini, wkey)
type TabRef = Int
data Tab = Tab {
tkey :: !TabRef,
tabWindows :: !(PL.PointedList Window),
tabLayout :: !(Layout WindowRef),
tabLayoutManager :: !AnyLayoutManager
}
deriving Typeable
tabFocus :: Tab -> Window
tabFocus = PL._focus . tabWindows
tabMiniWindows :: Tab -> [Window]
tabMiniWindows = Prelude.filter isMini . toList . tabWindows
tabWindowsA :: Functor f =>
(PL.PointedList Window -> f (PL.PointedList Window)) -> Tab -> f Tab
tabWindowsA f s = (`setter` s) <$> f (getter s)
where
setter ws t = relayoutIf (toList ws /= toList (tabWindows t)) (t { tabWindows = ws})
getter = tabWindows
tabLayoutManagerA :: Functor f =>
(AnyLayoutManager -> f AnyLayoutManager) -> Tab -> f Tab
tabLayoutManagerA f s = (`setter` s) <$> f (getter s)
where
setter lm t = relayoutIf (lm /= tabLayoutManager t) (t { tabLayoutManager = lm })
getter = tabLayoutManager
tabDividerPositionA :: DividerRef -> Lens' Tab DividerPosition
tabDividerPositionA ref = lens tabLayout (\ t l -> t{tabLayout = l}) . dividerPositionA ref
relayoutIf :: Bool -> Tab -> Tab
relayoutIf False t = t
relayoutIf True t = relayout t
relayout :: Tab -> Tab
relayout t = t { tabLayout = buildLayout (tabWindows t) (tabLayoutManager t) (tabLayout t) }
instance Binary.Binary Tab where
put (Tab tk ws _ _) = Binary.put tk >> Binary.put ws
get = makeTab <$> Binary.get <*> Binary.get
instance Eq Tab where
(==) t1 t2 = tkey t1 == tkey t2
instance Show Tab where
show t = "Tab " ++ show (tkey t)
mapWindows :: (Window -> Window) -> Tab -> Tab
mapWindows f = over tabWindowsA (fmap f)
forceTab :: Tab -> Tab
forceTab t = foldr seq t (t ^. tabWindowsA)
tabFoldl :: (a -> Window -> a) -> a -> Tab -> a
tabFoldl f z t = foldl f z (t ^. tabWindowsA)
buildLayout :: PL.PointedList Window -> AnyLayoutManager -> Layout WindowRef -> Layout WindowRef
buildLayout ws m l = pureLayout m l . fmap wkey . Prelude.filter (not . isMini) . toList $ ws
makeTab :: TabRef -> PL.PointedList Window -> Tab
makeTab key ws = Tab key ws (buildLayout ws def def) def
makeTab1 :: TabRef -> Window -> Tab
makeTab1 key win = makeTab key (PL.singleton win)