xmonad-windownames (empty) → 0.1.0.0
raw patch · 4 files changed
+246/−0 lines, 4 filesdep +basedep +containersdep +utf8-stringsetup-changed
Dependencies added: base, containers, utf8-string, xmonad, xmonad-contrib
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- src/XMonad/Actions/WindowNames.hs +191/−0
- xmonad-windownames.cabal +23/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, Phil Lindberg++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Phil Lindberg nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/XMonad/Actions/WindowNames.hs view
@@ -0,0 +1,191 @@+-----------------------------------------------------------------------------+-- |+-- Module : XMonad.Actions.WindowNames+-- Copyright : (c) 2015 Phil Lindberg <plindbe2@gmail.com>+-- License : BSD3-style (see LICENSE)+--+-- Maintainer : Phil Lindberg <plindbe2@gmail.com>+-- Stability : experimental+-- Portability : unportable+--+-- A library to automatically put named windows into the DynamicLog. It+-- provides a modification of 'XMonad.Hooks.DynamicLog.dynamicLogWithPP' and+-- some helper functions.+--+-----------------------------------------------------------------------------++module XMonad.Actions.WindowNames (+ -- * Usage+ -- $usage++ -- * Modified dynamic log functions+ dynamicLogStringMap+ , dynamicLogWithPPMap+ -- * Helper functions+ , evalLookup+ , filterShortNames+ -- * Stack and StackSet functions+ , getTagStack+ , getWindowNames+ , integrateM+ -- * Pretty-printer functions+ , pprWindowSetMap+ -- * To Do+ -- $todo+ ) where++import Codec.Binary.UTF8.String (encodeString)+import Control.Monad (mapM, MonadPlus(mplus))+import Data.List (intercalate)+import Data.Maybe (listToMaybe, catMaybes, fromMaybe, isJust)+import XMonad+import XMonad.Hooks.DynamicLog (PP(..))+import XMonad.Hooks.UrgencyHook (readUrgents)+import XMonad.Util.NamedWindows (getName)+import XMonad.Util.WorkspaceCompare (WorkspaceSort)++import qualified Data.Map as M+import qualified XMonad.StackSet as W+++-- $usage+-- You can add this to your @~\/.xmonad\/xmonad.hs@:+--+-- > import Data.List (isSuffixOf)+-- > import System.IO+-- > import WindowNames+-- > import XMonad+-- > import XMonad.Hooks.DynamicLog+-- > import XMonad.Util.Run(spawnPipe)+--+-- A simple example is a follows (the example uses xmobar but feel free to+-- substitute dzen or anything else):+--+-- > myShortNames :: [(String -> Bool, String -> String)]+-- > myShortNames = [ (("Pentadactyl" `isSuffixOf`), const "ff" )+-- > , ((=="Library"), const "ffdl")+-- > , (const True, take 4 ) -- catch all+-- > ]+-- >+-- > main = do+-- > h <- spawnPipe "xmobar -options -foo -bar"+-- > xmonad $ myXmonadConfig h+-- >+-- > myXmonadConfig h = defaultConfig {+-- > ...+-- > logHook = dynamicLogWithPPMap (getWindowNames (foc . filt) filt filt) xmobarPP { ppOutput = hPutStrLn h }+-- > ...+-- > }+-- > where foc = wrap "<fn=1>" "</fn>" -- xmobar font 1 (additionalFonts!!0)+-- > filt = filterShortNames myShortNames+--+-- This works nicely with named tmux sessions or screens. You can use it in+-- conjunction with other dynamicLog string modifiers.++-- $todo+-- * Incorporate with 'XMonad.Actions.TagWindows'+-- * Efficiency (ExtensionClass?)+-- * Make sure it works with the newest XMonad++-- | Helper function used by 'filterShortNames' which run the first function in+-- the tuple on the value. If it evalutes to true, the output of the second+-- function if returned.+evalLookup :: MonadPlus m => a -> [(a -> Bool, a -> b)] -> m b+evalLookup n ((f,g):xs) | f n = return (g n) `mplus` evalLookup n xs+ | otherwise = evalLookup n xs++-- | Example filter short name function.+filterShortNames :: [(String -> Bool, String -> String)] -> String -> String+filterShortNames filterList s = fromMaybe "" $ evalLookup s filterList++-- | Get a Map of window tag to strings in the format "wsId:w1,w2,...,wN" where+-- w1,...,wn represent the names of windows according to+-- 'XMonad.Util.NamedWindows.getName' after being run through the respective+-- focus, up, and down functions+getWindowNames :: (String -> String) -- ^ Function to apply to the focused window's name.+ -> (String -> String) -- ^ Function to apply to the up windows' names.+ -> (String -> String) -- ^ Function to apply to the down windows' names.+ -> W.StackSet WorkspaceId l Window sid sd -- ^ Stack set+ -> X (M.Map WorkspaceId String)+getWindowNames f u d w = fmap M.fromList $ mapM returnNameStr $ getTagStack w+ where joinWinNames x _ = fmap (((x ++ ":") ++) . intercalate "," . filter (not . null)) .+ integrateM (nameFunc f) (nameFunc u) (nameFunc d)++ returnNameStr (x, y) = maybe (return x) (joinWinNames x y) y >>= \z -> return (x, z)+ nameFunc f = fmap (f . show) . getName++-- | Run a monadic function on 'XMonad.StackSet.Stack' components.+integrateM :: Monad m =>+ (a -> m b) -- ^ Monadic function to run on focused components.+ -> (a -> m b) -- ^ Monadic function to run on up components.+ -> (a -> m b) -- ^ Monadic function to run on down components.+ -> W.Stack a -- ^ Current StackSet+ -> m [b]+integrateM f u d (W.Stack x l r) = do+ r2 <- mapM u r+ x2 <- f x+ l2 <- mapM d l+ return $ reverse l2 ++ x2 : r2++-- | Get a list of tag and maybe Stack.+getTagStack :: W.StackSet t l a sid sd -> [(t, Maybe (W.Stack a))]+getTagStack w = [ (i, a) | W.Workspace i _ a <- (W.workspace . W.current) w : map W.workspace (W.visible w) ++ W.hidden w ]++-- | Modified 'XMonad.Hooks.DynamicLog.dynamicLogWithPP' which takes an+-- additional WindowSet to Map of WorkspaceId to String.+dynamicLogWithPPMap :: (WindowSet -> X (M.Map WorkspaceId String)) -> PP -> X ()+dynamicLogWithPPMap wsIdMap pp = dynamicLogStringMap wsIdMap pp >>= io . ppOutput pp++-- | Modifed 'XMonad.Hooks.DynamicLog.dynamicLogString' which takes an+-- additional WindowSet to Map of WorkspaceId to String.+dynamicLogStringMap :: (WindowSet -> X (M.Map WorkspaceId String)) -> PP -> X String+dynamicLogStringMap wsIdMap pp = do+ winset <- gets windowset+ urgents <- readUrgents+ sort' <- ppSort pp++ -- layout description+ let ld = description . W.layout . W.workspace . W.current $ winset++ -- workspace list+ ws <- pprWindowSetMap wsIdMap sort' urgents pp winset++ -- window title+ wt <- maybe (return "") (fmap show . getName) . W.peek $ winset++ -- run extra loggers, ignoring any that generate errors.+ extras <- mapM (`catchX` return Nothing) $ ppExtras pp++ return $ encodeString . sepBy (ppSep pp) . ppOrder pp $+ [ ws+ , ppLayout pp ld+ , ppTitle pp $ ppTitleSanitize pp wt+ ]+ ++ catMaybes extras++-- | Format the workspace information+pprWindowSetMap :: (WindowSet -> X (M.Map WorkspaceId String)) -- ^ Map of WorkspaceId to a string to be displayed.+ -> WorkspaceSort -- ^ A workspace sorting function+ -> [Window] -- ^ A list of urgent windows+ -> PP -- ^ pretty-printer format+ -> WindowSet -- ^ current WindowSet+ -> X String+pprWindowSetMap wsIdFunc sort' urgents pp s = do+ wsIdMap <- wsIdFunc s+ return $ sepBy (ppWsSep pp) . map (fmt wsIdMap) . sort' $ map W.workspace (W.current s : W.visible s) ++ W.hidden s+ where this = W.currentTag s+ visibles = map (W.tag . W.workspace) (W.visible s)++ fmt wsIdMap w = printer pp (fromMaybe "" $ M.lookup (W.tag w) wsIdMap)+ where printer | any (\x -> maybe False (== W.tag w) (W.findTag x s)) urgents = ppUrgent+ | W.tag w == this = ppCurrent+ | W.tag w `elem` visibles = ppVisible+ | isJust (W.stack w) = ppHidden+ | otherwise = ppHiddenNoWindows++-- | Output a list of strings, ignoring empty ones and separating the+-- rest with the given separator.+sepBy :: String -- ^ separator+ -> [String] -- ^ fields to output+ -> String+sepBy sep = intercalate sep . filter (not . null)
+ xmonad-windownames.cabal view
@@ -0,0 +1,23 @@+name: xmonad-windownames+version: 0.1.0.0+synopsis: A library to automatically put named windows into the DynamicLog.+homepage: https://github.com/plindbe2/xmonad-windownames+license: BSD3+license-file: LICENSE+author: Phil Lindberg+maintainer: plindbe2@gmail.com+category: XMonad+build-type: Simple+cabal-version: >=1.10++library+ exposed-modules: XMonad.Actions.WindowNames++ build-depends: base >=4.7 && <4.8,+ utf8-string >=0.3 && <0.4,+ xmonad >=0.11 && <0.12,+ xmonad-contrib >=0.11 && <0.12,+ containers >=0.5 && <0.6++ hs-source-dirs: src+ default-language: Haskell2010