diff options
Diffstat (limited to 'dot_xmonad')
-rw-r--r-- | dot_xmonad/xmonad.hs | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/dot_xmonad/xmonad.hs b/dot_xmonad/xmonad.hs new file mode 100644 index 0000000..60b435c --- /dev/null +++ b/dot_xmonad/xmonad.hs @@ -0,0 +1,423 @@ +{-# OPTIONS_GHC -W -fwarn-unused-imports -fno-warn-missing-signatures -O2 #-} +import Control.Monad (liftM2) +import Data.Map (fromList, toList, union) +import System.Environment (getEnv, setEnv) +import System.IO (hPutStrLn) +import XMonad +import XMonad.Actions.CopyWindow (copy, kill1, killAllOtherCopies) +import XMonad.Actions.CycleWS (moveTo, nextWS, WSType(NonEmptyWS) + , prevWS, shiftToNext, shiftToPrev, toggleWS) +import XMonad.Actions.DynamicWorkspaces (addWorkspacePrompt, removeWorkspace + , renameWorkspace, selectWorkspace + , withWorkspace) +import XMonad.Actions.GridSelect (HasColorizer, GSConfig, buildDefaultGSConfig + , defaultColorizer, goToSelected + , gridselectWorkspace, gs_navigate, navNSearch) +import XMonad.Actions.Submap (submap) +import XMonad.Hooks.DynamicLog (dzenColor, dynamicLogWithPP + , ppCurrent, ppVisible, ppSep, ppHidden + , ppUrgent, ppTitle, ppExtras + , ppOrder, ppOutput, trim, wrap) +import XMonad.Hooks.ManageDocks (avoidStruts, docks, docksEventHook + , ToggleStruts(ToggleStruts)) +import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat) +import XMonad.Hooks.UrgencyHook (focusUrgent) +import XMonad.Layout.Accordion (Accordion(Accordion)) +import XMonad.Layout.Dishes (Dishes(Dishes)) +import XMonad.Layout.FixedColumn (FixedColumn(FixedColumn)) +import XMonad.Layout.Grid (Grid(Grid)) +import XMonad.Layout.LimitWindows (limitWindows) +import XMonad.Layout.Magnifier (magnifiercz') +import XMonad.Layout.MultiToggle (mkToggle, single, Toggle(Toggle)) +import XMonad.Layout.MultiToggle.Instances (StdTransformers(MIRROR)) +import XMonad.Layout.NoBorders (smartBorders) +import XMonad.Layout.NoFrillsDecoration (activeBorderColor, activeColor + , activeTextColor, decoHeight, fontName + , inactiveBorderColor, inactiveColor + , inactiveTextColor, urgentColor + , urgentTextColor) +import XMonad.Layout.PerWorkspace (onWorkspace) +import XMonad.Layout.ResizableTile (ResizableTall(ResizableTall)) +import XMonad.Layout.Tabbed (shrinkText, tabbed) +import XMonad.Layout.ThreeColumns (ThreeCol(ThreeColMid)) +import XMonad.Layout.ToggleLayouts (toggleLayouts, ToggleLayout(ToggleLayout)) +import XMonad.Layout.WindowNavigation (Navigate(Move)) +import XMonad.Prompt (fgColor, bgColor, XPPosition(Bottom), height + , position, promptBorderWidth) +import XMonad.Prompt.Shell (shellPrompt) +import XMonad.Util.Loggers (date, logCmd) +import XMonad.Util.Run (spawnPipe) +import XMonad.Util.Themes (theme, themeAuthor, themeDescription, ThemeInfo(TI) + , themeName) +import XMonad.Util.Types (Direction1D(Next, Prev), Direction2D(L, R, U, D)) +import XMonad.StackSet (shiftMaster, greedyView, shift) + +--------------- +-- BINDINGS +--------------- + +myMod = mod4Mask -- windows key +myCtrl = controlMask +myTerminal = "urxvtc" + +-- Mouse bindings: default actions bound to mouse events +myMouseBindings (XConfig {XMonad.modMask = modMask}) = fromList $ + -- mod-button1 %! Set the window to floating mode and move by dragging + [ ((modMask, button1), (\w -> focus w >> mouseMoveWindow w + >> windows shiftMaster)) + -- mod-button2 %! Raise the window to the top of the stack + , ((modMask, button2), (\w -> focus w >> windows shiftMaster)) + -- mod-button3 %! Set the window to floating mode and resize by dragging + , ((modMask, button3), (\w -> focus w >> mouseResizeWindow w + >> windows shiftMaster)) + -- you may also bind events to the mouse scroll wheel (button4 and button5) + , ((modMask, button5), (\_ -> moveTo Next NonEmptyWS)) + , ((modMask, button4), (\_ -> moveTo Prev NonEmptyWS )) + -- scroll wheel click, bottom right corner on trackball + , ((modMask, 6), (\w -> focus w >> kill)) + , ((modMask, 8), (\w -> focus w >> kill)) + ] + +mykeys x = [ + ((myMod, xK_Left), prevWS) + , ((myMod, xK_Right), nextWS) + , ((myMod .|. shiftMask, xK_Left), shiftToPrev >> prevWS) + , ((myMod .|. shiftMask, xK_Right), shiftToNext >> nextWS) + , ((myMod, xK_a), toggleWS) + , ((myMod, xK_z), shellPrompt myXPConfig) + , ((myMod, xK_g), goToSelected myGSConfig) + , ((myMod .|. shiftMask, xK_m), sendMessage $ Toggle MIRROR) + , ((myMod .|. shiftMask, xK_g), gridselectWorkspace myGSConfig greedyView) + , ((myMod, xK_x), sendMessage ToggleStruts) + , ((myMod, xK_F1), spawn "${HOME}/.screenlayout/`hostname`-work.sh") + , ((myMod, xK_F2), spawn "${HOME}/.screenlayout/`hostname`-home.sh") + , ((myMod, xK_F3), spawn "${HOME}/.screenlayout/`hostname`-solo.sh") + , ((myMod, xK_F4), spawn "sleep 0.5 && xset dpms force suspend") + , ((myMod, xK_F5), spawn "sleep 0.5 && xset dpms force off") + , ((myMod, xK_F6), spawn "sleep 0.5 && ${HOME}/bin/icd && ${HOME}/bin/mice.sh") + , ((myMod, xK_Up), spawn "sleep 0.5 && b u") + , ((myMod, xK_Down), spawn "sleep 0.5 && b d") + , ((myMod, xK_l), spawn "slock") + , ((myMod .|. myCtrl .|. shiftMask, xK_Right), sendMessage $ Move R) + , ((myMod .|. myCtrl .|. shiftMask, xK_Left), sendMessage $ Move L) + , ((myMod .|. myCtrl .|. shiftMask, xK_Up), sendMessage $ Move U) + , ((myMod .|. myCtrl .|. shiftMask, xK_Down), sendMessage $ Move D) + , ((myMod, xK_BackSpace), focusUrgent) + , ((myMod, xK_s), sendMessage $ ToggleLayout) + , ((myMod, xK_b), submap . fromList $ + [ ((m, k), f) + | m <- [0, myMod] + , (k, f) <- [ (xK_a, addWorkspacePrompt myXPConfig) + , (xK_c, withWorkspace myXPConfig + (windows . copy)) + , (xK_d, kill1) + , (xK_k, removeWorkspace) + , (xK_m, withWorkspace myXPConfig + (windows . shift)) + , (xK_o, killAllOtherCopies) + , (xK_r, renameWorkspace myXPConfig) + , (xK_s, selectWorkspace myXPConfig) + ] + ] + )] + +dvorakify kl = fromList $ map (\((m, k), d) -> ((m, dk k), d)) $ toList kl + where + dk :: KeySym -> KeySym + dk k | k == xK_grave = xK_dollar + | k == xK_asciitilde = xK_asciitilde + + | k == xK_1 = xK_ampersand + | k == xK_exclam = xK_percent + + | k == xK_2 = xK_bracketleft + | k == xK_at = xK_7 + + | k == xK_3 = xK_braceleft + | k == xK_numbersign = xK_5 + + | k == xK_4 = xK_braceright + | k == xK_dollar = xK_3 + + | k == xK_5 = xK_parenleft + | k == xK_percent = xK_1 + + | k == xK_6 = xK_equal + | k == xK_asciicircum = xK_9 + + | k == xK_7 = xK_asterisk + | k == xK_ampersand = xK_0 + + | k == xK_8 = xK_parenright + | k == xK_asterisk = xK_2 + + | k == xK_9 = xK_plus + | k == xK_parenleft = xK_4 + + | k == xK_0 = xK_bracketright + | k == xK_parenright = xK_6 + + | k == xK_minus = xK_exclam + | k == xK_underscore = xK_8 + + | k == xK_equal = xK_numbersign + | k == xK_plus = xK_grave + + | k == xK_q = xK_semicolon -- upper row, left side + | k == xK_Q = xK_colon + + | k == xK_w = xK_comma + | k == xK_W = xK_less + + | k == xK_e = xK_period + | k == xK_E = xK_greater + + | k == xK_bracketleft = xK_slash -- upper row, top right + | k == xK_braceleft = xK_question + + | k == xK_bracketright = xK_at + | k == xK_braceright = xK_asciicircum + + | k == xK_R = xK_P + | k == xK_T = xK_Y + | k == xK_Y = xK_F + | k == xK_U = xK_G + | k == xK_I = xK_C + | k == xK_O = xK_R + | k == xK_P = xK_L + | k == xK_A = xK_A + | k == xK_S = xK_O + | k == xK_D = xK_E + | k == xK_F = xK_U + | k == xK_G = xK_I + | k == xK_H = xK_D + | k == xK_J = xK_H + | k == xK_K = xK_T + | k == xK_L = xK_N + | k == xK_Z = xK_quotedbl + | k == xK_X = xK_Q + | k == xK_C = xK_J + | k == xK_V = xK_K + | k == xK_B = xK_X + | k == xK_N = xK_B + | k == xK_M = xK_M + + | k == xK_r = xK_p + | k == xK_t = xK_y + | k == xK_y = xK_f + | k == xK_u = xK_g + | k == xK_i = xK_c + | k == xK_o = xK_r + | k == xK_p = xK_l + | k == xK_a = xK_a + | k == xK_s = xK_o + | k == xK_d = xK_e + | k == xK_f = xK_u + | k == xK_g = xK_i + | k == xK_h = xK_d + | k == xK_j = xK_h + | k == xK_k = xK_t + | k == xK_l = xK_n + | k == xK_z = xK_apostrophe + | k == xK_x = xK_q + | k == xK_c = xK_j + | k == xK_v = xK_k + | k == xK_b = xK_x + | k == xK_n = xK_b + | k == xK_m = xK_m + + | k == xK_comma = xK_w -- bottom right + | k == xK_less = xK_W + + | k == xK_period = xK_v + | k == xK_greater = xK_V + + | k == xK_slash = xK_z + | k == xK_question = xK_Z + + | otherwise = k + +------------- +-- THEMES +------------- + +-- Color names are easier to remember: +colorBlack = "#000000" +colorOrange = "#ff7701" +-- colorDarkGray = "#171717" +-- colorPink = "#e3008d" +colorGreen = "#00aa4a" +colorBlue = "#008dd5" +colorYellow = "#fee100" +colorWhite = "#cfbfad" +-- colorBrightGreen = "#00FF00" +colorRed = "#FF0000" + +xftFont = "Inconsolata:size=8" + +newTheme :: ThemeInfo +newTheme = TI "" "" "" def + +rakTheme :: ThemeInfo +rakTheme = + newTheme { themeName = "rakTheme" + , themeAuthor = "Ryan Kavanagh" + , themeDescription = "Small decorations: orange and blue theme" + , theme = def { activeColor = colorBlack + , inactiveColor = colorBlack + , activeBorderColor = colorOrange + , inactiveBorderColor = colorBlack + , activeTextColor = colorOrange + , inactiveTextColor = colorBlue + , urgentColor = colorRed + , urgentTextColor = colorYellow + , decoHeight = 13 + , fontName = "Inconsolata" + } + } + +myTheme = theme rakTheme + +myXPConfig = def { + fgColor = "white" + , bgColor = "black" + , promptBorderWidth = 0 + , position = Bottom + , height = 15 + } + +----------------- +-- LAYOUTS +----------------- + +-- My workspaces + +myWorkspaces = ["term", "web", "chatter", "reading", "5", "music", "LaTeX"] + ++ (map show [8..20]) + +-- smartBorders removes borders when there's no ambiguity +myLayout = mkToggle (single MIRROR) (smartBorders $ toggleLayouts Full + $ avoidStruts perWS) + where + -- Per workspace layout selection. + perWS = onWorkspace "term" (myTall ||| customRyan) $ + onWorkspace "web" (tabbed shrinkText myTheme + ||| mySplit ||| myTCM) $ + onWorkspace "LaTeX" latexFirst $ + customRyan + + -- Each of these allows toggling through a set of layouts + -- in the same logical order, but from a different starting point. + customRyan = myGrid ||| myDish ||| Accordion ||| myCode + ||| myFixed ||| myTall + latexFirst = myFixed ||| customRyan + + -- This is a three column mode, with the master in the middle. + myTCM = ThreeColMid 1 (3/100) (1/2) + -- This is a tall-like layout with magnification. + -- The master window is fixed at 80 columns wide, making this good + -- for coding. Limited to 3 visible windows at a time to ensure all + -- are a good size. + myCode = limitWindows 3 $ magnifiercz' 1.4 $ FixedColumn 1 20 80 10 + + -- Stack with one large master window. + -- It's easy to overflow a stack to the point that windows are too + -- small, so only show first 5. + myDish = limitWindows 5 $ Dishes nmaster ratio + where + -- The default number of windows in the master pane + nmaster = 1 + -- Default proportion of screen occupied by other panes + ratio = 1/5 + + -- Split screen, optimized for web browsing. + mySplit = magnifiercz' 1.4 $ Tall nmaster delta ratio + where + -- The default number of windows in the master pane + nmaster = 1 + -- Percent of screen to increment by when resizing panes + delta = 3/100 + -- Default proportion of screen occupied by master pane + ratio = 60/100 + + -- Standard grid. + myGrid = Grid + + myFixed = FixedColumn 1 20 80 10 + + myTall = ResizableTall nmaster delta ratio [50/100] + where + nmaster = 1 + delta = 3/100 + ratio = 1/2 + +------------------- +-- STATUS BAR +------------------- + +statusBarCmd = "dzen2" ++ + " -dock" ++ + " -bg '" ++ colorBlack ++ "'" ++ + " -fg '" ++ colorBlue ++ "'" ++ + " -sa c" ++ + " -fn '" ++ xftFont ++ "'" ++ + " -w 925 -x 0 -y 0 -ta l -e ''" + +-- dynamiclog pretty printer for dzen +mPP h = def + { ppCurrent = dzenColor colorOrange colorBlack + , ppVisible = dzenColor colorGreen colorBlack + , ppHidden = dzenColor colorBlue colorBlack + , ppUrgent = dzenColor colorRed colorBlack . wrap "[" "]" + , ppSep = dzenColor "grey60" colorBlack " ^r(1x8) " + , ppTitle = dzenColor colorWhite colorBlack . trim + , ppOrder = \(ws:l:t:d:b:o) -> [b,d,ws,l,t] ++ o + , ppExtras = [date "%H:%M:%S", batteryCheck] + , ppOutput = hPutStrLn h + } + where + batteryCheck = logCmd ("${HOME}/.dzen/battery.sh") + +--------------------- +-- GENERAL CONFIG +-------------------- + +myGSConfig :: HasColorizer a => GSConfig a +myGSConfig = (buildDefaultGSConfig defaultColorizer) { gs_navigate = navNSearch } + +myManageHook = composeAll . concat $ + [ [ className =? c --> doFloat | c <- floats] + , [ className =? c --> viewShift "web" | c <- web] + , [ className =? c --> viewShift "chatter" | c <- chatter] + , [ className =? c --> viewShift "music" | c <- music] + , [ isFullscreen --> doFullFloat ] + ] + where + viewShift = doF . liftM2 (.) greedyView shift + floats = ["MPlayer"] + web = ["Firefox", "Firefox-esr", "Navigator", "google-chrome", "Google-chrome"] + chatter = ["slack", "Slack"] + music = ["pavucontrol", "Pavucontrol"] + +myConfig dzenPipe = docks $ def { + workspaces = myWorkspaces + , modMask = myMod + , terminal = myTerminal + , normalBorderColor = inactiveBorderColor myTheme + , focusedBorderColor = activeBorderColor myTheme + , borderWidth = 1 + , layoutHook = myLayout + , manageHook = manageHook def <+> myManageHook + , mouseBindings = myMouseBindings + , keys = \x -> (fromList $ mykeys x) + `union` dvorakify (keys def x) + , logHook = dynamicLogWithPP $ mPP dzenPipe + , handleEventHook = docksEventHook + } + +main = do + dzenPipe <- spawnPipe statusBarCmd + path <- getEnv "PATH" + home <- getEnv "HOME" + setEnv "PATH" (home ++ "/bin:" ++ path) + xmonad $ myConfig dzenPipe |