diff --git a/lib/KeyBindings.hs b/lib/KeyBindings.hs new file mode 100644 index 0000000..bd8ccac --- /dev/null +++ b/lib/KeyBindings.hs @@ -0,0 +1,80 @@ + +module KeyBindings ( + KeyBindings.modify +) where + +import Data.List (sort, isSuffixOf) +import Graphics.X11.Types +import System.Exit +import Text.EditDistance +import XMonad +import XMonad.Actions.CycleWS +import XMonad.Core +import XMonad.Layout.ToggleLayouts +import XMonad.Operations +import XMonad.Prompt +import XMonad.Prompt.ConfirmPrompt +import XMonad.Prompt.Shell +import XMonad.Util.EZConfig +import qualified Solarized as S +import qualified XMonad.StackSet as W + +modify :: XConfig l -> XConfig l +modify conf = conf + { modMask = mod4Mask -- Use the "Win" key for the mod key + } + + `additionalKeysP` -- Add some extra key bindings: + [ ("M-S-q", confirmPrompt promptConfig "exit" (io exitSuccess)) + , ("-b", sendMessage (Toggle "Full")) + , ("", spawn "/run/current-system/sw/bin/xbacklight -10") + , ("", spawn "/run/current-system/sw/bin/xbacklight +10") + , ("M-", kill) + , ("M-", windows W.focusDown) + , ("M-", sendMessage (Toggle "Full")) + , ("M-$", sendMessage (Toggle "Full")) + , ("M-", prevWS) + , ("M-e", nextScreen) + , ("M-", nextWS) + , ("M-", toggleWS) + , ("M-", windows W.focusUp) + , ("M-S-", spawn "/run/current-system/sw/bin/i3lock-fancy -g -p") + , ("M-S-", shiftToPrev >> prevWS) + , ("M-S-", shiftToNext >> nextWS) + , ("M-S-p", shellPrompt promptConfig) + , ("M-S-s", spawn "sleep 0.2 ; /run/current-system/sw/bin/scrot -s /tmp/screenSel.png") + , ("M-p", fuzzyPrompt promptConfig) + , ("M-s", spawn "/run/current-system/sw/bin/scrot /tmp/screen.png") + ] + + `additionalKeys`-- Add some more (automatic) key bindings: + [ ((mod4Mask .|. mask, key), windows $ actionWith tag) + | (tag, key) <- zip (workspaces conf) [ xK_F1 .. ] + , (mask, actionWith) <- zip [ 0, shiftMask ] [ W.view, W.shift ] ] + +promptConfig = def + { position = Top + , alwaysHighlight = True + , bgColor = S.magenta + , bgHLight = S.base0 + , borderColor = S.magenta + , defaultText = "" + , fgColor = S.base02 + , fgHLight = S.base03 + , font = "xft:Fira Code:style=Regular:size=9" + , height = 24 + , promptBorderWidth = 5 + } + +-- Slightly taken from +-- https://mail.haskell.org/pipermail/xmonad/2010-October/010671.html +data FuzzySpawn = FuzzySpawn deriving (Read, Show) +instance XPrompt FuzzySpawn where showXPrompt _ = "RunC: " +fuzzyPrompt config = do + cmds <- io getCommands + let compl s + | null s = [] + | otherwise = let weight c = levenshteinDistance defaultEditCosts s c + in map snd $ take 20 $ sort $ map (\c -> (weight c,c)) cmds + mkXPrompt FuzzySpawn config (return . compl) spawn + diff --git a/lib/StatusBar.hs b/lib/StatusBar.hs new file mode 100644 index 0000000..3630562 --- /dev/null +++ b/lib/StatusBar.hs @@ -0,0 +1,66 @@ +{-# LANGUAGE FlexibleContexts #-} + +module StatusBar ( + StatusBar.modify +) where + +import Data.List +import Data.Monoid +import Solarized as S +import XMonad.Core +import XMonad.Hooks.DynamicBars (dynStatusBarStartup,dynStatusBarEventHook,multiPP) +import XMonad.Hooks.DynamicLog +import XMonad.ManageHook +import XMonad.Util.Run + +-- Type constructors +import GHC.IO.Handle (Handle) + +modify :: XConfig l -> XConfig l +modify conf = conf + { startupHook = do + startupHook conf + dynStatusBarStartup runXmobar killXmobar + , handleEventHook = handleEventHook conf <+> dynStatusBarEventHook runXmobar killXmobar + , logHook = do + logHook conf + multiPP currentPP otherPP + } + +runXmobar :: ScreenId -> IO Handle +runXmobar (S id) = spawnPipe + $ "/run/current-system/sw/bin/xmobar --screen=" + <> show id + <> " /home/eeva/.xmonad/xmobarrc" + +killXmobar :: IO () +-- killXmobar = spawn "/run/current-system/sw/bin/pkill xmobar" +killXmobar = return () + +otherPP = currentPP + { ppCurrent = xmobarColor S.blue S.base03 + } + +currentPP = def + { ppCurrent = xmobarColor' S.orange + , ppVisible = xmobarColor' S.yellow -- other screen + , ppHidden = xmobarColor' S.foreground -- other workspaces with windows + , ppHiddenNoWindows = xmobarColor' S.foregroundll -- other workspaces + , ppSep = " " + , ppWsSep = " " + , ppLayout = printLayout + , ppTitle = printTitle + } + where xmobarColor' fg = xmobarColor fg S.base03 + + printLayout s | "Mirror ResizableTall" `isSuffixOf` s = "[ — ]" + printLayout s | "ResizableTall" `isSuffixOf` s = "[ | ]" + printLayout "Full" = "[ F ]" + printLayout l = "[" ++ l ++ "]" + + printTitle t = let t' = shorten 120 t + in xmobarColor' S.foregroundll "« " + ++ xmobarColor' S.foregroundhl t' + ++ xmobarColor' S.foregroundll " »" + + diff --git a/xmonad.hs b/xmonad.hs index b400961..372ca59 100755 --- a/xmonad.hs +++ b/xmonad.hs @@ -2,20 +2,15 @@ -- including best practises. -- https://github.com/xmonad/xmonad-contrib/blob/master/XMonad/Config/Example.hs -{-# LANGUAGE FlexibleContexts, OverloadedStrings #-} - module Main (main) where import Data.Ratio ((%)) -import Data.List (sort, isSuffixOf) -import Text.EditDistance -import System.Exit import XMonad -import XMonad.Actions.CycleWS import XMonad.Actions.UpdatePointer import XMonad.Config.Desktop import XMonad.Hooks.DynamicLog import XMonad.Hooks.ManageHelpers +import XMonad.Hooks.ManageDocks (docksEventHook) import XMonad.Layout.NoBorders (noBorders, smartBorders) import XMonad.Layout.ResizableTile (ResizableTall(..)) import XMonad.Layout.Spacing @@ -24,14 +19,17 @@ import XMonad.Prompt import XMonad.Prompt.ConfirmPrompt import XMonad.Prompt.Shell import XMonad.Util.EZConfig +import XMonad.Util.Run (spawnPipe) import qualified Solarized as S -import qualified XMonad.StackSet as W -- Contructors imports -import XMonad.Core (XConfig) import XMonad.Hooks.ManageDocks (AvoidStruts) import XMonad.Layout.LayoutModifier (ModifiedLayout) +-- Tidy modules +import StatusBar as Bar (modify) +import KeyBindings as Keys (modify) + wkspcs :: [String] -------- ["●", "◕", "◑", "◔", "◯", "◐", "◒", "◓", "☦", "λ"] -------- ["α", "β", "γ", "δ", "ε", "ζ", "η", "θ", "ι", "κ"] @@ -47,40 +45,14 @@ wkspcs = [ wrap "" "" "\xF0E0" --  email , wrap "" "" "\xF03D" --  movie ] -barPP = def - { ppCurrent = xmobarColor' S.orange - , ppVisible = xmobarColor' S.yellow -- other screen - , ppHidden = xmobarColor' S.foreground -- other workspaces with windows - , ppHiddenNoWindows = xmobarColor' S.foregroundll -- other workspaces - , ppSep = " " - , ppWsSep = " " - , ppLayout = printLayout - , ppTitle = printTitle - } - where xmobarColor' fg = xmobarColor fg S.base03 - - printLayout s | "Mirror ResizableTall" `isSuffixOf` s = "[ — ]" - printLayout s | "ResizableTall" `isSuffixOf` s = "[ | ]" - printLayout "Full" = "[ F ]" - printLayout l = "[" ++ l ++ "]" - - printTitle t = let t' = shorten 120 t - in xmobarColor' S.foregroundll "« " - ++ xmobarColor' S.foregroundhl t' - ++ xmobarColor' S.foregroundll " »" - -bar :: LayoutClass l Window => XConfig l -> IO (XConfig (ModifiedLayout AvoidStruts l)) -bar conf = statusBar "xmobar /home/eeva/.xmonad/xmobarrc" barPP hideBarsKey conf - where hideBarsKey XConfig{modMask = modm} = (modm, xK_b) - lh = do - ls <- dynamicLogString def - xmonadPropLog ls updatePointer (0.5,0.5) (0,0) + logHook desktopConfig -myConfig = desktopConfig - { modMask = mod4Mask -- Use the "Win" key for the mod key - , manageHook = myManageHook <+> manageHook desktopConfig +myConfig = Bar.modify + $ Keys.modify + $ desktopConfig + { manageHook = myManageHook <+> manageHook desktopConfig , layoutHook = desktopLayoutModifiers myLayouts , logHook = lh , terminal = "/run/current-system/sw/bin/kitty" @@ -90,34 +62,6 @@ myConfig = desktopConfig , borderWidth = 5 } - `additionalKeysP` -- Add some extra key bindings: - [ ("M-S-q", confirmPrompt myXPConfig "exit" (io exitSuccess)) - , ("-b", sendMessage (Toggle "Full")) - , ("", spawn "/run/current-system/sw/bin/xbacklight -10") - , ("", spawn "/run/current-system/sw/bin/xbacklight +10") - , ("M-", kill) - , ("M-", windows W.focusDown) - , ("M-", sendMessage (Toggle "Full")) - , ("M-$", sendMessage (Toggle "Full")) - , ("M-", prevWS) - , ("M-e", nextScreen) - , ("M-", nextWS) - , ("M-", toggleWS) - , ("M-", windows W.focusUp) - , ("M-S-", spawn "/run/current-system/sw/bin/i3lock-fancy -g -p") - , ("M-S-", shiftToPrev >> prevWS) - , ("M-S-", shiftToNext >> nextWS) - , ("M-S-p", shellPrompt myXPConfig) - , ("M-S-s", spawn "sleep 0.2 ; /run/current-system/sw/bin/scrot -s /tmp/screenSel.png") - , ("M-p", fuzzyPrompt myXPConfig) - , ("M-s", spawn "/run/current-system/sw/bin/scrot /tmp/screen.png") - ] - - `additionalKeys`-- Add some more (automatic) key bindings: - [ ((mod4Mask .|. mask, key), windows $ actionWith tag) - | (tag, key) <- zip wkspcs [ xK_F1 .. ] - , (mask, actionWith) <- zip [ 0, shiftMask ] [ W.view, W.shift ] ] - myLayouts = toggleLayouts fullscreen tiled where fullscreen = (noBorders Full) @@ -125,20 +69,6 @@ myLayouts = toggleLayouts fullscreen tiled smarts = (smartSpacingWithEdge 5) . smartBorders resizableTall = ResizableTall 1 (5/100) (1/2) [] -myXPConfig = def - { position = Top - , alwaysHighlight = True - , bgColor = S.magenta - , bgHLight = S.base0 - , borderColor = S.magenta - , defaultText = "" - , fgColor = S.base02 - , fgHLight = S.base03 - , font = "xft:Fira Code:style=Regular:size=9" - , height = 24 - , promptBorderWidth = 5 - } - -- Use the `xprop' tool to get the info you need for these matches. -- For className, use the second value that xprop gives you. myManageHook = composeOne @@ -152,22 +82,10 @@ myManageHook = composeOne ] -- Finally: -main = xmonad =<< bar myConfig +main = xmonad myConfig --- Slightly taken from --- https://mail.haskell.org/pipermail/xmonad/2010-October/010671.html -data FuzzySpawn = FuzzySpawn deriving (Read, Show) -instance XPrompt FuzzySpawn where showXPrompt _ = "RunC: " -fuzzyPrompt config = do - cmds <- io getCommands - let compl s - | null s = [] - | otherwise = let weight c = levenshteinDistance defaultEditCosts s c - in map snd $ take 20 $ sort $ map (\c -> (weight c,c)) cmds - mkXPrompt FuzzySpawn config (return . compl) spawn - --- import qualified Data.Map as Map --- import XMonad --- import XMonad.Util.EZConfig