git.fiddlerwoaroof.com
.xmonad/xmonad.hs
c68f2c18
 {-# LANGUAGE RankNTypes #-}
 
69fde253
 import Control.Monad
 
 import Data.List
da9336db
 import Data.Maybe
f9d1298d
 import Data.Monoid
69fde253
 import Data.Ratio ((%))
f9d1298d
 import Data.Word
69fde253
 
 import System.IO
 
 import XMonad hiding ( (|||) )
 import XMonad.Actions.CopyWindow(copy,copyWindow,kill1,killAllOtherCopies)
c68f2c18
 import XMonad.Actions.CycleWindows()
69fde253
 import XMonad.Actions.DynamicWorkspaces
 import XMonad.Actions.GridSelect
907e4c93
 import XMonad.Actions.PhysicalScreens
69fde253
 import XMonad.Actions.SpawnOn
c68f2c18
 import XMonad.Core()
69fde253
 import XMonad.Hooks.DynamicLog
f9d1298d
 import XMonad.Hooks.EwmhDesktops
 import XMonad.Hooks.ICCCMFocus
69fde253
 import XMonad.Hooks.ManageDocks
 import XMonad.Layout.Accordion
 import XMonad.Layout.Circle
c68f2c18
 import XMonad.Layout.Combo()
f9d1298d
 import XMonad.Layout.Decoration
69fde253
 import XMonad.Layout.DragPane
 import XMonad.Layout.Gaps
 import XMonad.Layout.Grid
 import XMonad.Layout.IM
 import XMonad.Layout.LayoutCombinators
c68f2c18
 import XMonad.Layout.LayoutModifier()
f9d1298d
 import XMonad.Layout.Maximize
69fde253
 import XMonad.Layout.NoBorders
 import XMonad.Layout.OneBig
 import XMonad.Layout.PerWorkspace
c68f2c18
 import XMonad.Layout.Reflect()
69fde253
 import XMonad.Layout.Renamed
 import XMonad.Layout.ResizableTile
 import XMonad.Layout.Simplest
 import XMonad.Layout.Spiral
c68f2c18
 import XMonad.Layout.SubLayouts()
69fde253
 import XMonad.Layout.Tabbed
 import XMonad.Layout.ThreeColumns
 import XMonad.Layout.TwoPane
 import XMonad.Layout.WindowNavigation
 import XMonad.Prompt
 import XMonad.StackSet as W
da9336db
 import XMonad.Util.Dzen
69fde253
 import XMonad.Util.EZConfig(additionalKeys)
 import XMonad.Util.Loggers
907e4c93
 import XMonad.Util.NamedScratchpad
69fde253
 import XMonad.Util.Run(spawnPipe)
7304bd7d
 import XMonad.Util.Scratchpad
c68f2c18
 
f9d1298d
 nmaster :: Int
69fde253
 nmaster = 1
f9d1298d
 
69fde253
 ratio = 13/21
f9d1298d
 
69fde253
 delta = 3/100
f9d1298d
 
 tiled :: Tall a
69fde253
 tiled = Tall nmaster delta ratio
f9d1298d
 
c68f2c18
 myTabbed :: ModifiedLayout Rename (ModifiedLayout (Decoration TabbedDecoration DefaultShrinker) Simplest) Word64
69fde253
 myTabbed = renamed [Replace "Tabbed"] $ tabbedBottom shrinkText defaultTheme
f9d1298d
 
 threeLayout :: ThreeCol a
69fde253
 threeLayout = ThreeColMid nmaster delta ratio
f9d1298d
 
 writingLayout :: ModifiedLayout Rename (ModifiedLayout Gaps Full) a
69fde253
 writingLayout = renamed [Replace "Writing"] $ gaps [(L,500), (R, 500)] Full
 
f9d1298d
 imLayout :: ModifiedLayout Rename (ModifiedLayout AddRoster Accordion) Window
 imLayout = renamed [Replace "im"] $ withIM myRatio empathyRoster Accordion where
     myRatio           = 1%6
69fde253
     empathyRoster   = And (ClassName "Empathy") (Role "contact_list")
 
 
f9d1298d
 base :: NewSelect
   (ModifiedLayout Rename (Mirror ThreeCol))
   (NewSelect (ModifiedLayout Rename (Mirror Tall))
907e4c93
    (NewSelect Full
     (NewSelect Accordion
      (NewSelect Circle
       (NewSelect SpiralWithDir
        (NewSelect (ModifiedLayout Rename (ModifiedLayout (Decoration TabbedDecoration DefaultShrinker) Simplest))
         (NewSelect (ModifiedLayout Rename (Mirror Accordion))
          (NewSelect (ModifiedLayout Rename (ModifiedLayout Gaps Full))
           (NewSelect (ModifiedLayout Rename DragPane)
            (NewSelect (ModifiedLayout Rename Grid)
             (NewSelect TwoPane OneBig))))))))))) Word64
 base = mthree ||| wide ||| Full ||| Accordion ||| Circle ||| spiral (6/7)
    ||| myTabbed ||| wideAccordion ||| writingLayout ||| rows ||| grid
    ||| TwoPane (3/100) (1/2) ||| OneBig (3/4) (3/4)
   where
     mthree = renamed [Replace "ThreeWide"] $ Mirror threeLayout
     wide = renamed [Replace "Wide"] $ Mirror tiled
     wideAccordion = renamed [Replace "WideAccordion"] $ Mirror Accordion
     grid = renamed [Replace "Gridding"] $ GridRatio (1/2)
     rows = renamed [Replace "WritingNew"] $ dragPane Vertical 1 0.5
 
 
 {-
  -
  -}
 
 tmp = onWorkspace "web" (myTabbed ||| Full ||| TwoPane (3/100) (1/2)) $
       onWorkspace "terminal" (tiled ||| threeLayout ||| Full) $
       onWorkspace "IM" imLayout $
       --onWorkspace "images" (gimpLayout ||| tiled ||| threeLayout ||| base) $
        tiled ||| threeLayout ||| base
  --where
  --  gimpLayout = renamed [Replace "gimp"] $ withIM (11/64) (Role "gimp-toolbox") $ ResizableTall 2 (1/118) (11/20) [1]
 
 myLayout = avoidStruts $ smartBorders tmp
69fde253
 
da9336db
 myDzenConfig :: DzenConfig
907e4c93
 myDzenConfig = timeout 1 >=> onCurr (vCenter 100)
                          >=> onCurr (hCenter 300)
                          >=> XMonad.Util.Dzen.font "xft:Source Code Pro:size=20:antialias=true"
da9336db
 
907e4c93
 makeLayoutList :: [t] -> [(t,t)]
 makeLayoutList = map (\ l -> (l, l))
da9336db
 
c68f2c18
 --changeLayout :: Maybe String -> X ()
 --changeLayout a =
 --  case a of
 --     Just r -> sendMessage $ JumpToLayout r
 --     _ -> error "this shouldn't happen"
da9336db
 
 -- This is the currently used layout change
 -- activated with Meta+;
 -- It displays the relevant list of layouts for the current display
 -- TODO: show new layout as a popup message
 nchooseLayout :: GSConfig String -> X ()
 nchooseLayout conf = do
    loName <- wrapped_loName
907e4c93
    wsName <- wrapped_wsName
da9336db
 
    a <- gridselect conf $ makeLayoutList $
       cycleFront loName $ case wsName of
          "web" -> webList
          "terminal" -> terminalList
          "im" -> imList
          "images" -> imagesList
          _ -> defaultList
 
    case a of
f9d1298d
       Just r -> do
          sendMessage $ JumpToLayout r
          dzenConfig myDzenConfig r
da9336db
    return ()
  where
907e4c93
    wrapped_loName :: X String
da9336db
    wrapped_loName =  liftM (fromMaybe "") logLayout
 
907e4c93
    wrapped_wsName :: X String 
da9336db
    wrapped_wsName =  liftM (fromMaybe "") logCurrent
 
    cycleFront :: String -> [String] -> [String]
907e4c93
    cycleFront n l = n: Data.List.delete n l
da9336db
 
    basicList = ["Accordion", "Full", "Tabbed", "Spiral", "Wide", "ThreeWide", "WideAccordion", "Writing", "WritingNew", "Gridding", "TwoPane", "OneBig"]
    defaultList = ["Tall", "ThreeCol"] ++ basicList
    webList = ["Tabbed", "Full", "TwoPane"]
    terminalList = ["Tall", "ThreeCol", "Full"]
    imList = ["im"]
    imagesList = ["gimp", "Tall", "ThreeCol"] ++ basicList
 
 
 
f9d1298d
 myPP :: PP
7304bd7d
 myPP = namedScratchpadFilterOutWorkspacePP $ sjanssenPP {
69fde253
    ppCurrent = xmobarColor "grey" "white",
7304bd7d
    ppHidden = xmobarColor "red" "black", -- . noScratchPad,
69fde253
    ppHiddenNoWindows = id,
da9336db
    ppTitle = xmobarColor "green" "" . shorten 126
69fde253
 }
 
f9d1298d
 myManageHook  :: Query (Endo (StackSet WorkspaceId (Layout Window) Window ScreenId ScreenDetail))
69fde253
 myManageHook = composeAll
    [
    (role =? "gimp-toolbox" <||> role =? "gimp-image-winow") --> (ask >>= doF . W.sink)
    , className =? "X-terminal-emulator"      --> doCopy "terminal"
    , className =? "Xmessage"  --> doFloat
    , className =? "Qasmixer" --> doFloat
    , className =? "Sonata" --> doFloat
    , className =? "feh" --> viewShift "images"
    , className =? "Display.im6" --> viewShift "images"
    , manageDocks
7304bd7d
    ] <+> manageScratchPad
69fde253
  where role = stringProperty "WM_WINDOW_ROLE"
 
7304bd7d
 manageScratchPad :: ManageHook
 manageScratchPad = namedScratchpadManageHook scratchpads
 
 scratchpads :: [NamedScratchpad]
 scratchpads = [
   -- run htop in xterm, find it by title, use default floating window placement
907e4c93
   NS "glances" "xterm -e glances" (title =? "glances") floatStyle ,
7304bd7d
   NS "mutt" "xterm -e mutt" (title =? "mutt") floatStyle ,
   NS "mcabber" "xterm -e mcabber" (title =? "mcabber") floatStyle ,
   NS "mpc" "stterm -c mpc -e ncmpcpp" (className =? "ncmpcpp") floatStyle ,
 
   -- run gvim, find by role
   NS "notes" "bash -c 'cd $HOME/mywiki; source /usr/local/share/chruby/chruby.sh; chruby 2.2.2; SOYWIKI_VIM=\"gvim --role notes\" /home/edwlan/.gem/ruby/2.2.2/bin/soywiki'" (role =? "notes") floatStyle
   ] where cls = stringProperty "WM_WINDOW_CLASS"
           role = stringProperty "WM_WINDOW_ROLE"
           floatStyle = customFloating $ W.RationalRect l t w h
           w = 1     -- terminal height, 10%
           h = 0.3333       -- terminal width, 100%
           t = 0.015  -- distance from top edge, 90%
           l = 0  -- distance from left edge, 0%
69fde253
 
 doCopy :: WorkspaceId -> ManageHook
 doCopy i = doF . copyWin i =<< ask
c68f2c18
 
 copyWin :: forall a i l s sd . (Eq a, Eq i, Eq s) => i -> a -> StackSet i l a s sd -> StackSet i l a s sd
69fde253
 copyWin i a = copyWindow a i
 
f9d1298d
 viewShift :: WorkspaceId -> Query (Endo (StackSet WorkspaceId l Window ScreenId sd))
69fde253
 viewShift = doF . liftM2 (.) W.greedyView W.shift
 
f9d1298d
 dShow :: String -> X ()
da9336db
 dShow = dzenConfig myDzenConfig
 
c68f2c18
 copyNSwitch :: forall l a s sd a1. (Eq s, Eq a) => ((StackSet String l a s sd -> StackSet String l a s sd) -> X a1)
                  -> String -> X ()
 copyNSwitch ws target = do
   ws $ copy target
907e4c93
   ws $ W.view target
da9336db
   dShow target
69fde253
 
c68f2c18
 shiftNSwitch :: forall l a s sd a1. (Eq s, Ord a) => ((StackSet String l a s sd -> StackSet String l a s sd) -> X a1)
                   -> String -> X ()
 shiftNSwitch ws target = do
   ws $ shift target
907e4c93
   ws $ W.view target
da9336db
   dShow target
 
907e4c93
 switchWorkspace :: forall l a s sd a1. (Eq s, Ord a) => ((StackSet String l a s sd -> StackSet String l a s sd) -> X a1)
                   -> String -> X ()
 switchWorkspace ws target = do
da9336db
   windows $ W.greedyView target
   dShow target
69fde253
 
f9d1298d
 maximizeSwitch :: X ()
a0d71cd9
 maximizeSwitch = do
   withFocused $ sendMessage . maximizeRestore
   windows W.focusUp
 
f9d1298d
 maximizeFlop :: X ()
a0d71cd9
 maximizeFlop = do
   windows W.focusUp
   withFocused $ sendMessage . maximizeRestore
 
907e4c93
 makeSwitchComb mod keyList num action = ((getMod mod, keyList !! num), action)
   where
     getMod Nothing = mod4Mask
     getMod (Just mod) = mod4Mask .|. mod
 
 workspaceNames = ["web", "2", "3", "4", "5", "6", "7", "terminal", "images"]
 
 numKeys :: [KeySym]
 numKeys = [xK_0, xK_1, xK_2, xK_3, xK_4, xK_5, xK_6, xK_7, xK_8, xK_9]
 
 numPadKeys :: [KeySym]
 numPadKeys = [xK_KP_Insert -- 0
              , xK_KP_End,  xK_KP_Down,  xK_KP_Page_Down -- 1, 2, 3
              , xK_KP_Left, xK_KP_Begin, xK_KP_Right     -- 4, 5, 6
              , xK_KP_Home, xK_KP_Up,    xK_KP_Page_Up   -- 7, 8, 9
              ]
 
 combForNum keyList action mod n = makeSwitchComb mod keyList n $ action windows $ workspaceNames !! (n-1)
 
 multiMap funs seq = concatMap (`map` seq) funs
 
 workspaceKeys =
     bindWorkspaces [
       bindNum copyNSwitch shiftMask,
       bindNum shiftNSwitch controlMask,
 
       bindNumPad copyNSwitch shiftMask,
       bindNumPad shiftNSwitch controlMask,
 
       combForNum numKeys switchWorkspace Nothing,
       combForNum numPadKeys switchWorkspace Nothing
       ] ++ [
       ((mod4Mask, xK_0), withNthWorkspace greedyView 0),
       ((mod4Mask .|. shiftMask, xK_0), withNthWorkspace copy 0),
       ((mod4Mask, head numPadKeys), withNthWorkspace greedyView 0) 
       ]
     where
       bindNum action = combForNum numKeys action . Just
       bindNumPad action = combForNum numPadKeys action . Just
       bindWorkspaces = flip multiMap [1..9]
 
f9d1298d
 main :: IO ()
69fde253
 main = do
893ef22d
    xmproc <- spawnPipe "/home/edwlan/.local/bin/xmobar /home/edwlan/.xmobarrc"
3af9a76e
    --xmproc1 <- spawnPipe "/home/edwlan/.cabal/bin/xmobar /home/edwlan/.xmobarrc1"
f9d1298d
    xmonad $ ewmh defaultConfig {
69fde253
          manageHook = myManageHook <+> manageSpawn <+> manageHook defaultConfig,
da9336db
          --handleEventHook = handleTimerEvent,
1c15fd45
          layoutHook = maximize myLayout,
907e4c93
          logHook = takeTopFocus >> dynamicLogWithPP myPP {
            ppOutput = hPutStrLn xmproc
          },
69fde253
          modMask = mod4Mask,
          focusFollowsMouse = False,
c68f2c18
          clickJustFocuses = False,
907e4c93
          XMonad.workspaces = ["web", "2", "3", "4", "5", "6", "7", "terminal", "images", "IM"]
       } `additionalKeys` (workspaceKeys ++
69fde253
       [
          ((mod4Mask .|. controlMask .|. shiftMask, xK_h ), sendMessage $ Move L),
          ((mod4Mask .|. controlMask .|. shiftMask, xK_j ), sendMessage $ Move D),
          ((mod4Mask .|. controlMask .|. shiftMask, xK_k   ), sendMessage $ Move U),
          ((mod4Mask .|. controlMask .|. shiftMask, xK_l), sendMessage $ Move R),
7304bd7d
          ((mod4Mask .|. controlMask, xK_backslash), maximizeFlop),
          ((mod4Mask .|. controlMask, xK_grave), shiftNSwitch windows "IM" ),
69fde253
          ((mod4Mask .|. controlMask, xK_m), withWorkspace defaultXPConfig (windows . shift)),
907e4c93
          ((mod4Mask .|. controlMask, xK_q     ), spawn "if type xmonad; then xmonad --recompile && xmonad --restart; else xmessage xmonad not in \\$PATH: \"$PATH\"; fi"),
7304bd7d
          ((mod4Mask .|. controlMask, xK_t), killAllOtherCopies),
          ((mod4Mask .|. shiftMask, xK_backslash), maximizeSwitch),
69fde253
          ((mod4Mask .|. shiftMask, xK_BackSpace), removeWorkspace),
7304bd7d
          ((mod4Mask .|. shiftMask, xK_grave), shiftNSwitch windows "IM" ),
69fde253
          ((mod4Mask .|. shiftMask, xK_m), withWorkspace defaultXPConfig (windows . copy)),
          ((mod4Mask .|. shiftMask, xK_n), addWorkspacePrompt defaultXPConfig),
          ((mod4Mask .|. shiftMask, xK_Return), spawnHere "/usr/bin/x-terminal-emulator"),
          ((mod4Mask .|. shiftMask, xK_r), renameWorkspace defaultXPConfig),
7304bd7d
          ((mod4Mask .|. shiftMask, xK_t), kill1),
69fde253
          ((mod4Mask .|. shiftMask, xK_w), gridselectWorkspace defaultGSConfig (\ws -> greedyView ws . shift ws)),
7304bd7d
          --((mod4Mask, xK_apostrophe), scratchpadSpawnActionTerminal "gvim"),
          ((mod4Mask, xK_backslash), withFocused (sendMessage . maximizeRestore)),
69fde253
          ((mod4Mask, xK_b), sendMessage ToggleStruts),
          ((mod4Mask, xK_g), goToSelected defaultGSConfig),
7304bd7d
          --((mod4Mask, xK_grave), scratchpadSpawnActionTerminal "urxvt"),
          {-((mod4Mask, xK_grave), switchWorkspace "IM" ),-}
69fde253
          ((mod4Mask, xK_KP_Add), spawn "/usr/bin/zsh /home/edwlan/bin/dzen_mpc_status"),
7304bd7d
          ((mod4Mask, xK_KP_Divide), spawn "/usr/bin/zsh /home/edwlan/bin/dmenu_play_mpd"),
          ((mod4Mask, xK_KP_Multiply), spawn "/usr/bin/zsh /home/edwlan/bin/dmenu_queue_mpd"),
          ((mod4Mask, xK_KP_Subtract), spawn "/usr/bin/zsh /home/edwlan/bin/dmenu_queueplay_mpd"),
893ef22d
          ((mod4Mask, xK_p), spawnHere "/home/edwlan/bin/yeganesh_run -f"),
907e4c93
          ((mod4Mask, xK_q), (withSelectedWindow $ windows . W.focusWindow) defaultGSConfig >> windows W.shiftMaster),
da9336db
          ((mod4Mask, xK_semicolon), nchooseLayout defaultGSConfig),
907e4c93
          ((mod4Mask, xK_w), gridselectWorkspace defaultGSConfig greedyView),
 
          ((mod4Mask, xK_Left), onPrevNeighbour W.view), 
          ((mod4Mask, xK_Right), onNextNeighbour W.view)
 
7304bd7d
       ]
       ++ [
          ((mod4Mask .|. mod1Mask, xK_1), namedScratchpadAction scratchpads "notes"),
          ((mod4Mask .|. mod1Mask, numPadKeys !! 1), namedScratchpadAction scratchpads "notes"),
          ((mod4Mask .|. mod1Mask, xK_2), namedScratchpadAction scratchpads "mutt"),
          ((mod4Mask .|. mod1Mask, numPadKeys !! 2), namedScratchpadAction scratchpads "mutt"),
907e4c93
          --((mod4Mask .|. mod1Mask, xK_3), namedScratchpadAction scratchpads "irc"),
          --((mod4Mask .|. mod1Mask, numPadKeys !! 3), namedScratchpadAction scratchpads "irc"),
7304bd7d
          ((mod4Mask .|. mod1Mask, xK_4), namedScratchpadAction scratchpads "htop"),
          ((mod4Mask .|. mod1Mask, numPadKeys !! 4), namedScratchpadAction scratchpads "htop"),
          ((mod4Mask .|. mod1Mask, xK_5), namedScratchpadAction scratchpads "mpc"),
          ((mod4Mask .|. mod1Mask, numPadKeys !! 5), namedScratchpadAction scratchpads "mpc"),
          ((mod4Mask .|. mod1Mask, xK_6), namedScratchpadAction scratchpads "mcabber"),
          ((mod4Mask .|. mod1Mask, numPadKeys !! 6), namedScratchpadAction scratchpads "mcabber")
907e4c93
       ])
69fde253