dot/.config/xmonad/xmonad.hs

371 lines
16 KiB
Haskell

import XMonad
import System.Directory
import System.IO (hClose, hPutStr, hPutStrLn)
import System.Exit (exitSuccess)
import qualified XMonad.StackSet as W
import XMonad.Actions.CopyWindow (kill1)
import XMonad.Actions.CycleWS
import XMonad.Actions.GridSelect
import XMonad.Actions.MouseResize
import XMonad.Actions.Promote
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
import XMonad.Actions.SpawnOn
import XMonad.Actions.UpdatePointer
import XMonad.Actions.WindowGo (runOrRaise)
import XMonad.Actions.WithAll (sinkAll, killAll)
import qualified XMonad.Actions.Search as S
import Data.Char (isSpace, toUpper)
import Data.Maybe (fromJust)
import Data.Monoid
import Data.Maybe (isJust)
import Data.Tree
import qualified Data.Map as M
import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..))
import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
import XMonad.Hooks.ManageDocks (avoidStruts, docks, manageDocks, ToggleStruts(..))
import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat, doCenterFloat)
import XMonad.Hooks.ServerMode
import XMonad.Hooks.SetWMName
import XMonad.Hooks.StatusBar
import XMonad.Hooks.StatusBar.PP
import XMonad.Hooks.WindowSwallowing
import XMonad.Hooks.WorkspaceHistory
import XMonad.Layout.Accordion
import XMonad.Layout.GridVariants (Grid(Grid))
import XMonad.Layout.SimplestFloat
import XMonad.Layout.Spiral
import XMonad.Layout.ResizableTile
import XMonad.Layout.Tabbed
import XMonad.Layout.ThreeColumns
import XMonad.Layout.LayoutModifier
import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
import XMonad.Layout.NoBorders
import XMonad.Layout.Renamed
import XMonad.Layout.ShowWName
import XMonad.Layout.Simplest
import XMonad.Layout.Spacing
import XMonad.Layout.SubLayouts
import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
import XMonad.Layout.WindowNavigation
import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
import XMonad.Prompt
import XMonad.Prompt.OrgMode
import XMonad.Util.Dmenu
import XMonad.Util.EZConfig
import XMonad.Util.Loggers
import XMonad.Util.NamedActions
import XMonad.Util.NamedScratchpad
import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
import XMonad.Util.SpawnOnce
import XMonad.Util.ClickableWorkspaces
import Colors.DoomOne
myBorderWidth :: Dimension
myBorderWidth = 2
windowCount :: X (Maybe String)
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
--Makes setting the spacingRaw simpler to write. The spacingRaw module adds a configurable amount of space around windows.
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
tall = renamed [Replace "tall"]
$ smartBorders
-- $ windowNavigation
$ addTabs shrinkText myTabTheme
$ subLayout [] (smartBorders Simplest)
$ mySpacing 8
$ ResizableTall 1 (3/100) (1/2) []
monocle = renamed [Replace "monocle"]
$ smartBorders
$ windowNavigation
$ mySpacing 8
$ addTabs shrinkText myTabTheme
$ subLayout [] (smartBorders Simplest)
$ Full
tabs = renamed [Replace "tabs"]
-- I cannot add spacing to this layout because it will
-- add spacing between window and tabs which looks bad.
$ tabbed shrinkText myTabTheme
myTabTheme = def { fontName = "xft:Iosevka-9"
, activeColor = color15
, inactiveColor = colorBack
, activeBorderColor = color15
, inactiveBorderColor = colorFore
, activeTextColor = colorBack
, inactiveTextColor = colorFore }
myWorkspaces = ["1", "2", "3", "4", "5", "6", "7", "8", "9",
"e",
"w", "g", "d", "b", "j", "f", "o", "u",
"r", "s", "t", "h", "v", "y", "n", "a", "i", "l",
"x", "c", "m", "k", "q", "z", "p"]
myManageHook = manageSpawn <> composeAll
[ className =? "confirm" --> doFloat
, className =? "file_progress" --> doFloat
, className =? "dialog" --> doFloat
, className =? "download" --> doFloat
, className =? "error" --> doFloat
, className =? "Gimp" --> doFloat
, className =? "notification" --> doFloat
, className =? "pinentry-gtk-2" --> doFloat
, className =? "splash" --> doFloat
, className =? "toolbar" --> doFloat
, className =? "zoom" --> doFloat
, className =? "Yad" --> doCenterFloat
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
, isFullscreen --> doFullFloat
]
myStartupHook = do
setWMName "LG3D"
spawnOnce "lxsession"
spawnOnce "setxkbmap -model pc104 -layout pl -option compose:rctrl"
spawnOnce "gocryptfs ~/.bajsicki enc --extpass lxqt-openssh-askpass"
spawnOnce "feh --recursive --randomize --bg-fill /mnt/ext1/media/Images/Wallpapers/*"
spawn "killall trayer" -- kill current trayer on each
spawn ("sleep 2 && trayer --edge top --align right --widthtype request --padding 6 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 " ++ colorTrayer ++ " --height 20")
spawnOnce "dunst"
spawnOnce "picom -b"
spawnOnce "aw-server"
spawnOnce "aw-watcher-afk"
spawnOnce "aw-watcher-window"
spawnOnce "poetry run aw-watcher-spotify"
spawnOnce "/usr/bin/emacs --daemon"
spawnOn "1" "firefox-developer-edition"
spawnOn "2" "evolution"
spawnOn "9" "steam"
spawnOn "3" "discord"
spawnOn "6" "google-chrome-stable"
spawnOn "e" "/usr/bin/emacsclient"
spawnOn "j" "keepassxc"
myXmobarPP :: PP
myXmobarPP = def
{ ppSep = magenta " "
, ppTitleSanitize = xmobarStrip
, ppCurrent = xmobarBorder "Top" "#8be9fd" 2
, ppHidden = white
, ppHiddenNoWindows = lowWhite
, ppUrgent = red . wrap (yellow "!") (yellow "!")
, ppOrder = \[ws, l, _, wins] -> [ws, l, wins]
, ppExtras = [logTitles formatFocused formatUnfocused]
}
where
formatFocused = wrap (white "[") (white "]") . magenta . ppWindow
formatUnfocused = wrap (lowWhite "[") (lowWhite "]") . blue . ppWindow
-- | Windows should have *some* title, which should not not exceed a
-- sane length.
ppWindow :: String -> String
ppWindow = xmobarRaw . (\w -> if null w then "untitled" else w) . shorten 30
blue, lowWhite, magenta, red, white, yellow :: String -> String
magenta = xmobarColor "#ff79c6" ""
blue = xmobarColor "#bd93f9" ""
white = xmobarColor "#f8f8f2" ""
yellow = xmobarColor "#f1fa8c" ""
red = xmobarColor "#ff5555" ""
lowWhite = xmobarColor "#bbbbbb" ""
xmobar0 = statusBarProp "xmobar -x 0 ~/.config/xmobar/xmobarrc" (pure myXmobarPP)
xmobar1 = statusBarProp "xmobar -x 1 ~/.config/xmobar/xmobarrc-no-trayer" (pure myXmobarPP)
xmobar2 = statusBarProp "xmobar -x 2 ~/.config/xmobar/xmobarrc-no-trayer" (pure myXmobarPP)
xmobar3 = statusBarProp "xmobar -x 2 ~/.config/xmobar/xmobarrc-no-trayer" (pure myXmobarPP)
main :: IO ()
main = do
xmonad
$ ewmh
$ docks
$ withSB (xmobar0 <> xmobar1 <> xmobar2)
$ def
{ manageHook = myManageHook <+> manageDocks
, handleEventHook = swallowEventHook (className =? "Alacritty" <||> className =? "st-256color" <||> className =? "XTerm") (return True)
, modMask = mod4Mask
, terminal = "alacritty"
, startupHook = myStartupHook
, layoutHook = avoidStruts
$ windowNavigation
$ subTabbed
$ windowArrange
$ mkToggle (NBFULL ?? NOBORDERS ?? EOT)
$ withBorder myBorderWidth tall
||| noBorders monocle
||| noBorders tabs
, workspaces = myWorkspaces
, borderWidth = myBorderWidth
, normalBorderColor = colorBack
, focusedBorderColor = color15
, logHook = updatePointer (0.5, 0.5) (0, 0)
}
`additionalKeysP`
[ ("M-s 1", (windows $ W.greedyView $ myWorkspaces !! 0))
, ("M-s 2", (windows $ W.greedyView $ myWorkspaces !! 1))
, ("M-s 3", (windows $ W.greedyView $ myWorkspaces !! 2))
, ("M-s 4", (windows $ W.greedyView $ myWorkspaces !! 3))
, ("M-s 5", (windows $ W.greedyView $ myWorkspaces !! 4))
, ("M-s 6", (windows $ W.greedyView $ myWorkspaces !! 5))
, ("M-s 7", (windows $ W.greedyView $ myWorkspaces !! 6))
, ("M-s 8", (windows $ W.greedyView $ myWorkspaces !! 7))
, ("M-s 9", (windows $ W.greedyView $ myWorkspaces !! 8))
, ("M-s e", (windows $ W.greedyView $ myWorkspaces !! 9))
, ("M-s w", (windows $ W.greedyView $ myWorkspaces !! 10))
, ("M-s g", (windows $ W.greedyView $ myWorkspaces !! 11))
, ("M-s d", (windows $ W.greedyView $ myWorkspaces !! 12))
, ("M-s b", (windows $ W.greedyView $ myWorkspaces !! 13))
, ("M-s j", (windows $ W.greedyView $ myWorkspaces !! 14))
, ("M-s f", (windows $ W.greedyView $ myWorkspaces !! 15))
, ("M-s o", (windows $ W.greedyView $ myWorkspaces !! 16))
, ("M-s u", (windows $ W.greedyView $ myWorkspaces !! 17))
, ("M-s r", (windows $ W.greedyView $ myWorkspaces !! 18))
, ("M-s s", (windows $ W.greedyView $ myWorkspaces !! 19))
, ("M-s t", (windows $ W.greedyView $ myWorkspaces !! 20))
, ("M-s h", (windows $ W.greedyView $ myWorkspaces !! 21))
, ("M-s v", (windows $ W.greedyView $ myWorkspaces !! 22))
, ("M-s y", (windows $ W.greedyView $ myWorkspaces !! 23))
, ("M-s n", (windows $ W.greedyView $ myWorkspaces !! 24))
, ("M-s a", (windows $ W.greedyView $ myWorkspaces !! 25))
, ("M-s i", (windows $ W.greedyView $ myWorkspaces !! 26))
, ("M-s l", (windows $ W.greedyView $ myWorkspaces !! 27))
, ("M-s x", (windows $ W.greedyView $ myWorkspaces !! 28))
, ("M-s c", (windows $ W.greedyView $ myWorkspaces !! 29))
, ("M-s m", (windows $ W.greedyView $ myWorkspaces !! 30))
, ("M-s k", (windows $ W.greedyView $ myWorkspaces !! 31))
, ("M-s q", (windows $ W.greedyView $ myWorkspaces !! 32))
, ("M-s z", (windows $ W.greedyView $ myWorkspaces !! 33))
, ("M-s p", (windows $ W.greedyView $ myWorkspaces !! 34))
, ("M-t 1", (windows $ W.shift $ myWorkspaces !! 0))
, ("M-t 2", (windows $ W.shift $ myWorkspaces !! 1))
, ("M-t 3", (windows $ W.shift $ myWorkspaces !! 2))
, ("M-t 4", (windows $ W.shift $ myWorkspaces !! 3))
, ("M-t 5", (windows $ W.shift $ myWorkspaces !! 4))
, ("M-t 6", (windows $ W.shift $ myWorkspaces !! 5))
, ("M-t 7", (windows $ W.shift $ myWorkspaces !! 6))
, ("M-t 8", (windows $ W.shift $ myWorkspaces !! 7))
, ("M-t 9", (windows $ W.shift $ myWorkspaces !! 8))
, ("M-t e", (windows $ W.shift $ myWorkspaces !! 9))
, ("M-t w", (windows $ W.shift $ myWorkspaces !! 10))
, ("M-t g", (windows $ W.shift $ myWorkspaces !! 11))
, ("M-t d", (windows $ W.shift $ myWorkspaces !! 12))
, ("M-t b", (windows $ W.shift $ myWorkspaces !! 13))
, ("M-t j", (windows $ W.shift $ myWorkspaces !! 14))
, ("M-t f", (windows $ W.shift $ myWorkspaces !! 15))
, ("M-t o", (windows $ W.shift $ myWorkspaces !! 16))
, ("M-t u", (windows $ W.shift $ myWorkspaces !! 17))
, ("M-t r", (windows $ W.shift $ myWorkspaces !! 18))
, ("M-t s", (windows $ W.shift $ myWorkspaces !! 19))
, ("M-t t", (windows $ W.shift $ myWorkspaces !! 20))
, ("M-t h", (windows $ W.shift $ myWorkspaces !! 21))
, ("M-t v", (windows $ W.shift $ myWorkspaces !! 22))
, ("M-t y", (windows $ W.shift $ myWorkspaces !! 23))
, ("M-t n", (windows $ W.shift $ myWorkspaces !! 24))
, ("M-t a", (windows $ W.shift $ myWorkspaces !! 25))
, ("M-t i", (windows $ W.shift $ myWorkspaces !! 26))
, ("M-t l", (windows $ W.shift $ myWorkspaces !! 27))
, ("M-t x", (windows $ W.shift $ myWorkspaces !! 28))
, ("M-t c", (windows $ W.shift $ myWorkspaces !! 29))
, ("M-t m", (windows $ W.shift $ myWorkspaces !! 30))
, ("M-t k", (windows $ W.shift $ myWorkspaces !! 31))
, ("M-t q", (windows $ W.shift $ myWorkspaces !! 32))
, ("M-t z", (windows $ W.shift $ myWorkspaces !! 33))
, ("M-t p", (windows $ W.shift $ myWorkspaces !! 34))
, ("M-o", windows W.focusUp)
, ("M-a", windows W.focusDown)
, ("M-S-o", windows W.swapUp)
, ("M-S-a", windows W.swapDown)
, ("M-S-y", windows W.swapMaster)
, ("M-<Backspace>", promote)
, ("M-S-,", rotSlavesDown)
, ("M-S-.", rotAllDown)
, ("M-.", nextScreen)
, ("M-,", prevScreen)
, ("M-<Tab>", sendMessage NextLayout)
, ("M-f", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts)
, ("M-y", sendMessage Shrink)
, ("M-l", sendMessage Expand)
, ("M-b", sinkAll)
-- Sublayouts
-- This is used to push windows to tabbed sublayouts, or pull them out of it.
, ("C-S-M1-n",sendMessage $ pullGroup L)
, ("C-S-M1-i",sendMessage $ pullGroup R)
, ("C-S-M1-o",sendMessage $ pullGroup U)
, ("C-S-M1-a",sendMessage $ pullGroup D)
, ("C-S-M1-f",withFocused (sendMessage . MergeAll))
-- , ("M-C-u",withFocused (sendMessage . UnMerge))
, ("C-S-M1-u", withFocused (sendMessage . UnMergeAll))
, ("C-S-M1-j", onGroup W.focusUp')
, ("C-S-M1-y", onGroup W.focusDown')
, ("C-M1-S-0", sequence_ [spawn "xmonad --restart", spawn "xmonad --recompile"])
, ("M-S-M1-C-0", io exitSuccess)
, ("S-C-M1-q", kill1)
, ("M-S-C-M1-q", killAll)
, ("M-d", spawn "rofi -show drun")
, ("M-e", spawn "emacsclient -c -a 'emacs'")
, ("M-<Return>", spawn "alacritty")
, ("M-S-<F11>", spawn "feh --randomize --bg-fill /mnt/ext1/media/Images/Wallpapers/*")
, ("M-<Print>", spawn "dm-maim")
, ("<Print>", spawn "flameshot gui")
, ("M-j p", spawn "setxkbmap -model pc104 -layout pl -option compose:rctrl")
, ("M-j g", spawn "setxkbmap -model pc104 -layout gr -option compose:rctrl")
, ("M-c i", orgPrompt def "TODO" "~/enc/org/inbox.org")
, ("M-c l", orgPromptPrimary def "LINK" "~/enc/org/inbox.org")
, ("M-c n", orgPrompt def "NOTE" "~/enc/org/inbox.org")
, ("M-c p", orgPromptRefile def "TODO" "~/enc/org/phil.org")
-- Time! Timestamps!
, ("M-w l", spawn "sleep 0.5 && xdotool type \"$(date +'%Y.%m.%d %H:%M:%S %Z')\"")
, ("M-w e", spawn "sleep 0.5 && xdotool type \"$(TZ=America/New_York date +'%Y.%m.%d %H:%M:%S %Z')\"")
, ("M-w m", spawn "sleep 0.5 && xdotool type \"$(TZ=America/Denver date +'%Y.%m.%d %H:%M:%S %Z')\"")
, ("<XF86AudioPlay>", spawn "mpc toggle")
, ("<XF86AudioPrev>", spawn "mpc prev")
, ("<XF86AudioNext>", spawn "mpc next")
, ("<XF86AudioMute>", spawn "amixer set Master toggle")
, ("<XF86AudioLowerVolume>", spawn "pactl set-sink-volume \"bluez_output.E8_EE_CC_02_F6_8A.1\" -5%")
, ("<XF86AudioRaiseVolume>", spawn "pactl set-sink-volume \"bluez_output.E8_EE_CC_02_F6_8A.1\" +5%")
]
`additionalMouseBindings`
[ ((mod4Mask, button4), \w -> focus w >> prevWS)
, ((mod4Mask, button5), \w -> focus w >> nextWS)]