From f8c8240793a9992db68f07e75281e7f549406648 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 12 Apr 2022 13:07:17 -0600 Subject: Add type-static way to get the length of a LayoutList --- src/Rahm/Desktop/Keys.hs | 9 +++++++-- src/Rahm/Desktop/Layout.hs | 17 ++++++++++++----- src/Rahm/Desktop/Layout/List.hs | 35 +++++++++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/Rahm/Desktop/Keys.hs b/src/Rahm/Desktop/Keys.hs index 87f88cf..321d185 100644 --- a/src/Rahm/Desktop/Keys.hs +++ b/src/Rahm/Desktop/Keys.hs @@ -53,7 +53,8 @@ import Rahm.Desktop.PassMenu import Rahm.Desktop.Logger import Rahm.Desktop.RebindKeys import Rahm.Desktop.Swallow -import Rahm.Desktop.Layout.List (toNextLayout, toPreviousLayout, toFirstLayout) +import Rahm.Desktop.Layout.List ( + toNextLayout, toPreviousLayout, toFirstLayout, toIndexedLayout) import Rahm.Desktop.Layout.Hole (toggleHole) import Rahm.Desktop.Layout.Pop (togglePop) import Rahm.Desktop.Layout.Flip (flipHorizontally, flipVertically) @@ -438,10 +439,14 @@ keymap = runKeys $ do (noMod -|- justMod) $ doc "Rotate the layout 90 degrees" $ sendMessage rotateLayout - bind xK_t $ + bind xK_c $ (noMod -|- justMod) $ doc "Toggle the pop window" $ sendMessage togglePop + bind xK_t $ + (noMod -|- justMod) $ doc "Jump to the middle layout." $ + sendMessage (toIndexedLayout (nLayouts `div` 2)) + bind xK_x $ (noMod -|- justMod) $ doc "Toggle the hole" $ sendMessage toggleHole diff --git a/src/Rahm/Desktop/Layout.hs b/src/Rahm/Desktop/Layout.hs index b416111..bd875d0 100644 --- a/src/Rahm/Desktop/Layout.hs +++ b/src/Rahm/Desktop/Layout.hs @@ -37,13 +37,17 @@ import Rahm.Desktop.Layout.Hole import qualified Data.Map as M import qualified XMonad.StackSet as W -withSpacing = spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True -mods = - withSpacing . poppable . flippable . rotateable . hole - myLayout = fullscreenFull $ - avoidStruts $ + avoidStruts myLayoutList + +mySpacing = spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True + + +mods = + mySpacing . poppable . flippable . rotateable . hole + +myLayoutList = layoutList $ mods (reinterpretIncMaster $ spiral (6/7)) |: mods (modifyMosaic (MosaicAlt M.empty :: MosaicAlt Window)) |: @@ -55,6 +59,9 @@ myLayout = mods (reinterpretIncMaster $ D.Dwindle D.R D.CW 1.5 1.1) |: nil +nLayouts :: Int +nLayouts = layoutListLength myLayoutList + -- Mosaic doesn't have the concept of a "Master Space", so reinterpret messages -- intended to modify the master space and instead have those messages expand -- and shrink the current window. diff --git a/src/Rahm/Desktop/Layout/List.hs b/src/Rahm/Desktop/Layout/List.hs index 96f9be5..f533ea2 100644 --- a/src/Rahm/Desktop/Layout/List.hs +++ b/src/Rahm/Desktop/Layout/List.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableInstances, TypeOperators #-} {- - This module provides a more powerful version of the "Choose" layout that can @@ -15,18 +15,22 @@ module Rahm.Desktop.Layout.List ( toNextLayout, toPreviousLayout, toFirstLayout, + toIndexedLayout, (|:), - nil + nil, + layoutListLength, + layoutListLengthProxy )where import Control.Applicative ((<|>)) -import Data.Void +import Control.Arrow (second, (>>>)) import Control.Monad.Identity (runIdentity) import Data.Maybe (fromMaybe, fromJust) -import Control.Arrow (second) +import Data.Proxy +import Data.Void +import GHC.TypeLits import XMonad import qualified XMonad.StackSet as W -import Data.Proxy -- Type-level lists. LNil is the final of the list. LCons contains a layout and a -- tail. @@ -156,6 +160,20 @@ data LayoutList l a where deriving instance (LayoutSelect l a) => Show (LayoutList l a) deriving instance (LayoutSelect l a) => Read (LayoutList l a) +-- Type family to get the LengthOf a ConsList. +type family LengthOf (x :: * -> *) :: Nat where + LengthOf LNil = 0 + LengthOf (LCons l t) = 1 + LengthOf t + +-- Length of a LayoutList. This is calculated at Compile-time using +-- typefamilies and Nat TypeLits. +layoutListLength :: forall l n a. (LengthOf l ~ n, KnownNat n) => LayoutList l a -> Int +layoutListLength = fromIntegral . natVal . layoutListLengthProxy + +-- Proxy for the type-level Nat length of a LayoutList. +layoutListLengthProxy :: (LengthOf l ~ n) => LayoutList l a -> Proxy n +layoutListLengthProxy _ = Proxy + -- Cons two LayoutSelect types together. (|:) :: (LayoutSelect t a, LayoutClass l a) => l a -> t a -> LCons l t a (|:) = LCons @@ -189,10 +207,15 @@ toNextLayout = NavigateLayout $ addSelector (intToSelector 1) toPreviousLayout :: NavigateLayout toPreviousLayout = NavigateLayout $ \c -> fromMaybe c (decrement c <|> final) --- NavigateLayotu instance to move to the first layout. +-- NavigateLayout instance to move to the first layout. toFirstLayout :: NavigateLayout toFirstLayout = NavigateLayout (`fromMaybe` initial) +-- NavigateLayout instance to go to an indexed layout. +toIndexedLayout :: Int -> NavigateLayout +toIndexedLayout i = NavigateLayout $ + (`fromMaybe` initial) >>> addSelector (intToSelector i) + instance Message NavigateLayout where -- LayoutSelect class Describes a type that can be used to select a layout using -- cgit