alkaa/roles/xmonad/files/xmonad_qwerty.hs

264 lines
11 KiB
Haskell

{-# LANGUAGE BlockArguments #-}
-- Imports
import XMonad
import Data.Monoid
import System.Exit
import XMonad.Util.Run
import XMonad.Util.SpawnOnce
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Layout.Spacing
import XMonad.Layout.ThreeColumns
import XMonad.Layout.LayoutModifier
import XMonad.Layout.Renamed
import XMonad.Hooks.SetWMName
import XMonad.Util.Cursor
import XMonad.Layout.NoBorders
import XMonad.Layout.PerWorkspace
import XMonad.Layout.LimitWindows
import XMonad.Hooks.EwmhDesktops
import XMonad.Util.EZConfig
import XMonad.Util.NamedScratchpad
import XMonad.Actions.TopicSpace
import XMonad.Prompt
import XMonad.Prompt.FuzzyMatch
import XMonad.Prompt.Workspace
import XMonad.Prompt.Shell
import XMonad.Hooks.WorkspaceHistory (workspaceHistoryHook)
import XMonad.Hooks.DynamicProperty
import qualified XMonad.StackSet as W
import qualified Data.Map as M
import Text.Regex.Posix
import XMonad.Util.WorkspaceCompare ( getSortByIndex, filterOutWs )
-- variables
myTerminal = "alacritty"
myBorderWidth = 1
myNormalBorderColor = "#dcdccc"
myFocusedBorderColor = "#dca3a3"
myModMask = mod4Mask
-- scratchpads
myScratchpads :: [NamedScratchpad]
myScratchpads =
[ NS "cmus" "st -n cmus -e cmus" (resource =? "cmus") (customFloating $ W.RationalRect (1/6) (1/6) (4/6) (4/6))
, NS "nnn" "st -t nnn -e nnnwrapper" (title =? "nnn") (customFloating $ W.RationalRect (1/4) (1/6) (2/4) (4/6))
, NS "neomutt" "st -t neomutt -e neomutt -f posteo-Inbox" (title =? "neomutt") (customFloating $ W.RationalRect (1/10) (1/10) (8/10) (8/10))
, NS "vimwiki" "st -t vimwiki -e vwwrapper" (title =? "vimwiki") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
, NS "keepassxc" "keepassxc ~/dokumente/Database.kdbx" (title =? "Database.kdbx - KeePassXC" <||> title =? "Database.kdbx [Gesperrt] - KeePassXC") defaultFloating
, NS "discord" "firejail discord" (title *!? "Discord") (customFloating $ W.RationalRect (1/10) (1/10) (8/10) (8/10))
]
-- Topic Space
topicItems :: [TopicItem]
topicItems =
[ noAction "1" "~/"
, noAction "2" "~/"
, noAction "3" "~/"
, noAction "4" "~/"
, noAction "5" "~/"
, TI "recipes" "~/projekte/recipes" (switchToLayout "Programming" *> spawnShellAndExecute "hugo server" *> proc (inProgram "librewolf") *> spawnEditor)
, TI "alkaa" "~/projekte/alkaa" (switchToLayout "Programming" *> spawnShell *> spawnEditor)
, TI "steam" "~" (switchToLayout "Steam" *> spawn "steam")
, TI "game" "~" (switchToLayout "Full")
, TI "micro" "~/projekte/microcontroller" (switchToLayout "Programming" *> spawnShell *> spawnEditor)
, TI "aoc" "~/projekte/aoc" (switchToLayout "Programming" *> spawnShell *> spawnEditor)
]
myTopicConfig :: TopicConfig
myTopicConfig = def
{ topicDirs = tiDirs topicItems
, topicActions = tiActions topicItems
, defaultTopicAction = const (pure ()) -- by default, do nothing
, defaultTopic = "1" -- fallback
}
spawnShell :: X ()
spawnShell = proc $ termInDir >-$ currentTopicDir myTopicConfig
spawnEditor :: X ()
spawnEditor = proc $ (termInDir >-$ currentTopicDir myTopicConfig) >-> execute "nvim"
switchToLayout :: String -> X ()
switchToLayout = sendMessage . JumpToLayout
spawnShellAndExecute :: String -> X ()
spawnShellAndExecute cmd = proc $ (termInDir >-$ currentTopicDir myTopicConfig) >-> execute cmd
toggleTopic :: X ()
toggleTopic = switchNthLastFocusedByScreen myTopicConfig 1
myWorkSpacePrompt :: XPConfig -> (String -> X ()) -> X ()
myWorkSpacePrompt c job = do ws <- gets (W.workspaces . windowset)
sort <- getSortByIndex
let filter = filterOutWs ["1", "2", "3", "4", "5", "NSP"]
let ts = map W.tag $ filter ws
mkXPrompt (Wor "") c (mkComplFunFromList' c ts) job
topicPrompt :: XPConfig
topicPrompt = def
{ historySize = 0 -- No history in the prompt.
, fgColor = "#dcdccc"
, fgHLight = "#3f3f3f"
, bgHLight = "#dca3a3"
, alwaysHighlight = True -- Current best match
, font = "xft:Iosevka-11"
, height = 25
, position = CenteredAt 0.45 0.3
, promptBorderWidth = myBorderWidth -- Fit in with rest of config
, borderColor = "#dca3a3"
, maxComplRows = Just 10 -- Max rows to show in completion window
, maxComplColumns = Just 1
, searchPredicate = fuzzyMatch
, sorter = fuzzySort
}
-- keybindings
myAdditionalKeys :: [(String, X ())]
myAdditionalKeys =
-- xmonad specific
[ ("M-q", spawn "xmonad --recompile; xmonad --restart")
, ("M-S-c", kill)
, ("M-j", windows W.focusDown)
, ("M-k", windows W.focusUp)
, ("M-S-j", windows W.swapDown)
, ("M-S-k", windows W.swapUp)
, ("M-h", sendMessage Shrink)
, ("M-l", sendMessage Expand)
, ("M-,", sendMessage (IncMasterN 1))
, ("M-S-,", sendMessage (IncMasterN (-1)))
, ("M-.", sendMessage ToggleStruts)
-- dmenu prompts
, ("M-<Return>", spawn "dm-recent-aliases")
, ("M-p p", shellPrompt topicPrompt)
, ("M-p s", spawn "dm-screenshot")
, ("M-p k", spawn "dm-kill")
-- scratchpads
, ("M-s c", namedScratchpadAction myScratchpads "cmus")
, ("M-s m", namedScratchpadAction myScratchpads "neomutt")
, ("M-s v", namedScratchpadAction myScratchpads "vimwiki")
, ("M-s d", namedScratchpadAction myScratchpads "discord")
, ("M-S-a", namedScratchpadAction myScratchpads "keepassxc")
, ("M-n", namedScratchpadAction myScratchpads "nnn")
-- some shortcuts for prorgrams
, ("M-S-<Return>", spawnShell)
, ("M-b", spawn "librewolf")
-- layout
, ("M-t t", switchToLayout "Tall")
, ("M-t h", switchToLayout "Programming")
, ("M-t f", switchToLayout "Full")
, ("M-S-f", withFocused $ windows . W.sink)
-- media keys
, ("<XF86AudioMute>", spawn "amixer sset Master toggle")
, ("<XF86AudioLowerVolume>", spawn "amixer sset Master 5%- unmute")
, ("<XF86AudioRaiseVolume>", spawn "amixer sset Master 5%+ unmute")
, ("<XF86AudioMicMute>", spawn "amixer sset Capture toggle")
, ("M-S-m", spawn "amixer sset Capture toggle")
-- lock screen
, ("M-S-l", spawn "slock")
-- workspace switching
, ("M-<Tab>", toggleTopic)
, ("M-<Space>", myWorkSpacePrompt topicPrompt (switchTopic myTopicConfig))
, ("M-S-<Space>", myWorkSpacePrompt topicPrompt (windows . W.shift))
]
++
-- use 1-5 for switching (Shift Mod shifts into) workspaces 1-5
[ ("M-" ++ m ++ k, f i)
| (i, k) <- zip (topicNames topicItems) (map show [1 .. 5 :: Int])
, (f, m) <- [(switchTopic myTopicConfig, ""), (windows . W.shift, "S-")]
]
-- Layouts
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
mySpacing i = spacingRaw True (Border i i i i) True (Border i i i i) True
myLayout = avoidStruts $ tiling ||| hacking ||| full ||| steam
where
tiling = renamed [Replace "Tall"] $ smartBorders $ mySpacing 6 $ Tall 1 (3/100) (1/2)
hacking = renamed [Replace "Programming"] $ smartBorders $ mySpacing 6 $ Tall 1 (3/100) (5/8)
full = noBorders Full
steam = renamed [Replace "Steam"] $ noBorders $ mySpacing 3 $ limitWindows 2 $ ThreeCol 1 (3/100) (5/8)
-- Regex lifted up to use in manageHook
(*!?) :: Functor f => f String -> String -> f Bool
q *!? x = fmap (=~ x) q
-- window rules
myManageHook = composeAll . concat $
[ [ resource =? "desktop_window" --> doIgnore ]
, [ resource =? "kdesktop" --> doIgnore ]
, [ ( className =? "LibreWolf" <&&> role =? "Organizer" ) --> doFloat ]
-- Steam and games
, [ className =? "Steam" --> doShift "steam" ]
, [ ( className =? "Steam" <&&> title *!? "Friends List" <||> title *!? "News" ) --> doF W.swapDown ]
, [ title =? t <&&> title *!? t --> doShift "game" | t <- myGames ]
-- float specific classes
, [ className =? c --> doFloat | c <- myFloatingClasses ]
-- scratchpads
, [ namedScratchpadManageHook myScratchpads ]
]
where
role = stringProperty "WM_WINDOW_ROLE"
myFloatingClasses = ["Gimp", "Origin"]
myGames = ["Grim Dawn", "Der Herr der Ringe Online™", "Dota 2", "Project Zomboid", "Valheim", "Factorio", "Path of Exile", "Paradox Launcher", "Europa Universalis IV", "Bannerlord"]
------------------------------------------------------------------------
-- Event handling
-- * EwmhDesktops users should change this to ewmhDesktopsEventHook
--
-- Defines a custom handler function for X Events. The function should
-- return (All True) if the default handler is to be run afterwards. To
-- combine event hooks use mappend or mconcat from Data.Monoid.
--
myEventHook = dynamicPropertyChange "WM_NAME" (title =? "Database.kdbx - KeePassXC" <||> title =? "Database.kdbx [Gesperrt] - KeePassXC" --> floating)
where floating = customFloating $ W.RationalRect (1/8) (1/8) (3/4) (3/4)
-- Startup hook
myStartupHook = do
setWMName "LG3D"
setDefaultCursor xC_left_ptr
spawnOnce("redshift -c /home/max/.config/redshift/redshiftrc")
spawnOnce("feh --bg-fill ~/bilder/bg.jpg")
spawnOnce("/usr/bin/syncthing -no-browser -logfile=default")
-- Main
main = do
xmproc <- spawnPipe "xmobar /home/max/.config/xmobar/xmobarrc"
xmonad $ spawnExternalProcess def $ docks $ def {
-- simple stuff
terminal = myTerminal,
borderWidth = myBorderWidth,
modMask = myModMask,
workspaces = topicNames topicItems,
normalBorderColor = myNormalBorderColor,
focusedBorderColor = myFocusedBorderColor,
-- hooks, layouts
layoutHook = myLayout,
manageHook = myManageHook,
handleEventHook = myEventHook,
logHook = workspaceHistoryHook >> (dynamicLogWithPP $ filterOutWsPP ["NSP"] $ xmobarPP {
ppCurrent = xmobarColor "#dca3a3" "" . wrap "[ " " ]",
ppHidden = xmobarColor "#8cd0d3" "",
ppLayout = xmobarColor "#8c8cbc" "",
ppTitle = xmobarColor "#ffcfaf" "" . shorten 90,
ppSep = " | ",
ppOutput = hPutStrLn xmproc
}),
startupHook = myStartupHook
} `additionalKeysP` myAdditionalKeys