From 3a62b6bd8a617f68786b8552e9ac79050be6823c Mon Sep 17 00:00:00 2001 From: jasmine Date: Sun, 23 Feb 2025 17:26:57 +0800 Subject: [PATCH] feat: import our src configuration --- src/Main.hs | 20 ---- src/XMonadConfig/GruvboxMaterial.hs | 50 ++++++++++ src/xmobar.hs | 98 +++++++++++++++++++ src/xmonad.hs | 143 ++++++++++++++++++++++++++++ 4 files changed, 291 insertions(+), 20 deletions(-) delete mode 100644 src/Main.hs create mode 100644 src/XMonadConfig/GruvboxMaterial.hs create mode 100644 src/xmobar.hs create mode 100644 src/xmonad.hs diff --git a/src/Main.hs b/src/Main.hs deleted file mode 100644 index a5fe8ef..0000000 --- a/src/Main.hs +++ /dev/null @@ -1,20 +0,0 @@ -module Main where - -import Main.Utf8 qualified as Utf8 - -data Example = Example - { name :: Text - , age :: Int - } - deriving stock (Show, Eq) - -{- | - Main entry point. - - `just run` will invoke this function. --} -main :: IO () -main = do - -- For withUtf8, see https://serokell.io/blog/haskell-with-utf8 - Utf8.withUtf8 $ do - putTextLn "Hello 🌎 (from xmonad-config)" diff --git a/src/XMonadConfig/GruvboxMaterial.hs b/src/XMonadConfig/GruvboxMaterial.hs new file mode 100644 index 0000000..15d8f2d --- /dev/null +++ b/src/XMonadConfig/GruvboxMaterial.hs @@ -0,0 +1,50 @@ +-- | +-- Module: XMonadConfig.GruvboxMaterial +-- Author: Jasmine Marie Wilson +-- +-- Creates xmobar escape codes for use in our status bar, +-- Based on Gruvbox Material Dark and Hard by sainnhe. +module XMonadConfig.GruvboxMaterial + ( background + , foreground + , bg0 + , bg1 + , fg0 + , fg1 + , red + , orange + , yellow + , green + , aqua + , blue + , purple + , grey0 + , grey1 + , grey2 + ) where + +import XMonad.Hooks.StatusBar.PP (xmobarColor) + +background :: String +background = "#1d2021" + +foreground :: String +foreground = "#d4be98" + +bg0, bg1, fg0, fg1, red, orange, yellow, green, aqua, blue, purple, grey0, grey1, grey2 :: String -> String +{- FOURMOLU_DISABLE -} +bg0 = xmobarColor "#1d2021" "" +bg1 = xmobarColor "#282828" "" +fg0 = xmobarColor "#d4be98" "" +fg1 = xmobarColor "#ddc7a1" "" +red = xmobarColor "#ea6962" "" +orange = xmobarColor "#e78a4e" "" +yellow = xmobarColor "#d8a657" "" +green = xmobarColor "#a9b665" "" +aqua = xmobarColor "#89b482" "" +blue = xmobarColor "#7daea3" "" +purple = xmobarColor "#d3869b" "" +grey0 = xmobarColor "#7c6f64" "" +grey1 = xmobarColor "#928374" "" +grey2 = xmobarColor "#a89984" "" +{- FOURMOLU_ENABLE -} diff --git a/src/xmobar.hs b/src/xmobar.hs new file mode 100644 index 0000000..ac51265 --- /dev/null +++ b/src/xmobar.hs @@ -0,0 +1,98 @@ +import Xmobar + +import XMonad.Hooks.StatusBar.PP (wrap) + +import XMonadConfig.GruvboxMaterial + +-- | Configures how things should be displayed on the bar +config :: Config +config = + defaultConfig + { font = "Fira Code Semi Bold 9" + , additionalFonts = ["Symbols Nerd Font 2048-em 24"] + , bgColor = background + , fgColor = foreground + , position = Static {xpos = 1920, ypos = 0, width = 2560, height = 24} + , commands = myCommands + , sepChar = "%" + , alignSep = "}{" + , -- The output template is how xmobar will end up printing all of our configured commands. + template = + myLogo + ++ wrap " " " " (green "%uname%") + ++ "%uptime%" + ++ "%_XMONAD_LOG_1%" + ++ "} %date% {" + ++ "%YPJT% %disku%" + } + where + myLogo :: String + myLogo = wrap " " " " "\59255" + + -- Commands to run xmobar modules on start + myCommands :: [Runnable] + myCommands = + [ -- XPropertyLog PropName + Run $ XPropertyLog "_XMONAD_LOG_1" + , -- Com ProgramName Args Alias RefreshRate + Run $ + Com + "uname" + ["-r", "-s"] + "" + (0 `seconds`) + , -- Date Format Alias RefreshRate + Run $ + Date + (grey2 "%a %b %_d %Y " ++ yellow "%H:%M:%S") + "date" + (1 `seconds`) + , -- Weather StationID Args RefreshRate + Run $ + Weather + "YPJT" + [ "--template" + , inWrapper (ppTitle "Temp" ++ green "C") + ++ inWrapper (ppTitle "Wind" ++ purple "km/h") + ++ inWrapper (ppTitle "Humidity" ++ blue "%") + ] + (30 `minutes`) + , -- DiskU Disks Args RefreshRate + Run $ + DiskU + [ ("/", inWrapper' (ppTitle "System" ++ ppDiskSpace)) + , ("/home/sajenim", inWrapper' (ppTitle "Home" ++ ppDiskSpace)) + ] + [] + (30 `minutes`) + , -- Uptime Args RefreshRate + Run $ + Uptime + [ "--template" + , inWrapper (ppTitle "Uptime" ++ red "d h m") + ] + (60 `seconds`) + ] + where + -- Stylistic formatting + ppDiskSpace :: String + ppDiskSpace = orange "" ++ grey0 "/" ++ aqua "" + + -- Convenience functions + seconds :: Int -> Int + seconds = (* 10) + + minutes :: Int -> Int + minutes = (60 *) . seconds + + ppTitle :: String -> String + ppTitle = wrap "" ": " . grey2 + + inWrapper :: String -> String + inWrapper = wrap (grey0 " [ ") (grey0 " ] ") + + inWrapper' :: String -> String + inWrapper' = wrap (grey0 "[ ") (grey0 " ] ") + +main :: IO () +main = configFromArgs config >>= xmobar diff --git a/src/xmonad.hs b/src/xmonad.hs new file mode 100644 index 0000000..c007042 --- /dev/null +++ b/src/xmonad.hs @@ -0,0 +1,143 @@ +import Graphics.X11.ExtraTypes.XF86 +import XMonad +import XMonad.Actions.CycleWS +import XMonad.Hooks.DynamicLog +import XMonad.Hooks.EwmhDesktops +import XMonad.Hooks.ManageDocks +import XMonad.Hooks.StatusBar +import XMonad.Layout.BinarySpacePartition +import XMonad.Layout.NoBorders +import XMonad.Layout.Renamed +import XMonad.Layout.Spacing +import XMonad.StackSet qualified as W +import XMonad.Util.EZConfig (additionalKeys) +import XMonadConfig.GruvboxMaterial + +{- FOURMOLU_DISABLE -} + +-- | The main function +main :: IO () +main = xmonad + . docks + . ewmhFullscreen + . ewmh + . withSB myXmobar + $ myConfig + +myConfig = def + { modMask = myModMask + , layoutHook = myLayouts + , terminal = myTerminal + , borderWidth = myBorderWidth + , normalBorderColor = myNormalBorderColor + , focusedBorderColor = myFocusedBorderColor + , workspaces = myWorkspaces + } `additionalKeys` myKeybindings + +-- | Configuration +myTerminal = "wezterm" +myModMask = mod4Mask +myBorderWidth = 3 +myNormalBorderColor = background +myFocusedBorderColor = foreground +myWorkspaces = ["code", "chat", "web", "games", "misc"] +myLauncher = "rofi -modi run,calc -show run" +myScrot = "scrot -s '%Y%m%d_%H%M%S.png' -e 'mv $f ~/Pictures/scrots/'" +volumeDown = "pactl set-sink-volume @DEFAULT_SINK@ -10%" +volumeUp = "pactl set-sink-volume @DEFAULT_SINK@ +10%" + +-- | Keybindings +myKeybindings = + -- launching and killing programs + [ ((myModMask, xK_Return), spawn myTerminal) -- %! Launch terminal + , ((myModMask, xK_Tab ), spawn myLauncher) -- %! Launch rofi + , ((myModMask, xK_s ), spawn myScrot ) -- %! Take screenshot + , ((myModMask, xK_Escape), kill ) -- %! Close the focused window + , ((myModMask .|. controlMask, xK_Escape), io exitSuccess ) -- %! Quit xmonad + + -- multimedia + , ((noModMask, xF86XK_AudioPlay ), spawn "mpc toggle") -- %! Play/Pause music + , ((noModMask, xF86XK_AudioStop ), spawn "mpc stop" ) -- %! Stop music + , ((noModMask, xF86XK_AudioNext ), spawn "mpc next" ) -- %! Next track + , ((noModMask, xF86XK_AudioPrev ), spawn "mpc prev" ) -- %! Previous track + , ((noModMask, xF86XK_AudioLowerVolume), spawn volumeDown ) -- %! Volume down + , ((noModMask, xF86XK_AudioRaiseVolume), spawn volumeUp ) -- %! Volume up + + -- layouts + , ((myModMask, xK_t), sendMessage $ JumpToLayout "dynamic tiling" ) -- %! Jump to our tiled layout + , ((myModMask, xK_b), sendMessage $ JumpToLayout "binary space partition") -- %! Jump to our bsp layout + , ((myModMask, xK_m), sendMessage $ JumpToLayout "maximised" ) -- %! Jump to our maximized layout + , ((myModMask, xK_f), sendMessage $ JumpToLayout "fullscreen" ) -- %! Jump to our fullscreen layout + , ((myModMask .|. shiftMask, xK_t), withFocused $ windows . W.sink ) -- %! Push window back into tiling + + -- window stack + , ((myModMask, xK_Down), windows W.focusDown) -- %! Move focus to the next window + , ((myModMask, xK_Up ), windows W.focusUp ) -- %! Move focus to the previous window + , ((myModMask .|. shiftMask, xK_Down), windows W.swapDown ) -- %! Swap the focused window with the next window + , ((myModMask .|. shiftMask, xK_Up ), windows W.swapUp ) -- %! Swap the focused window with the previous window + + -- master slave + , ((myModMask, xK_space ), windows W.focusMaster ) -- %! Move focus to the master window + , ((myModMask .|. shiftMask, xK_space ), windows W.swapMaster ) -- %! Swap the focused window with the master window + , ((myModMask, xK_Page_Up ), sendMessage Shrink ) -- %! Shrink the master area + , ((myModMask, xK_Page_Down), sendMessage Expand ) -- %! Expand the master area + , ((myModMask .|. shiftMask, xK_Page_Up ), sendMessage (IncMasterN 1) ) -- %! Increase the number of windows in the master area + , ((myModMask .|. shiftMask, xK_Page_Down), sendMessage (IncMasterN (-1))) -- %! Decrease the number of windows in the master area + + -- workspaces + , ((myModMask, xK_Right), moveTo Next hiddenWS) -- %! Move focus to the next hidden workspace + , ((myModMask, xK_Left ), moveTo Prev hiddenWS) -- %! Move focus to the previous hidden workspace + , ((myModMask .|. shiftMask, xK_Right), shiftTo Next hiddenWS) -- %! Move focused window to the next hidden workspace + , ((myModMask .|. shiftMask, xK_Left ), shiftTo Prev hiddenWS) -- %! Move focused window to the previous hidden workspace + + -- monitors + , ((myModMask, xK_End ), nextScreen ) -- %! Move focus to the next screen + , ((myModMask, xK_Home), prevScreen ) -- %! Move focus to the previous screen + , ((myModMask .|. shiftMask, xK_End ), shiftNextScreen) -- %! Move focused window to the next screen + , ((myModMask .|. shiftMask, xK_Home), shiftPrevScreen) -- %! Move focused window to the previous screen + + -- binary space partition + , ((myModMask .|. mod1Mask, xK_Right ), sendMessage $ ExpandTowardsBy R 0.01) -- %! Expand window towards the right + , ((myModMask .|. mod1Mask, xK_Left ), sendMessage $ ExpandTowardsBy L 0.01) -- %! Expand window towards the left + , ((myModMask .|. mod1Mask, xK_Down ), sendMessage $ ExpandTowardsBy D 0.01) -- %! Expand window downwards + , ((myModMask .|. mod1Mask, xK_Up ), sendMessage $ ExpandTowardsBy U 0.01) -- %! Expand window upwards + , ((myModMask .|. mod1Mask .|. controlMask, xK_Right ), sendMessage $ ShrinkFromBy R 0.01) -- %! Shrink window from the right + , ((myModMask .|. mod1Mask .|. controlMask, xK_Left ), sendMessage $ ShrinkFromBy L 0.01) -- %! Shrink window from the left + , ((myModMask .|. mod1Mask .|. controlMask, xK_Down ), sendMessage $ ShrinkFromBy D 0.01) -- %! Shrink window downwards + , ((myModMask .|. mod1Mask .|. controlMask, xK_Up ), sendMessage $ ShrinkFromBy U 0.01) -- %! Shrink window upwards + , ((myModMask .|. mod1Mask, xK_Page_Up ), sendMessage Rotate ) -- %! Rotate a split (horizontal/vertical) in the BSP + , ((myModMask .|. mod1Mask, xK_Page_Down), sendMessage Swap ) -- %! Swap the left child of a split with the right child of split + , ((myModMask .|. mod1Mask, xK_Home ), sendMessage $ SplitShift Prev ) -- %! Shift window by splitting previous neighbour + , ((myModMask .|. mod1Mask, xK_End ), sendMessage $ SplitShift Next ) -- %! Shift window by splitting next neighbour + ] + +-- | Layouts +myLayouts = myTile ||| myBsp ||| myMax ||| myFull + where + -- our layouts + myTile = renamed [Replace "tile"] . avoidStruts . myGaps $ Tall nmaster delta ratio + myBsp = renamed [Replace "bsp" ] . avoidStruts . myGaps $ emptyBSP + myMax = renamed [Replace "max" ] . avoidStruts . myGaps $ Full + myFull = renamed [Replace "full"] . noBorders $ Full + -- add a configurable amount of space around windows. + myGaps = spacingRaw False (Border 10 10 10 10) True (Border 10 10 10 10) True + -- layout configuration + nmaster = 1 -- Default number of windows in the master pane + ratio = 2/3 -- Default proportion of screen occupied by master pane + delta = 3/100 -- Percent of screen to increment by when resizing panes + +-- | Statusbar +myXmobar = statusBarPropTo "_XMONAD_LOG_1" "xmobar" (pure myXmobarPP) + +myXmobarPP :: PP +myXmobarPP = def + { ppSep = grey0 " | " + , ppCurrent = purple . wrap " " "" + , ppVisible = blue . wrap " " "" + , ppHidden = grey0 . wrap " " "" + , ppHiddenNoWindows = grey0 . wrap " " "" + , ppUrgent = red . wrap " " "" + , ppLayout = aqua . wrap "" "" + , ppOrder = \[ws, l, _] -> [ws, l] + } +