Personal tools

Xmonad/Config archive/sereven xmonad.hs

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
(Move to page properly named for config download script)
m (Update for vi + arrow window navigation)
Line 2: Line 2:
{-# OPTIONS_GHC -Wall -fno-warn-missing-signatures #-}
{-# OPTIONS_GHC -Wall -fno-warn-missing-signatures #-}
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -- for TallAlt
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -- for TallAlt
-
 
+
--
-
-- sereven's xmonad.hs (0.9.2 - 0.10) $ 2011-03-15
+
-- sereven xmonad.hs, 0.9.1 - 0.10 2011-11-02
 +
--
-- imports {{{
-- imports {{{
 +
import XMonad hiding (keys)
import XMonad hiding (keys)
import qualified XMonad.StackSet as W
import qualified XMonad.StackSet as W
-- standard libraries
-- standard libraries
-
import Control.Applicative ((<$>))
+
import Control.Applicative ((<$>)) -- , liftA2)
-
import Control.Monad (liftM2)
+
import Control.Monad (liftM2, (>=>))
 +
--import Data.List (isPrefixOf, isInfixOf, nub)
import Data.List (isPrefixOf, nub)
import Data.List (isPrefixOf, nub)
-
import Data.Maybe (fromMaybe)
+
--import Data.Maybe (fromMaybe)
import System.Exit
import System.Exit
-
-- xmonad-contrib
+
-- xmonad-contrib (darcs || 0.10)
-
import XMonad.Actions.CycleWS (swapNextScreen, toggleOrDoSkip, nextWS, prevWS)
+
import XMonad.Actions.CycleWS
import XMonad.Actions.FlexibleManipulate as Flex
import XMonad.Actions.FlexibleManipulate as Flex
import XMonad.Actions.OnScreen (onlyOnScreen)
import XMonad.Actions.OnScreen (onlyOnScreen)
-
import XMonad.Actions.Search hiding (isPrefixOf)
+
import XMonad.Actions.UpdatePointer
import XMonad.Actions.WindowNavigation
import XMonad.Actions.WindowNavigation
import XMonad.Config.Gnome
import XMonad.Config.Gnome
-
import XMonad.Hooks.DynamicLog
+
--import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.SetWMName
import XMonad.Hooks.SetWMName
-
import XMonad.Layout.IM
 
import XMonad.Layout.LayoutHints
import XMonad.Layout.LayoutHints
-
import XMonad.Layout.LayoutScreens
 
import XMonad.Layout.LimitWindows
import XMonad.Layout.LimitWindows
import XMonad.Layout.NoBorders
import XMonad.Layout.NoBorders
import XMonad.Layout.PerWorkspace
import XMonad.Layout.PerWorkspace
-
import XMonad.Layout.Reflect (reflectHoriz)
+
import XMonad.Layout.Spacing
import XMonad.Layout.ToggleLayouts
import XMonad.Layout.ToggleLayouts
import XMonad.Layout.WorkspaceDir
import XMonad.Layout.WorkspaceDir
Line 39: Line 40:
import XMonad.Prompt.RunOrRaise
import XMonad.Prompt.RunOrRaise
import XMonad.Util.EZConfig
import XMonad.Util.EZConfig
-
import XMonad.Util.Run (hPutStrLn, spawnPipe)
+
--import XMonad.Util.Run (hPutStrLn, spawnPipe)
-
import XMonad.Util.Scratchpad
+
import XMonad.Util.NamedScratchpad
-
import XMonad.Util.WorkspaceCompare
+
--import XMonad.Util.WorkspaceCompare
-- }}}
-- }}}
 +
 +
-- Workspace ID list is used all over the place
wsIds = map return "123456789" ++ ["NSP"]
wsIds = map return "123456789" ++ ["NSP"]
-
infixr 0 ~> -- <http://mauke.ath.cx/stuff/xmonad/xmonad.hs>
+
-- Infix (,) to clean up key and mouse bindings
 +
infixr 0 ~>
(~>) :: a -> b -> (a, b)
(~>) :: a -> b -> (a, b)
(~>) = (,)
(~>) = (,)
-- main {{{
-- main {{{
 +
main = do
main = do
-
dz <- spawnPipe themedDzen
+
conf <- viAndArrowNav $ -- play nicer with irssi nav
-
conf <- withNavKeys (xK_k, xK_h, xK_j, xK_l) $
+
gnomeConfig
gnomeConfig
{ terminal = "urxvt"
{ terminal = "urxvt"
, modMask = mod4Mask
, modMask = mod4Mask
-
, normalBorderColor = bgColor promptConfig
+
, normalBorderColor = fgColor promptConfig
-
, focusedBorderColor = fgColor promptConfig
+
, focusedBorderColor = bgColor promptConfig
 +
, borderWidth = 2
, workspaces = wsIds
, workspaces = wsIds
-
, logHook = dynamicLogWithPP dzPP { ppOutput = hPutStrLn dz }
 
, manageHook = manageHooks
, manageHook = manageHooks
, layoutHook = layouts
, layoutHook = layouts
}
}
`additionalKeysP` keys `additionalMouseBindings` buttons
`additionalKeysP` keys `additionalMouseBindings` buttons
-
xmonad conf { startupHook = do
+
xmonad conf
-
startupHook gnomeConfig
+
{ startupHook = do
-
checkKeymap conf keys
+
startupHook gnomeConfig
-
setWMName "LG3D"
+
checkKeymap conf keys
-
windows $ onlyOnScreen 1 "8"
+
setWMName "LG3D"
-
}
+
windows $ onlyOnScreen 1 "8"
 +
-- spawn "xcompmgr -Cc -r 3 -l -5 -t -5 &"
 +
, logHook = do
 +
updatePointer $ Relative 0.88 0.88
 +
-- fadeMostInactives 0.89 -- plus xcompmgr
 +
}
 +
where
 +
viAndArrowNav =
 +
withNavKeys (xK_k, xK_h, xK_j, xK_l) >=> withNavKeys (xK_Up, xK_Left, xK_Down, xK_Right)
 +
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 ]
 +
 
-- }}}
-- }}}
-- keyboard and mouse {{{
-- keyboard and mouse {{{
-
-- uses mod4 on winkey and on capslock via ` Option "XkbOptions" "caps:super" '
 
-
withNavKeys (u,l,d,r) = withWindowNavigationKeys
+
-- Uses mod4 on win key *and* caps lock
-
[ (mod4Mask , u) ~> WNGo U
+
-- via `Option "XkbOptions" "caps:super"'
-
, (mod4Mask , l) ~> WNGo L
+
-- Both shift keys pressed together turns on capslock, either one alone turns it off,
-
, (mod4Mask , d) ~> WNGo D
+
-- via "shift:both_capslock_cancel"
-
, (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 =
buttons =
Line 90: Line 106:
, (mod4Mask , button4) ~> const $ windows W.swapDown
, (mod4Mask , button4) ~> const $ windows W.swapDown
, (mod4Mask , button5) ~> const $ windows W.swapUp
, (mod4Mask , button5) ~> const $ windows W.swapUp
-
, (mod1Mask .|. mod4Mask, button4) ~> const nextWS
+
, (mod4Mask .|. mod1Mask, button4) ~> const $ moveTo Next HiddenWS
-
, (mod1Mask .|. mod4Mask, button5) ~> const prevWS ]
+
, (mod4Mask .|. mod1Mask, button5) ~> const $ moveTo Prev HiddenWS ]
 +
 
-
keys =
+
keys = --
-
[ "M-M1-S-q" ~> io (exitWith ExitSuccess)
+
[ "M-C-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-<Space>" ~> sendMessage ToggleLayout -- toggle fullscreen
, "M-c" ~> sendMessage NextLayout
, "M-c" ~> sendMessage NextLayout
-
, "M-M1-." ~> sendMessage Shrink
+
, "M-<Return>" ~> windows W.focusMaster
-
, "M-M1-," ~> sendMessage Expand
+
, "M-M1-<Return>" ~> windows $ W.focusUp . W.focusMaster
-
, "M-<F9>" ~> layoutScreens 3 $ fixedLayout
+
, "M-M1-," ~> sendMessage Shrink
-
[Rectangle 0 0 1600 1200, Rectangle 1600 0 1600 480
+
, "M-M1-." ~> sendMessage Expand
-
, Rectangle 1600 480 1280 720]
+
-
, "M-<F8>" ~> rescreen
+
]
]
-
-- workspaces and screens -- 1 2 3 \
+
-- workspaces and screens -- 1 2 3 \
-
-- q w e \
+
-- q w e \
-
-- a s d \ f g
+
++ -- a s d \ f g
-
++ -- \ v b
+
[ "M-v" ~> swapNextScreen -- \ v b
-
[ mask ++ [key] ~> action i
+
, "M-b" ~> toggleWS ]
-
| (key, i) <- zip "123qweasd=" wsIds
+
-- , "M-b" ~> toggleWS' ["NSP"] ]
 +
++
 +
[ mask ++ [key] ~> action i | (key, i) <- zip "123qweasd=" wsIds
, (mask, action) <- [ ("M-", toggled W.greedyView)
, (mask, action) <- [ ("M-", toggled W.greedyView)
, ("M-M1-", toggled followShift) ] ]
, ("M-M1-", toggled followShift) ] ]
++
++
[ mask ++ [key] ~> screenWorkspace s >>= flip whenJust (windows . action)
[ mask ++ [key] ~> screenWorkspace s >>= flip whenJust (windows . action)
-
| (key, s) <- zip "fgb" [0..]
+
| (key, s) <- zip "fg" [0..]
, (mask, action) <- [ ("M-", W.view)
, (mask, action) <- [ ("M-", W.view)
, ("M-M1-", W.shift) ] ]
, ("M-M1-", W.shift) ] ]
-
++
+
++ -- toolbox
-
[ "M-v" ~> swapNextScreen
+
[ "M-<Tab>" ~> namedScratchpadAction pads "scratch"
-
-- scratch term, prompts and searches
+
, "M-<F1>" ~> namedScratchpadAction pads "nautilus"
-
, "M-<Tab>" ~> scratchpadSpawnActionTerminal "urxvt -pe tabbed"
+
, "M-<F2>" ~> namedScratchpadAction pads "cryptote"
-
, "M-r" ~> runOrRaisePrompt promptConfig
+
, "M-M1-<F2>" ~> namedScratchpadAction pads "keepassx"
-
, "M-M1-r" ~> changeDir promptConfig ]
+
, "M-<F3>" ~> namedScratchpadAction pads "picard"
-
++
+
, "M-M1-<F3>" ~> namedScratchpadAction pads "asunder"
-
[ "M-/ " ++ ks ~> promptSearch promptConfig s | (ks,s) <- searches ]
+
, "M-r" ~> runOrRaisePrompt promptConfig
-
++
+
, "M-M1-r" ~> changeDir promptConfig
-
[ "M-M1-/ " ++ ks ~> selectSearch s | (ks,s) <- searches ]
+
]
where
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"]
toggled = toggleOrDoSkip ["NSP"]
followShift = liftM2 (.) W.view W.shift
followShift = liftM2 (.) W.view W.shift
 +
-- }}}
-- }}}
-
-- manage hook {{{
+
-- scratchpad descriptions - used in key bindings and manageHook {{{
-
manageHooks = composeAll
+
 
-
[ ("OpenOffice" `isPrefixOf`) <$> className --> doShift "3"
+
pads =
-
, ("Gimp" `isPrefixOf`) <$> className --> doShift "5"
+
[ NS "scratch" "urxvt -pe tabbed -name scratch" (resource =? "scratch") scratchHook
-
, className =? "Acroread" --> doShift "2"
+
, NS "nautilus" "nautilus --browser --sm-client-disable" (resource =? "nautilus") nautilusHook
-
, className =? "Qjackctl" --> doFloat
+
, NS "cryptote" "cryptote" (resource =? "cryptote") cryptoteHook
-
, className =? "feh" --> doFloat
+
, NS "keepassx" "keepassx" (title =? "KeePassX - Password Manager") keepassxHook
-
, className =? "" --> doFloat -- low budget gtk windows
+
, NS "picard" "picard" (title =? "MusicBrainz Picard") picardHook
-
, className =? "XFontSel" --> doF W.shiftMaster <+> doCenterFloat
+
, NS "asunder" "asunder" (("Asunder" `isPrefixOf`) <$> title) asunderHook
-
, className =? "Xmessage" --> doF W.shiftMaster <+> doCenterFloat
+
-
, isDialog --> doF W.shiftMaster <+> doFloat
+
-
, scratchpadManageHook (W.RationalRect 0.43 0.575 0.53 0.34)
+
-
, transience'
+
-
, manageDocks
+
]
]
 +
where
 +
scratchHook = doRectFloat $ rr 0.51 0.52 0.46 0.44
 +
nautilusHook = doRectFloat $ rr 0.45 0.19 0.5 0.65
 +
cryptoteHook = doRectFloat $ rr 0.42 0.07 0.48 0.6
 +
keepassxHook = doRectFloat $ rr 0.49 0.03 0.51 0.52
 +
picardHook = doRectFloat $ rr 0.35 0.28 0.64 0.65
 +
asunderHook = doRectFloat $ rr 0.61 0.156 0.3 0.72
 +
rr = W.RationalRect -- in fractions of screen: x y w h
 +
 +
-- }}}
 +
 +
-- manage hook {{{
 +
manageHooks = namedScratchpadManageHook pads <+> composeOne
 +
[ isDialog -?> doF W.shiftMaster <+> doFloat
 +
, ("libreoffice" `isPrefixOf`) <$> className -?> doShift "3"
 +
, ("Gimp" `isPrefixOf`) <$> className -?> doShift "5"
 +
, title =? "Quick Alarm" -?> doF W.shiftMaster <+> doFloat
 +
, role =? "reminderFoxEdit" -?>
 +
doF W.shiftMaster <+> doRectFloat (W.RationalRect 0.15 0.46 0.52 0.432)
 +
, className =? "Gpick" -?> doFloat
 +
, className =? "Wuala" -?> doShift "NSP"
 +
, className =? "Audacity" -?> doShift "9"
 +
, className =? "Firefox" -?> doShift "8"
 +
, isMPlayerFull -?> doShift "6"
 +
, className =? "Apvlv" -?> doShift "2"
 +
, className =? "Xmessage" -?> doF W.shiftMaster <+> doCenterFloat
 +
, className =? "feh" -?> doF W.shiftMaster <+> doFloat
 +
, className =? "" -?> doFloat -- low budget gtk windows
 +
] <+> transience' <+> manageDocks
 +
where
 +
role = stringProperty "WM_WINDOW_ROLE"
 +
isMPlayerFull = (className =? "MPlayer" <&&> appName =? "gl2")
 +
<||> title =? "Gnome MPlayer Fullscreen"
-- }}}
-- }}}
-- layouts {{{
-- layouts {{{
 +
 +
layouts = modifiers
 +
. onWorkspaces ["1", "4"] (workspaceDir "~" edit)
 +
. onWorkspaces ["2", "3"] (workspaceDir "~/doc" doc)
 +
. onWorkspace "5" (workspaceDir "~/images" edit)
 +
. onWorkspace "7" (workspaceDir "~/.xmonad" edit) $ workspaceDir cwd many
 +
where
 +
cwd = "/e4/av/Music"
 +
modifiers = smartBorders . toggleLayouts (noBorders Full)
 +
. layoutHintsToCenter . spacing 1 . avoidStruts
 +
doc = limitWindows 6 $ TallAlt i 0.5 ||| Mirror (Tall 1 i 0.516)
 +
edit = limitWindows 4 (TallAlt i 0.516) ||| Full
 +
many = Mirror (TallAlt i 0.705) ||| Full ||| Tall 1 i 0.591
 +
i = 0.00125
-- TallAlt from <http://www.haskell.org/pipermail/xmonad/2009-July/008270.html>
-- TallAlt from <http://www.haskell.org/pipermail/xmonad/2009-July/008270.html>
Line 187: Line 227:
Shrink -> TallAlt i (d-i)
Shrink -> TallAlt i (d-i)
-
-- Note: Workspace dir prompt only works on layouts mod'd by workspaceDir
 
-
layouts =
 
-
modifiers . onWorkspaces (take 4 wsIds) (workspaceDir cwd many) . onWorkspace "5" gimp
 
-
. onWorkspace "7" (workspaceDir "~/.xmonad" four) $ workspaceDir "~" many
 
-
where
 
-
modifiers =
 
-
smartBorders . toggleLayouts (noBorders Full) . layoutHintsToCenter . avoidStruts
 
-
four = limitWindows 4 . Mirror $ TallAlt 0.03 (31/44) ||| Full
 
-
gimp = workspaceDir "~/images" . 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 {{{
+
-- prompt {{{
 +
 
 +
-- solarized color pallette
 +
solbase03 = "#002b36"
 +
solbase02 = "#073642"
 +
solbase01 = "#586e75"
 +
solbase00 = "#657b83"
 +
solbase0 = "#839496"
 +
solbase1 = "#93a1a1"
 +
solbase2 = "#eee8d5"
 +
solbase3 = "#fdf6e3"
 +
solyellow = "#b58900"
 +
solorange = "#cb4b16"
 +
solred = "#dc322f"
 +
solmagenta = "#d33682"
 +
solviolet = "#6c71c4"
 +
solblue = "#268bd2"
 +
solcyan = "#2aa198"
 +
solgreen = "#859900"
promptConfig = defaultXPConfig
promptConfig = defaultXPConfig
-
{ font = "xft:Denmark:Thin:size=11"
+
{ font = "xft:Consolas:12"
-
, bgColor = "gray5"
+
, bgColor = solbase03
-
, fgColor = "wheat3"
+
, fgColor = solbase1
-
, fgHLight = "DodgerBlue3"
+
-- , fgColor = solbase2
-
, bgHLight = "black"
+
, bgHLight = solyellow
 +
, fgHLight = solbase02
, promptBorderWidth = 0
, promptBorderWidth = 0
-
, height = 24
+
, height = 28
, historyFilter = nub
, historyFilter = nub
, showCompletionOnTab = True
, 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
-- vim:foldmethod=marker
</haskell>
</haskell>

Revision as of 03:35, 3 October 2011

{-# OPTIONS_GHC -Wall -fno-warn-missing-signatures #-}
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} -- for TallAlt
--
-- sereven xmonad.hs,  0.9.1 - 0.10  2011-11-02
--
 
-- imports {{{
 
import XMonad hiding (keys)
import qualified XMonad.StackSet as W
 
-- standard libraries
import Control.Applicative ((<$>)) -- , liftA2)
import Control.Monad (liftM2, (>=>))
--import Data.List (isPrefixOf, isInfixOf, nub)
import Data.List (isPrefixOf, nub)
--import Data.Maybe (fromMaybe)
import System.Exit
 
-- xmonad-contrib (darcs || 0.10)
import XMonad.Actions.CycleWS
import XMonad.Actions.FlexibleManipulate as Flex
import XMonad.Actions.OnScreen (onlyOnScreen)
import XMonad.Actions.UpdatePointer
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.LayoutHints
import XMonad.Layout.LimitWindows
import XMonad.Layout.NoBorders
import XMonad.Layout.PerWorkspace
import XMonad.Layout.Spacing
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.NamedScratchpad
--import XMonad.Util.WorkspaceCompare
-- }}}
 
 
-- Workspace ID list is used all over the place
wsIds = map return "123456789" ++ ["NSP"]
 
-- Infix (,) to clean up key and mouse bindings
infixr 0 ~>
(~>) :: a -> b -> (a, b)
(~>) = (,)
 
-- main {{{
 
main = do
    conf <- viAndArrowNav $ -- play nicer with irssi nav
        gnomeConfig
            { terminal           = "urxvt"
            , modMask            = mod4Mask
            , normalBorderColor  = fgColor promptConfig
            , focusedBorderColor = bgColor promptConfig
            , borderWidth        = 2
            , workspaces         = wsIds
            , manageHook         = manageHooks
            , layoutHook         = layouts
            }
        `additionalKeysP` keys `additionalMouseBindings` buttons
    xmonad conf
        { startupHook = do
            startupHook gnomeConfig
            checkKeymap conf keys
            setWMName "LG3D"
            windows $ onlyOnScreen 1 "8"
--          spawn "xcompmgr -Cc -r 3 -l -5 -t -5 &"
        , logHook = do
            updatePointer $ Relative 0.88 0.88
--          fadeMostInactives 0.89 -- plus xcompmgr
        }
      where
        viAndArrowNav =
            withNavKeys (xK_k, xK_h, xK_j, xK_l) >=> withNavKeys (xK_Up, xK_Left, xK_Down, xK_Right)
        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 ]
 
-- }}}
 
-- keyboard and mouse {{{
 
 -- Uses mod4 on win key *and* caps lock
 --     via `Option "XkbOptions" "caps:super"'
 -- Both shift keys pressed together turns on capslock, either one alone turns it off,
 --     via "shift:both_capslock_cancel"
 
buttons =
    [ (mod4Mask             , button3) ~> Flex.mouseWindow Flex.discrete
    , (mod4Mask             , button4) ~> const $ windows W.swapDown
    , (mod4Mask             , button5) ~> const $ windows W.swapUp
    , (mod4Mask .|. mod1Mask, button4) ~> const $ moveTo Next HiddenWS
    , (mod4Mask .|. mod1Mask, button5) ~> const $ moveTo Prev HiddenWS ]
 
 
keys = --
    [ "M-C-S-q"       ~> io (exitWith ExitSuccess)
    , "M-<Space>"     ~> sendMessage ToggleLayout  -- toggle fullscreen
    , "M-c"           ~> sendMessage NextLayout
    , "M-<Return>"    ~> windows W.focusMaster
    , "M-M1-<Return>" ~> windows $ W.focusUp . W.focusMaster
    , "M-M1-,"        ~> sendMessage Shrink
    , "M-M1-."        ~> sendMessage Expand
    ]
    -- workspaces and screens  -- 1 2 3 \
                               --  q w e \
    ++                         --   a s d \ f g
    [ "M-v" ~> swapNextScreen  --          \ v b
    , "M-b" ~> toggleWS ]
--  , "M-b" ~> toggleWS' ["NSP"] ]
    ++
    [ 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 "fg" [0..]
         , (mask, action) <- [ ("M-", W.view)
                             , ("M-M1-", W.shift) ] ]
    ++ -- toolbox
    [ "M-<Tab>"   ~> namedScratchpadAction pads "scratch"
    , "M-<F1>"    ~> namedScratchpadAction pads "nautilus"
    , "M-<F2>"    ~> namedScratchpadAction pads "cryptote"
    , "M-M1-<F2>" ~> namedScratchpadAction pads "keepassx"
    , "M-<F3>"    ~> namedScratchpadAction pads "picard"
    , "M-M1-<F3>" ~> namedScratchpadAction pads "asunder"
    , "M-r"       ~> runOrRaisePrompt promptConfig
    , "M-M1-r"    ~> changeDir promptConfig
    ]
  where
    toggled = toggleOrDoSkip ["NSP"]
    followShift = liftM2 (.) W.view W.shift
 
-- }}}
 
-- scratchpad descriptions - used in key bindings and manageHook {{{
 
pads =
    [ NS "scratch" "urxvt -pe tabbed -name scratch" (resource =? "scratch") scratchHook
    , NS "nautilus" "nautilus --browser --sm-client-disable" (resource =? "nautilus") nautilusHook
    , NS "cryptote" "cryptote" (resource =? "cryptote") cryptoteHook
    , NS "keepassx" "keepassx" (title =? "KeePassX - Password Manager") keepassxHook
    , NS "picard" "picard" (title =? "MusicBrainz Picard") picardHook
    , NS "asunder" "asunder" (("Asunder" `isPrefixOf`) <$> title) asunderHook
    ]
  where
    scratchHook  = doRectFloat $ rr 0.51 0.52 0.46 0.44
    nautilusHook = doRectFloat $ rr 0.45 0.19 0.5 0.65
    cryptoteHook = doRectFloat $ rr 0.42 0.07 0.48 0.6
    keepassxHook = doRectFloat $ rr 0.49 0.03 0.51 0.52
    picardHook   = doRectFloat $ rr 0.35 0.28 0.64 0.65
    asunderHook  = doRectFloat $ rr 0.61 0.156 0.3 0.72
    rr = W.RationalRect -- in fractions of screen: x y w h
 
-- }}}
 
-- manage hook {{{
manageHooks = namedScratchpadManageHook pads <+> composeOne
    [ isDialog                -?> doF W.shiftMaster <+> doFloat
    , ("libreoffice" `isPrefixOf`) <$> className -?> doShift "3"
    , ("Gimp"        `isPrefixOf`) <$> className -?> doShift "5"
    , title =? "Quick Alarm"  -?> doF W.shiftMaster <+> doFloat
    , role =? "reminderFoxEdit" -?>
        doF W.shiftMaster <+> doRectFloat (W.RationalRect 0.15 0.46 0.52 0.432)
    , className =? "Gpick"    -?> doFloat
    , className =? "Wuala"    -?> doShift "NSP"
    , className =? "Audacity" -?> doShift "9"
    , className =? "Firefox"  -?> doShift "8"
    , isMPlayerFull           -?> doShift "6"
    , className =? "Apvlv"    -?> doShift "2"
    , className =? "Xmessage" -?> doF W.shiftMaster <+> doCenterFloat
    , className =? "feh"      -?> doF W.shiftMaster <+> doFloat
    , className =? ""         -?> doFloat -- low budget gtk windows
    ] <+> transience' <+> manageDocks
  where
    role = stringProperty "WM_WINDOW_ROLE"
    isMPlayerFull = (className =? "MPlayer" <&&> appName =? "gl2")
                        <||> title =? "Gnome MPlayer Fullscreen"
-- }}}
 
-- layouts {{{
 
layouts = modifiers
            . onWorkspaces ["1", "4"] (workspaceDir "~" edit)
            . onWorkspaces ["2", "3"] (workspaceDir "~/doc" doc)
            . onWorkspace "5" (workspaceDir "~/images" edit)
            . onWorkspace "7" (workspaceDir "~/.xmonad" edit) $ workspaceDir cwd many
  where
    cwd  = "/e4/av/Music"
    modifiers = smartBorders . toggleLayouts (noBorders Full)
        . layoutHintsToCenter . spacing 1 . avoidStruts
    doc = limitWindows 6 $ TallAlt i 0.5 ||| Mirror (Tall 1 i 0.516)
    edit = limitWindows 4 (TallAlt i 0.516) ||| Full
    many = Mirror (TallAlt i 0.705) ||| Full ||| Tall 1 i 0.591
    i = 0.00125
 
-- 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)
 
-- }}}
 
-- prompt {{{
 
-- solarized color pallette
solbase03  = "#002b36"
solbase02  = "#073642"
solbase01  = "#586e75"
solbase00  = "#657b83"
solbase0   = "#839496"
solbase1   = "#93a1a1"
solbase2   = "#eee8d5"
solbase3   = "#fdf6e3"
solyellow  = "#b58900"
solorange  = "#cb4b16"
solred     = "#dc322f"
solmagenta = "#d33682"
solviolet  = "#6c71c4"
solblue    = "#268bd2"
solcyan    = "#2aa198"
solgreen   = "#859900"
 
promptConfig = defaultXPConfig
    { font = "xft:Consolas:12"
    , bgColor  = solbase03
    , fgColor  = solbase1
--  , fgColor  = solbase2
    , bgHLight = solyellow
    , fgHLight = solbase02
    , promptBorderWidth = 0
    , height   = 28
    , historyFilter = nub
    , showCompletionOnTab = True
    }
 
-- }}}
 
-- vim:foldmethod=marker