Difference between revisions of "Xmonad/Config archive/sereven-xmonad.hs"

From HaskellWiki
Jump to: navigation, search
m
(update config to latest 0.9.2 - 0.10 version)
Line 1: Line 1:
 
<haskell>
 
<haskell>
 
{-# OPTIONS_GHC -Wall -fno-warn-missing-signatures #-}
 
{-# OPTIONS_GHC -Wall -fno-warn-missing-signatures #-}
-- ~/.xmonad/xmonad.hs (0.9) $ 2009-10-04
 
  +
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -- for TallAlt
   
-- imports {{{
 
  +
-- sereven's xmonad.hs (0.9.2 - 0.10) $ 2011-03-15
import XMonad
 
  +
  +
-- imports {{{
  +
import XMonad hiding (keys)
 
import qualified XMonad.StackSet as W
 
import qualified XMonad.StackSet as W
   
-- standard libraries --
+
-- standard libraries
import Prelude hiding (mod)
+
import Control.Applicative ((<$>))
import Control.Arrow (first)
 
 
import Control.Monad (liftM2)
 
import Control.Monad (liftM2)
import Data.List (isInfixOf,nub)
+
import Data.List (isInfixOf, nub)
  +
import Data.Maybe (fromMaybe)
  +
import System.Exit
   
-- xmonad-contrib-darcs --
+
-- xmonad-contrib
import XMonad.Actions.CycleWS (swapNextScreen, toggleWS, toggleOrDoSkip)
+
import XMonad.Actions.CycleWS (swapNextScreen, toggleOrDoSkip, nextWS, prevWS)
import XMonad.Actions.DynamicWorkspaces
 
 
import XMonad.Actions.FlexibleManipulate as Flex
 
import XMonad.Actions.FlexibleManipulate as Flex
  +
import XMonad.Actions.OnScreen (onlyOnScreen)
 
import XMonad.Actions.Search
 
import XMonad.Actions.Search
import XMonad.Actions.UpdatePointer
 
 
import XMonad.Actions.WindowNavigation
 
import XMonad.Actions.WindowNavigation
  +
import XMonad.Config.Gnome
 
import XMonad.Hooks.DynamicLog
 
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.FadeInactive
 
 
import XMonad.Hooks.ManageDocks
 
import XMonad.Hooks.ManageDocks
 
import XMonad.Hooks.ManageHelpers
 
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.UrgencyHook
+
import XMonad.Hooks.SetWMName
 
import XMonad.Layout.IM
 
import XMonad.Layout.IM
  +
import XMonad.Layout.LayoutHints
 
import XMonad.Layout.LayoutScreens
 
import XMonad.Layout.LayoutScreens
 
import XMonad.Layout.LimitWindows
 
import XMonad.Layout.LimitWindows
Line 30: Line 33:
 
import XMonad.Layout.Reflect (reflectHoriz)
 
import XMonad.Layout.Reflect (reflectHoriz)
 
import XMonad.Layout.ToggleLayouts
 
import XMonad.Layout.ToggleLayouts
  +
import XMonad.Layout.WorkspaceDir
 
import XMonad.Prompt
 
import XMonad.Prompt
  +
import XMonad.Prompt.RunOrRaise
 
import XMonad.Util.EZConfig
 
import XMonad.Util.EZConfig
import XMonad.Util.NamedWindows
 
 
import XMonad.Util.Run (hPutStrLn, spawnPipe)
 
import XMonad.Util.Run (hPutStrLn, spawnPipe)
 
import XMonad.Util.Scratchpad
 
import XMonad.Util.Scratchpad
import XMonad.Util.WorkspaceCompare (getSortByIndex)
+
import XMonad.Util.WorkspaceCompare
 
-- ~/.xmonad/lib/ --
 
-- (~>) is infix (,)
 
import ExtraCombinators ((~>)) -- http://code.haskell.org/~wwolff/_xmonad/lib/ExtraCombinators.hs -- thanks mauke!
 
import XMonad.Layout.TallAlt -- http://www.haskell.org/pipermail/xmonad/2009-July/008270.html -- thanks aavogt!
 
 
 
-- }}}
 
-- }}}
   
-- main {{{
 
  +
wsIds = map return "123456789" ++ ["NSP"]
   
home = ("/home/me/" ++)
 
  +
infixr 0 ~> -- <http://mauke.ath.cx/stuff/xmonad/xmonad.hs>
xmpath = id -- xmpath = (home ".cabal/bin/" ++) -- (home "tmp/bin/" ++)
 
  +
(~>) :: a -> b -> (a, b)
promptConfig = darkXPConfig
 
  +
(~>) = (,)
wsIds = map return "ASDQWE123" ++ ["NSP"] -- bound on these qwerty keys
 
   
  +
-- main {{{
 
main = do
 
main = do
dz <- spawnPipe $ toDzenCmd darkXPConfig
+
dz <- spawnPipe themedDzen
conf <- withWindowNavigation vi . withUnfocusedUrgents $
+
conf <- withNavKeys (xK_k, xK_h, xK_j, xK_l) $
defaultConfig
+
gnomeConfig
 
{ terminal = "urxvt"
 
{ terminal = "urxvt"
 
, modMask = mod4Mask
 
, modMask = mod4Mask
, focusedBorderColor = fgColor promptConfig
 
 
, normalBorderColor = bgColor promptConfig
 
, normalBorderColor = bgColor promptConfig
  +
, focusedBorderColor = fgColor promptConfig
 
, workspaces = wsIds
 
, workspaces = wsIds
, logHook = onAllEvents dz
+
, logHook = dynamicLogWithPP dzPP { ppOutput = hPutStrLn dz }
, manageHook = onWindowCreation
+
, manageHook = manageHooks
 
, layoutHook = layouts
 
, layoutHook = layouts
 
}
 
}
`additionalKeysP` keybindings `additionalMouseBindings` mousebindings
+
`additionalKeysP` keys `additionalMouseBindings` buttons
 
xmonad conf { startupHook = do
 
xmonad conf { startupHook = do
return () >> checkKeymap conf keybindings
+
startupHook gnomeConfig
spawnOnce apps
+
checkKeymap conf keys
  +
setWMName "LG3D"
  +
windows $ onlyOnScreen 1 "8"
 
}
 
}
where
 
  +
-- }}}
vi = (xK_k, xK_h, xK_j, xK_l)
 
-- visible urgents not really displayed nicely, more for testing at the moment:
 
withUnfocusedUrgents = withUrgencyHookC NoUrgencyHook urgencyConfig {suppressWhen = Focused}
 
apps = [ (home ".cabal/bin/xmobar", home ".xmobarrc-1-top")
 
, ("xcompmgr", "-c -r 3 -l -5 -t -5")
 
]
 
onAllEvents h = do
 
dynamicLogWithPP dzdarkPP { ppOutput = hPutStrLn h }
 
fadeMostInactives 0.9375 -- ~0xefffffff
 
updatePointer (Relative 0.8 0.96)
 
   
-- # helpers to move to lib/ or contrib
 
  +
-- keyboard and mouse {{{
spawnOnce :: (MonadIO m) => [(String, String)] -> m ()
 
spawnOnce = mapM_ $ uncurry sp
 
where sp cmd rest = spawn $ concat ["[ ! $(pidof ", cmd, ") ] && ", cmd, " ", rest]
 
   
fadeMostInactives :: Rational -> X ()
 
  +
withNavKeys (u,l,d,r) = withWindowNavigationKeys
fadeMostInactives = fadeOutLogHook . fadeIf (isUnfocused <&&> noneOf qs)
 
  +
[ (mod4Mask , u) ~> WNGo U
where noneOf = fmap not . foldr1 (<||>)
 
  +
, (mod4Mask , l) ~> WNGo L
qs = [isFullscreen, fmap ("layer" `isInfixOf`) className, className =? "Cinelerra", className =? "Gimp"]
 
  +
, (mod4Mask , d) ~> WNGo D
  +
, (mod4Mask , r) ~> WNGo R
  +
, (mod4Mask .|. mod1Mask, u) ~> WNSwap U
  +
, (mod4Mask .|. mod1Mask, l) ~> WNSwap L
  +
, (mod4Mask .|. mod1Mask, d) ~> WNSwap D
  +
, (mod4Mask .|. mod1Mask, r) ~> WNSwap R ]
   
-- }}}
 
  +
buttons =
  +
[ (mod4Mask , button3) ~> Flex.mouseWindow Flex.discrete
  +
, (mod4Mask , button4) ~> const $ windows W.swapDown
  +
, (mod4Mask , button5) ~> const $ windows W.swapUp
  +
, (mod1Mask .|. mod4Mask, button4) ~> const nextWS
  +
, (mod1Mask .|. mod4Mask, button5) ~> const prevWS ]
   
-- bindings {{{
 
  +
keys =
keybindings =
 
  +
[ "M-M1-S-q" ~> io (exitWith ExitSuccess)
maskedBy nix
 
  +
, "M-S-q" ~> spawn "xmessage -- [ Shift+Mod1+Mod4+Q to exit; no gnome-session mgr] --"
[ "<Tab>" ~> scratchpadSpawnActionTerminal "urxvt -pe tabbed"
 
  +
, "M-<Space>" ~> sendMessage ToggleLayout -- toggle fullscreen
, "<Space>" ~> sendMessage ToggleLayout -- fullscreen
 
  +
, "M-c" ~> sendMessage NextLayout
, "\\" ~> sendMessage NextLayout
+
, "M-M1-." ~> sendMessage Shrink
-- , "t" ~> sendMessage ToggleStruts
+
, "M-M1-," ~> sendMessage Expand
, "<F12>" ~> clearUrgents
+
, "M-<F9>" ~> layoutScreens 3 $ fixedLayout
, "<F8>" ~> rescreen -- two screens: left, right
+
[Rectangle 0 0 1600 1200, Rectangle 1600 0 1600 480
, "<F9>" ~> layoutScreens 3 (Tall 2 0.5 0.5) -- three screens: left, right_top, right_bottom
+
, Rectangle 1600 480 1280 720]
  +
, "M-<F8>" ~> rescreen
 
]
 
]
++ maskedBy mod
 
  +
-- workspaces and screens -- 1 2 3 \
[ "<Space>" ~> sendMessage ToggleLayout -- fullscreen
+
-- q w e \
, "\\" ~> sendMessage NextLayout
+
-- a s d \ f g
, "<Return>" ~> windows W.shiftMaster
+
++ -- \ v b
, "=" ~> windows $ W.greedyView "NSP"
+
[ mask ++ [key] ~> action i
, "q" ~> spawn $ xmpath "xmonad --recompile; " ++ xmpath "xmonad --restart"
+
| (key, i) <- zip "123qweasd=" wsIds
]
+
, (mask, action) <- [ ("M-", toggled W.greedyView)
++ maskedBy (control . mod)
+
, ("M-M1-", toggled followShift) ] ]
[ "h" ~> sendMessage Shrink
+
++
, "l" ~> sendMessage Expand
+
[ mask ++ [key] ~> screenWorkspace s >>= flip whenJust (windows . action)
, "k" ~> windows W.swapUp
+
| (key, s) <- zip "fgb" [0..]
, "j" ~> windows W.swapDown
+
, (mask, action) <- [ ("M-", W.view)
]
+
, ("M-M1-", W.shift) ] ]
-- searches
+
++
++ maskedBy win
+
[ "M-v" ~> swapNextScreen
["/ " ++ ks ~> promptSearch promptConfig s | (ks,s) <- searches]
+
-- scratch term, prompts and searches
++ maskedBy (control . win)
+
, "M-<Tab>" ~> scratchpadSpawnActionTerminal "urxvt -pe tabbed"
["/ " ++ ks ~> selectSearch s | (ks,s) <- searches]
+
, "M-r" ~> runOrRaisePrompt promptConfig
-- displays
+
, "M-M1-r" ~> changeDir promptConfig ]
++ maskedBy nix workspacesAndScreens
+
++
  +
[ "M-/ " ++ ks ~> promptSearch promptConfig s | (ks,s) <- searches ]
  +
++
  +
[ "M-M1-/ " ++ ks ~> selectSearch s | (ks,s) <- searches ]
 
where
 
where
workspacesAndScreens = -- 1 2 3 \ 4 \ backspace
 
  +
searches = [ ("f" , fgo)
-- q w e \ r
+
, ("r" , rseek)
-- a s d \ f g -- screens
+
, ("s" , scroogle)
-- \ v b
+
, ("x" , xm_gmane)
[ othermasks ++ [key] ~> action i
+
, ("g" , google)
| (i, key) <- zip wsIds "asdqwe123="
+
, ("i" , images)
, (othermasks, action) <- [ ("", toggled W.greedyView)
+
, ("w" , wikipedia)
, ("S-", toggled W.shift)
+
]
, ("S-C-", toggled followShift) ] ]
+
fgo = searchEngineF "gentoo forums" $
++
+
wrap "http://www.google.com/search?q="
[ "4" ~> toggleWS
+
"+site%3Aforums.gentoo.org+-inurl%3Asearch.php" . escape
, "v" ~> swapNextScreen
+
rseek = searchEngineF "RSeek" $
, "<Backspace>" ~> removeWorkspace
+
wrap "http://www.rseek.org/?cx=010923144343702598753%3Aboaz1reyxd4&newwindow=1&q="
]
+
"&sa=Search&cof=FORID%3A11&siteurl=rseek.org%252F#1666" . escape
++
+
scroogle = searchEngine "scroogle"
[ othermasks ++ [key] ~> screenWorkspace i >>= flip whenJust (windows . action)
+
"https://ssl.scroogle.org/cgi-bin/nbbwssl.cgi?Gw="
| (i, key) <- zip [0..] "fgb"
+
xm_gmane = searchEngine "xmonad ml"
, (othermasks, action) <- [ ("", W.view) , ("S-", W.shift)] ]
+
"http://search.gmane.org/?group=gmane.comp.lang.haskell.xmonad&query="
--
+
 
toggled = toggleOrDoSkip ["NSP"]
 
toggled = toggleOrDoSkip ["NSP"]
 
followShift = liftM2 (.) W.view W.shift
 
followShift = liftM2 (.) W.view W.shift
--
 
  +
-- }}}
hayoo = searchEngine "Hayoo" "http://holumbus.fh-wedel.de/hayoo/hayoo.html?query="
 
hpaste = searchEngine "hpaste" "http://hpaste.org/fastcgi/hpaste.fcgi/?search="
 
gmane_beg = searchEngine "beg" "http://search.gmane.org/?group=gmane.comp.lang.haskell.beginners&query="
 
gmane_cafe = searchEngine "cafe" "http://search.gmane.org/?group=gmane.comp.lang.haskell.cafe&query="
 
gmane_sup = searchEngine "sup" "http://search.gmane.org/?group=gmane.mail.sup.general&query="
 
gmane_xm = searchEngine "xm" "http://search.gmane.org/?group=gmane.comp.lang.haskell.xmonad&query="
 
bugsall_xm = searchEngine "bugsAll_xm" "http://code.google.com/p/xmonad/issues/list?can=1&q="
 
bugsopen_xm = searchEngine "bugsOpen_xm" "http://code.google.com/p/xmonad/issues/list?can=2&q="
 
bugsnew_xm = searchEngine "bugsNew_xm" "http://code.google.com/p/xmonad/issues/list?can=6&q="
 
searches = [ ("g" , google)
 
, ("h" , hoogle)
 
, ("S-h", hayoo)
 
, ("p" , hpaste)
 
, ("w" , wikipedia)
 
, ("b" , gmane_beg)
 
, ("c" , gmane_cafe)
 
, ("s" , gmane_sup)
 
, ("x x", gmane_xm)
 
, ("x a", bugsall_xm)
 
, ("x o", bugsopen_xm)
 
, ("x n", bugsnew_xm)
 
]
 
-- excessively cute helpers
 
maskedBy = map . first
 
[_,control] = let ezstr c = (++) (c : "-") in map ezstr "SC"
 
[_,_,nix,win,_] = map ((++) . ezstring) [1..5] :: [String -> String]
 
mod = ( "M-" ++)
 
ezstring :: Int -> String -- default would have been Integer
 
ezstring n | n `elem` [1..5] = 'M' : (show n ++ "-")
 
| otherwise = "M-"
 
 
mousebindings = -- FlexibleManipulate rulez! -- change mod3Mask to your mod:
 
-- If use IM Full try these mouse wheel bindings over gimp toolbox to
 
-- select main window, prevents nasty switching.
 
[ (mod3Mask, button3) ~> Flex.mouseWindow Flex.discrete
 
, (mod3Mask, button4) ~> const $ windows W.swapDown
 
, (mod3Mask, button5) ~> const $ windows W.swapUp ]
 
-- }}}
 
   
-- window hooks {{{
+
-- manage hook {{{
onWindowCreation = composeAll
+
manageHooks = composeAll
[ scratchpadManageHook (W.RationalRect 0.325 0.6 0.641 0.35)
+
[ ("OpenOffice" `isPrefixOf`) <$> className --> doShift "3"
, title =? "" --> doFloat
+
, ("Gimp" `isPrefixOf`) <$> className --> doShift "5"
, title =? "x" --> doFloat -- weird cinelerra splash window
+
, className =? "Acroread" --> doShift "2"
, className =? "Cinelerra" --> doFloat
+
, className =? "Qjackctl" --> doFloat
, className =? "Xloadimage" --> doCenterFloat
+
, className =? "feh" --> doFloat
, className =? "XFontSel" --> doCenterFloat
+
, className =? "" --> doFloat -- low budget gtk windows
, className =? "Xmessage" --> doCenterFloat
+
, className =? "XFontSel" --> doF W.shiftMaster <+> doCenterFloat
, className =? "Hback" --> doCenterFloat
+
, className =? "Xmessage" --> doF W.shiftMaster <+> doCenterFloat
, fmap ("Gimp" `isPrefixOf`) className --> doShift "W"
+
, isDialog --> doF W.shiftMaster <+> doFloat
, role =? "conversation" --> doShift "D"
+
, scratchpadManageHook (W.RationalRect 0.43 0.575 0.53 0.34)
, title =? "Buddy List" --> doShift "NSP"
 
, fmap ("layer" `isInfixOf`) className --> doF W.focusDown <+> doFloat -- MP.layer|Gnome-[Mm]p.layer
 
, isFullscreen --> doF W.focusDown <+> doFullFloat
 
, isDialog --> doFloat
 
 
, transience'
 
, transience'
 
, manageDocks
 
, manageDocks
 
]
 
]
where role = stringProperty "WM_WINDOW_ROLE"
 
  +
-- }}}
  +
  +
-- layouts {{{
  +
  +
-- TallAlt from <http://www.haskell.org/pipermail/xmonad/2009-July/008270.html>
  +
data TallAlt a = TallAlt
  +
{ tallAltIncrement :: !Rational
  +
, tallAltRatio :: !Rational
  +
} deriving (Read, Show)
  +
  +
instance LayoutClass TallAlt a where
  +
doLayout (TallAlt i d) r st =
  +
fmap (\(x,_) -> (x,Nothing)) $ doLayout (Tall nmaster i d) r st
  +
where nmaster | stlen > 3 = 2
  +
| otherwise = 1
  +
stlen = length $ W.integrate st
  +
pureMessage (TallAlt i d) m = (`fmap` fromMessage m) $ \x -> case x of
  +
Expand -> TallAlt i (d+i)
  +
Shrink -> TallAlt i (d-i)
   
layouts = smartBorders . toggleLayouts (noBorders Full) . avoidStruts $
 
  +
layouts = modifiers . onWorkspaces ["3", "4"] (workspaceDir cwd four) . onWorkspace "5" gimp
onWorkspaces ["D","E","3"] moreWindows . onWorkspace "W" gimp $ defaults
+
. onWorkspaces ["6", "9"] many $ four
 
where
 
where
defaults = mirror4 ||| moreWindows ||| Full
 
  +
modifiers =
mirror4 = limitWindows 4 (Mirror $ TallAlt (1/vpixels) (817/1182))
 
  +
smartBorders . toggleLayouts (noBorders Full) . layoutHintsToCenter . avoidStruts
moreWindows = TallAlt (1/800) (722/1325)
 
  +
four = limitWindows 4 . Mirror $ TallAlt 0.03 (31/44) ||| Full
gimp = reflectHoriz $ withIM 0.16 (Role "gimp-toolbox") (mirror4 ||| Full)
+
gimp = reflectHoriz $ withIM 0.145 (Role "gimp-toolbox") four
vpixels = fromIntegral $ 1200 - height promptConfig - 3
+
many = Mirror $ TallAlt 0.03 (31/44) ||| Full ||| Tall 1 0.03 (13/22)
  +
cwd = "~/cet_spr/phy/labs"
 
-- }}}
 
-- }}}
   
-- prompt and dzen {{{ -- hideousity creeping slowly toward beauty
+
-- prompt and dzen {{{
toDzenCmd xpc =
 
"dzen2 -xs 1"
 
++ " -h " ++ show (height xpc)
 
-- with xft use:
 
++ " -fn " ++ "'" ++ drop 4 (font xpc) ++ "'"
 
-- with core fonts use:
 
-- ++ " -fn " ++ "'" ++ font xpc ++ "'"
 
++ " -bg " ++ "'" ++ bgColor xpc ++ "'"
 
++ " -fg " ++ "'" ++ fgColor xpc ++ "'"
 
++ " -ta l"
 
++ " -e 'onstart=lower'"
 
   
darkXPConfig = defaultXPConfig
+
promptConfig = defaultXPConfig
{ font = "xft:Nimbus Sans L Bold Condensed:size=10"
+
{ font = "xft:Denmark:Thin:size=11"
, height = 15 -- 18 px line height - 3 border px
+
, bgColor = "gray5"
, bgColor = "gray14"
+
, fgColor = "wheat3"
, fgColor = "cornsilk4"
+
, fgHLight = "DodgerBlue3"
, bgHLight = "#785"
+
, bgHLight = "black"
, fgHLight = "black"
 
 
, promptBorderWidth = 0
 
, promptBorderWidth = 0
, showCompletionOnTab = True
+
, height = 24
, historySize = 12
 
 
, historyFilter = nub
 
, historyFilter = nub
  +
, showCompletionOnTab = True
 
}
 
}
   
-- PP {{{
 
  +
themedDzen = "dzen2 -xs 1 -x 25 -ta l -e 'onstart=lower'"
dzdarkPP = defaultPP
 
  +
++ " -bg " ++ "'" ++ bgColor promptConfig ++ "'"
-- ppOutput defined in main
 
  +
++ " -fg " ++ "'" ++ fgColor promptConfig ++ "'"
{ ppUrgent = dzenColor "black" urgentCol
 
  +
++ " -fn " ++ "'" ++ drop 4 (font promptConfig) ++ "'" -- dzen doesn't use xft prefix
, ppCurrent = dzfg hlightCol . (box 4 ++) . dzfg currentCol
 
  +
++ " -h " ++ show (height promptConfig + 2)
, ppVisible = dzfg visibleCol . (obox 4 ++)
 
  +
, ppHiddenNoWindows = dzfg fadedCol
 
  +
dzPP = defaultPP
, ppHidden = dzfg hiddenCol
 
  +
{ ppCurrent = \i -> wsColorCurrent i (wrap "|" "|" (wsIcon i)) ++ "^p(6;)"
, ppWsSep = "^p(+12)"
+
, ppVisible = \i -> wsColorVisible i (wrap "|" "|" (wsIcon i)) ++ "^p(6;)"
  +
, ppHidden = fg "wheat4" . wsIcon
  +
, ppHiddenNoWindows = fg "gray28" . wsIcon
  +
, ppWsSep = "^p(6;)"
  +
, ppTitle = take 108 . dzenEscape
 
, ppSep = ""
 
, ppSep = ""
, ppSort = fmap (.scratchpadFilterOutWorkspace) getSortByIndex
+
, ppSort = getSortByXineramaRule -- ensure wsIds alphabetical
, ppOrder = \(ws:_:t:_) -> [" ", ws, " ^p(;-1)", t] -- \(ws:l:t:xs) -> (?strs :: [String])
+
, ppOrder = \(ws:_:t:_) -> ["^p(18;)", ws, "^p(30;).: ", t, " :."]
 
}
 
}
where dzfg fgc = dzenColor fgc ""
 
  +
where
box, obox :: Int -> String
 
  +
fg c = dzenColor c ""
box y = concat ["^p(;+", show y, ")^r(5x5)^p(+2;-", show y,")"]
 
  +
wsIcon = wrap "^i(" ")" . ("/home/gvg/.config/dzen/icons/" ++) . wrap "ws-" ".xbm"
obox y = concat ["^p(;+", show y, ")^ro(5x5)^p(+2;-", show y, ")"]
 
  +
wsColorCurrent i =
hlightCol = "#4d5"
 
  +
fg . fromMaybe "wheat2" . lookup i . zip wsIds $
currentCol = "#bca"
 
  +
concatMap (replicate 3) ["DarkOrchid1", "DodgerBlue1", "OliveDrab2"]
visibleCol = "#ab9"
 
  +
wsColorVisible i =
fadedCol = "#554"
 
  +
fg . fromMaybe "wheat4" . lookup i . zip wsIds $
urgentCol = "#d54"
 
  +
concatMap (replicate 3) ["DarkOrchid3", "DodgerBlue4", "OliveDrab4"]
hiddenCol = "#786"
 
-- }}}
 
 
 
-- }}}
 
-- }}}
   

Revision as of 12:55, 19 March 2011

{-# OPTIONS_GHC -Wall -fno-warn-missing-signatures #-}
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -- for TallAlt

-- sereven's xmonad.hs (0.9.2 - 0.10) $ 2011-03-15

-- imports {{{
import XMonad hiding (keys)
import qualified XMonad.StackSet as W

-- standard libraries
import Control.Applicative ((<$>))
import Control.Monad (liftM2)
import Data.List (isInfixOf, nub)
import Data.Maybe (fromMaybe)
import System.Exit

-- xmonad-contrib
import XMonad.Actions.CycleWS (swapNextScreen, toggleOrDoSkip, nextWS, prevWS)
import XMonad.Actions.FlexibleManipulate as Flex
import XMonad.Actions.OnScreen (onlyOnScreen)
import XMonad.Actions.Search
import XMonad.Actions.WindowNavigation
import XMonad.Config.Gnome
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.SetWMName
import XMonad.Layout.IM
import XMonad.Layout.LayoutHints
import XMonad.Layout.LayoutScreens
import XMonad.Layout.LimitWindows
import XMonad.Layout.NoBorders
import XMonad.Layout.PerWorkspace
import XMonad.Layout.Reflect (reflectHoriz)
import XMonad.Layout.ToggleLayouts
import XMonad.Layout.WorkspaceDir
import XMonad.Prompt
import XMonad.Prompt.RunOrRaise
import XMonad.Util.EZConfig
import XMonad.Util.Run (hPutStrLn, spawnPipe)
import XMonad.Util.Scratchpad
import XMonad.Util.WorkspaceCompare
-- }}}

wsIds = map return "123456789" ++ ["NSP"]

infixr 0 ~> -- <http://mauke.ath.cx/stuff/xmonad/xmonad.hs>
(~>) :: a -> b -> (a, b)
(~>) = (,)

-- main {{{
main = do
    dz <- spawnPipe themedDzen
    conf <- withNavKeys (xK_k, xK_h, xK_j, xK_l) $
        gnomeConfig
            { terminal           = "urxvt"
            , modMask            = mod4Mask
            , normalBorderColor  = bgColor promptConfig
            , focusedBorderColor = fgColor promptConfig
            , workspaces         = wsIds
            , logHook            = dynamicLogWithPP dzPP { ppOutput = hPutStrLn dz }
            , manageHook         = manageHooks
            , layoutHook         = layouts
            }
        `additionalKeysP` keys `additionalMouseBindings` buttons
    xmonad conf { startupHook = do
                    startupHook gnomeConfig
                    checkKeymap conf keys
                    setWMName "LG3D"
                    windows $ onlyOnScreen 1 "8"
                    }
-- }}}

-- keyboard and mouse {{{

withNavKeys (u,l,d,r) = withWindowNavigationKeys
    [ (mod4Mask             , u) ~> WNGo   U
    , (mod4Mask             , l) ~> WNGo   L
    , (mod4Mask             , d) ~> WNGo   D
    , (mod4Mask             , r) ~> WNGo   R
    , (mod4Mask .|. mod1Mask, u) ~> WNSwap U
    , (mod4Mask .|. mod1Mask, l) ~> WNSwap L
    , (mod4Mask .|. mod1Mask, d) ~> WNSwap D
    , (mod4Mask .|. mod1Mask, r) ~> WNSwap R ]

buttons =
    [ (mod4Mask             , button3) ~> Flex.mouseWindow Flex.discrete
    , (mod4Mask             , button4) ~> const $ windows W.swapDown
    , (mod4Mask             , button5) ~> const $ windows W.swapUp
    , (mod1Mask .|. mod4Mask, button4) ~> const nextWS
    , (mod1Mask .|. mod4Mask, button5) ~> const prevWS ]

keys =
    [ "M-M1-S-q"      ~> io (exitWith ExitSuccess)
    , "M-S-q"         ~> spawn "xmessage -- [ Shift+Mod1+Mod4+Q to exit; no gnome-session mgr] --"
    , "M-<Space>"     ~> sendMessage ToggleLayout  -- toggle fullscreen
    , "M-c"           ~> sendMessage NextLayout
    , "M-M1-."        ~> sendMessage Shrink
    , "M-M1-,"        ~> sendMessage Expand
    , "M-<F9>"        ~> layoutScreens 3 $ fixedLayout
                            [Rectangle 0 0 1600 1200, Rectangle 1600 0   1600 480
                                                    , Rectangle 1600 480 1280 720]
    , "M-<F8>"        ~> rescreen
    ]
    -- workspaces and screens -- 1 2 3 \
                              --  q w e \
                              --   a s d \ f g
    ++                        --          \ v b
    [ mask ++ [key] ~> action i
         | (key, i) <- zip "123qweasd=" wsIds
         , (mask, action) <- [ ("M-", toggled W.greedyView)
                             , ("M-M1-", toggled followShift) ] ]
    ++
    [ mask ++ [key] ~> screenWorkspace s >>= flip whenJust (windows . action)
         | (key, s) <- zip "fgb" [0..]
         , (mask, action) <- [ ("M-", W.view)
                             , ("M-M1-", W.shift) ] ]
    ++
    [ "M-v"         ~> swapNextScreen
    -- scratch term, prompts and searches
    , "M-<Tab>" ~> scratchpadSpawnActionTerminal "urxvt -pe tabbed"
    , "M-r"     ~> runOrRaisePrompt promptConfig
    , "M-M1-r"  ~> changeDir promptConfig ]
    ++
    [ "M-/ "    ++ ks ~> promptSearch promptConfig s | (ks,s) <- searches ]
    ++
    [ "M-M1-/ " ++ ks ~> selectSearch s | (ks,s) <- searches ]
  where
    searches = [ ("f"  , fgo)
               , ("r"  , rseek)
               , ("s"  , scroogle)
               , ("x"  , xm_gmane)
               , ("g"  , google)
               , ("i"  , images)
               , ("w"  , wikipedia)
               ]
    fgo      = searchEngineF "gentoo forums" $
                  wrap "http://www.google.com/search?q="
                       "+site%3Aforums.gentoo.org+-inurl%3Asearch.php" . escape
    rseek    = searchEngineF "RSeek" $
                  wrap "http://www.rseek.org/?cx=010923144343702598753%3Aboaz1reyxd4&newwindow=1&q="
                       "&sa=Search&cof=FORID%3A11&siteurl=rseek.org%252F#1666" . escape
    scroogle = searchEngine  "scroogle"
                  "https://ssl.scroogle.org/cgi-bin/nbbwssl.cgi?Gw="
    xm_gmane = searchEngine  "xmonad ml"
                  "http://search.gmane.org/?group=gmane.comp.lang.haskell.xmonad&query="

    toggled = toggleOrDoSkip ["NSP"]
    followShift = liftM2 (.) W.view W.shift
-- }}}

-- manage hook {{{
manageHooks = composeAll
    [ ("OpenOffice" `isPrefixOf`) <$> className --> doShift "3"
    , ("Gimp" `isPrefixOf`)       <$> className --> doShift "5"
    , className =? "Acroread" --> doShift "2"
    , className =? "Qjackctl" --> doFloat
    , className =? "feh"      --> doFloat
    , className =? ""         --> doFloat -- low budget gtk windows
    , className =? "XFontSel" --> doF W.shiftMaster <+> doCenterFloat
    , className =? "Xmessage" --> doF W.shiftMaster <+> doCenterFloat
    , isDialog --> doF W.shiftMaster <+> doFloat
    , scratchpadManageHook (W.RationalRect 0.43 0.575 0.53 0.34)
    , transience'
    , manageDocks
    ]
-- }}}

-- layouts {{{

-- TallAlt from <http://www.haskell.org/pipermail/xmonad/2009-July/008270.html>
data TallAlt a = TallAlt
    { tallAltIncrement :: !Rational
    , tallAltRatio :: !Rational
    } deriving (Read, Show)

instance LayoutClass TallAlt a where
    doLayout (TallAlt i d) r st =
     fmap (\(x,_) -> (x,Nothing)) $ doLayout (Tall nmaster i d) r st
        where nmaster | stlen > 3 = 2
                      | otherwise = 1
              stlen = length $ W.integrate st
    pureMessage (TallAlt i d) m = (`fmap` fromMessage m) $ \x -> case x of
        Expand -> TallAlt i (d+i)
        Shrink -> TallAlt i (d-i)

layouts = modifiers . onWorkspaces ["3", "4"] (workspaceDir cwd four) . onWorkspace "5" gimp
                    . onWorkspaces ["6", "9"] many $ four
  where
    modifiers =
        smartBorders . toggleLayouts (noBorders Full) . layoutHintsToCenter . avoidStruts
    four = limitWindows 4 . Mirror $ TallAlt 0.03 (31/44) ||| Full
    gimp = reflectHoriz $ withIM 0.145 (Role "gimp-toolbox") four
    many = Mirror $ TallAlt 0.03 (31/44) ||| Full ||| Tall 1 0.03 (13/22)
    cwd  = "~/cet_spr/phy/labs"
-- }}}

-- prompt and dzen {{{

promptConfig = defaultXPConfig
    { font = "xft:Denmark:Thin:size=11"
    , bgColor  = "gray5"
    , fgColor  = "wheat3"
    , fgHLight = "DodgerBlue3"
    , bgHLight = "black"
    , promptBorderWidth = 0
    , height   = 24
    , historyFilter = nub
    , showCompletionOnTab = True
    }

themedDzen = "dzen2 -xs 1 -x 25 -ta l -e 'onstart=lower'"
      ++ " -bg " ++ "'" ++ bgColor promptConfig ++ "'"
      ++ " -fg " ++ "'" ++ fgColor promptConfig ++ "'"
      ++ " -fn " ++ "'" ++ drop 4 (font promptConfig) ++ "'" -- dzen doesn't use xft prefix
      ++ " -h "  ++ show (height promptConfig + 2)

dzPP  = defaultPP
    { ppCurrent         = \i -> wsColorCurrent i (wrap "|" "|" (wsIcon i)) ++ "^p(6;)"
    , ppVisible         = \i -> wsColorVisible i (wrap "|" "|" (wsIcon i)) ++ "^p(6;)"
    , ppHidden          = fg "wheat4" . wsIcon
    , ppHiddenNoWindows = fg "gray28" . wsIcon
    , ppWsSep           = "^p(6;)"
    , ppTitle           = take 108 . dzenEscape
    , ppSep             = ""
    , ppSort            = getSortByXineramaRule -- ensure wsIds alphabetical
    , ppOrder           = \(ws:_:t:_) ->  ["^p(18;)", ws, "^p(30;).: ", t, " :."]
    }
  where
    fg c = dzenColor c ""
    wsIcon = wrap "^i(" ")" . ("/home/gvg/.config/dzen/icons/" ++) . wrap "ws-" ".xbm"
    wsColorCurrent i =
        fg . fromMaybe "wheat2" . lookup i . zip wsIds $
                concatMap (replicate 3) ["DarkOrchid1", "DodgerBlue1", "OliveDrab2"]
    wsColorVisible i =
        fg . fromMaybe "wheat4" . lookup i . zip wsIds $
                concatMap (replicate 3) ["DarkOrchid3", "DodgerBlue4", "OliveDrab4"]
-- }}}

-- vim:foldmethod=marker