alkaa/roles/xmonad/files/xmonad_qwerty.hs

280 lines
12 KiB
Haskell

-- imports
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Actions.TopicSpace (TopicConfig (..), TopicItem (..), noAction, tiDirs, tiActions, currentTopicDir, switchNthLastFocusedByScreen, switchTopic, topicNames)
import XMonad.Actions.Search (SearchEngine, openstreetmap, hackage, wikipedia, youtube, searchEngine, promptSearch, selectSearch)
import XMonad.Hooks.DynamicLog (PP(..), dynamicLogWithPP, filterOutWsPP, xmobarPP, xmobarColor, wrap, shorten)
import XMonad.Hooks.ManageDocks (ToggleStruts(..), avoidStruts, docks)
import XMonad.Hooks.DynamicProperty (dynamicPropertyChange)
import XMonad.Hooks.SetWMName (setWMName)
import XMonad.Hooks.WorkspaceHistory (workspaceHistoryHook)
import XMonad.Layout.Spacing (Spacing, spacingRaw, Border (..))
import XMonad.Layout.LayoutModifier (ModifiedLayout)
import XMonad.Layout.Renamed (renamed, Rename (..))
import XMonad.Layout.NoBorders (noBorders, smartBorders)
import XMonad.Util.WorkspaceCompare ( getSortByIndex, filterOutWs )
import XMonad.Util.NamedScratchpad (NamedScratchpad (NS), customFloating, defaultFloating, namedScratchpadAction, namedScratchpadManageHook)
import XMonad.Util.Run (proc, inProgram, termInDir, (>-$), (>->), execute, spawnPipe, spawnExternalProcess, hPutStrLn)
import XMonad.Util.Cursor (setDefaultCursor)
import XMonad.Util.SpawnOnce (spawnOnce)
import XMonad.Util.EZConfig (additionalKeysP)
import XMonad.Prompt (XPConfig (..), mkXPrompt, mkComplFunFromList', XPPosition (..))
import XMonad.Prompt.Workspace (Wor(..))
import XMonad.Prompt.FuzzyMatch (fuzzyMatch, fuzzySort)
import XMonad.Prompt.Shell (shellPrompt, unsafePrompt)
import Text.Regex.Posix ((=~))
-- variables
myTerminal = "alacritty"
myBrowser = "librewolf"
myBorderWidth = 1
myModMask = mod4Mask
white = "#dcdccc"
yellow = "#efef8f"
orange = "#ffcfaf"
red = "#dca3a3"
blue = "#8cd0d3"
darkBlue = "#8c8cbc"
green = "#7f9f7f"
grey = "#3f3f3f"
darkGrey = "#262626"
-- scratchpads
myScratchpads :: [NamedScratchpad]
myScratchpads =
[ NS "cmus" "alacritty -n cmus -e cmus" (resource =? "cmus") (customFloating $ W.RationalRect (1/6) (1/6) (4/6) (4/6))
, NS "nnn" "alacritty -t nnn -e run_in_bash n" (title =? "nnn") (customFloating $ W.RationalRect (1/4) (1/6) (2/4) (4/6))
, NS "neomutt" "alacritty -t neomutt -e neomutt -f posteo-Inbox" (title =? "neomutt") (customFloating $ W.RationalRect (1/10) (1/10) (8/10) (8/10))
, NS "vimwiki" "alacritty -t vimwiki -e run_in_bash vw" (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 "qalculate" "qalculate-gtk" (title =? "Qalculate!") (customFloating $ W.RationalRect (3/6) (1/6) (1/6) (1/6))
, NS "pavucontrol" "pavucontrol" (title =? "Lautstärkeregler") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
]
-- 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 myBrowser) *> 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)
, TI "brass" "~/projekte/brass" (switchToLayout "Programming" *> spawnShell *> spawnEditor)
, TI "infra" "~/projekte/infrastruktuuri" (switchToLayout "Programming" *> spawnShell *> spawnEditor)
]
myTopicConfig :: TopicConfig
myTopicConfig = def
{ topicDirs = tiDirs topicItems
, topicActions = tiActions topicItems
, defaultTopicAction = const (pure ())
, defaultTopic = "1"
}
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
, fgColor = white
, fgHLight = grey
, bgHLight = red
, alwaysHighlight = True
, font = "xft:Iosevka-11"
, height = 25
, position = CenteredAt 0.45 0.3
, promptBorderWidth = myBorderWidth
, borderColor = red
, maxComplRows = Just 10
, maxComplColumns = Just 1
, searchPredicate = fuzzyMatch
, sorter = fuzzySort
}
-- search
searx :: SearchEngine
searx = searchEngine "searx" "https://search.tfld.de/search?q="
wiktionary :: SearchEngine
wiktionary = searchEngine "wiktionary" "https://wiktionary.org/w/index.php?search="
searchList :: [(String, SearchEngine)]
searchList = [ ("o", openstreetmap)
, ("h", hackage)
, ("w", wikipedia)
, ("y", youtube)
, ("s", searx)
, ("t", wiktionary)
]
-- 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 "dmenu_run")
, ("M-p s", spawn "dmenu_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-a", namedScratchpadAction myScratchpads "keepassxc")
, ("M-n", namedScratchpadAction myScratchpads "nnn")
, ("M-s a", namedScratchpadAction myScratchpads "pavucontrol")
, ("M-s q", namedScratchpadAction myScratchpads "qalculate")
-- some shortcuts for prorgrams
, ("M-S-<Return>", spawnShell)
, ("M-b", spawn myBrowser)
-- layout
, ("M-t t", switchToLayout "Tall")
, ("M-t p", switchToLayout "Programming")
, ("M-t f", switchToLayout "Full")
, ("M-S-f", withFocused $ windows . W.sink)
-- media keys
, ("<XF86AudioMute>", spawn "pamixer -t")
, ("<XF86AudioLowerVolume>", spawn "pamixer -d 5")
, ("<XF86AudioRaiseVolume>", spawn "pamixer -i 5")
, ("<XF86AudioMicMute>", spawn "pamixer --default-source -t")
-- 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-")]
]
-- Search commands
++ [("M-d " ++ k, promptSearch topicPrompt f) | (k,f) <- searchList ]
++ [("M-S-d " ++ k, selectSearch f) | (k,f) <- searchList ]
-- Layouts
mySpacing :: Integer -> l a -> 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 $ Tall 1 (3/100) (6/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" ]
, [ (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"]
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 {
terminal = myTerminal,
borderWidth = myBorderWidth,
modMask = myModMask,
workspaces = topicNames topicItems,
normalBorderColor = white,
focusedBorderColor = red,
layoutHook = myLayout,
manageHook = myManageHook,
handleEventHook = myEventHook,
logHook = workspaceHistoryHook >> dynamicLogWithPP (filterOutWsPP ["NSP"] $ xmobarPP {
ppCurrent = xmobarColor red "" . wrap "[ " " ]",
ppHidden = xmobarColor blue "",
ppLayout = xmobarColor darkBlue "",
ppTitle = xmobarColor orange "" . shorten 90,
ppSep = " | ",
ppOutput = hPutStrLn xmproc
}),
startupHook = myStartupHook
} `additionalKeysP` myAdditionalKeys