From c8c81474a2bef2012f4a76e5cb6400688b2a4149 Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Tue, 19 Sep 2023 08:36:07 +0200 Subject: [PATCH 1/7] X.A.CycleWindows: Move rot{Up,Down} to X.A.RotSlaves Reexport them instead. --- XMonad/Actions/CycleWindows.hs | 10 ---------- XMonad/Actions/RotSlaves.hs | 23 ++++++++++++++++++----- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/XMonad/Actions/CycleWindows.hs b/XMonad/Actions/CycleWindows.hs index 1d647f217b..c26bb965db 100644 --- a/XMonad/Actions/CycleWindows.hs +++ b/XMonad/Actions/CycleWindows.hs @@ -50,7 +50,6 @@ module XMonad.Actions.CycleWindows ( -- $pointer -- * Generic list rotations - -- $generic rotUp, rotDown ) where @@ -223,12 +222,3 @@ rotUnfocused' f s@(W.Stack _ [] _ ) = rotSlaves' f s -- Master h rotUnfocused' f (W.Stack t ls rs) = W.Stack t (reverse revls') rs' -- otherwise where (master :| revls) = NE.reverse (let l:ll = ls in l :| ll) (revls',rs') = splitAt (length ls) (f $ master:revls ++ rs) - --- $generic --- Generic list rotations such that @rotUp [1..4]@ is equivalent to --- @[2,3,4,1]@ and @rotDown [1..4]@ to @[4,1,2,3]@. They both are --- @id@ for null or singleton lists. -rotUp :: [a] -> [a] -rotUp l = drop 1 l ++ take 1 l -rotDown :: [a] -> [a] -rotDown = reverse . rotUp . reverse diff --git a/XMonad/Actions/RotSlaves.hs b/XMonad/Actions/RotSlaves.hs index 3fc458033e..cceda0165e 100644 --- a/XMonad/Actions/RotSlaves.hs +++ b/XMonad/Actions/RotSlaves.hs @@ -17,7 +17,11 @@ module XMonad.Actions.RotSlaves ( -- $usage rotSlaves', rotSlavesUp, rotSlavesDown, - rotAll', rotAllUp, rotAllDown + rotAll', rotAllUp, rotAllDown, + + -- * Generic list rotations + -- $generic + rotUp, rotDown ) where import XMonad @@ -44,8 +48,8 @@ import XMonad.Prelude -- | Rotate the windows in the current stack, excluding the first one -- (master). rotSlavesUp,rotSlavesDown :: X () -rotSlavesUp = windows $ modify' (rotSlaves' (\l -> tail l++[head l])) -rotSlavesDown = windows $ modify' (rotSlaves' (\l -> last l : init l)) +rotSlavesUp = windows $ modify' (rotSlaves' rotUp) +rotSlavesDown = windows $ modify' (rotSlaves' rotDown) -- | The actual rotation, as a pure function on the window stack. rotSlaves' :: ([a] -> [a]) -> Stack a -> Stack a @@ -57,10 +61,19 @@ rotSlaves' f s@(Stack _ ls _ ) = Stack t' (reverse revls') rs' -- otherwise -- | Rotate all the windows in the current stack. rotAllUp,rotAllDown :: X () -rotAllUp = windows $ modify' (rotAll' (\l -> tail l++[head l])) -rotAllDown = windows $ modify' (rotAll' (\l -> last l : init l)) +rotAllUp = windows $ modify' (rotAll' rotUp) +rotAllDown = windows $ modify' (rotAll' rotDown) -- | The actual rotation, as a pure function on the window stack. rotAll' :: ([a] -> [a]) -> Stack a -> Stack a rotAll' f s = Stack r (reverse revls) rs where (revls, notEmpty -> r :| rs) = splitAt (length (up s)) (f (integrate s)) + +-- $generic +-- Generic list rotations such that @rotUp [1..4]@ is equivalent to +-- @[2,3,4,1]@ and @rotDown [1..4]@ to @[4,1,2,3]@. They both are +-- @id@ for null or singleton lists. +rotUp :: [a] -> [a] +rotUp l = drop 1 l ++ take 1 l +rotDown :: [a] -> [a] +rotDown = reverse . rotUp . reverse From 52a40f376c9647d3041d8fc9707a9938057d8828 Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Tue, 19 Sep 2023 09:10:11 +0200 Subject: [PATCH 2/7] Replace tail with drop 1 Where appropriate. --- XMonad/Actions/EasyMotion.hs | 2 +- XMonad/Actions/Navigation2D.hs | 5 ++--- XMonad/Actions/Search.hs | 2 +- XMonad/Actions/WorkspaceCursors.hs | 2 +- XMonad/Hooks/DebugEvents.hs | 4 +--- XMonad/Hooks/InsertPosition.hs | 2 +- XMonad/Hooks/StatusBar/PP.hs | 2 +- XMonad/Layout/CenteredMaster.hs | 2 +- XMonad/Layout/Combo.hs | 2 +- XMonad/Layout/Dwindle.hs | 4 ++-- XMonad/Layout/Grid.hs | 2 +- XMonad/Layout/Groups/Helpers.hs | 2 +- XMonad/Layout/MultiColumns.hs | 2 +- XMonad/Layout/OneBig.hs | 2 +- XMonad/Layout/Spiral.hs | 4 ++-- XMonad/Prompt.hs | 10 +++++----- XMonad/Util/DebugWindow.hs | 10 ++++------ XMonad/Util/EZConfig.hs | 2 +- XMonad/Util/Stack.hs | 6 +++--- tests/Selective.hs | 4 ++-- 20 files changed, 33 insertions(+), 38 deletions(-) diff --git a/XMonad/Actions/EasyMotion.hs b/XMonad/Actions/EasyMotion.hs index 8f449f6ca7..1d27a294d6 100644 --- a/XMonad/Actions/EasyMotion.hs +++ b/XMonad/Actions/EasyMotion.hs @@ -387,5 +387,5 @@ handleKeyboard dpy drawFn cancel selected deselected = do _ -> handleKeyboard dpy drawFn cancel (trim fg) (clear bg) >>= retryBackspace where (fg, bg) = partition ((== Just keySym) . listToMaybe . chord) selected - trim = map (\o -> o { chord = tail $ chord o }) + trim = map (\o -> o { chord = drop 1 $ chord o }) clear = map (\o -> o { chord = [] }) diff --git a/XMonad/Actions/Navigation2D.hs b/XMonad/Actions/Navigation2D.hs index 6cb59874f9..1c1c635e06 100644 --- a/XMonad/Actions/Navigation2D.hs +++ b/XMonad/Actions/Navigation2D.hs @@ -783,8 +783,7 @@ doCenterNavigation dir (cur, rect) winrects -- All the points that coincide with the current center and succeed it -- in the (appropriately ordered) window stack. - onCtr' = L.tail $ L.dropWhile ((cur /=) . fst) onCtr - -- tail should be safe here because cur should be in onCtr + onCtr' = L.drop 1 $ L.dropWhile ((cur /=) . fst) onCtr -- All the points that do not coincide with the current center and which -- lie in the (rotated) right cone. @@ -885,7 +884,7 @@ swap win winset = W.focusWindow cur newvisws = zipWith (\ws wns -> ws { W.stack = W.differentiate wns }) visws newwins newscrs = zipWith (\scr ws -> scr { W.workspace = ws }) scrs newvisws newwinset = winset { W.current = head newscrs - , W.visible = tail newscrs + , W.visible = drop 1 newscrs } -- | Calculates the center of a rectangle diff --git a/XMonad/Actions/Search.hs b/XMonad/Actions/Search.hs index 3f4ca274fb..1fd6b841f4 100644 --- a/XMonad/Actions/Search.hs +++ b/XMonad/Actions/Search.hs @@ -322,7 +322,7 @@ searchEngine name site = searchEngineF name (\s -> site ++ escape s) inside of a URL instead of in the end) you can use the alternative 'searchEngineF' function. > searchFunc :: String -> String -> searchFunc s | "wiki:" `isPrefixOf` s = "https://en.wikipedia.org/wiki/" ++ (escape $ tail $ snd $ break (==':') s) +> searchFunc s | "wiki:" `isPrefixOf` s = "https://en.wikipedia.org/wiki/" ++ (escape $ drop 1 $ snd $ break (==':') s) > | "https://" `isPrefixOf` s = s > | otherwise = (use google) s > myNewEngine = searchEngineF "mymulti" searchFunc diff --git a/XMonad/Actions/WorkspaceCursors.hs b/XMonad/Actions/WorkspaceCursors.hs index 6f3f1693b7..226f554cea 100644 --- a/XMonad/Actions/WorkspaceCursors.hs +++ b/XMonad/Actions/WorkspaceCursors.hs @@ -98,7 +98,7 @@ makeCursors :: [[String]] -> Cursors String makeCursors [] = error "Workspace Cursors cannot be empty" makeCursors a = concat . reverse <$> foldl addDim x xs where x = end $ map return $ head a - xs = map (map return) $ tail a + xs = map (map return) $ drop 1 a -- this could probably be simplified, but this true: -- toList . makeCursors == map (concat . reverse) . sequence . reverse . map (map (:[])) -- the strange order is used because it makes the regular M-1..9 diff --git a/XMonad/Hooks/DebugEvents.hs b/XMonad/Hooks/DebugEvents.hs index f74e223b3d..f200fd1bcb 100644 --- a/XMonad/Hooks/DebugEvents.hs +++ b/XMonad/Hooks/DebugEvents.hs @@ -687,9 +687,7 @@ dumpString = do \s -> if null s then Nothing else let (w,s'') = break (== '\NUL') s - s' = if null s'' - then s'' - else tail s'' + s' = drop 1 s'' in Just (w,s') case ss of [s] -> append $ show s diff --git a/XMonad/Hooks/InsertPosition.hs b/XMonad/Hooks/InsertPosition.hs index fc88ffe62d..1d1a92d118 100644 --- a/XMonad/Hooks/InsertPosition.hs +++ b/XMonad/Hooks/InsertPosition.hs @@ -83,4 +83,4 @@ insertDown w = W.swapDown . W.insertUp w focusLast' :: W.Stack a -> W.Stack a focusLast' st = let ws = W.integrate st - in W.Stack (last ws) (tail $ reverse ws) [] + in W.Stack (last ws) (drop 1 $ reverse ws) [] diff --git a/XMonad/Hooks/StatusBar/PP.hs b/XMonad/Hooks/StatusBar/PP.hs index 9b7f9fa660..e3c1f30cf7 100644 --- a/XMonad/Hooks/StatusBar/PP.hs +++ b/XMonad/Hooks/StatusBar/PP.hs @@ -464,7 +464,7 @@ xmobarStrip = converge (xmobarStripTags ["fc","icon","action"]) converge :: (Eq a) => (a -> a) -> a -> a converge f a = let xs = iterate f a - in fst $ head $ dropWhile (uncurry (/=)) $ zip xs $ tail xs + in fst $ head $ dropWhile (uncurry (/=)) $ zip xs $ drop 1 xs xmobarStripTags :: [String] -- ^ tags -> String -> String -- ^ with all \...\ removed diff --git a/XMonad/Layout/CenteredMaster.hs b/XMonad/Layout/CenteredMaster.hs index 819cb0324d..4538b94370 100644 --- a/XMonad/Layout/CenteredMaster.hs +++ b/XMonad/Layout/CenteredMaster.hs @@ -84,7 +84,7 @@ applyPosition pos wksp rect = do runLayout wksp rect else do let firstW = head ws - let other = tail ws + let other = drop 1 ws let filtStack = stack >>= W.filter (firstW /=) wrs <- runLayout (wksp {W.stack = filtStack}) rect return $ first ((firstW, place pos other rect) :) wrs diff --git a/XMonad/Layout/Combo.hs b/XMonad/Layout/Combo.hs index e5e41c70c1..7252f95d4e 100644 --- a/XMonad/Layout/Combo.hs +++ b/XMonad/Layout/Combo.hs @@ -132,7 +132,7 @@ instance (LayoutClass l (), LayoutClass l1 a, LayoutClass l2 a, Read a, Show a, differentiate :: Eq q => [q] -> [q] -> Maybe (Stack q) differentiate (z:zs) xs | z `elem` xs = Just $ Stack { focus=z , up = reverse $ takeWhile (/=z) xs - , down = tail $ dropWhile (/=z) xs } + , down = drop 1 $ dropWhile (/=z) xs } | otherwise = differentiate zs xs differentiate [] xs = W.differentiate xs diff --git a/XMonad/Layout/Dwindle.hs b/XMonad/Layout/Dwindle.hs index dadf8adf08..222b7721c1 100644 --- a/XMonad/Layout/Dwindle.hs +++ b/XMonad/Layout/Dwindle.hs @@ -159,8 +159,8 @@ squeeze dir ratio rect st = zip wins rects nwins = length wins sizes = take nwins $ unfoldr (\r -> Just (r * ratio, r * ratio)) 1 totals' = 0 : zipWith (+) sizes totals' - totals = tail totals' - splits = zip (tail sizes) totals + totals = drop 1 totals' + splits = zip (drop 1 sizes) totals ratios = reverse $ map (uncurry (/)) splits rects = genRects rect ratios genRects r [] = [r] diff --git a/XMonad/Layout/Grid.hs b/XMonad/Layout/Grid.hs index 3e5f44b780..a89fc8bb5d 100644 --- a/XMonad/Layout/Grid.hs +++ b/XMonad/Layout/Grid.hs @@ -61,7 +61,7 @@ arrange aspectRatio (Rectangle rx ry rw rh) st = zip st rectangles mincs = max 1 $ nwins `div` ncols extrs = nwins - ncols * mincs chop :: Int -> Dimension -> [(Position, Dimension)] - chop n m = ((0, m - k * fromIntegral (pred n)) :) . map (, k) . tail . reverse . take n . tail . iterate (subtract k') $ m' + chop n m = ((0, m - k * fromIntegral (pred n)) :) . map (, k) . drop 1 . reverse . take n . drop 1 . iterate (subtract k') $ m' where k :: Dimension k = m `div` fromIntegral n diff --git a/XMonad/Layout/Groups/Helpers.hs b/XMonad/Layout/Groups/Helpers.hs index 808d2c024a..40b799cf33 100644 --- a/XMonad/Layout/Groups/Helpers.hs +++ b/XMonad/Layout/Groups/Helpers.hs @@ -155,7 +155,7 @@ focusHelper :: (Bool -> Bool) -- ^ if you want to focus a floating window, 'id'. -> X () focusHelper f g = withFocused $ \w -> do ws <- getWindows - let (before, tail -> after) = span (/=w) ws + let (before, drop 1 -> after) = span (/=w) ws let toFocus = g $ after ++ before floats <- getFloats case filter (f . flip elem floats) toFocus of diff --git a/XMonad/Layout/MultiColumns.hs b/XMonad/Layout/MultiColumns.hs index b32642aad7..3dc4d6929f 100644 --- a/XMonad/Layout/MultiColumns.hs +++ b/XMonad/Layout/MultiColumns.hs @@ -96,7 +96,7 @@ instance LayoutClass MultiCol a where ,fmap incmastern (fromMessage m)] where resize Shrink = l { multiColSize = max (-0.5) $ s-ds } resize Expand = l { multiColSize = min 1 $ s+ds } - incmastern (IncMasterN x) = l { multiColNWin = take a n ++ [newval] ++ tail r } + incmastern (IncMasterN x) = l { multiColNWin = take a n ++ [newval] ++ drop 1 r } where newval = max 0 $ head r + x r = drop a n n = multiColNWin l diff --git a/XMonad/Layout/OneBig.hs b/XMonad/Layout/OneBig.hs index cd1d2f3945..787c9f39a9 100644 --- a/XMonad/Layout/OneBig.hs +++ b/XMonad/Layout/OneBig.hs @@ -66,7 +66,7 @@ oneBigLayout (OneBig cx cy) rect stack = [(master,masterRect)] w = wd rect m = calcBottomWs n w h' master = head ws - other = tail ws + other = drop 1 ws bottomWs = take m other rightWs = drop m other masterRect = cmaster n m cx cy rect diff --git a/XMonad/Layout/Spiral.hs b/XMonad/Layout/Spiral.hs index 258b6b0840..a2fd10ec15 100644 --- a/XMonad/Layout/Spiral.hs +++ b/XMonad/Layout/Spiral.hs @@ -45,7 +45,7 @@ import XMonad.StackSet ( integrate ) -- "XMonad.Doc.Extending#Editing_the_layout_hook". fibs :: [Integer] -fibs = 1 : 1 : zipWith (+) fibs (tail fibs) +fibs = 1 : 1 : zipWith (+) fibs (drop 1 fibs) mkRatios :: [Integer] -> [Rational] mkRatios (x1:x2:xs) = (x1 % x2) : mkRatios (x2:xs) @@ -82,7 +82,7 @@ data SpiralWithDir a = SpiralWithDir Direction Rotation Rational instance LayoutClass SpiralWithDir a where pureLayout (SpiralWithDir dir rot scale) sc stack = zip ws rects where ws = integrate stack - ratios = blend scale . reverse . take (length ws - 1) . mkRatios $ tail fibs + ratios = blend scale . reverse . take (length ws - 1) . mkRatios $ drop 1 fibs rects = divideRects (zip ratios dirs) sc dirs = dropWhile (/= dir) $ case rot of CW -> cycle [East .. North] diff --git a/XMonad/Prompt.hs b/XMonad/Prompt.hs index f2d850807c..020cfa6a55 100644 --- a/XMonad/Prompt.hs +++ b/XMonad/Prompt.hs @@ -540,7 +540,7 @@ mkXPromptWithModes modes conf = do let defaultMode = head modes modeStack = W.Stack { W.focus = defaultMode -- Current mode , W.up = [] - , W.down = tail modes -- Other modes + , W.down = drop 1 modes -- Other modes } om = XPMultipleModes modeStack st' <- mkXPromptImplementation (showXPrompt defaultMode) conf { alwaysHighlight = True } om @@ -650,7 +650,7 @@ eventLoop handle stopAction = do return (ks, s, ev) else return (noSymbol, "", ev) l -> do - modify $ \s -> s { eventBuffer = tail l } + modify $ \s -> s { eventBuffer = drop 1 l } return $ head l handle (keysym,keystr) event stopAction >>= \stop -> unless stop (eventLoop handle stopAction) @@ -1315,7 +1315,7 @@ deleteString d = c oc oo | oo >= length oc && d == Prev = take (oo - 1) oc | oo < length oc && d == Prev = take (oo - 1) f ++ ss - | oo < length oc && d == Next = f ++ tail ss + | oo < length oc && d == Next = f ++ drop 1 ss | otherwise = oc where (f,ss) = splitAt oo oc @@ -1523,7 +1523,7 @@ printPrompt drw = do (preCursor, cursor, postCursor) = if offset >= length com then (str, " ","") -- add a space: it will be our cursor ;-) else let (a, b) = splitAt offset com - in (prt ++ a, [head b], tail b) + in (prt ++ a, take 1 b, drop 1 b) -- vertical and horizontal text alignment (asc, desc) <- io $ textExtentsXMF fontS str -- font ascent and descent @@ -1780,7 +1780,7 @@ breakAtSpace s | " \\" `isPrefixOf` s2 = (s1 ++ " " ++ s1', s2') | otherwise = (s1, s2) where (s1, s2 ) = break isSpace s - (s1',s2') = breakAtSpace $ tail s2 + (s1',s2') = breakAtSpace $ drop 1 s2 -- | 'historyCompletion' provides a canned completion function much like -- 'getShellCompl'; you pass it to mkXPrompt, and it will make completions work diff --git a/XMonad/Util/DebugWindow.hs b/XMonad/Util/DebugWindow.hs index b0b72b8e44..7b5fdfc555 100644 --- a/XMonad/Util/DebugWindow.hs +++ b/XMonad/Util/DebugWindow.hs @@ -57,9 +57,7 @@ debugWindow w = do \s -> if null s then Nothing else let (w'',s'') = break (== '\NUL') s - s' = if null s'' - then s'' - else tail s'' + s' = drop 1 s'' in Just (w'',s') t <- catchX' (wrap <$> getEWMHTitle "VISIBLE" w) $ catchX' (wrap <$> getEWMHTitle "" w) $ @@ -202,7 +200,7 @@ windowType d w ts = do Just s'' -> s'' _ -> '<':show a ++ ">" unAtoms as (t ++ (if i then ' ':s else s)) True - + simplify :: String -> Atom -> X String simplify pfx a = do s' <- io $ getAtomName d a @@ -214,10 +212,10 @@ windowType d w ts = do return s -- note that above it says this checks all of them before simplifying. - -- I'll do that after I'm confident this works as intended. + -- I'll do that after I'm confident this works as intended. windowState :: [Atom] -> X String windowState [] = return "" windowState as' = go as' ";" where go [] t = return t - go (a:as) t = simplify "_NET_WM_STATE_" a >>= \t' -> go as (t ++ ' ':t') + go (a:as) t = simplify "_NET_WM_STATE_" a >>= \t' -> go as (t ++ ' ':t') diff --git a/XMonad/Util/EZConfig.hs b/XMonad/Util/EZConfig.hs index d69a92ab13..7a852bffa0 100644 --- a/XMonad/Util/EZConfig.hs +++ b/XMonad/Util/EZConfig.hs @@ -439,7 +439,7 @@ mkSubmaps' subm binds = map combine gathered $ binds combine [([k],act)] = (k,act) combine ks = (head . fst . head $ ks, - subm . mkSubmaps' subm $ map (first tail) ks) + subm . mkSubmaps' subm $ map (first (drop 1)) ks) fstKey = (==) `on` (head . fst) -- | Given a configuration record and a list of (key sequence diff --git a/XMonad/Util/Stack.hs b/XMonad/Util/Stack.hs index 0ef69a93a2..27f3d25e49 100644 --- a/XMonad/Util/Stack.hs +++ b/XMonad/Util/Stack.hs @@ -162,20 +162,20 @@ focusUpZ :: Zipper a -> Zipper a focusUpZ Nothing = Nothing focusUpZ (Just s) | u:up <- W.up s = Just $ W.Stack u up (W.focus s:W.down s) focusUpZ (Just s) | null $ W.down s = Just s -focusUpZ (Just (W.Stack f _ down)) = Just $ W.Stack (last down) (tail (reverse down) ++ [f]) [] +focusUpZ (Just (W.Stack f _ down)) = Just $ W.Stack (last down) (drop 1 (reverse down) ++ [f]) [] -- | Move the focus to the next element focusDownZ :: Zipper a -> Zipper a focusDownZ Nothing = Nothing focusDownZ (Just s) | d:down <- W.down s = Just $ W.Stack d (W.focus s:W.up s) down focusDownZ (Just s) | null $ W.up s = Just s -focusDownZ (Just (W.Stack f up _)) = Just $ W.Stack (last up) [] (tail (reverse up) ++ [f]) +focusDownZ (Just (W.Stack f up _)) = Just $ W.Stack (last up) [] (drop 1 (reverse up) ++ [f]) -- | Move the focus to the first element focusMasterZ :: Zipper a -> Zipper a focusMasterZ Nothing = Nothing focusMasterZ (Just (W.Stack f up down)) | not $ null up - = Just $ W.Stack (last up) [] (tail (reverse up) ++ [f] ++ down) + = Just $ W.Stack (last up) [] (drop 1 (reverse up) ++ [f] ++ down) focusMasterZ (Just s) = Just s -- | Refocus a @Stack a@ on an element satisfying the predicate, or fail to diff --git a/tests/Selective.hs b/tests/Selective.hs index c9df5ddfe5..1842f7dcf5 100644 --- a/tests/Selective.hs +++ b/tests/Selective.hs @@ -34,14 +34,14 @@ prop_select_focus sel (stk :: Stack Int) = focus stk == focus (select sel' stk) prop_select_increasing :: Selection l -> Stack Int -> Bool prop_select_increasing sel (stk :: Stack Int) = let res = integrate $ select sel stk - in and . zipWith (<) res $ tail res + in and . zipWith (<) res $ drop 1 res -- selection has the form [0..l] ++ [m..n] -- relies on the Arbitrary instance for Stack Int generating stacks like [0..k] prop_select_two_consec :: Selection l -> Stack Int -> Bool prop_select_two_consec sel (stk :: Stack Int) = let wins = integrate $ select sel stk - in (length . filter not . zipWith ((==) . (+1)) wins $ tail wins) <= 1 + in (length . filter not . zipWith ((==) . (+1)) wins $ drop 1 wins) <= 1 -- update preserves invariants on selections prop_update_nm :: Selection l -> Stack Int -> Bool From 8ee129483a9bbc67efe58ac9fce1b4e12c00da77 Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Tue, 19 Sep 2023 09:13:15 +0200 Subject: [PATCH 3/7] X.U.Stack: Add zipperFocusedAtFirstOf --- CHANGES.md | 5 +++++ XMonad/Layout/Combo.hs | 25 ++++++++++--------------- XMonad/Layout/ComboP.hs | 26 ++++++++------------------ XMonad/Layout/LayoutBuilder.hs | 11 +++-------- XMonad/Layout/TallMastersCombo.hs | 28 ++++++++-------------------- XMonad/Util/Stack.hs | 13 +++++++++++++ 6 files changed, 47 insertions(+), 61 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 72d0fcefdf..c7f5975a59 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -265,6 +265,11 @@ - Added `passOTPTypePrompt` to type out one-time-passwords via `xdotool`. + * `XMonad.Util.Stack` + + - Added `zipperFocusedAtFirstOf` to differentiate two lists into a + zipper. + ### Other changes ## 0.17.1 (September 3, 2022) diff --git a/XMonad/Layout/Combo.hs b/XMonad/Layout/Combo.hs index 7252f95d4e..805857aa39 100644 --- a/XMonad/Layout/Combo.hs +++ b/XMonad/Layout/Combo.hs @@ -1,5 +1,8 @@ -{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, - UndecidableInstances, PatternGuards #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PatternGuards #-} +{-# LANGUAGE UndecidableInstances #-} ----------------------------------------------------------------------------- -- | @@ -24,10 +27,10 @@ module XMonad.Layout.Combo ( ) where import XMonad hiding (focus) +import XMonad.Layout.WindowNavigation (MoveWindowToWindow (..)) import XMonad.Prelude (delete, fromMaybe, intersect, isJust, (\\)) -import XMonad.StackSet ( integrate', Workspace (..), Stack(..) ) -import XMonad.Layout.WindowNavigation ( MoveWindowToWindow(..) ) -import qualified XMonad.StackSet as W ( differentiate ) +import XMonad.StackSet (Stack (..), Workspace (..), integrate') +import XMonad.Util.Stack (zipperFocusedAtFirstOf) -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: @@ -94,8 +97,8 @@ instance (LayoutClass l (), LayoutClass l1 a, LayoutClass l2 a, Read a, Show a, [] -> init x _ -> x superstack = Stack { focus=(), up=[], down=[()] } - s1 = differentiate f' (origws \\ w2') - s2 = differentiate f' w2' + s1 = zipperFocusedAtFirstOf f' (origws \\ w2') + s2 = zipperFocusedAtFirstOf f' w2' f' = case s of (Just s') -> focus s':delete (focus s') f Nothing -> f ([((),r1),((),r2)], msuper') <- runLayout (Workspace "" super (Just superstack)) rinput @@ -128,14 +131,6 @@ instance (LayoutClass l (), LayoutClass l1 a, LayoutClass l2 a, Read a, Show a, description (C2 _ _ super l1 l2) = "combining "++ description l1 ++" and "++ description l2 ++" with "++ description super - -differentiate :: Eq q => [q] -> [q] -> Maybe (Stack q) -differentiate (z:zs) xs | z `elem` xs = Just $ Stack { focus=z - , up = reverse $ takeWhile (/=z) xs - , down = drop 1 $ dropWhile (/=z) xs } - | otherwise = differentiate zs xs -differentiate [] xs = W.differentiate xs - broadcastPrivate :: LayoutClass l b => SomeMessage -> [l b] -> X (Maybe [l b]) broadcastPrivate a ol = do nml <- mapM f ol if any isJust nml diff --git a/XMonad/Layout/ComboP.hs b/XMonad/Layout/ComboP.hs index a1631cb37c..81d7892bbd 100644 --- a/XMonad/Layout/ComboP.hs +++ b/XMonad/Layout/ComboP.hs @@ -25,12 +25,13 @@ module XMonad.Layout.ComboP ( Property(..) ) where -import XMonad.Prelude import XMonad hiding (focus) -import XMonad.StackSet ( Workspace (..), Stack(..) ) import XMonad.Layout.WindowNavigation -import XMonad.Util.WindowProperties +import XMonad.Prelude +import XMonad.StackSet ( Workspace (..), Stack(..) ) import qualified XMonad.StackSet as W +import XMonad.Util.Stack (zipperFocusedAtFirstOf) +import XMonad.Util.WindowProperties -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: @@ -99,10 +100,10 @@ instance (LayoutClass l (), LayoutClass l1 Window, LayoutClass l2 Window) => f' = focus s:delete (focus s) f -- list of focused windows, contains 2 elements at most in do matching <- hasProperty prop `filterM` new -- new windows matching predecate - let w1' = w1c ++ matching -- updated first pane windows - w2' = w2c ++ (new \\ matching) -- updated second pane windows - s1 = differentiate f' w1' -- first pane stack - s2 = differentiate f' w2' -- second pane stack + let w1' = w1c ++ matching -- updated first pane windows + w2' = w2c ++ (new \\ matching) -- updated second pane windows + s1 = zipperFocusedAtFirstOf f' w1' -- first pane stack + s2 = zipperFocusedAtFirstOf f' w2' -- second pane stack ([((),r1),((),r2)], msuper') <- runLayout (Workspace "" super superstack) rinput (wrs1, ml1') <- runLayout (Workspace "" l1 s1) r1 (wrs2, ml2') <- runLayout (Workspace "" l2 s2) r2 @@ -177,15 +178,4 @@ forwardIfFocused l w m = do then handleMessage l m else return Nothing --- code from CombineTwo --- given two sets of zs and xs takes the first z from zs that also belongs to xs --- and turns xs into a stack with z being current element. Acts as --- StackSet.differentiate if zs and xs don't intersect -differentiate :: Eq q => [q] -> [q] -> Maybe (Stack q) -differentiate (z:zs) xs | z `elem` xs = Just $ Stack { focus=z - , up = reverse $ takeWhile (/=z) xs - , down = tail $ dropWhile (/=z) xs } - | otherwise = differentiate zs xs -differentiate [] xs = W.differentiate xs - -- vim:ts=4:shiftwidth=4:softtabstop=4:expandtab:foldlevel=20: diff --git a/XMonad/Layout/LayoutBuilder.hs b/XMonad/Layout/LayoutBuilder.hs index 2e38e523af..fef7778b6b 100644 --- a/XMonad/Layout/LayoutBuilder.hs +++ b/XMonad/Layout/LayoutBuilder.hs @@ -57,9 +57,11 @@ module XMonad.Layout.LayoutBuilder ( LayoutN, ) where +import Data.Maybe (maybeToList) import XMonad import XMonad.Prelude (foldM, (<|>), isJust, fromMaybe, isNothing, listToMaybe) import qualified XMonad.StackSet as W +import XMonad.Util.Stack (zipperFocusedAtFirstOf) import XMonad.Util.WindowProperties -------------------------------------------------------------------------------- @@ -452,11 +454,4 @@ calcArea (SubBox xpos ypos width height) rect = -------------------------------------------------------------------------------- differentiate' :: Eq q => Maybe q -> [q] -> Maybe (W.Stack q) -differentiate' _ [] = Nothing -differentiate' Nothing w = W.differentiate w -differentiate' (Just f) w - | f `elem` w = Just W.Stack { W.focus = f - , W.up = reverse $ takeWhile (/=f) w - , W.down = tail $ dropWhile (/=f) w - } - | otherwise = W.differentiate w +differentiate' = zipperFocusedAtFirstOf . maybeToList diff --git a/XMonad/Layout/TallMastersCombo.hs b/XMonad/Layout/TallMastersCombo.hs index 3a86351047..055bae03ef 100644 --- a/XMonad/Layout/TallMastersCombo.hs +++ b/XMonad/Layout/TallMastersCombo.hs @@ -42,12 +42,13 @@ module XMonad.Layout.TallMastersCombo ( ) where import XMonad hiding (focus, (|||)) -import XMonad.Prelude (delete, find, foldM, fromMaybe, isJust) -import XMonad.StackSet (Workspace(..),integrate',Stack(..)) -import qualified XMonad.StackSet as W import qualified XMonad.Layout as LL -import XMonad.Layout.Simplest (Simplest(..)) import XMonad.Layout.Decoration +import XMonad.Layout.Simplest (Simplest (..)) +import XMonad.Prelude (delete, find, foldM, fromMaybe, isJust) +import XMonad.StackSet (Stack (..), Workspace (..), integrate') +import qualified XMonad.StackSet as W +import XMonad.Util.Stack (zipperFocusedAtFirstOf) --------------------------------------------------------------------------------- -- $usage @@ -302,19 +303,6 @@ instance (GetFocused l1 Window, GetFocused l2 Window) => LayoutClass (TMSCombine mlayout2 <- handleMessage layout2 m return $ mergeSubLayouts mlayout1 mlayout2 i False - - --- code from CombineTwo --- given two sets of zs and xs takes the first z from zs that also belongs to xs --- and turns xs into a stack with z being current element. Acts as --- StackSet.differentiate if zs and xs don't intersect -differentiate :: Eq q => [q] -> [q] -> Maybe (Stack q) -differentiate (z:zs) xs | z `elem` xs = Just $ Stack { focus=z - , up = reverse $ takeWhile (/=z) xs - , down = tail $ dropWhile (/=z) xs } - | otherwise = differentiate zs xs -differentiate [] xs = W.differentiate xs - -- | Swap a given window with the focused window. swapWindow :: (Eq a) => a -> Stack a -> Stack a swapWindow w (Stack foc upLst downLst) @@ -388,9 +376,9 @@ splitStack f nmaster frac s = Nothing -> f snum = length slst (slst1, slst2) = splitAt nmaster slst - s0 = differentiate f' slst - s1' = differentiate f' slst1 - s2' = differentiate f' slst2 + s0 = zipperFocusedAtFirstOf f' slst + s1' = zipperFocusedAtFirstOf f' slst1 + s2' = zipperFocusedAtFirstOf f' slst2 (s1,s2,frac') | nmaster == 0 = (Nothing,s0,0) | nmaster >= snum = (s0,Nothing,1) | otherwise = (s1',s2',frac) diff --git a/XMonad/Util/Stack.hs b/XMonad/Util/Stack.hs index 27f3d25e49..75f09e2864 100644 --- a/XMonad/Util/Stack.hs +++ b/XMonad/Util/Stack.hs @@ -27,6 +27,7 @@ module XMonad.Util.Stack ( -- * Usage , toIndex , fromTags , toTags + , zipperFocusedAtFirstOf -- * 'Zipper' manipulation functions -- ** Insertion, movement @@ -123,6 +124,18 @@ toTags Nothing = [] toTags (Just s) = map Left (reverse . W.up $ s) ++ [Right . W.focus $ s] ++ map Left (W.down s) +-- | @differentiate zs xs@ takes the first @z@ from @z2 that also belongs to +-- @xs@ and turns @xs@ into a stack with @z@ being the current element. Acts +-- as 'XMonad.StackSet.differentiate' if @zs@ and @xs@ don't intersect. +zipperFocusedAtFirstOf :: Eq q => [q] -> [q] -> Zipper q +zipperFocusedAtFirstOf [] xs = W.differentiate xs +zipperFocusedAtFirstOf (z : zs) xs + | z `elem` xs = Just $ + W.Stack { W.focus = z + , W.up = reverse $ takeWhile (/= z) xs + , W.down = drop 1 $ dropWhile (/= z) xs + } + | otherwise = zipperFocusedAtFirstOf zs xs -- * Zipper functions From 7599c898ef91383ab86bb9f9f99f07313e9221e2 Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Sun, 15 Oct 2023 11:31:40 +0200 Subject: [PATCH 4/7] X.Prelude: Add infinite stream type Stolen from X.A.MostRecentlyUsed. This can be used in favour of lists when we know the generated lists are definitely infinite. --- XMonad/Actions/MostRecentlyUsed.hs | 18 +------------ XMonad/Actions/Plane.hs | 2 +- XMonad/Config/Dmwit.hs | 2 +- XMonad/Prelude.hs | 42 ++++++++++++++++++++++++++++-- XMonad/Prompt.hs | 2 +- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/XMonad/Actions/MostRecentlyUsed.hs b/XMonad/Actions/MostRecentlyUsed.hs index c183805e0b..59513a3c95 100644 --- a/XMonad/Actions/MostRecentlyUsed.hs +++ b/XMonad/Actions/MostRecentlyUsed.hs @@ -68,6 +68,7 @@ import XMonad.Util.PureX (handlingRefresh, curScreenId, curTag, greedyView, view, peek, focusWindow) import XMonad.Util.History (History, origin, event, erase, ledger) import XMonad.Actions.Repeatable (repeatableSt) +import XMonad.Prelude (Stream (..), cycleS) -- }}} @@ -208,20 +209,3 @@ winHistEH ev = All True <$ case ev of where collect w = XS.modify $ \wh@WinHist{hist} -> wh{ hist = erase w hist } -- }}} - --- --< Auxiliary Data Type: Stream >-- {{{ - --- To satisfy the almighty exhaustivity checker. - -data Stream a = !a :~ Stream a -infixr 5 :~ - -(+~) :: [a] -> Stream a -> Stream a -xs +~ s = foldr (:~) s xs -infixr 5 +~ - -cycleS :: NonEmpty a -> Stream a -cycleS (x :| xs) = s where s = x :~ xs +~ s - --- }}} - diff --git a/XMonad/Actions/Plane.hs b/XMonad/Actions/Plane.hs index dd692d80ee..d6a4b3f8fa 100644 --- a/XMonad/Actions/Plane.hs +++ b/XMonad/Actions/Plane.hs @@ -41,7 +41,7 @@ module XMonad.Actions.Plane import Data.Map (Map, fromList) -import XMonad.Prelude +import XMonad.Prelude hiding (fromList) import XMonad import XMonad.StackSet hiding (workspaces) import XMonad.Util.Run diff --git a/XMonad/Config/Dmwit.hs b/XMonad/Config/Dmwit.hs index 72fa3212bd..768fd41aee 100644 --- a/XMonad/Config/Dmwit.hs +++ b/XMonad/Config/Dmwit.hs @@ -34,7 +34,7 @@ import XMonad.Layout.Grid import XMonad.Layout.IndependentScreens hiding (withScreen) import XMonad.Layout.Magnifier import XMonad.Layout.NoBorders -import XMonad.Prelude +import XMonad.Prelude hiding (fromList) import XMonad.Util.Dzen hiding (x, y) import XMonad.Util.SpawnOnce -- }}} diff --git a/XMonad/Prelude.hs b/XMonad/Prelude.hs index ce6e92fe0b..d52f49027c 100644 --- a/XMonad/Prelude.hs +++ b/XMonad/Prelude.hs @@ -1,7 +1,9 @@ {-# OPTIONS_GHC -Wno-dodgy-imports #-} {-# LANGUAGE BangPatterns #-} +{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeFamilies #-} -------------------------------------------------------------------- -- | -- Module : XMonad.Prelude @@ -37,6 +39,13 @@ module XMonad.Prelude ( multimediaKeys, functionKeys, WindowScreen, + + -- * Infinite streams + Stream(..), + (+~), + cycleS, + toList, + fromList, ) where import Foreign (alloca, peek) @@ -46,7 +55,7 @@ import Control.Applicative as Exports import Control.Monad as Exports import Data.Bool as Exports import Data.Char as Exports -import Data.Foldable as Exports +import Data.Foldable as Exports hiding (toList) import Data.Function as Exports import Data.Functor as Exports hiding (unzip) import Data.List as Exports hiding ((!?)) @@ -57,14 +66,15 @@ import Data.Traversable as Exports import qualified Data.Map.Strict as Map import Control.Arrow ((&&&), first) +import Control.Exception (SomeException, handle) import Data.Bifunctor (bimap) import Data.Bits import Data.List.NonEmpty (NonEmpty ((:|))) import Data.Tuple (swap) +import GHC.Exts (IsList(..)) import GHC.Stack import System.Directory (getHomeDirectory) import System.Environment (getEnv) -import Control.Exception (SomeException, handle) import qualified XMonad.StackSet as W -- | Short for 'fromIntegral'. @@ -466,3 +476,31 @@ multimediaKeys = filter ((/= noSymbol) . snd) . map (id &&& stringToKeysym) $ -- | The specialized 'W.Screen' derived from 'WindowSet'. type WindowScreen -- FIXME move to core = W.Screen WorkspaceId (Layout Window) Window ScreenId ScreenDetail + +-- | An infinite stream type +data Stream a = !a :~ Stream a +infixr 5 :~ + +instance Functor Stream where + fmap :: (a -> b) -> Stream a -> Stream b + fmap f = go + where go (x :~ xs) = f x :~ go xs + +instance IsList (Stream a) where + type (Item (Stream a)) = a + + fromList :: [a] -> Stream a + fromList (x : xs) = x :~ fromList xs + fromList [] = errorWithoutStackTrace "XMonad.Prelude.Stream.fromList: Can't create stream out of finite list." + + toList :: Stream a -> [a] + toList (x :~ xs) = x : toList xs + +-- | Absorb a list into an infinite stream. +(+~) :: [a] -> Stream a -> Stream a +xs +~ s = foldr (:~) s xs +infixr 5 +~ + +-- | Absorb a non-empty list into an infinite stream. +cycleS :: NonEmpty a -> Stream a +cycleS (x :| xs) = s where s = x :~ xs +~ s diff --git a/XMonad/Prompt.hs b/XMonad/Prompt.hs index 020cfa6a55..37ebe83887 100644 --- a/XMonad/Prompt.hs +++ b/XMonad/Prompt.hs @@ -99,7 +99,7 @@ module XMonad.Prompt ) where import XMonad hiding (cleanMask, config) -import XMonad.Prelude hiding (toList) +import XMonad.Prelude hiding (toList, fromList) import qualified XMonad.StackSet as W import XMonad.Util.Font import XMonad.Util.Types From c3d16bfa99e8ed108117631e952a83d7bf69b0ee Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Sun, 15 Oct 2023 11:43:12 +0200 Subject: [PATCH 5/7] X.L.Groups: Rewrite gen using infinite streams --- XMonad/Layout/Groups.hs | 43 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/XMonad/Layout/Groups.hs b/XMonad/Layout/Groups.hs index 7eabad31d1..ff3b34f231 100644 --- a/XMonad/Layout/Groups.hs +++ b/XMonad/Layout/Groups.hs @@ -105,8 +105,8 @@ data Uniq = U Integer Integer -- seed. All keys generated with this method will be different -- provided you don't use 'gen' again with a key from the list. -- (if you need to do that, see 'split' instead) -gen :: Uniq -> (Uniq, [Uniq]) -gen (U i1 i2) = (U (i1+1) i2, map (U i1) [i2..]) +gen :: Uniq -> (Uniq, Stream Uniq) +gen (U i1 i2) = (U (i1+1) i2, fmap (U i1) (fromList [i2..])) -- | Split an infinite list into two. I ended up not -- needing this, but let's keep it just in case. @@ -197,16 +197,16 @@ instance Message GroupsMessage modifyGroups :: (Zipper (Group l a) -> Zipper (Group l a)) -> Groups l l2 a -> Groups l l2 a -modifyGroups f g = let (seed', ids) = gen (seed g) - defaultGroups = fromJust $ singletonZ $ G (ID (head ids) $ baseLayout g) emptyZ +modifyGroups f g = let (seed', ident :~ _) = gen (seed g) + defaultGroups = fromJust $ singletonZ $ G (ID ident $ baseLayout g) emptyZ in g { groups = fromMaybe defaultGroups . f . Just $ groups g , seed = seed' } modifyGroupsX :: (Zipper (Group l a) -> X (Zipper (Group l a))) -> Groups l l2 a -> X (Groups l l2 a) modifyGroupsX f g = do - let (seed', ids) = gen (seed g) - defaultGroups = fromJust $ singletonZ $ G (ID (head ids) $ baseLayout g) emptyZ + let (seed', ident :~ _) = gen (seed g) + defaultGroups = fromJust $ singletonZ $ G (ID ident $ baseLayout g) emptyZ g' <- f . Just $ groups g return g { groups = fromMaybe defaultGroups g', seed = seed' } @@ -218,12 +218,12 @@ modifyGroupsX f g = do -- other stack changes as gracefully as possible. readapt :: Eq a => Zipper a -> Groups l l2 a -> Groups l l2 a readapt z g = let mf = getFocusZ z - (seed', ids) = gen $ seed g + (seed', ident :~ _) = gen $ seed g g' = g { seed = seed' } in flip modifyGroups g' $ mapZ_ (onZipper $ removeDeleted z) >>> filterKeepLast (isJust . gZipper) >>> findNewWindows (W.integrate' z) - >>> addWindows (ID (head ids) $ baseLayout g) + >>> addWindows (ID ident $ baseLayout g) >>> focusGroup mf >>> onFocusedZ (onZipper $ focusWindow mf) where filterKeepLast _ Nothing = Nothing @@ -379,10 +379,10 @@ type ModifySpecX = forall l. WithID l Window -- | Apply a ModifySpec. applySpec :: ModifySpec -> Groups l l2 Window -> Maybe (Groups l l2 Window) applySpec f g = - let (seed', ids) = gen $ seed g - g' = flip modifyGroups g $ f (ID (head ids) $ baseLayout g) + let (seed', ident :~ ids) = gen $ seed g -- gen generates an infinite list + g' = flip modifyGroups g $ f (ID ident $ baseLayout g) >>> toTags - >>> foldr (reID g) ((tail ids, []), []) + >>> foldr (reID g) ((ids, []), []) >>> snd >>> fromTags in if groups g == groups g' @@ -391,10 +391,10 @@ applySpec f g = applySpecX :: ModifySpecX -> Groups l l2 Window -> X (Maybe (Groups l l2 Window)) applySpecX f g = do - let (seed', ids) = gen $ seed g - g' <- flip modifyGroupsX g $ f (ID (head ids) $ baseLayout g) + let (seed', ident :~ ids) = gen $ seed g -- gen generates an infinite list + g' <- flip modifyGroupsX g $ f (ID ident $ baseLayout g) >>> fmap toTags - >>> fmap (foldr (reID g) ((tail ids, []), [])) + >>> fmap (foldr (reID g) ((ids, []), [])) >>> fmap snd >>> fmap fromTags return $ if groups g == groups g' @@ -403,14 +403,13 @@ applySpecX f g = do reID :: Groups l l2 Window -> Either (Group l Window) (Group l Window) - -> (([Uniq], [Uniq]), [Either (Group l Window) (Group l Window)]) - -> (([Uniq], [Uniq]), [Either (Group l Window) (Group l Window)]) -reID _ _ (([], _), _) = undefined -- The list of ids is infinite -reID g eg ((id:ids, seen), egs) = if myID `elem` seen - then ((ids, seen), mapE_ (setID id) eg:egs) - else ((id:ids, myID:seen), eg:egs) - where myID = getID $ gLayout $ fromE eg - setID id (G (ID _ _) z) = G (ID id $ baseLayout g) z + -> ((Stream Uniq, [Uniq]), [Either (Group l Window) (Group l Window)]) + -> ((Stream Uniq, [Uniq]), [Either (Group l Window) (Group l Window)]) +reID g eg ((ident :~ ids, seen), egs) + | myID `elem` seen = ((ids, seen), mapE_ (setID ident) eg:egs) + | otherwise = ((ident :~ ids, myID:seen), eg:egs) + where myID = getID $ gLayout $ fromE eg + setID id (G (ID _ _) z) = G (ID id $ baseLayout g) z -- ** Misc. ModifySpecs From 7680ebb93bb64c28dea126cc186281c8c5fc6a20 Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Sun, 15 Oct 2023 12:12:51 +0200 Subject: [PATCH 6/7] Import X.Prelude unqualified if necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This gets rid of, for example, The import of ‘liftA2’ from module ‘XMonad.Prelude’ is redundant -type warnings. --- XMonad/Actions/MessageFeedback.hs | 2 +- XMonad/Actions/MostRecentlyUsed.hs | 10 ++-------- XMonad/Actions/WorkspaceCursors.hs | 2 +- XMonad/Prompt/RunOrRaise.hs | 2 +- XMonad/Util/ExclusiveScratchpads.hs | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/XMonad/Actions/MessageFeedback.hs b/XMonad/Actions/MessageFeedback.hs index 58df3721b1..7ff9a569be 100644 --- a/XMonad/Actions/MessageFeedback.hs +++ b/XMonad/Actions/MessageFeedback.hs @@ -47,7 +47,7 @@ module XMonad.Actions.MessageFeedback import XMonad ( Window ) import XMonad.Core ( X(), Message, SomeMessage(..), LayoutClass(..), windowset, catchX, WorkspaceId, Layout, whenJust ) import XMonad.Operations ( updateLayout, windowBracket, modifyWindowSet ) -import XMonad.Prelude ( isJust, liftA2, void ) +import XMonad.Prelude import XMonad.StackSet ( Workspace, current, workspace, layout, tag ) import Control.Monad.State ( gets ) diff --git a/XMonad/Actions/MostRecentlyUsed.hs b/XMonad/Actions/MostRecentlyUsed.hs index 59513a3c95..2ac6b6a708 100644 --- a/XMonad/Actions/MostRecentlyUsed.hs +++ b/XMonad/Actions/MostRecentlyUsed.hs @@ -31,14 +31,8 @@ module XMonad.Actions.MostRecentlyUsed ( ) where -- base -import Data.Maybe (fromMaybe) -import Data.List.NonEmpty (NonEmpty(..), nonEmpty) -import Data.Monoid (All(..), Any) -import Data.Foldable (for_) -import Data.Functor (($>)) +import Data.List.NonEmpty (nonEmpty) import Data.IORef (newIORef, readIORef, writeIORef, modifyIORef) -import Control.Applicative (liftA2) -import Control.Monad (when, unless, join) import Control.Monad.IO.Class (MonadIO) -- mtl @@ -68,7 +62,7 @@ import XMonad.Util.PureX (handlingRefresh, curScreenId, curTag, greedyView, view, peek, focusWindow) import XMonad.Util.History (History, origin, event, erase, ledger) import XMonad.Actions.Repeatable (repeatableSt) -import XMonad.Prelude (Stream (..), cycleS) +import XMonad.Prelude -- }}} diff --git a/XMonad/Actions/WorkspaceCursors.hs b/XMonad/Actions/WorkspaceCursors.hs index 226f554cea..bb93ac576c 100644 --- a/XMonad/Actions/WorkspaceCursors.hs +++ b/XMonad/Actions/WorkspaceCursors.hs @@ -50,7 +50,7 @@ import XMonad.Layout.LayoutModifier(ModifiedLayout(..), import XMonad(Message, WorkspaceId, X, XState(windowset), fromMessage, sendMessage, windows, gets) import XMonad.Util.Stack (reverseS) -import XMonad.Prelude (find, fromJust, guard, liftA2, toList, when, (<=<)) +import XMonad.Prelude -- $usage -- diff --git a/XMonad/Prompt/RunOrRaise.hs b/XMonad/Prompt/RunOrRaise.hs index 9618d2b2fe..60e2ba640f 100644 --- a/XMonad/Prompt/RunOrRaise.hs +++ b/XMonad/Prompt/RunOrRaise.hs @@ -22,7 +22,7 @@ module XMonad.Prompt.RunOrRaise ) where import XMonad hiding (config) -import XMonad.Prelude (isNothing, isSuffixOf, liftA2) +import XMonad.Prelude import XMonad.Prompt import XMonad.Prompt.Shell import XMonad.Actions.WindowGo (runOrRaise) diff --git a/XMonad/Util/ExclusiveScratchpads.hs b/XMonad/Util/ExclusiveScratchpads.hs index 05da0fd6fd..02a0a8436b 100644 --- a/XMonad/Util/ExclusiveScratchpads.hs +++ b/XMonad/Util/ExclusiveScratchpads.hs @@ -39,7 +39,7 @@ module XMonad.Util.ExclusiveScratchpads customFloating ) where -import XMonad.Prelude (appEndo, filterM, liftA2, (<=<)) +import XMonad.Prelude import XMonad import XMonad.Actions.Minimize import XMonad.Actions.TagWindows (addTag,delTag) From 46a26487ba6c5e4a44343e3d544291108c2852a2 Mon Sep 17 00:00:00 2001 From: Tony Zorman Date: Sun, 15 Oct 2023 12:29:56 +0200 Subject: [PATCH 7/7] Reduce head usage --- XMonad/Actions/CycleSelectedLayouts.hs | 5 +++-- XMonad/Actions/OnScreen.hs | 9 ++++----- XMonad/Hooks/CurrentWorkspaceOnTop.hs | 13 ++++++++----- XMonad/Hooks/InsertPosition.hs | 6 ++++-- XMonad/Hooks/StatusBar/PP.hs | 2 +- XMonad/Hooks/WallpaperSetter.hs | 2 +- XMonad/Hooks/WorkspaceHistory.hs | 4 ++-- XMonad/Layout/CenteredMaster.hs | 8 +++----- XMonad/Layout/Combo.hs | 2 +- XMonad/Prompt/Shell.hs | 2 +- 10 files changed, 28 insertions(+), 25 deletions(-) diff --git a/XMonad/Actions/CycleSelectedLayouts.hs b/XMonad/Actions/CycleSelectedLayouts.hs index cf3db3ff03..2a99e55972 100644 --- a/XMonad/Actions/CycleSelectedLayouts.hs +++ b/XMonad/Actions/CycleSelectedLayouts.hs @@ -39,8 +39,9 @@ cycleToNext lst a = do -- | If the current layout is in the list, cycle to the next layout. Otherwise, -- apply the first layout from list. cycleThroughLayouts :: [String] -> X () -cycleThroughLayouts lst = do +cycleThroughLayouts [] = pure () +cycleThroughLayouts lst@(x: _) = do winset <- gets windowset let ld = description . S.layout . S.workspace . S.current $ winset - let newld = fromMaybe (head lst) (cycleToNext lst ld) + let newld = fromMaybe x (cycleToNext lst ld) sendMessage $ JumpToLayout newld diff --git a/XMonad/Actions/OnScreen.hs b/XMonad/Actions/OnScreen.hs index dff88dba28..ec13a14ecb 100644 --- a/XMonad/Actions/OnScreen.hs +++ b/XMonad/Actions/OnScreen.hs @@ -27,7 +27,7 @@ module XMonad.Actions.OnScreen ( ) where import XMonad -import XMonad.Prelude (fromMaybe, guard) +import XMonad.Prelude (fromMaybe, guard, empty) import XMonad.StackSet hiding (new) @@ -140,10 +140,9 @@ toggleOrView' f i st = fromMaybe (f i st) $ do let st' = hidden st -- make sure we actually have to do something guard $ i == (tag . workspace $ current st) - guard $ not (null st') - -- finally, toggle! - return $ f (tag . head $ st') st - + case st' of + [] -> empty + (h : _) -> return $ f (tag h) st -- finally, toggle! -- $usage -- diff --git a/XMonad/Hooks/CurrentWorkspaceOnTop.hs b/XMonad/Hooks/CurrentWorkspaceOnTop.hs index 2af126e7c9..dda47ad485 100644 --- a/XMonad/Hooks/CurrentWorkspaceOnTop.hs +++ b/XMonad/Hooks/CurrentWorkspaceOnTop.hs @@ -22,11 +22,12 @@ module XMonad.Hooks.CurrentWorkspaceOnTop ( currentWorkspaceOnTop ) where +import qualified Data.List.NonEmpty as NE (nonEmpty) +import qualified Data.Map as M import XMonad +import XMonad.Prelude (NonEmpty ((:|)), when) import qualified XMonad.StackSet as S import qualified XMonad.Util.ExtensibleState as XS -import XMonad.Prelude (unless, when) -import qualified Data.Map as M -- $usage -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: @@ -63,7 +64,9 @@ currentWorkspaceOnTop = withDisplay $ \d -> do wins = fltWins ++ map fst rs -- order: first all floating windows, then the order the layout returned -- end of reimplementation - unless (null wins) $ do - io $ raiseWindow d (head wins) -- raise first window of current workspace to the very top, - io $ restackWindows d wins -- then use restackWindows to let all other windows from the workspace follow + case NE.nonEmpty wins of + Nothing -> pure () + Just (w :| ws') -> do + io $ raiseWindow d w -- raise first window of current workspace to the very top, + io $ restackWindows d (w : ws') -- then use restackWindows to let all other windows from the workspace follow XS.put(CWOTS curTag) diff --git a/XMonad/Hooks/InsertPosition.hs b/XMonad/Hooks/InsertPosition.hs index 1d1a92d118..487b24c05a 100644 --- a/XMonad/Hooks/InsertPosition.hs +++ b/XMonad/Hooks/InsertPosition.hs @@ -82,5 +82,7 @@ insertDown :: (Eq a) => a -> W.StackSet i l a s sd -> W.StackSet i l a s sd insertDown w = W.swapDown . W.insertUp w focusLast' :: W.Stack a -> W.Stack a -focusLast' st = let ws = W.integrate st - in W.Stack (last ws) (drop 1 $ reverse ws) [] +focusLast' st = + case reverse (W.integrate st) of + [] -> st + (l : ws) -> W.Stack l ws [] diff --git a/XMonad/Hooks/StatusBar/PP.hs b/XMonad/Hooks/StatusBar/PP.hs index e3c1f30cf7..599a933f5b 100644 --- a/XMonad/Hooks/StatusBar/PP.hs +++ b/XMonad/Hooks/StatusBar/PP.hs @@ -401,7 +401,7 @@ dzenStrip = strip [] where strip keep x | null x = keep | "^^" `isPrefixOf` x = strip (keep ++ "^") (drop 2 x) - | '^' == head x = strip keep (drop 1 . dropWhile (/= ')') $ x) + | "^" `isPrefixOf` x = strip keep (drop 1 . dropWhile (/= ')') $ x) | otherwise = let (good,x') = span (/= '^') x in strip (keep ++ good) x' diff --git a/XMonad/Hooks/WallpaperSetter.hs b/XMonad/Hooks/WallpaperSetter.hs index 12d6132a7a..4e49be0562 100644 --- a/XMonad/Hooks/WallpaperSetter.hs +++ b/XMonad/Hooks/WallpaperSetter.hs @@ -140,7 +140,7 @@ getPicPath conf (WallpaperDir dir) = do direxists <- doesDirectoryExist $ wallpaperBaseDir conf dir if direxists then do files <- getDirectoryContents $ wallpaperBaseDir conf dir - let files' = filter ((/='.').head) files + let files' = filter (not . ("." `isPrefixOf`)) files file <- pickFrom files' return $ Just $ wallpaperBaseDir conf dir file else return Nothing diff --git a/XMonad/Hooks/WorkspaceHistory.hs b/XMonad/Hooks/WorkspaceHistory.hs index 3af6e17d2d..b54be0f648 100644 --- a/XMonad/Hooks/WorkspaceHistory.hs +++ b/XMonad/Hooks/WorkspaceHistory.hs @@ -34,7 +34,7 @@ import Control.DeepSeq import Prelude import XMonad import XMonad.StackSet hiding (delete, filter, new) -import XMonad.Prelude (delete, find, foldl', groupBy, nub, sortBy) +import XMonad.Prelude (delete, find, foldl', groupBy, nub, sortBy, listToMaybe) import qualified XMonad.Util.ExtensibleState as XS -- $usage @@ -90,7 +90,7 @@ workspaceHistoryWithScreen = XS.gets history workspaceHistoryByScreen :: X [(ScreenId, [WorkspaceId])] workspaceHistoryByScreen = - map (\wss -> (fst $ head wss, map snd wss)) . + map (\wss -> (maybe 0 fst (listToMaybe wss), map snd wss)) . groupBy (\a b -> fst a == fst b) . sortBy (\a b -> compare (fst a) $ fst b)<$> workspaceHistoryWithScreen diff --git a/XMonad/Layout/CenteredMaster.hs b/XMonad/Layout/CenteredMaster.hs index 4538b94370..103e86ad0b 100644 --- a/XMonad/Layout/CenteredMaster.hs +++ b/XMonad/Layout/CenteredMaster.hs @@ -80,11 +80,9 @@ applyPosition :: (LayoutClass l a, Eq a) => applyPosition pos wksp rect = do let stack = W.stack wksp let ws = W.integrate' stack - if null ws then - runLayout wksp rect - else do - let firstW = head ws - let other = drop 1 ws + case ws of + [] -> runLayout wksp rect + (firstW : other) -> do let filtStack = stack >>= W.filter (firstW /=) wrs <- runLayout (wksp {W.stack = filtStack}) rect return $ first ((firstW, place pos other rect) :) wrs diff --git a/XMonad/Layout/Combo.hs b/XMonad/Layout/Combo.hs index 805857aa39..067546412f 100644 --- a/XMonad/Layout/Combo.hs +++ b/XMonad/Layout/Combo.hs @@ -91,7 +91,7 @@ instance (LayoutClass l (), LayoutClass l1 a, LayoutClass l2 a, Read a, Show a, handleMessage super (SomeMessage ReleaseResources) return ([(w,rinput)], Just $ C2 [w] [w] super' l1' l2') arrange origws = - do let w2' = case origws `intersect` w2 of [] -> [head origws] + do let w2' = case origws `intersect` w2 of [] -> take 1 origws [x] -> [x] x -> case origws \\ x of [] -> init x diff --git a/XMonad/Prompt/Shell.hs b/XMonad/Prompt/Shell.hs index 000babbfb8..3d36e20c81 100644 --- a/XMonad/Prompt/Shell.hs +++ b/XMonad/Prompt/Shell.hs @@ -197,7 +197,7 @@ getCommands = do p <- getEnv "PATH" `E.catch` econst [] let ds = filter (/= "") $ split ':' p es <- forM ds $ \d -> getDirectoryContents d `E.catch` econst [] - return . uniqSort . filter ((/= '.') . head) . concat $ es + return . uniqSort . filter (not . ("." `isPrefixOf`)) . concat $ es split :: Eq a => a -> [a] -> [[a]] split _ [] = []