xmonad-masser/src/XMonad/Config/MasseR.hs

277 lines
12 KiB
Haskell
Raw Normal View History

2019-06-03 15:27:18 +03:00
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
2019-03-19 10:10:18 +02:00
module XMonad.Config.MasseR where
2019-04-08 12:10:55 +03:00
import Control.Lens ((^.))
import Data.Generics.Product (field)
2019-03-19 10:10:18 +02:00
import qualified Data.List as List
import XMonad
import XMonad.Actions.CycleWS (swapNextScreen)
import XMonad.Actions.Search
2019-04-08 12:10:55 +03:00
import XMonad.CustomPrompt
2019-03-19 10:10:18 +02:00
import XMonad.Hooks.EwmhDesktops (ewmh, ewmhDesktopsStartup)
import XMonad.Hooks.SetWMName (setWMName)
import XMonad.Hooks.UrgencyHook (args, dzenUrgencyHook,
withUrgencyHook)
import XMonad.Layout.Accordion
import XMonad.Layout.BinarySpacePartition (emptyBSP)
import XMonad.Layout.Decoration (Decoration,
DefaultShrinker)
import XMonad.Layout.DwmStyle
import XMonad.Layout.LayoutModifier (ModifiedLayout)
import XMonad.Layout.Master
2019-06-03 15:27:18 +03:00
import XMonad.Layout.NoBorders (noBorders, smartBorders)
2019-03-19 10:10:18 +02:00
import XMonad.Layout.PerWorkspace (onWorkspace)
import XMonad.Layout.Renamed
import XMonad.Layout.Simplest (Simplest)
import XMonad.Layout.Spiral
import XMonad.Layout.Tabbed (TabbedDecoration,
Theme (..), shrinkText,
tabbed)
2019-06-03 15:27:18 +03:00
import XMonad.Layout.ToggleLayouts (ToggleLayout (..),
toggleLayouts)
2019-04-08 12:10:55 +03:00
import XMonad.Password
2019-03-19 10:10:18 +02:00
import XMonad.Prompt.RunOrRaise (runOrRaisePrompt)
2019-11-19 12:57:05 +02:00
import XMonad.Prompt.Shell (shellPrompt)
2019-03-19 10:10:18 +02:00
import qualified XMonad.StackSet as W
2019-04-08 12:10:55 +03:00
import XMonad.TopicSpace
2019-03-19 10:10:18 +02:00
import XMonad.Util.EZConfig
2019-04-08 12:10:55 +03:00
import XMonad.XMobar (zenburnPP)
2019-03-19 10:10:18 +02:00
import Data.Monoid (Endo, (<>))
import XMonad.Util.NamedScratchpad
import XMonad.Util.SpawnOnce
import System.IO (hClose, hPutStr)
import XMonad.Actions.Navigation2D
2019-08-23 13:05:58 +03:00
import XMonad.Actions.UpdatePointer (updatePointer)
2019-03-19 10:10:18 +02:00
import XMonad.Util.NamedActions
import XMonad.Util.Run (spawnPipe)
import XMonad.Config.MasseR.ExtraConfig
-- import Customizations
import qualified Data.Text as T
import XMonad.Hooks.DynamicLog (statusBar)
import qualified Data.Set as S
2019-05-13 08:48:06 +03:00
spotify :: ExtraConfig -> XConfig l -> NamedAction
spotify extraConf conf = submapName . mkNamedKeymap conf $
[ ("M-p", addName "Play" $ spawn (musicToggle . applications $ extraConf)) ]
2019-03-19 10:10:18 +02:00
scratchpads :: [NamedScratchpad]
scratchpads = [
NS "notes" "vim -g --role notes -c 'e ~/wikidata/index.md'" (wmRole =? "notes") nonFloating
]
where wmRole = stringProperty "WM_WINDOW_ROLE"
scratchSubmaps :: XConfig l -> NamedAction
scratchSubmaps conf = submapName . mkNamedKeymap conf $ [
("M-n", addName "Open notes" $ namedScratchpadAction scratchpads "notes")
]
-- Search engines inside submaps
2019-03-21 23:36:00 +02:00
searchSubmaps :: ExtraConfig -> XConfig l -> NamedAction
searchSubmaps extraConfig conf =
2019-04-08 12:10:55 +03:00
let mkBrowser = promptSearchBrowser def (extraConfig ^. field @"applications" . field @"browser")
2019-03-19 10:10:18 +02:00
_googleP = addName "Search google" $ mkBrowser google
2019-11-19 12:57:05 +02:00
_ddgP = addName "Search duckduckgo" $ mkBrowser (searchEngine "duckduckgo" "http://duckduckgo.com/?q=")
2019-10-04 09:28:43 +03:00
searx = addName "Search searx" $ mkBrowser (searchEngine "searx" "https://searx.me/?q=")
2019-03-21 23:36:00 +02:00
extras = [(key, addName name $ mkBrowser (searchEngine name url)) | Search{..} <- searchEndpoints extraConfig]
2019-03-19 10:10:18 +02:00
in submapName . mkNamedKeymap conf $
2019-10-04 09:28:43 +03:00
[ ("d", searx) -- Training to use ddg again
, ("g", searx) -- training to use ddg again
2019-03-21 23:36:00 +02:00
] ++ extras
2019-03-19 10:10:18 +02:00
myNav2d :: Navigation2DConfig
myNav2d = def { defaultTiledNavigation = lineNavigation }
showKeybindings :: [((KeyMask, KeySym), NamedAction)] -> NamedAction
showKeybindings x = addName "Show keybindings" $ io $ do
h <- spawnPipe "zenity --text-info --font=terminus"
hPutStr h (unlines $ showKm x)
hClose h
-- Layout
myTabConfig :: Theme
myTabConfig = def {
activeBorderColor = "#DCDCCC"
, activeTextColor = "#DCDCCC"
, activeColor = "#3F3F3F"
, fontName = "xft:Inconsolata-9"
, inactiveBorderColor = "#262626"
, inactiveTextColor = "#9FAFAF"
, inactiveColor = "#262626"
}
(=~?) :: XMonad.Query String -> String -> XMonad.Query Bool
q =~? x = fmap (x `List.isInfixOf`) q
-- Manage hooks
-- Move programs to their workspaces
myManageHook :: XMonad.Query (Endo WindowSet)
myManageHook = composeAll $ concat [
dynamicsHook
, webHooks
, pdfHooks
, documentHooks
, floatHooks
, debuggerHooks
, ideHooks
, flowHook
]
where
classHook y = map (\x -> className =? x --> y)
ideHooks = classHook (doShift "eclipse") [
"Anypoint Studio"
]
webHooks = classHook (doShift "web") [
"Firefox"
, "qutebrowser"
, "Midori"
, "chromium-browser"
, "Uzbl-tabbed"
, "Uzbl-core"
]
pdfHooks = classHook (doShift "pdf") [
"Evince"
, "Okular"
, "Kpdf"
, "Xdvi"
, ".zathura-wrapped_"
]
documentHooks = classHook (doShift "documents") [
"libreoffice"
, "libreoffice-calc"
, "Assistant"
, "Bouml"
]
floatHooks = classHook doFloat [
"SMplayer"
, "Gimp"
, "MPlayer"
, "Kaffeine"
, "Xmessage"
, "Wfica_Seamless"
, "mpv"
]
debuggerHooks = classHook (doShift "debugger") [
"JSwat Debugger",
"DBeaver"
]
dynamicsHook = [title =~? "Dynamics" --> doShift "dynamics"]
flowHook = [title =~? "www.flowdock.com" --> doShift "flowdock"]
myKeys :: ExtraConfig -> XConfig l -> [((KeyMask, KeySym), NamedAction)]
myKeys extraConfig conf =
let subKeys str ks = subtitle str : mkNamedKeymap conf ks in
2019-03-19 11:02:08 +02:00
subKeys "Actions" [ ("M-S-r", addName "foobar" (recompile True >> spawn "xmonad --restart"))
2019-03-19 10:10:18 +02:00
, ("M-C-l", addName "Lock screen" $ spawn locker)] ^++^
subKeys "System" [ ("<XF86Sleep>", addName "Suspend machine" $ spawn "sudo pm-suspend")
, ("<XF86AudioRaiseVolume>", addName "Increase volume" $ spawn "amixer set Master 2%+")
, ("<XF86AudioLowerVolume>", addName "Decrease volume" $ spawn "amixer set Master 2%-")
, ("M-<plus>", addName "Increase volume" $ spawn "amixer set Master 2+")
, ("M-<minus>", addName "Decrease volume" $ spawn "amixer set Master 2-")
, ("<XF86AudioPlay>", addName "Play/pause mopidy" $ spawn "mpc toggle")
2019-05-13 08:48:06 +03:00
, ("M-m", spotify extraConfig conf)
2019-03-19 10:10:18 +02:00
, ("M-S-<Space>", addName "Swap screens" swapNextScreen)
, ("M-<Backspace>", addName "Kill window" kill)
-- scrot requires `unGrab`
, ("M-<Print>", addName "Take screenshot" $ spawn (screenshot . applications $ extraConfig))] ^++^
2019-11-19 12:57:05 +02:00
subKeys "Launchers" [ ("M-S-<Return>", addName "Open terminal" $ spawn $ XMonad.terminal conf)
2019-03-19 10:10:18 +02:00
, ("M-n", scratchSubmaps conf)
2019-03-21 23:36:00 +02:00
, ("M-s", searchSubmaps extraConfig conf)
2019-03-19 10:10:18 +02:00
, ("M-p", addName "Retrieve password" $ passPrompt def)
2019-11-19 12:57:05 +02:00
, ("M-e", addName "Run app" $ runOrRaisePrompt def)
, ("M-S-e", addName "Run shell command" $ shellPrompt def)] ^++^
2019-03-19 10:10:18 +02:00
subKeys "Windows" [ ("M-j", addName "Go down" $ windowGo D False)
, ("M-k", addName "Go up" $ windowGo U False)
, ("M-h", addName "Go left" $ windowGo L False)
, ("M-l", addName "Go right" $ windowGo R False)
, ("M-S-j", addName "Shift window down" $ windowSwap D False)
, ("M-S-k", addName "Shift window up" $ windowSwap U False)
, ("M-S-h", addName "Shift window left" $ windowSwap L False)
, ("M-S-l", addName "Shift window right" $ windowSwap R False)
, ("M-.", addName "Go to previous window" $ windows W.focusDown)
, ("M-,", addName "Go to next window" $ windows W.focusUp)
, ("M-S-m", addName "Swap master" $ windows W.swapMaster)
] ^++^
subKeys "Projects & Workspaces" (topicKeys' extraConfig conf) ^++^
subKeys "Layout management" [ ("M-C-<Space>", addName "Toggle layout" $ sendMessage ToggleLayout)
2019-06-03 15:27:18 +03:00
, ("M-z", addName "Toggle zoom" $ sendMessage (Toggle "Zoom"))
2019-03-19 10:10:18 +02:00
, ("M-<Space>", addName "Next layout" $ sendMessage NextLayout)] ^++^
subKeys "Resize" []
where
2019-08-09 16:31:38 +03:00
locker = "xset s activate"
2019-03-19 10:10:18 +02:00
myStartupHook :: X ()
myStartupHook = spawnOnce "$HOME/wminit"
masser :: ExtraConfig -> IO ()
masser extraConfig = xmonad =<< statusBar (bar extraConfig) zenburnPP toggleStrutsKey myConfig
where
toggleStrutsKey XConfig{modMask=modm} = (modm, xK_b)
bar = prompt . applications
myConfig = withUrgencyHook dzenUrgencyHook { args = ["-bg", "darkgreen", "-xs", "1"]} $
withNavigation2DConfig myNav2d $
ewmh $
addDescrKeys' ((mod4Mask, xK_F1), showKeybindings) (myKeys extraConfig) $
def {
modMask = mod4Mask -- Hyper
, terminal = urxvt . applications $ extraConfig
, keys = const mempty
, workspaces = let defaults = ["irc", "web", "mail"]
external = map (T.unpack . topicName) . topics $ extraConfig
in S.toList (S.fromList defaults <> S.fromList external)
, layoutHook = smartBorders myLayout
, clickJustFocuses = False
, startupHook = myStartupHook >> ewmhDesktopsStartup >> setWMName "LG3D"
, borderWidth = 2
, normalBorderColor = "#262626"
, focusedBorderColor = "#7F9F7F"
, manageHook = myManageHook
2019-08-23 13:05:58 +03:00
, focusFollowsMouse = True
, logHook = updatePointer (0.25, 0.25) (0.25, 0.25)
2019-03-19 10:10:18 +02:00
}
2019-06-03 15:27:18 +03:00
myLayout = toggleLayouts zoom workspaceLayouts
2019-03-19 10:10:18 +02:00
where
2019-06-03 15:27:18 +03:00
zoom = renamed [Replace "Zoom"] (noBorders Full)
workspaceLayouts = onWorkspace "web" webLayout $
onWorkspace "dynamics" webLayout $
onWorkspace "pdf" pdfLayout $
onWorkspace "documents" documentLayout $
onWorkspace "mail" mailLayout
defLayout
2019-03-19 10:10:18 +02:00
-- Default layout
defLayout = tiled ||| tabLayout ||| readLayout ||| bspLayout ||| vimLayout ||| spiral (6/7) ||| Full
-- Pdfs are restricted to tabs
vimLayout = Mirror (mastered (1/100) (4/5) Accordion)
pdfLayout = readLayout ||| tiled ||| tabLayout
readLayout = renamed [Replace "2/3"] (dwmStyle shrinkText myTabConfig (mastered (1/100) (2/3) Accordion))
bspLayout = renamed [Replace "master bsp"] (dwmStyle shrinkText myTabConfig (mastered (1/100) (2/3) (Mirror emptyBSP)))
-- Documents are by default tabs, but have looser restrictions
documentLayout = tabLayout ||| Full ||| tiled ||| Mirror tiled
-- Web is either tabbed, full, or tiled
webLayout = readLayout ||| tabLayout ||| Full ||| tiled
tiled = Tall nmaster delta ratio
-- I need to restrict the type or type inferencer can't deduce type classes
tabLayout :: ModifiedLayout (Decoration TabbedDecoration DefaultShrinker) Simplest Window
tabLayout = tabbed shrinkText myTabConfig
mailLayout = readLayout ||| tabLayout
delta = 3/100
ratio = 1/2
nmaster = 1