rcfiles/.xmonad/xmonad.hs

328 lines
9.8 KiB
Haskell

import XMonad
import XMonad.Actions.CopyWindow
import XMonad.Actions.DynamicProjects
import XMonad.Actions.Navigation2D
import XMonad.Actions.SinkAll
import XMonad.Actions.SpawnOn
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.StatusBar
import XMonad.Layout.Decoration
import XMonad.Layout.Hidden
import XMonad.Layout.Spacing
import XMonad.Layout.Spiral
import XMonad.Layout.ThreeColumns
import XMonad.Prompt
import XMonad.Util.EZConfig
import XMonad.Util.Loggers
import XMonad.Util.SpawnOnce
----------
-- Init --
----------
main :: IO ()
main =
xmonad
-- ewmhFullscreen and ewmh don't commute, they MUST be in this order
. dynamicProjects projects
. ewmhFullscreen
. ewmh
. withNavigation2DConfig myNav2DConf
. (`additionalKeysP` myKeybinds)
. withEasySB (statusBarProp "polybar" (pure myPolybarPP)) defToggleStrutsKey
$ myConfig
-- myConfig :: XConfig (Choose (ModifiedLayout Spacing Tall) (Choose (Mirror (ModifiedLayout Spacing Tall)) Full))
myConfig =
def
{ borderWidth = 1,
clickJustFocuses = False,
focusFollowsMouse = False,
focusedBorderColor = myFocusedBorderColor,
layoutHook = myLayout,
modMask = mod4Mask,
startupHook = myStartupHook,
normalBorderColor = myNormalBorderColor,
workspaces = myWorkspaces
}
myStartupHook :: X ()
myStartupHook = do
spawnOnce myBackground
spawnOnce myScreenLockCmd
spawnOnce notificationDaemon
------------
-- polybar --
------------
myPolybarPP :: PP
myPolybarPP =
def
{ ppCurrent = wrap "" "" . xmobarBorder "Top" blue 2,
ppExtras = [logTitles formatFocused formatUnfocused],
ppHidden = xmobarBase0 . wrap "[" "]",
ppHiddenNoWindows = const "",
ppOrder = \[ws, l, _, wins] -> [" " ++ ws, l], -- and wins to [ws, l] to get window names
ppSep = xmobarMagenta "",
ppTitleSanitize = xmobarStrip,
ppUrgent = xmobarRed . wrap (xmobarYellow "!") (xmobarYellow "!")
}
where
formatFocused :: String -> String
formatFocused = wrap (xmobarBase0 "[") (xmobarBase0 "]") . xmobarBlue . ppWindow
formatUnfocused :: String -> String
formatUnfocused = wrap (xmobarBase0 "[") (xmobarBase0 "]") . xmobarBase0 . ppWindow
ppWindow :: String -> String
ppWindow = xmobarRaw . (\w -> if null w then "untitled" else w) . shorten 30
xmobarBase0, xmobarBase2, xmobarYellow, xmobarRed, xmobarMagenta, xmobarBlue :: String -> String
xmobarBase0 = xmobarColor base0 ""
xmobarBase2 = xmobarColor base2 ""
xmobarYellow = xmobarColor yellow ""
xmobarRed = xmobarColor red ""
xmobarMagenta = xmobarColor magenta ""
xmobarBlue = xmobarColor blue ""
----------------
-- Workspaces --
----------------
myWorkspaces :: [String]
myWorkspaces = [wsSIG, wsIOG, wsMIO, wsSEC, wsLOG, wsMUS, wsREC, wsVID, wsADA]
wsIOG, wsSEC, wsSIG, wsMIO, wsLOG, wsMUS, wsREC, wsVID, wsADA :: String
wsIOG = "iog"
wsSEC = "sec"
wsSIG = "sig"
wsMIO = "mio"
wsLOG = "log"
wsMUS = "mus"
wsREC = "rec"
wsVID = "vid"
wsADA = "ada"
--------------
-- Projects --
--------------
projects :: [Project]
projects =
[ Project
{ projectName = wsIOG,
projectDirectory = "~/source/IOG",
projectStartHook = Just $ do
spawnOn wsIOG iogBrowser
spawnOn wsIOG slack
spawnOn wsIOG iogTerminal
spawnOn wsIOG iogNeomuttTerminal
},
Project
{ projectName = wsSEC,
projectDirectory = "~/.dotfiles",
projectStartHook = Just $ do spawnOn wsSEC incognitoBrowser
},
Project
{ projectName = wsSIG,
projectDirectory = "~/",
projectStartHook = Just $ do
spawnOn wsSIG signal
},
Project
{ projectName = wsMIO,
projectDirectory = "~/forge/mio-ops",
projectStartHook = Just $ do
spawnOn wsMIO browser
spawnOn wsMIO element
spawnOn wsMIO mastodon
spawnOn wsMIO mioTerminal
spawnOn wsMIO myNeomuttTerminal
},
Project
{ projectName = wsLOG,
projectDirectory = "~/",
projectStartHook = Just $ do spawnOn wsIOG myTerminal
},
Project
{ projectName = wsMUS,
projectDirectory = "~/",
projectStartHook = Just $ do spawnOn wsMUS musicPlayer
},
Project
{ projectName = wsREC,
projectDirectory = "~/Videos/obs-recordings",
projectStartHook = Just $ do spawnOn wsREC obs
},
Project
{ projectName = wsVID,
projectDirectory = "~/",
projectStartHook = Nothing
},
Project
{ projectName = wsADA,
projectDirectory = "~/",
projectStartHook = Just $ do spawnOn wsADA daedalus
}
]
promptTheme :: XPConfig
promptTheme =
def
{ bgColor = base03,
bgHLight = base02,
fgColor = base0,
fgHLight = base1,
height = 31,
position = Top,
promptBorderWidth = 0
}
------------------
-- Applications --
------------------
brightnessDown, brightnessUp, browser, discord, editor, element, hibernate, incognitoBrowser, iogBrowser, launcher, logseq, musicPlayer, notificationDaemon, obs, screenshot, signal, slack, iogNeomuttTerminal, iogTerminal, mioTerminal, myNeomuttTerminal, myTerminal, volumeDown, volumeMute, volumeUp :: String
brightnessDown = "light -U 10 ; notify-send -h int:value:$(light -G) \"Brightness\""
brightnessUp = "light -A 10 ; notify-send -h int:value:$(light -G) \"Brightness\""
browser = "firefox"
daedalus = "daedalus"
discord = "discord"
editor = "codium"
element = "element-desktop"
enableEDP1 = "xrandr --output eDP-1 --primary --auto --output HDMI-1 --off"
enableHDMI1 = "xrandr --output eDP-1 --off --output HDMI-1 --primary --mode 3840x2160"
hibernate = "sudo systemctl hibernate"
incognitoBrowser = "firefox --private-window"
iogBrowser = "brave --profile-directory='Profile 1'"
launcher = "rofi -show drun"
logseq = "logseq"
musicPlayer = "spotify"
myBackground = "feh --bg-fill ~/Documents/images/posters/auroraAustralis.jpg"
notificationDaemon = "dunst"
obs = "obs"
screenshot = "flameshot gui"
signal = "signal-desktop"
slack = "slack"
mastodon = "whalebird"
iogNeomuttTerminal = "terminology -e neomutt -F ~/.mutt/profile.IOHK"
iogTerminal = "terminology -e 'tmux new-session -f /etc/tmux.conf -c ~/source/IOG -s IOG'"
mioTerminal = "terminology -e 'tmux new-session -f /etc/tmux.conf -c ~/forge/mio-ops -s mio'"
myNeomuttTerminal = "terminology -e neomutt"
myTerminal = "terminology"
myScreenLockCmd = "xscreensaver --no-splash"
myScreenLock = "xscreensaver-command -lock"
volumeDown = "amixer set Master 2%- ; notify-send \"Volume\" -h int:value:$(amixer sget Master | awk '$0~/%/{print $5}' | tr -d '[]') -h string:x-canonical-private-synchronous:volume"
volumeMute = "amixer set Master toggle"
volumeUp = "amixer set Master 2%+ ; notify-send \"Volume\" -h int:value:$(amixer sget Master | awk '$0~/%/{print $5}' | tr -d '[]') -h string:x-canonical-private-synchronous:volume"
--------------
-- Keybinds --
--------------
myKeybinds :: [(String, X ())]
myKeybinds =
[ -- Spawn/kill
("M-b", spawn browser),
("M-i", spawn incognitoBrowser),
("M-f", spawn screenshot),
("M-p", spawn launcher),
("M-S-e", spawn enableEDP1 >> spawn myBackground ),
("M-S-h", spawn enableHDMI1 >> spawn myBackground ),
("M-S-<Return>", spawn myTerminal),
("M-<Backspace>", kill1),
-- Layout control
("M-z", sendMessage Expand),
("M-d", sendMessage NextLayout),
("M-v", sendMessage Shrink),
("M-C-S-l", spawn myScreenLock),
("M-C-d", setLayout $ Layout (layoutHook myConfig)),
("M-C-w", shiftToProjectPrompt promptTheme),
("M-w", switchProjectPrompt promptTheme),
("M-S-f", sinkAll), -- re-tile all floating windows
-- Environment controls
("<XF86AudioLowerVolume>", spawn volumeDown),
("<XF86AudioMute>", spawn volumeMute),
("<XF86AudioRaiseVolume>", spawn volumeUp),
("<XF86MonBrightnessDown>", spawn brightnessDown),
("<XF86MonBrightnessUp>", spawn brightnessUp),
("<XF86Sleep>", spawn hibernate)
]
-- Navigation
++ zipWith (makeKeybindZipper "M-" windowGo) htnsKeys dirs
++ zipWith (makeKeybindZipper "M-" windowSwap) gcrlKeys dirs
++ zipWith (makeKeybindZipper "M-C-" screenGo) htnsKeys dirs
++ zipWith (makeKeybindZipper "M-C-" windowToScreen) gcrlKeys dirs
where
makeKeybindZipper :: String -> (direction2D -> Bool -> xUnit) -> String -> direction2D -> (String, xUnit)
makeKeybindZipper startOfCmd func restOfCmd dir = (startOfCmd ++ restOfCmd, func dir True)
dirs :: [Direction2D]
dirs = [L, D, U, R]
gcrlKeys :: [String]
gcrlKeys = ["g", "c", "r", "l"]
htnsKeys :: [String]
htnsKeys = ["h", "t", "n", "s"]
------------
-- Layout --
------------
-- myLayout :: Choose (ModifiedLayout Spacing Tall) (Choose (Mirror (ModifiedLayout Spacing Tall)) Full) a
myLayout = spacedThreeColMid
||| spacedSpiral
||| tiled
||| Mirror tiled
||| Full
where
tiled = spacing 3 $ Tall nmaster delta ratio
spacedSpiral = spacing 3 $ spiral (6/7)
spacedThreeColMid = spacing 3 $ ThreeColMid nmaster delta ratio
nmaster = 1
ratio = 1 / 2
delta = 3 / 100
----------------
-- Navigation --
----------------
myNav2DConf :: Navigation2DConfig
myNav2DConf = def {defaultTiledNavigation = sideNavigation}
-------------
-- Palette --
-------------
-- solarized
base03, base02, base01, base00, base0, base1, base2, base3, yellow, orange, red, magenta, violet, blue, cyan, green :: String
base03 = "#002b36"
base02 = "#073642"
base01 = "#586e75"
base00 = "#657b83"
base0 = "#839496"
base1 = "#93a1a1"
base2 = "#eee8d5"
base3 = "#fdf6e3"
yellow = "#b58900"
orange = "#cb4b16"
red = "#dc322f"
magenta = "#d33682"
violet = "#6c71c4"
blue = "#268bd2"
cyan = "#2aa198"
green = "#859900"
-- uses of palette
myNormalBorderColor :: String
myNormalBorderColor = violet
myFocusedBorderColor :: String
myFocusedBorderColor = red